forked from OSchip/llvm-project
[llvm-objcopy] Allow strip symtab in executables and DSOs
Re-commit of the patch after addressing -Wl,--emit-relocs case. Differential revision: https://reviews.llvm.org/D61672 llvm-svn: 366787
This commit is contained in:
parent
78b5e9bc25
commit
c7e6d14c6c
|
@ -13,7 +13,7 @@
|
|||
# BEFORE: Type: PT_LOAD
|
||||
# BEFORE-NEXT: Offset: 0x240
|
||||
|
||||
# AFTER: SectionHeaderCount: 5
|
||||
# AFTER: SectionHeaderCount: 3
|
||||
# AFTER: Type: PT_LOAD
|
||||
# AFTER-NEXT: Offset: 0x0
|
||||
# AFTER: Type: PT_LOAD
|
||||
|
|
|
@ -87,34 +87,6 @@ Sections:
|
|||
# CHECK: }
|
||||
# CHECK: Section {
|
||||
# CHECK: Index: 4
|
||||
# CHECK: Name: .symtab
|
||||
# CHECK: Type: SHT_SYMTAB (0x2)
|
||||
# CHECK: Flags [ (0x0)
|
||||
# CHECK: ]
|
||||
# CHECK: Address: 0x0
|
||||
# CHECK: Offset:
|
||||
# CHECK: Size:
|
||||
# CHECK: Link: 5
|
||||
# CHECK: Info: 1
|
||||
# CHECK: AddressAlignment: 8
|
||||
# CHECK: EntrySize: 24
|
||||
# CHECK: }
|
||||
# CHECK: Section {
|
||||
# CHECK: Index: 5
|
||||
# CHECK: Name: .strtab
|
||||
# CHECK: Type: SHT_STRTAB (0x3)
|
||||
# CHECK: Flags [ (0x0)
|
||||
# CHECK: ]
|
||||
# CHECK: Address: 0x0
|
||||
# CHECK: Offset:
|
||||
# CHECK: Size:
|
||||
# CHECK: Link: 0
|
||||
# CHECK: Info: 0
|
||||
# CHECK: AddressAlignment: 1
|
||||
# CHECK: EntrySize: 0
|
||||
# CHECK: }
|
||||
# CHECK: Section {
|
||||
# CHECK: Index: 6
|
||||
# CHECK: Name: .shstrtab
|
||||
# CHECK: Type: SHT_STRTAB (0x3)
|
||||
# CHECK: Flags [ (0x0)
|
||||
|
|
|
@ -41,7 +41,7 @@ ProgramHeaders:
|
|||
Sections:
|
||||
- Section: .text3
|
||||
|
||||
#CHECK: SectionHeaderCount: 6
|
||||
#CHECK: SectionHeaderCount: 4
|
||||
|
||||
# CHECK: Sections [
|
||||
# CHECK-NEXT: Section {
|
||||
|
@ -92,34 +92,6 @@ ProgramHeaders:
|
|||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index: 3
|
||||
# CHECK-NEXT: Name: .symtab
|
||||
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x0
|
||||
# CHECK-NEXT: Offset: 0x3000
|
||||
# CHECK-NEXT: Size: 24
|
||||
# CHECK-NEXT: Link: 4
|
||||
# CHECK-NEXT: Info: 1
|
||||
# CHECK-NEXT: AddressAlignment: 8
|
||||
# CHECK-NEXT: EntrySize: 24
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index: 4
|
||||
# CHECK-NEXT: Name: .strtab
|
||||
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x0
|
||||
# CHECK-NEXT: Offset: 0x3018
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link: 0
|
||||
# CHECK-NEXT: Info: 0
|
||||
# CHECK-NEXT: AddressAlignment: 1
|
||||
# CHECK-NEXT: EntrySize: 0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index: 5
|
||||
# CHECK-NEXT: Name: .shstrtab
|
||||
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
|
|
|
@ -46,7 +46,7 @@ ProgramHeaders:
|
|||
# Make sure that when we remove a section we overwrite it with zeros
|
||||
# DATA: {{^[^[:blank:]]+}} 00 00 00 00
|
||||
|
||||
#CHECK: SectionHeaderCount: 6
|
||||
#CHECK: SectionHeaderCount: 4
|
||||
|
||||
# CHECK: Sections [
|
||||
# CHECK: Section {
|
||||
|
@ -97,34 +97,6 @@ ProgramHeaders:
|
|||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index: 3
|
||||
# CHECK-NEXT: Name: .symtab
|
||||
# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x0
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link: 4
|
||||
# CHECK-NEXT: Info: 1
|
||||
# CHECK-NEXT: AddressAlignment: 8
|
||||
# CHECK-NEXT: EntrySize: 24
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index: 4
|
||||
# CHECK-NEXT: Name: .strtab
|
||||
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x0
|
||||
# CHECK-NEXT: Offset:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Link: 0
|
||||
# CHECK-NEXT: Info: 0
|
||||
# CHECK-NEXT: AddressAlignment: 1
|
||||
# CHECK-NEXT: EntrySize: 0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Section {
|
||||
# CHECK-NEXT: Index: 5
|
||||
# CHECK-NEXT: Name: .shstrtab
|
||||
# CHECK-NEXT: Type: SHT_STRTAB (0x3)
|
||||
# CHECK-NEXT: Flags [ (0x0)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
## Stripping unneeded symbols from execuatble/DSO should
|
||||
## eliminate the static symbol table, because it's not used
|
||||
## by the dynamic loader.
|
||||
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: cp %t %t1
|
||||
# RUN: llvm-objcopy --strip-unneeded %t %t2
|
||||
# RUN: llvm-readobj --section-headers %t2 | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Symbols:
|
||||
- Name: bar
|
||||
- Name: foo
|
||||
Binding: STB_GLOBAL
|
||||
|
||||
# CHECK-NOT: .symtab
|
|
@ -423,7 +423,7 @@ static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
|
|||
|
||||
if ((Config.StripUnneeded ||
|
||||
is_contained(Config.UnneededSymbolsToRemove, Sym.Name)) &&
|
||||
isUnneededSymbol(Sym))
|
||||
(!Obj.isRelocatable() || isUnneededSymbol(Sym)))
|
||||
return true;
|
||||
|
||||
// We want to remove undefined symbols if all references have been stripped.
|
||||
|
|
|
@ -1995,6 +1995,25 @@ template <class ELFT> Error ELFWriter<ELFT>::write() {
|
|||
return Buf.commit();
|
||||
}
|
||||
|
||||
static Error removeUnneededSections(Object &Obj) {
|
||||
// We can remove an empty symbol table from non-relocatable objects.
|
||||
// Relocatable objects typically have relocation sections whose
|
||||
// sh_link field points to .symtab, so we can't remove .symtab
|
||||
// even if it is empty.
|
||||
if (Obj.isRelocatable() || Obj.SymbolTable == nullptr ||
|
||||
!Obj.SymbolTable->empty())
|
||||
return Error::success();
|
||||
|
||||
// .strtab can be used for section names. In such a case we shouldn't
|
||||
// remove it.
|
||||
auto *StrTab = Obj.SymbolTable->getStrTab() == Obj.SectionNames
|
||||
? nullptr
|
||||
: Obj.SymbolTable->getStrTab();
|
||||
return Obj.removeSections(false, [&](const SectionBase &Sec) {
|
||||
return &Sec == Obj.SymbolTable || &Sec == StrTab;
|
||||
});
|
||||
}
|
||||
|
||||
template <class ELFT> Error ELFWriter<ELFT>::finalize() {
|
||||
// It could happen that SectionNames has been removed and yet the user wants
|
||||
// a section header table output. We need to throw an error if a user tries
|
||||
|
@ -2004,6 +2023,8 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
|
|||
"cannot write section header table because "
|
||||
"section header string table was removed");
|
||||
|
||||
if (Error E = removeUnneededSections(Obj))
|
||||
return E;
|
||||
Obj.sortSections();
|
||||
|
||||
// We need to assign indexes before we perform layout because we need to know
|
||||
|
|
|
@ -1018,6 +1018,7 @@ public:
|
|||
uint32_t Flags;
|
||||
|
||||
bool HadShdrs = true;
|
||||
bool MustBeRelocatable = false;
|
||||
StringTableSection *SectionNames = nullptr;
|
||||
SymbolTableSection *SymbolTable = nullptr;
|
||||
SectionIndexSection *SectionIndexTable = nullptr;
|
||||
|
@ -1043,6 +1044,7 @@ public:
|
|||
template <class T, class... Ts> T &addSection(Ts &&... Args) {
|
||||
auto Sec = llvm::make_unique<T>(std::forward<Ts>(Args)...);
|
||||
auto Ptr = Sec.get();
|
||||
MustBeRelocatable |= isa<RelocationSection>(*Ptr);
|
||||
Sections.emplace_back(std::move(Sec));
|
||||
Ptr->Index = Sections.size();
|
||||
return *Ptr;
|
||||
|
@ -1051,6 +1053,9 @@ public:
|
|||
Segments.emplace_back(llvm::make_unique<Segment>(Data));
|
||||
return *Segments.back();
|
||||
}
|
||||
bool isRelocatable() const {
|
||||
return (Type != ELF::ET_DYN && Type != ELF::ET_EXEC) || MustBeRelocatable;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace elf
|
||||
|
|
Loading…
Reference in New Issue