aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/coffgen.c8
-rw-r--r--bfd/peXXigen.c2
-rw-r--r--bfd/peicode.h46
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