summaryrefslogtreecommitdiff
path: root/bfd/peicode.h
diff options
context:
space:
mode:
authorKai Tietz <kai.tietz@onevision.com>2013-03-21 14:07:08 +0000
committerKai Tietz <kai.tietz@onevision.com>2013-03-21 14:07:08 +0000
commitce63b7b388b808bf574fe2d1de675b038857312e (patch)
tree358cd88b0a6ffb93939d935e83e15113d38763f5 /bfd/peicode.h
parent31fd86f1cf4e96c59614385d8038ed521f31ee1e (diff)
downloadbinutils-ce63b7b388b808bf574fe2d1de675b038857312e.tar.gz
binutils-ce63b7b388b808bf574fe2d1de675b038857312e.tar.bz2
binutils-ce63b7b388b808bf574fe2d1de675b038857312e.zip
* 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.
Diffstat (limited to 'bfd/peicode.h')
-rw-r--r--bfd/peicode.h46
1 files changed, 39 insertions, 7 deletions
diff --git a/bfd/peicode.h b/bfd/peicode.h
index f1d45caf16a..66c8198bffc 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