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.
This commit is contained in:
H.J. Lu 2001-02-06 19:43:19 +00:00
parent 9853629004
commit 15e0ecd9c7
2 changed files with 37 additions and 44 deletions

View file

@ -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.

View file

@ -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)
{