This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: PR binutils/5299: Duplicated sections for COFF/PE
- From: "H.J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Sat, 10 Nov 2007 07:52:16 -0800
- Subject: PATCH: PR binutils/5299: Duplicated sections for COFF/PE
PE target may have duplicated sections due to calling
coff_real_object_p more than once. This patch saves and restores
previous sections if needed. I also fixed a bug where we
failed to update subsystem with
# objcopy -O efi-app-ia32 a.exe e.efi
H.J.
---
2007-11-10 H.J. Lu <hongjiu.lu@intel.com>
* peXXigen.c (_bfd_XX_bfd_copy_private_bfd_data_common): Update
subsystem if needed.
PR binutils/5299
* peicode.h (pe_bfd_object_p): Save and restore previous
sections if needed.
--- bfd/peXXigen.c.dup 2007-07-03 19:35:09.000000000 -0700
+++ bfd/peXXigen.c 2007-11-10 07:45:25.000000000 -0800
@@ -1987,13 +1987,22 @@ _bfd_XX_print_private_bfd_data_common (b
bfd_boolean
_bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
{
+ pe_data_type *ipe, *ope;
+
/* One day we may try to grok other private data. */
if (ibfd->xvec->flavour != bfd_target_coff_flavour
|| obfd->xvec->flavour != bfd_target_coff_flavour)
return TRUE;
- pe_data (obfd)->pe_opthdr = pe_data (ibfd)->pe_opthdr;
- pe_data (obfd)->dll = pe_data (ibfd)->dll;
+ ipe = pe_data (ibfd);
+ ope = pe_data (obfd);
+
+ ope->pe_opthdr = ipe->pe_opthdr;
+ ope->dll = ipe->dll;
+
+ /* We may need to update subsystem. */
+ if (obfd->xvec != ibfd->xvec)
+ ope->pe_opthdr.Subsystem = ope->target_subsystem;
/* For strip: if we removed .reloc, we'll make a real mess of things
if we don't remove this entry as well. */
--- bfd/peicode.h.dup 2007-07-12 11:59:24.000000000 -0700
+++ bfd/peicode.h 2007-11-10 07:48:03.000000000 -0800
@@ -1263,6 +1263,8 @@ pe_bfd_object_p (bfd * abfd)
struct external_PEI_IMAGE_hdr image_hdr;
file_ptr offset;
const bfd_target *target;
+ struct bfd_section *sections, *section_last;
+ unsigned int section_count;
/* Detect if this a Microsoft Import Library Format element. */
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
@@ -1327,6 +1329,23 @@ pe_bfd_object_p (bfd * abfd)
return NULL;
}
+ /* FIXME: coff_object_p will load sections. Do we need to restore
+ the previous sections if the current target doesn't match? */
+ section_count = abfd->section_count;
+ if (section_count != 0)
+ {
+ sections = abfd->sections;
+ section_last = abfd->section_last;
+ abfd->section_count = 0;
+ abfd->sections = NULL;
+ abfd->section_last = NULL;
+ }
+ else
+ {
+ sections = NULL;
+ section_last = NULL;
+ }
+
target = coff_object_p (abfd);
if (target)
{
@@ -1361,8 +1380,17 @@ pe_bfd_object_p (bfd * abfd)
if (efi)
{
+no_match:
/* TARGET_PTR is an EFI backend. Don't match
TARGET with a EFI file. */
+
+ if (section_count != 0)
+ {
+ abfd->section_count = section_count;
+ abfd->sections = sections;
+ abfd->section_last = section_last;
+ }
+
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
@@ -1377,12 +1405,17 @@ pe_bfd_object_p (bfd * abfd)
{
/* TARGET_PTR is a PE backend. Don't match
TARGET with a PE file. */
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
+ goto no_match;
}
}
}
}
+ else if (section_count != 0)
+ {
+ abfd->section_count = section_count;
+ abfd->sections = sections;
+ abfd->section_last = section_last;
+ }
return target;
}