diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/peicode.h | 74 |
2 files changed, 37 insertions, 44 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 60b19c3..c841163 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2001-02-06 H.J. Lu <hjl@gnu.org> + + * 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. + 2001-02-06 Kazu Hirata <kazu@hxi.com> * elf-m10200.c: Fix formatting. diff --git a/bfd/peicode.h b/bfd/peicode.h index 4a022f2..666e68c 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -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 type (0x%x) in Import Library Format arc 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) { |