[llvm] r355821 - [llvm-objcopy] - Fix --compress-debug-sections when there are relocations.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 11 04:01:24 PDT 2019


Author: grimar
Date: Mon Mar 11 04:01:24 2019
New Revision: 355821

URL: http://llvm.org/viewvc/llvm-project?rev=355821&view=rev
Log:
[llvm-objcopy] - Fix --compress-debug-sections when there are relocations.

When --compress-debug-sections is given,
llvm-objcopy removes the uncompressed sections and adds compressed to the section list.
This makes all the pointers to old sections to be outdated.

Currently, code already has logic for replacing the target sections of the relocation
sections. But we also have to update the relocations by themselves.

This fixes https://bugs.llvm.org/show_bug.cgi?id=40885.

Differential revision: https://reviews.llvm.org/D58960

Modified:
    llvm/trunk/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml
    llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib-gnu.test
    llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test
    llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
    llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp
    llvm/trunk/tools/llvm-objcopy/ELF/Object.h

Modified: llvm/trunk/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml?rev=355821&r1=355820&r2=355821&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/Inputs/compress-debug-sections.yaml Mon Mar 11 04:01:24 2019
@@ -18,4 +18,15 @@ Sections:
       - Offset:          0x1
         Symbol:          .debug_foo
         Type:            R_X86_64_32
+      - Offset:          0x2
+        Symbol:          .notdebug_foo
+        Type:            R_X86_64_32
+Symbols:
+  Global:
+    - Name:    .debug_foo
+      Type:    STT_SECTION
+      Section: .debug_foo
+    - Name:    .notdebug_foo
+      Type:    STT_SECTION
+      Section: .notdebug_foo
 ...

Modified: llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib-gnu.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib-gnu.test?rev=355821&r1=355820&r2=355821&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib-gnu.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib-gnu.test Mon Mar 11 04:01:24 2019
@@ -57,7 +57,8 @@
 
 # CHECK-FLAGS: Relocations [
 # CHECK-FLAGS-NEXT:   .rela.debug_foo {
-# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 - 0x0
+# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 .zdebug_foo 0x0
+# CHECK-FLAGS-NEXT:     0x2 R_X86_64_32 .notdebug_foo 0x0
 # CHECK-FLAGS-NEXT:   }
 # CHECK-FLAGS-NEXT: ]
 

Modified: llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test?rev=355821&r1=355820&r2=355821&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test Mon Mar 11 04:01:24 2019
@@ -57,7 +57,7 @@
 
 # CHECK-FLAGS: Relocations [
 # CHECK-FLAGS-NEXT:   .rela.debug_foo {
-# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 - 0x0
+# CHECK-FLAGS-NEXT:     0x1 R_X86_64_32 .debug_foo 0x0
+# CHECK-FLAGS-NEXT:     0x2 R_X86_64_32 .notdebug_foo 0x0
 # CHECK-FLAGS-NEXT:   }
 # CHECK-FLAGS-NEXT: ]
-

Modified: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp?rev=355821&r1=355820&r2=355821&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp Mon Mar 11 04:01:24 2019
@@ -232,27 +232,24 @@ static void replaceDebugSections(
     const CopyConfig &Config, Object &Obj, SectionPred &RemovePred,
     function_ref<bool(const SectionBase &)> shouldReplace,
     function_ref<SectionBase *(const SectionBase *)> addSection) {
+  // Build a list of the debug sections we are going to replace.
+  // We can't call `addSection` while iterating over sections,
+  // because it would mutate the sections array.
   SmallVector<SectionBase *, 13> ToReplace;
-  SmallVector<RelocationSection *, 13> RelocationSections;
-  for (auto &Sec : Obj.sections()) {
-    if (RelocationSection *R = dyn_cast<RelocationSection>(&Sec)) {
-      if (shouldReplace(*R->getSection()))
-        RelocationSections.push_back(R);
-      continue;
-    }
-
+  for (auto &Sec : Obj.sections())
     if (shouldReplace(Sec))
       ToReplace.push_back(&Sec);
-  }
 
-  for (SectionBase *S : ToReplace) {
-    SectionBase *NewSection = addSection(S);
+  // Build a mapping from original section to a new one.
+  DenseMap<SectionBase *, SectionBase *> FromTo;
+  for (SectionBase *S : ToReplace)
+    FromTo[S] = addSection(S);
 
-    for (RelocationSection *RS : RelocationSections) {
-      if (RS->getSection() == S)
-        RS->setSection(NewSection);
-    }
-  }
+  // Now we want to update the target sections of relocation
+  // sections. Also we will update the relocations themselves
+  // to update the symbol references.
+  for (auto &Sec : Obj.sections())
+    Sec.replaceSectionReferences(FromTo);
 
   RemovePred = [shouldReplace, RemovePred](const SectionBase &Sec) {
     return shouldReplace(Sec) || RemovePred(Sec);

Modified: llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp?rev=355821&r1=355820&r2=355821&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp Mon Mar 11 04:01:24 2019
@@ -62,6 +62,8 @@ Error SectionBase::removeSymbols(functio
 void SectionBase::initialize(SectionTableRef SecTable) {}
 void SectionBase::finalize() {}
 void SectionBase::markSymbols() {}
+void SectionBase::replaceSectionReferences(
+    const DenseMap<SectionBase *, SectionBase *> &) {}
 
 template <class ELFT> void ELFWriter<ELFT>::writeShdr(const SectionBase &Sec) {
   uint8_t *B = Buf.getBufferStart();
@@ -634,6 +636,19 @@ void RelocationSection::markSymbols() {
     Reloc.RelocSymbol->Referenced = true;
 }
 
+void RelocationSection::replaceSectionReferences(
+    const DenseMap<SectionBase *, SectionBase *> &FromTo) {
+  // Update the target section if it was replaced.
+  if (SectionBase *To = FromTo.lookup(SecToApplyRel))
+    SecToApplyRel = To;
+
+  // Change the sections where symbols are defined in if their
+  // original sections were replaced.
+  for (const Relocation &R : Relocations)
+    if (SectionBase *To = FromTo.lookup(R.RelocSymbol->DefinedIn))
+      R.RelocSymbol->DefinedIn = To;
+}
+
 void SectionWriter::visit(const DynamicRelocationSection &Sec) {
   llvm::copy(Sec.Contents,
             Out.getBufferStart() + Sec.Offset);

Modified: llvm/trunk/tools/llvm-objcopy/ELF/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/ELF/Object.h?rev=355821&r1=355820&r2=355821&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/Object.h Mon Mar 11 04:01:24 2019
@@ -280,6 +280,8 @@ public:
   virtual void accept(SectionVisitor &Visitor) const = 0;
   virtual void accept(MutableSectionVisitor &Visitor) = 0;
   virtual void markSymbols();
+  virtual void
+  replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &);
 };
 
 class Segment {
@@ -596,6 +598,8 @@ public:
       function_ref<bool(const SectionBase *)> ToRemove) override;
   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
   void markSymbols() override;
+  void replaceSectionReferences(
+      const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
 
   static bool classof(const SectionBase *S) {
     if (S->Flags & ELF::SHF_ALLOC)




More information about the llvm-commits mailing list