From 52db4335b3a121333f8954ee27d0f09c1596a46b Mon Sep 17 00:00:00 2001 From: Alexander Shaposhnikov Date: Fri, 20 Apr 2018 20:46:04 +0000 Subject: [PATCH] [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 --- llvm/test/tools/llvm-objcopy/armexidx-link.test | 48 ++++++++++++++++++++++ .../llvm-objcopy/dynsym-error-remove-strtab.test | 2 +- llvm/tools/llvm-objcopy/Object.cpp | 27 +++++------- llvm/tools/llvm-objcopy/Object.h | 27 ++++-------- 4 files changed, 69 insertions(+), 35 deletions(-) create mode 100644 llvm/test/tools/llvm-objcopy/armexidx-link.test 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 0000000..ec942a1 --- /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 ef6ef24..a6df5df 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 e4c268d..c7ce230 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(S) || isa(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 bf8b522..ddc0da1 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 Contents; + SectionBase *LinkSection = nullptr; public: explicit Section(ArrayRef 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 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 Data) - : SectionWithStrTab(Data) {} + explicit DynamicSymbolTableSection(ArrayRef 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 Data) : SectionWithStrTab(Data) {} + explicit DynamicSection(ArrayRef Data) : Section(Data) {} static bool classof(const SectionBase *S) { return S->Type == ELF::SHT_DYNAMIC; -- 2.7.4