diff options
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/coffgen.c | 8 | ||||
-rw-r--r-- | bfd/peXXigen.c | 2 | ||||
-rw-r--r-- | bfd/peicode.h | 46 |
4 files changed, 56 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 85d5389..a7d29dc 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2013-03-21 Kai Tietz <ktietz@redhat.com> + + * coffgen.c (coff_real_object_p): Make global. + * peicode.h (coff_real_object_p): Add prototype. + (FILHDR): Defined for COFF_IMAGE_WITH_PE as + external_PEI_IMAGE_hdr structure. + (coff_swap_filehdr_in): Handle variable header-size. + * peXXigen.c (_bfd_XXi_swap_aouthdr_in): Just handle amount + of directory-entiries as specified in pe-header. + 2013-03-21 Nick Clifton <nickc@redhat.com> PR sim/15286 diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 7d48ea9..07a527d 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -221,8 +221,12 @@ make_a_section_from_file (bfd *abfd, /* Read in a COFF object and make it into a BFD. This is used by ECOFF as well. */ - -static const bfd_target * +const bfd_target * +coff_real_object_p (bfd *, + unsigned, + struct internal_filehdr *, + struct internal_aouthdr *); +const bfd_target * coff_real_object_p (bfd *abfd, unsigned nscns, struct internal_filehdr *internal_f, diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index 0e0056e..d0f7a96 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -461,7 +461,7 @@ _bfd_XXi_swap_aouthdr_in (bfd * abfd, { int idx; - for (idx = 0; idx < 16; idx++) + for (idx = 0; idx < a->NumberOfRvaAndSizes; idx++) { /* If data directory is empty, rva also should be 0. */ int size = diff --git a/bfd/peicode.h b/bfd/peicode.h index f1d45ca..66c8198 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -123,6 +123,9 @@ typedef struct } pe_ILF_vars; #endif /* COFF_IMAGE_WITH_PE */ + +const bfd_target *coff_real_object_p + (bfd *, unsigned, struct internal_filehdr *, struct internal_aouthdr *); #ifndef NO_COFF_RELOCS static void @@ -159,6 +162,11 @@ coff_swap_reloc_out (bfd * abfd, void * src, void * dst) } #endif /* not NO_COFF_RELOCS */ +#ifdef COFF_IMAGE_WITH_PE +#undef FILHDR +#define FILHDR struct external_PEI_IMAGE_hdr +#endif + static void coff_swap_filehdr_in (bfd * abfd, void * src, void * dst) { @@ -1248,6 +1256,9 @@ pe_bfd_object_p (bfd * abfd) bfd_byte buffer[4]; struct external_PEI_DOS_hdr dos_hdr; struct external_PEI_IMAGE_hdr image_hdr; + struct internal_filehdr internal_f; + struct internal_aouthdr internal_a; + file_ptr opt_hdr_size; file_ptr offset; /* Detect if this a Microsoft Import Library Format element. */ @@ -1303,17 +1314,38 @@ pe_bfd_object_p (bfd * abfd) return NULL; } - /* Here is the hack. coff_object_p wants to read filhsz bytes to - 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, (file_ptr) (offset - sizeof (dos_hdr)), SEEK_SET) != 0) + /* Swap file header, so that we get the location for calling + real_object_p. */ + bfd_coff_swap_filehdr_in (abfd, (PTR)&image_hdr, &internal_f); + + if (! bfd_coff_bad_format_hook (abfd, &internal_f) + || internal_f.f_opthdr > bfd_coff_aoutsz (abfd)) { - if (bfd_get_error () != bfd_error_system_call) - bfd_set_error (bfd_error_wrong_format); + bfd_set_error (bfd_error_wrong_format); return NULL; } - return coff_object_p (abfd); + /* Read the optional header, which has variable size. */ + opt_hdr_size = internal_f.f_opthdr; + + if (opt_hdr_size != 0) + { + PTR opthdr; + + opthdr = bfd_alloc (abfd, opt_hdr_size); + if (opthdr == NULL) + return NULL; + if (bfd_bread (opthdr, opt_hdr_size, abfd) + != (bfd_size_type) opt_hdr_size) + return NULL; + + bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) & internal_a); + } + + return coff_real_object_p (abfd, internal_f.f_nscns, &internal_f, + (opt_hdr_size != 0 + ? &internal_a + : (struct internal_aouthdr *) NULL)); } #define coff_object_p pe_bfd_object_p |