[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:
Eugene Leviant 2019-07-23 08:03:30 +00:00
parent 78b5e9bc25
commit c7e6d14c6c
8 changed files with 51 additions and 88 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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