mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-04 17:56:53 +00:00
[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
This commit is contained in:
parent
1843ad6f11
commit
374396ccbc
164
test/tools/llvm-objcopy/localize-hidden.test
Normal file
164
test/tools/llvm-objcopy/localize-hidden.test
Normal file
@ -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:]
|
@ -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>(
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user