diff options
| author | Jake Ehrlich <jakehehrlich@google.com> | 2018-01-05 19:19:09 +0000 |
|---|---|---|
| committer | Jake Ehrlich <jakehehrlich@google.com> | 2018-01-05 19:19:09 +0000 |
| commit | 27a29b0290065c44ceab765ac4eb47459bcf1833 (patch) | |
| tree | 5776e3bec802f020fa2ebd3b5fddab2fdc4c1555 /llvm | |
| parent | 6047858270b2fe122563da0d02053a84d869cbb6 (diff) | |
| download | bcm5719-llvm-27a29b0290065c44ceab765ac4eb47459bcf1833.tar.gz bcm5719-llvm-27a29b0290065c44ceab765ac4eb47459bcf1833.zip | |
[llvm-objcopy] Add --localize-hidden option
This change adds support in llvm-objcopy for GNU objcopy's --localize-hidden
option. This option changes every hidden or internal symbol into a local symbol.
llvm-svn: 321884
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/test/tools/llvm-objcopy/localize-hidden.test | 164 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 19 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 3 | ||||
| -rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 12 |
4 files changed, 197 insertions, 1 deletions
diff --git a/llvm/test/tools/llvm-objcopy/localize-hidden.test b/llvm/test/tools/llvm-objcopy/localize-hidden.test new file mode 100644 index 00000000000..92577075f07 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/localize-hidden.test @@ -0,0 +1,164 @@ +# RUN: yaml2obj %s > %t +# RUN: llvm-objcopy -localize-hidden %t %t2 +# RUN: llvm-readobj -relocations -symbols %t2 | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x1000 + AddressAlign: 0x0000000000000010 + Size: 64 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + AddressAlign: 0x0000000000000010 + Content: "0000000000000000" + - Name: .rel.text + Type: SHT_REL + Info: .text + Relocations: + - Offset: 0x1000 + Symbol: undefGlobal + Type: R_X86_64_PC32 +Symbols: + Local: + - Name: hiddenLocal + Type: STT_FUNC + Section: .text + Value: 0x1008 + Size: 8 + Visibility: STV_HIDDEN + Weak: + - Name: hiddenWeak + Type: STT_FUNC + Section: .text + Value: 0x1010 + Size: 8 + Visibility: STV_HIDDEN + Global: + - Name: defaultGlobal + Type: STT_FUNC + Size: 8 + Section: .text + Value: 0x1000 + - Name: hiddenGlobal + Type: STT_OBJECT + Section: .data + Value: 0x2006 + Size: 2 + Visibility: STV_HIDDEN + - Name: undefGlobal + Type: STT_FUNC + Size: 8 + - Name: internalGlobal + Type: STT_OBJECT + Section: .data + Value: 0x2002 + Size: 2 + Visibility: STV_INTERNAL + - Name: protectedGlobal + Type: STT_OBJECT + Section: .data + Value: 0x2000 + Size: 4 + Visibility: STV_PROTECTED + +#CHECK: Relocations [ +#CHECK-NEXT: Section (3) .rel.text { +#CHECK-NEXT: 0x1000 R_X86_64_PC32 undefGlobal 0x0 +#CHECK-NEXT: } +#CHECK-NEXT:] + + +#CHECK: Symbols [ +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: +#CHECK-NEXT: Value: 0x0 +#CHECK-NEXT: Size: 0 +#CHECK-NEXT: Binding: Local +#CHECK-NEXT: Type: None +#CHECK-NEXT: Other: 0 +#CHECK-NEXT: Section: Undefined +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: hiddenLocal +#CHECK-NEXT: Value: 0x1008 +#CHECK-NEXT: Size: 8 +#CHECK-NEXT: Binding: Local +#CHECK-NEXT: Type: Function +#CHECK-NEXT: Other [ +#CHECK-NEXT: STV_HIDDEN +#CHECK-NEXT: ] +#CHECK-NEXT: Section: .text +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: hiddenGlobal +#CHECK-NEXT: Value: 0x2006 +#CHECK-NEXT: Size: 2 +#CHECK-NEXT: Binding: Local +#CHECK-NEXT: Type: Object +#CHECK-NEXT: Other [ +#CHECK-NEXT: STV_HIDDEN +#CHECK-NEXT: ] +#CHECK-NEXT: Section: .data +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: internalGlobal +#CHECK-NEXT: Value: 0x2002 +#CHECK-NEXT: Size: 2 +#CHECK-NEXT: Binding: Local +#CHECK-NEXT: Type: Object +#CHECK-NEXT: Other [ +#CHECK-NEXT: STV_INTERNAL +#CHECK-NEXT: ] +#CHECK-NEXT: Section: .data +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: hiddenWeak +#CHECK-NEXT: Value: 0x1010 +#CHECK-NEXT: Size: 8 +#CHECK-NEXT: Binding: Local +#CHECK-NEXT: Type: Function +#CHECK-NEXT: Other [ +#CHECK-NEXT: STV_HIDDEN +#CHECK-NEXT: ] +#CHECK-NEXT: Section: .text +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: defaultGlobal +#CHECK-NEXT: Value: 0x1000 +#CHECK-NEXT: Size: 8 +#CHECK-NEXT: Binding: Global +#CHECK-NEXT: Type: Function +#CHECK-NEXT: Other: 0 +#CHECK-NEXT: Section: .text +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: undefGlobal +#CHECK-NEXT: Value: 0x0 +#CHECK-NEXT: Size: 8 +#CHECK-NEXT: Binding: Global +#CHECK-NEXT: Type: Function +#CHECK-NEXT: Other: 0 +#CHECK-NEXT: Section: +#CHECK-NEXT: } +#CHECK-NEXT: Symbol { +#CHECK-NEXT: Name: protectedGlobal +#CHECK-NEXT: Value: 0x2000 +#CHECK-NEXT: Size: 4 +#CHECK-NEXT: Binding: Global +#CHECK-NEXT: Type: Object +#CHECK-NEXT: Other [ +#CHECK-NEXT: STV_PROTECTED +#CHECK-NEXT: ] +#CHECK-NEXT: Section: .data +#CHECK-NEXT: } +#CHECK-NEXT:] diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index 9e82448187e..a0708ed59b4 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -175,6 +175,25 @@ void SymbolTableSection::removeSectionReferences(const SectionBase *Sec) { Symbols.erase(Iter, std::end(Symbols)); } +void SymbolTableSection::localize( + std::function<bool(const Symbol &)> ToLocalize) { + for (const auto &Sym : Symbols) { + if (ToLocalize(*Sym)) + Sym->Binding = STB_LOCAL; + } + + // Now that the local symbols aren't grouped at the start we have to reorder + // the symbols to respect this property. + std::stable_partition( + std::begin(Symbols), std::end(Symbols), + [](const SymPtr &Sym) { return Sym->Binding == STB_LOCAL; }); + + // Lastly we fix the symbol indexes. + uint32_t Index = 0; + for (auto &Sym : Symbols) + Sym->Index = Index++; +} + void SymbolTableSection::initialize(SectionTableRef SecTable) { Size = 0; setStrTab(SecTable.getSectionOfType<StringTableSection>( diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 639f0f29ceb..17ea6c9413b 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -214,6 +214,7 @@ public: const SectionBase *getStrTab() const { return SymbolNames; } const Symbol *getSymbolByIndex(uint32_t Index) const; void removeSectionReferences(const SectionBase *Sec) override; + void localize(std::function<bool(const Symbol &)> ToLocalize); void initialize(SectionTableRef SecTable) override; void finalize() override; @@ -384,7 +385,7 @@ public: Object(const object::ELFObjectFile<ELFT> &Obj); virtual ~Object() = default; - const SymbolTableSection *getSymTab() const { return SymbolTable; } + SymbolTableSection *getSymTab() const { return SymbolTable; } const SectionBase *getSectionHeaderStrTab() const { return SectionNames; } void removeSections(std::function<bool(const SectionBase &)> ToRemove); void addSection(StringRef SecName, ArrayRef<uint8_t> Data); diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 20ce93bb40e..eb1d0de90d5 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -117,6 +117,10 @@ static cl::list<std::string> AddSection( "add-section", cl::desc("Make a section named <section> with the contents of <file>."), cl::value_desc("section=file")); +static cl::opt<bool> LocalizeHidden( + "localize-hidden", + cl::desc( + "Mark all symbols that have hidden or internal visibility as local")); using SectionPred = std::function<bool(const SectionBase &Sec)>; @@ -180,6 +184,14 @@ template <class ELFT> void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) { if (!SplitDWO.empty()) SplitDWOToFile<ELFT>(ObjFile, SplitDWO.getValue()); + // Localize: + + if (LocalizeHidden) { + Obj->getSymTab()->localize([](const Symbol &Sym) { + return Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL; + }); + } + SectionPred RemovePred = [](const SectionBase &) { return false; }; // Removes: |

