[llvm] r354962 - [llvm-objcopy] - Check for invalidated relocations when removing a section.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 27 03:18:27 PST 2019


Author: grimar
Date: Wed Feb 27 03:18:27 2019
New Revision: 354962

URL: http://llvm.org/viewvc/llvm-project?rev=354962&view=rev
Log:
[llvm-objcopy] - Check for invalidated relocations when removing a section.

This is https://bugs.llvm.org/show_bug.cgi?id=40818

Removing a section that is used by relocation is an error
we did not report. The patch fixes that.

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

Added:
    llvm/trunk/test/tools/llvm-objcopy/ELF/strip-section-err.test
Modified:
    llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp
    llvm/trunk/tools/llvm-objcopy/ELF/Object.h

Added: llvm/trunk/test/tools/llvm-objcopy/ELF/strip-section-err.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/strip-section-err.test?rev=354962&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/strip-section-err.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/strip-section-err.test Wed Feb 27 03:18:27 2019
@@ -0,0 +1,51 @@
+## Check we cannot remove a section containing symbols
+## referenced by relocations contained in the object.
+
+# RUN: yaml2obj %s > %t1
+# RUN: not llvm-objcopy -R .data %t1 2>&1 | FileCheck %s
+# CHECK: error: Section .data cannot be removed because of symbol 'foo' used by the relocation patching offset 0x1 from section .rela.text.
+
+## Check the behavior when we also remove the relocation section.
+## We have no reference in this case and hence no error should be emitted.
+
+# RUN: yaml2obj %s > %t2
+# RUN: llvm-objcopy -R .data -R .rela.text %t2 %t3
+# RUN: llvm-objdump --section-headers %t3 | FileCheck %s --check-prefix=NOSEC
+# NOSEC-NOT: .data
+# NOSEC-NOT: .rela.text
+
+--- !ELF
+FileHeader:      
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:        
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         E800000000
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Link:            .symtab
+    AddressAlign:    0x0000000000000008
+    EntSize:         0x0000000000000018
+    Info:            .text
+    Relocations:     
+      - Offset:          0x0000000000000001
+        Symbol:          foo
+        Type:            R_X86_64_GOTPCREL
+        Addend:          -4
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         '0102'
+Symbols:         
+  Local:           
+    - Name:            foo
+      Section:         .data
+      Value:           0x0000000000000001
+DynamicSymbols:  {}
+...

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=354962&r1=354961&r2=354962&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/Object.cpp Wed Feb 27 03:18:27 2019
@@ -546,14 +546,25 @@ void SymbolTableSection::accept(MutableS
   Visitor.visit(*this);
 }
 
-template <class SymTabType>
-Error RelocSectionWithSymtabBase<SymTabType>::removeSectionReferences(
+Error RelocationSection::removeSectionReferences(
     function_ref<bool(const SectionBase *)> ToRemove) {
   if (ToRemove(Symbols))
     return createStringError(llvm::errc::invalid_argument,
                              "Symbol table %s cannot be removed because it is "
                              "referenced by the relocation section %s.",
                              Symbols->Name.data(), this->Name.data());
+
+  for (const Relocation &R : Relocations) {
+    if (!R.RelocSymbol->DefinedIn || !ToRemove(R.RelocSymbol->DefinedIn))
+      continue;
+    return createStringError(
+        llvm::errc::invalid_argument,
+        "Section %s cannot be removed because of symbol '%s' "
+        "used by the relocation patching offset 0x%" PRIx64 " from section %s.",
+        R.RelocSymbol->DefinedIn->Name.data(), R.RelocSymbol->Name.c_str(),
+        R.Offset, this->Name.data());
+  }
+
   return Error::success();
 }
 
@@ -1361,12 +1372,20 @@ Error Object::removeSections(
       Segment->removeSection(RemoveSec.get());
     RemoveSections.insert(RemoveSec.get());
   }
-  for (auto &KeepSec : make_range(std::begin(Sections), Iter))
+
+  // For each section that remains alive, we want to remove the dead references.
+  // This either might update the content of the section (e.g. remove symbols
+  // from symbol table that belongs to removed section) or trigger an error if
+  // a live section critically depends on a section being removed somehow
+  // (e.g. the removed section is referenced by a relocation).
+  for (auto &KeepSec : make_range(std::begin(Sections), Iter)) {
     if (Error E = KeepSec->removeSectionReferences(
             [&RemoveSections](const SectionBase *Sec) {
               return RemoveSections.find(Sec) != RemoveSections.end();
             }))
       return E;
+  }
+
   // Now finally get rid of them all togethor.
   Sections.erase(Iter, std::end(Sections));
   return Error::success();

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=354962&r1=354961&r2=354962&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/ELF/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/ELF/Object.h Wed Feb 27 03:18:27 2019
@@ -570,15 +570,14 @@ public:
 // that code between the two symbol table types.
 template <class SymTabType>
 class RelocSectionWithSymtabBase : public RelocationSectionBase {
-  SymTabType *Symbols = nullptr;
   void setSymTab(SymTabType *SymTab) { Symbols = SymTab; }
 
 protected:
   RelocSectionWithSymtabBase() = default;
 
+  SymTabType *Symbols = nullptr;
+
 public:
-  Error removeSectionReferences(
-      function_ref<bool(const SectionBase *)> ToRemove) override;
   void initialize(SectionTableRef SecTable) override;
   void finalize() override;
 };
@@ -593,6 +592,8 @@ public:
   void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
   void accept(SectionVisitor &Visitor) const override;
   void accept(MutableSectionVisitor &Visitor) override;
+  Error removeSectionReferences(
+      function_ref<bool(const SectionBase *)> ToRemove) override;
   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
   void markSymbols() override;
 




More information about the llvm-commits mailing list