From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KOf5O-0004yH-28 for mharc-grub-devel@gnu.org; Thu, 31 Jul 2008 16:49:22 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KOf5N-0004xR-4e for grub-devel@gnu.org; Thu, 31 Jul 2008 16:49:21 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KOf5M-0004wj-Jf for grub-devel@gnu.org; Thu, 31 Jul 2008 16:49:20 -0400 Received: from [199.232.76.173] (port=38968 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KOf5M-0004wY-3a for grub-devel@gnu.org; Thu, 31 Jul 2008 16:49:20 -0400 Received: from aybabtu.com ([69.60.117.155]:37536) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1KOf5L-0003zW-Sq for grub-devel@gnu.org; Thu, 31 Jul 2008 16:49:20 -0400 Received: from [192.168.10.10] (helo=thorin) by aybabtu.com with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1KOeyX-0005Ux-4y for grub-devel@gnu.org; Thu, 31 Jul 2008 22:42:18 +0200 Received: from rmh by thorin with local (Exim 4.63) (envelope-from ) id 1KOf4M-0006tK-Tb for grub-devel@gnu.org; Thu, 31 Jul 2008 22:48:18 +0200 Date: Thu, 31 Jul 2008 22:48:18 +0200 From: Robert Millan To: grub-devel@gnu.org Message-ID: <20080731204818.GA26465@thorin> References: <20071014134818.GA26460@thorin> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20071014134818.GA26460@thorin> Organization: free as in freedom X-Message-Flag: Worried about Outlook viruses? Switch to Thunderbird! www.mozilla.com/thunderbird X-Debbugs-No-Ack: true User-Agent: Mutt/1.5.13 (2006-08-11) X-detected-kernel: by monty-python.gnu.org: Genre and OS details not recognized. Subject: Re: [PATCH] access phdr header entries like an array X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Jul 2008 20:49:21 -0000 Committed. On Sun, Oct 14, 2007 at 03:48:18PM +0200, Robert Millan wrote: > > This patch makes it easier and more intuitive to access entries in the phdr > header as if it were a C array. It has otherwise no effect on the current > code (other than saving some space for an awkward reason), but is needed to > implement the ability to load segments at an arbitrary address, distinguishing > the relative offset rather than their absolute requested address. > > I have the code for all the dance, including the ability to relocate the > payload later on, but I've chosen to split it up for revision tracking > purposes (besides, the rest needs quite a bit of cleanup yet ;-)). > > I've checked there are no regressions (at least with invaders). If there are > no objections in a few days I'll check it in. > > -- > Robert Millan > > I know my rights; I want my phone call! > What use is a phone call, if you are unable to speak? > (as seen on /.) > 2007-10-14 Robert Millan > > * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): When loading > ELF segments, use a macro for arbitrarily accessing any of them instead > of preparing a pointer that allows access to one at a time. > (grub_multiboot_load_elf64): Likewise. > > diff -ur grub2/loader/i386/pc/multiboot.c grub2.phdr_array/loader/i386/pc/multiboot.c > --- grub2/loader/i386/pc/multiboot.c 2007-07-25 21:29:24.000000000 +0200 > +++ grub2.phdr_array/loader/i386/pc/multiboot.c 2007-10-14 15:32:37.000000000 +0200 > @@ -94,7 +94,7 @@ > grub_multiboot_load_elf32 (grub_file_t file, void *buffer) > { > Elf32_Ehdr *ehdr = (Elf32_Ehdr *) buffer; > - Elf32_Phdr *phdr; > + void *phdr_base; > int i; > > if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) > @@ -112,35 +112,38 @@ > > entry = ehdr->e_entry; > > + phdr_base = (void *) buffer + ehdr->e_phoff; > +#define phdr(i) ((Elf32_Phdr *) (phdr_base + (i) * ehdr->e_phentsize)) > + > /* Load every loadable segment in memory. */ > for (i = 0; i < ehdr->e_phnum; i++) > { > - phdr = (Elf32_Phdr *) ((char *) buffer + ehdr->e_phoff > - + i * ehdr->e_phentsize); > - if (phdr->p_type == PT_LOAD) > + if (phdr(i)->p_type == PT_LOAD) > { > /* The segment should fit in the area reserved for the OS. */ > - if ((phdr->p_paddr < grub_os_area_addr) > - || (phdr->p_paddr + phdr->p_memsz > + if ((phdr(i)->p_paddr < grub_os_area_addr) > + || (phdr(i)->p_paddr + phdr(i)->p_memsz > > grub_os_area_addr + grub_os_area_size)) > return grub_error (GRUB_ERR_BAD_OS, > "segment doesn't fit in memory reserved for the OS"); > > - if (grub_file_seek (file, (grub_off_t) phdr->p_offset) > + if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset) > == (grub_off_t) -1) > return grub_error (GRUB_ERR_BAD_OS, > "invalid offset in program header"); > > - if (grub_file_read (file, (void *) phdr->p_paddr, phdr->p_filesz) > - != (grub_ssize_t) phdr->p_filesz) > + if (grub_file_read (file, (void *) phdr(i)->p_paddr, phdr(i)->p_filesz) > + != (grub_ssize_t) phdr(i)->p_filesz) > return grub_error (GRUB_ERR_BAD_OS, > "couldn't read segment from file"); > > - if (phdr->p_filesz < phdr->p_memsz) > - grub_memset ((char *) phdr->p_paddr + phdr->p_filesz, 0, > - phdr->p_memsz - phdr->p_filesz); > + if (phdr(i)->p_filesz < phdr(i)->p_memsz) > + grub_memset ((char *) phdr(i)->p_paddr + phdr(i)->p_filesz, 0, > + phdr(i)->p_memsz - phdr(i)->p_filesz); > } > } > + > +#undef phdr > > return grub_errno; > } > @@ -158,7 +161,7 @@ > grub_multiboot_load_elf64 (grub_file_t file, void *buffer) > { > Elf64_Ehdr *ehdr = (Elf64_Ehdr *) buffer; > - Elf64_Phdr *phdr; > + void *phdr_base; > int i; > > if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) > @@ -186,39 +189,42 @@ > > entry = ehdr->e_entry; > > + phdr_base = (void *) buffer + ehdr->e_phoff; > +#define phdr(i) ((Elf64_Phdr *) (phdr_base + (i) * ehdr->e_phentsize)) > + > /* Load every loadable segment in memory. */ > for (i = 0; i < ehdr->e_phnum; i++) > { > - phdr = (Elf64_Phdr *) ((char *) buffer + ehdr->e_phoff > - + i * ehdr->e_phentsize); > - if (phdr->p_type == PT_LOAD) > + if (phdr(i)->p_type == PT_LOAD) > { > /* The segment should fit in the area reserved for the OS. */ > - if ((phdr->p_paddr < (grub_uint64_t) grub_os_area_addr) > - || (phdr->p_paddr + phdr->p_memsz > + if ((phdr(i)->p_paddr < (grub_uint64_t) grub_os_area_addr) > + || (phdr(i)->p_paddr + phdr(i)->p_memsz > > ((grub_uint64_t) grub_os_area_addr > + (grub_uint64_t) grub_os_area_size))) > return grub_error (GRUB_ERR_BAD_OS, > "segment doesn't fit in memory reserved for the OS"); > > - if (grub_file_seek (file, (grub_off_t) phdr->p_offset) > + if (grub_file_seek (file, (grub_off_t) phdr(i)->p_offset) > == (grub_off_t) -1) > return grub_error (GRUB_ERR_BAD_OS, > "invalid offset in program header"); > > - if (grub_file_read (file, (void *) ((grub_uint32_t) phdr->p_paddr), > - phdr->p_filesz) > - != (grub_ssize_t) phdr->p_filesz) > + if (grub_file_read (file, (void *) ((grub_uint32_t) phdr(i)->p_paddr), > + phdr(i)->p_filesz) > + != (grub_ssize_t) phdr(i)->p_filesz) > return grub_error (GRUB_ERR_BAD_OS, > "couldn't read segment from file"); > > - if (phdr->p_filesz < phdr->p_memsz) > - grub_memset (((char *) ((grub_uint32_t) phdr->p_paddr) > - + phdr->p_filesz), > + if (phdr(i)->p_filesz < phdr(i)->p_memsz) > + grub_memset (((char *) ((grub_uint32_t) phdr(i)->p_paddr) > + + phdr(i)->p_filesz), > 0, > - phdr->p_memsz - phdr->p_filesz); > + phdr(i)->p_memsz - phdr(i)->p_filesz); > } > } > + > +#undef phdr > > return grub_errno; > } > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel -- Robert Millan The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and how) you may access your data; but nobody's threatening your freedom: we still allow you to remove your data and not access it at all."