This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 4/4] pe/coff: Don't break .build-id with objcopy/strip


The file offsets in the debug directory need to be recalculated in
_bfd_XX_bfd_copy_private_bfd_data_common(), so that if an objcopy or strip adds
or removes something which causes the file offset of the CV record to change,
those offsets are correct.

(This can happen due to either sections being added or removed before the
.build-id section directly affecting it's file offset, or by the addition or
removal of sufficent section headers to change the first section's file offset
and hence all subsequent sections' file offsets.)

(In general _bfd_XX_bfd_copy_private_bfd_data_common() could be a whole lot
smarter about adjusting the DataDirectory.  If a section corresponding to a RVA
is removed or no longer has any contents, that entry should be cleared?  Offsets
should always be recomputed?)

bfd/ChangeLog:

2014-04-10  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* peXXigen.c (is_vma_in_section, find_section_by_vma): New
	functions.
	(_bfd_XX_bfd_copy_private_bfd_data_common): Recalculate file
	offsets in the debug directory.

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
 bfd/peXXigen.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index c00a655..837ff6c 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -2651,6 +2651,19 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile)
   return TRUE;
 }
 
+static bfd_boolean
+is_vma_in_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
+{
+  bfd_vma addr = *(bfd_vma *)obj;
+  return (addr >= sect->vma) && (addr < (sect->vma + sect->size));
+}
+
+static asection *
+find_section_by_vma (bfd *abfd, bfd_vma addr)
+{
+  return bfd_sections_find_if (abfd, is_vma_in_section, (void *)&addr);
+}
+
 /* Copy any private info we understand from the input bfd
    to the output bfd.  */
 
@@ -2689,6 +2702,43 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd)
       && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED))
     pe_data (obfd)->dont_strip_reloc = 1;
 
+  /* The file offsets contained in the debug directory need rewriting. */
+  if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0)
+    {
+      bfd_vma addr = ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].VirtualAddress + ope->pe_opthdr.ImageBase;
+      asection *section = find_section_by_vma (obfd, addr);
+      bfd_byte *data;
+
+      if (section && bfd_malloc_and_get_section (obfd, section, &data))
+        {
+          unsigned int i;
+          struct external_IMAGE_DEBUG_DIRECTORY *dd = (struct external_IMAGE_DEBUG_DIRECTORY *)(data + (addr - section->vma));
+
+          for (i = 0; i < ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size/sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++)
+            {
+              asection *ddsection;
+              struct external_IMAGE_DEBUG_DIRECTORY *edd = &(dd[i]);
+              struct internal_IMAGE_DEBUG_DIRECTORY idd;
+
+              _bfd_XXi_swap_debugdir_in (obfd, edd, &idd);
+
+              if (idd.AddressOfRawData == 0)
+                continue; /* RVA 0 means only offset is valid, not handled yet. */
+
+              ddsection = find_section_by_vma (obfd, idd.AddressOfRawData + ope->pe_opthdr.ImageBase);
+              if (!ddsection)
+                continue; /* Not in a section! */
+
+              idd.PointerToRawData = ddsection->filepos + (idd.AddressOfRawData + ope->pe_opthdr.ImageBase) - ddsection->vma;
+
+              _bfd_XXi_swap_debugdir_out (obfd, &idd, edd);
+            }
+
+          if (!bfd_set_section_contents (obfd, section, data, 0, section->size))
+            _bfd_error_handler (_("Failed to update file offsets in debug directory"));
+        }
+    }
+
   return TRUE;
 }
 
-- 
1.8.3.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]