diff options
| author | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-04-20 20:46:04 +0000 | 
|---|---|---|
| committer | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-04-20 20:46:04 +0000 | 
| commit | 52db4335b3a121333f8954ee27d0f09c1596a46b (patch) | |
| tree | e565202e934ff617d526bd282354f1800e2ae2f5 | |
| parent | 334c379e32b8fcc7f73ffaba3baf88a5be29a269 (diff) | |
| download | bcm5719-llvm-52db4335b3a121333f8954ee27d0f09c1596a46b.tar.gz bcm5719-llvm-52db4335b3a121333f8954ee27d0f09c1596a46b.zip  | |
[llvm-objcopy] Fix sh_link
This diff fixes sh_link for various types of sections 
(i.e. for SHT_ARM_EXIDX, SHT_HASH). In particular, this change enables us
to use llvm-objcopy with clang -gsplit-dwarf for the target android-arm.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D45851
llvm-svn: 330478
| -rw-r--r-- | llvm/test/tools/llvm-objcopy/armexidx-link.test | 48 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-objcopy/dynsym-error-remove-strtab.test | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 27 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 27 | 
4 files changed, 69 insertions, 35 deletions
diff --git a/llvm/test/tools/llvm-objcopy/armexidx-link.test b/llvm/test/tools/llvm-objcopy/armexidx-link.test new file mode 100644 index 00000000000..ec942a1e6fc --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/armexidx-link.test @@ -0,0 +1,48 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy -remove-section=.text.bar %t %t2 +# RUN: llvm-readobj -sections %t2 | FileCheck %s + +# CHECK:          Index: 2 +# CHECK-NEXT:     Name: .ARM.exidx.text.foo (1) +# CHECK-NEXT:     Type: SHT_ARM_EXIDX (0x70000001) +# CHECK:          Address: 0x0 +# CHECK-NEXT:     Offset: 0x34 +# CHECK-NEXT:     Size: 0 +# CHECK-NEXT:     Link: 1 +# CHECK-NEXT:     Info: 0 + +--- !ELF +FileHeader:       +  Class:           ELFCLASS32 +  Data:            ELFDATA2LSB +  Type:            ET_REL +  Machine:         EM_ARM +  Flags:           [ EF_ARM_EABI_VER5 ] +Sections:         +  - Name:            .text.bar +    Type:            SHT_PROGBITS +    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ] +    AddressAlign:    0x0000000000000004 +    Content:         '' +  - Name:            .text.foo +    Type:            SHT_PROGBITS +    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ] +    AddressAlign:    0x0000000000000004 +    Content:         '' +  - Name:            .ARM.exidx.text.foo +    Type:            SHT_ARM_EXIDX +    Flags:           [ SHF_ALLOC, SHF_LINK_ORDER ] +    Link:            .text.foo +    AddressAlign:    0x0000000000000004 +    Content:         '' +Symbols:          +  Local:            +    - Name:            .text.bar +      Type:            STT_SECTION +      Section:         .text.bar +    - Name:            .text.foo +      Type:            STT_SECTION +      Section:         .text.foo +    - Name:            .ARM.exidx.text.foo +      Type:            STT_SECTION +      Section:         .ARM.exidx.text.foo diff --git a/llvm/test/tools/llvm-objcopy/dynsym-error-remove-strtab.test b/llvm/test/tools/llvm-objcopy/dynsym-error-remove-strtab.test index ef6ef243295..a6df5dfa885 100644 --- a/llvm/test/tools/llvm-objcopy/dynsym-error-remove-strtab.test +++ b/llvm/test/tools/llvm-objcopy/dynsym-error-remove-strtab.test @@ -1,3 +1,3 @@  # RUN: not llvm-objcopy -R .dynstr %p/Inputs/dynsym.so %t 2>&1 >/dev/null | FileCheck %s -# CHECK: String table .dynstr cannot be removed because it is referenced by the section .dynsym +# CHECK: Section .dynstr cannot be removed because it is referenced by the section .dynsym diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index e4c268d115c..c7ce2309ffb 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -353,9 +353,9 @@ void DynamicRelocationSection::accept(SectionVisitor &Visitor) const {    Visitor.visit(*this);  } -void SectionWithStrTab::removeSectionReferences(const SectionBase *Sec) { -  if (StrTab == Sec) { -    error("String table " + StrTab->Name + +void Section::removeSectionReferences(const SectionBase *Sec) { +  if (LinkSection == Sec) { +    error("Section " + LinkSection->Name +            " cannot be removed because it is "            "referenced by the section " +            this->Name); @@ -367,23 +367,18 @@ void GroupSection::finalize() {    this->Link = SymTab->Index;  } -bool SectionWithStrTab::classof(const SectionBase *S) { -  return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S); +void Section::initialize(SectionTableRef SecTable) { +  if (Link != ELF::SHN_UNDEF) +    LinkSection = +        SecTable.getSection(Link, "Link field value " + Twine(Link) + +                                      " in section " + Name + " is invalid");  } -void SectionWithStrTab::initialize(SectionTableRef SecTable) { -  auto StrTab = -      SecTable.getSection(Link, "Link field value " + Twine(Link) + -                                    " in section " + Name + " is invalid"); -  if (StrTab->Type != SHT_STRTAB) { -    error("Link field value " + Twine(Link) + " in section " + Name + -          " is not a string table"); -  } -  setStrTab(StrTab); +void Section::finalize() { +  if (LinkSection) +    this->Link = LinkSection->Index;  } -void SectionWithStrTab::finalize() { this->Link = StrTab->Index; } -  void GnuDebugLinkSection::init(StringRef File, StringRef Data) {    FileName = sys::path::filename(File);    // The format for the .gnu_debuglink starts with the file name and is diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index bf8b52244d8..ddc0da16aa4 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -259,11 +259,15 @@ class Section : public SectionBase {    MAKE_SEC_WRITER_FRIEND    ArrayRef<uint8_t> Contents; +  SectionBase *LinkSection = nullptr;  public:    explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}    void accept(SectionVisitor &Visitor) const override; +  void removeSectionReferences(const SectionBase *Sec) override; +  void initialize(SectionTableRef SecTable) override; +  void finalize() override;  };  class OwnedDataSection : public SectionBase { @@ -456,7 +460,7 @@ public:    void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }    void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); } -  void initialize(SectionTableRef SecTable) override {}; +  void initialize(SectionTableRef SecTable) override{};    void accept(SectionVisitor &) const override;    void finalize() override; @@ -465,31 +469,18 @@ public:    }  }; -class SectionWithStrTab : public Section { -  const SectionBase *StrTab = nullptr; -  void setStrTab(const SectionBase *StringTable) { StrTab = StringTable; } - -public: -  explicit SectionWithStrTab(ArrayRef<uint8_t> Data) : Section(Data) {} -  void removeSectionReferences(const SectionBase *Sec) override; -  void initialize(SectionTableRef SecTable) override; -  void finalize() override; -  static bool classof(const SectionBase *S); -}; - -class DynamicSymbolTableSection : public SectionWithStrTab { +class DynamicSymbolTableSection : public Section {  public: -  explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) -      : SectionWithStrTab(Data) {} +  explicit DynamicSymbolTableSection(ArrayRef<uint8_t> Data) : Section(Data) {}    static bool classof(const SectionBase *S) {      return S->Type == ELF::SHT_DYNSYM;    }  }; -class DynamicSection : public SectionWithStrTab { +class DynamicSection : public Section {  public: -  explicit DynamicSection(ArrayRef<uint8_t> Data) : SectionWithStrTab(Data) {} +  explicit DynamicSection(ArrayRef<uint8_t> Data) : Section(Data) {}    static bool classof(const SectionBase *S) {      return S->Type == ELF::SHT_DYNAMIC;  | 

