Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Date: Fri, 26 Jan 2001 00:39:03 -0500 From: Christopher Faylor To: cygwin-developers AT cygwin DOT com Subject: Re: [hjl AT valinux DOT com: Re: A PE patch.] Message-ID: <20010126003903.C14969@redhat.com> Reply-To: cygwin-developers AT cygwin DOT com Mail-Followup-To: cygwin-developers AT cygwin DOT com References: <200101242033 DOT PAA16287 AT envy DOT delorie DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.11i In-Reply-To: <200101242033.PAA16287@envy.delorie.com>; from dj@delorie.com on Wed, Jan 24, 2001 at 03:33:44PM -0500 On Wed, Jan 24, 2001 at 03:33:44PM -0500, DJ Delorie wrote: >Could people please look at this patch and try it? The original code >assumed things it shouldn't, and thus you couldn't run, say, objdump >on MS system DLLs. I like the idea about making bfd dynamic, but I >refuse to accept patches to this code without a "gut feeling" that it >will work *and* lots of testing, so the more people test it the >better. Shouldn't the PEI*_header stuff come from some w32api file or other? cgf >------- Start of forwarded message ------- >Date: Wed, 24 Jan 2001 11:15:05 -0800 >From: "H . J . Lu" >To: DJ Delorie >Subject: Re: A PE patch. >Content-Disposition: inline >User-Agent: Mutt/1.2.5i >In-Reply-To: <200101241909 DOT OAA06907 AT greed DOT delorie DOT com>; from dj AT redhat DOT com on Wed, Jan 24, 2001 at 02:09:12PM -0500 >Content-Type: text/plain; charset=us-ascii > >Here is the updated version. There is a bug in my old patch. > >-- >H.J. Lu (hjl AT valinux DOT com) >--- >2001-01-23 H.J. Lu > > * include/coff/pe.h (struct external_PEI_DOS_hdr): New. > (struct external_PEI_IMAGE_hdr): New. > > * bfd/peicode.h (coff_swap_filehdr_in): Remove the e_magic > checking. > (pe_bfd_object_p): Rewrite with external_PEI_DOS_hdr and > external_PEI_IMAGE_hdr. > >Index: include/coff/pe.h >=================================================================== >RCS file: /work/cvs/gnu/binutils/include/coff/pe.h,v >retrieving revision 1.1.1.7 >diff -u -p -r1.1.1.7 pe.h >--- include/coff/pe.h 2000/09/05 17:49:11 1.1.1.7 >+++ include/coff/pe.h 2001/01/24 18:46:34 >@@ -125,6 +125,45 @@ > #undef FILNMLEN > #define FILNMLEN 18 /* # characters in a file name. */ > >+struct external_PEI_DOS_hdr >+{ >+ /* DOS header fields - always at offset zero in the EXE file. */ >+ char e_magic[2]; /* Magic number, 0x5a4d. */ >+ char e_cblp[2]; /* Bytes on last page of file, 0x90. */ >+ char e_cp[2]; /* Pages in file, 0x3. */ >+ char e_crlc[2]; /* Relocations, 0x0. */ >+ char e_cparhdr[2]; /* Size of header in paragraphs, 0x4. */ >+ char e_minalloc[2]; /* Minimum extra paragraphs needed, 0x0. */ >+ char e_maxalloc[2]; /* Maximum extra paragraphs needed, 0xFFFF. */ >+ char e_ss[2]; /* Initial (relative) SS value, 0x0. */ >+ char e_sp[2]; /* Initial SP value, 0xb8. */ >+ char e_csum[2]; /* Checksum, 0x0. */ >+ char e_ip[2]; /* Initial IP value, 0x0. */ >+ char e_cs[2]; /* Initial (relative) CS value, 0x0. */ >+ char e_lfarlc[2]; /* File address of relocation table, 0x40. */ >+ char e_ovno[2]; /* Overlay number, 0x0. */ >+ char e_res[4][2]; /* Reserved words, all 0x0. */ >+ char e_oemid[2]; /* OEM identifier (for e_oeminfo), 0x0. */ >+ char e_oeminfo[2]; /* OEM information; e_oemid specific, 0x0. */ >+ char e_res2[10][2]; /* Reserved words, all 0x0. */ >+ char e_lfanew[4]; /* File address of new exe header, usually 0x80. */ >+ char dos_message[16][4]; /* Other stuff, always follow DOS header. */ >+}; >+ >+struct external_PEI_IMAGE_hdr >+{ >+ char nt_signature[4]; /* required NT signature, 0x4550. */ >+ >+ /* From standard header. */ >+ char f_magic[2]; /* Magic number. */ >+ char f_nscns[2]; /* Number of sections. */ >+ char f_timdat[4]; /* Time & date stamp. */ >+ char f_symptr[4]; /* File pointer to symtab. */ >+ char f_nsyms[4]; /* Number of symtab entries. */ >+ char f_opthdr[2]; /* Sizeof(optional hdr). */ >+ char f_flags[2]; /* Flags. */ >+}; >+ > struct external_PEI_filehdr > { > /* DOS header fields - always at offset zero in the EXE file. */ >Index: bfd/peicode.h >=================================================================== >RCS file: /work/cvs/gnu/binutils/bfd/peicode.h,v >retrieving revision 1.9 >diff -u -p -r1.9 peicode.h >--- bfd/peicode.h 2001/01/23 20:11:14 1.9 >+++ bfd/peicode.h 2001/01/24 18:36:09 >@@ -208,26 +208,6 @@ coff_swap_filehdr_in (abfd, src, dst) > filehdr_dst->f_flags = bfd_h_get_16(abfd, (bfd_byte *)filehdr_src-> f_flags); > filehdr_dst->f_symptr = bfd_h_get_32 (abfd, (bfd_byte *) filehdr_src->f_symptr); > >-#ifdef COFF_IMAGE_WITH_PE >- /* There are really two magic numbers involved; the magic number >- that says this is a NT executable (PEI) and the magic number that >- determines the architecture. The former is DOSMAGIC, stored in >- the e_magic field. The latter is stored in the f_magic field. >- If the NT magic number isn't valid, the architecture magic number >- could be mimicked by some other field (specifically, the number >- of relocs in section 3). Since this routine can only be called >- correctly for a PEI file, check the e_magic number here, and, if >- it doesn't match, clobber the f_magic number so that we don't get >- a false match. */ >-#if 0 >- /* We can't assume that the PE header is at offset 0x80. When it >- isn't, the DOS header isn't read correctly, so we can't assume >- e_magic is set even for valid PE files. */ >- if (bfd_h_get_16 (abfd, (bfd_byte *) filehdr_src->e_magic) != DOSMAGIC) >- filehdr_dst->f_magic = -1; >-#endif >-#endif >- > /* Other people's tools sometimes generate headers with an nsyms but > a zero symptr. */ > if (filehdr_dst->f_nsyms != 0 && filehdr_dst->f_symptr == 0) >@@ -1255,16 +1235,10 @@ _("%s: Recognised but unhandled machine > static const bfd_target * > pe_bfd_object_p (bfd * abfd) > { >- /* We need to handle a PE image correctly. In PE images created by >- the GNU linker, the offset to the COFF header is always the size. >- However, this is not the case in images generated by other PE >- linkers. The PE format stores a four byte offset to the PE >- signature just before the COFF header at location 0x3c of the file. >- We pick up that offset, verify that the PE signature is there, and >- then set ourselves up to read in the COFF header. */ > bfd_byte buffer[4]; >+ struct external_PEI_DOS_hdr dos_hdr; >+ struct external_PEI_IMAGE_hdr image_hdr; > file_ptr offset; >- unsigned long signature; > > /* Detect if this a Microsoft Import Library Format element. */ > if (bfd_seek (abfd, 0x00, SEEK_SET) != 0 >@@ -1275,44 +1249,56 @@ pe_bfd_object_p (bfd * abfd) > return NULL; > } > >- signature = bfd_h_get_32 (abfd, buffer); >- >- if (signature == 0xffff0000) >+ if (bfd_h_get_32 (abfd, buffer) == 0xffff0000) > return pe_ILF_object_p (abfd); > >- if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0 >- || bfd_read (buffer, 1, 4, abfd) != 4) >+ if (bfd_seek (abfd, 0x00, SEEK_SET) != 0 >+ || bfd_read (&dos_hdr, 1, sizeof (dos_hdr), abfd) >+ != sizeof (dos_hdr)) > { > if (bfd_get_error () != bfd_error_system_call) > bfd_set_error (bfd_error_wrong_format); > return NULL; > } > >- offset = bfd_h_get_32 (abfd, buffer); >+ /* There are really two magic numbers involved; the magic number >+ that says this is a NT executable (PEI) and the magic number that >+ determines the architecture. The former is DOSMAGIC, stored in >+ the e_magic field. The latter is stored in the f_magic field. >+ If the NT magic number isn't valid, the architecture magic number >+ could be mimicked by some other field (specifically, the number >+ of relocs in section 3). Since this routine can only be called >+ correctly for a PEI file, check the e_magic number here, and, if >+ it doesn't match, clobber the f_magic number so that we don't get >+ a false match. */ >+ if (bfd_h_get_16 (abfd, (bfd_byte *) dos_hdr.e_magic) != DOSMAGIC) >+ { >+ bfd_set_error (bfd_error_wrong_format); >+ return NULL; >+ } > >- if (bfd_seek (abfd, offset, SEEK_SET) != 0 >- || bfd_read (buffer, 1, 4, abfd) != 4) >+ offset = bfd_h_get_32 (abfd, (bfd_byte *) dos_hdr.e_lfanew); >+ if (bfd_seek (abfd, (file_ptr) offset, SEEK_SET) != 0 >+ || bfd_read (&image_hdr, 1, sizeof (image_hdr), abfd) >+ != sizeof (image_hdr)) > { > if (bfd_get_error () != bfd_error_system_call) > bfd_set_error (bfd_error_wrong_format); > return NULL; > } >- >- signature = bfd_h_get_32 (abfd, buffer); > >- if (signature != 0x4550) >+ if (bfd_h_get_32 (abfd, (bfd_byte *) image_hdr.nt_signature) >+ != 0x4550) > { > bfd_set_error (bfd_error_wrong_format); > return NULL; > } > > /* Here is the hack. coff_object_p wants to read filhsz bytes to >- pick up the COFF header. We adjust so that that will work. 20 >- is the size of the i386 COFF filehdr. */ >+ pick up the COFF header for PE, see "struct external_PEI_filehdr" >+ in include/coff/pe.h. We adjust so that that will work. */ > if (bfd_seek (abfd, >- (bfd_tell (abfd) >- - bfd_coff_filhsz (abfd) >- + 20), >+ (file_ptr) (offset - sizeof (dos_hdr)), > SEEK_SET) > != 0) > { >------- End of forwarded message ------- -- cgf AT cygnus DOT com Red Hat, Inc. http://sources.redhat.com/ http://www.redhat.com/