Move PE format object file detection code into common place.

This commit is contained in:
Nick Clifton 1999-12-17 19:03:09 +00:00
parent eaeaa15ca4
commit cb665cd3e2
4 changed files with 96 additions and 128 deletions

View file

@ -361,3 +361,84 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd)
_bfd_pe_bfd_copy_private_section_data
#define coff_get_symbol_info _bfd_pe_get_symbol_info
static const bfd_target *
pe_bfd_object_p (abfd)
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];
file_ptr offset;
unsigned long signature;
/* Detect if this a Microsoft Import Library Format element. */
if (bfd_seek (abfd, 0x00, SEEK_SET) != 0
|| bfd_read (buffer, 1, 4, abfd) != 4)
{
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 == 0xffff0000)
{
_bfd_error_handler (_("%s: Import Library Format archives are not currently supported"),
bfd_get_filename (abfd));
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
if (bfd_seek (abfd, 0x3c, SEEK_SET) != 0
|| bfd_read (buffer, 1, 4, abfd) != 4)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
offset = bfd_h_get_32 (abfd, buffer);
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|| bfd_read (buffer, 1, 4, abfd) != 4)
{
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)
{
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. */
if (bfd_seek (abfd,
(bfd_tell (abfd)
- bfd_coff_filhsz (abfd)
+ 20),
SEEK_SET)
!= 0)
{
if (bfd_get_error () != bfd_error_system_call)
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
return coff_object_p (abfd);
}
#define coff_object_p pe_bfd_object_p