mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[llvm-objcopy] Fix null symbol handling
This fixes the bug where strip-all option was leading to a malformed outputted ELF file. Differential Revision: https://reviews.llvm.org/D47414 llvm-svn: 333772
This commit is contained in:
parent
952cd75480
commit
df343b1764
@ -29,6 +29,15 @@ Symbols:
|
||||
|
||||
#STRIPALL: Symbols [
|
||||
#STRIPALL-NEXT: Symbol {
|
||||
#STRIPALL-NEXT: Name:
|
||||
#STRIPALL-NEXT: Value: 0x0
|
||||
#STRIPALL-NEXT: Size: 0
|
||||
#STRIPALL-NEXT: Binding: Local
|
||||
#STRIPALL-NEXT: Type: None
|
||||
#STRIPALL-NEXT: Other: 0
|
||||
#STRIPALL-NEXT: Section: Undefined
|
||||
#STRIPALL-NEXT: }
|
||||
#STRIPALL-NEXT: Symbol {
|
||||
#STRIPALL-NEXT: Name: foo
|
||||
#STRIPALL-NEXT: Value: 0x0
|
||||
#STRIPALL-NEXT: Size: 0
|
||||
|
28
test/tools/llvm-objcopy/null-symbol.test
Normal file
28
test/tools/llvm-objcopy/null-symbol.test
Normal file
@ -0,0 +1,28 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-objcopy %t %t2
|
||||
# RUN: llvm-readobj -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: 8
|
||||
|
||||
#CHECK: Symbols [
|
||||
#CHECK-NEXT: Symbol {
|
||||
#CHECK-NEXT: Name: (0)
|
||||
#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: }
|
@ -58,6 +58,15 @@ Symbols:
|
||||
|
||||
#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: foo
|
||||
#CHECK-NEXT: Value: 0x1000
|
||||
#CHECK-NEXT: Size: 8
|
||||
|
@ -200,8 +200,8 @@ void SymbolTableSection::removeSectionReferences(const SectionBase *Sec) {
|
||||
}
|
||||
|
||||
void SymbolTableSection::updateSymbols(function_ref<void(Symbol &)> Callable) {
|
||||
for (auto &Sym : Symbols)
|
||||
Callable(*Sym);
|
||||
std::for_each(std::begin(Symbols) + 1, std::end(Symbols),
|
||||
[Callable](SymPtr &Sym) { Callable(*Sym); });
|
||||
std::stable_partition(
|
||||
std::begin(Symbols), std::end(Symbols),
|
||||
[](const SymPtr &Sym) { return Sym->Binding == STB_LOCAL; });
|
||||
@ -211,7 +211,7 @@ void SymbolTableSection::updateSymbols(function_ref<void(Symbol &)> Callable) {
|
||||
void SymbolTableSection::removeSymbols(
|
||||
function_ref<bool(const Symbol &)> ToRemove) {
|
||||
Symbols.erase(
|
||||
std::remove_if(std::begin(Symbols), std::end(Symbols),
|
||||
std::remove_if(std::begin(Symbols) + 1, std::end(Symbols),
|
||||
[ToRemove](const SymPtr &Sym) { return ToRemove(*Sym); }),
|
||||
std::end(Symbols));
|
||||
Size = Symbols.size() * EntrySize;
|
||||
|
@ -367,7 +367,8 @@ public:
|
||||
SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility,
|
||||
uint16_t Shndx, uint64_t Sz);
|
||||
void addSymbolNames();
|
||||
bool empty() const { return Symbols.empty(); }
|
||||
// An 'empty' symbol table still contains a null symbol.
|
||||
bool empty() const { return Symbols.size() == 1; }
|
||||
const SectionBase *getStrTab() const { return SymbolNames; }
|
||||
const Symbol *getSymbolByIndex(uint32_t Index) const;
|
||||
Symbol *getSymbolByIndex(uint32_t Index);
|
||||
|
@ -292,9 +292,7 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader,
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: We might handle the 'null symbol' in a different way
|
||||
// by probably handling it the same way as we handle 'null section' ?
|
||||
if (Config.StripUnneeded && !Sym.Referenced && Sym.Index != 0 &&
|
||||
if (Config.StripUnneeded && !Sym.Referenced &&
|
||||
(Sym.Binding == STB_LOCAL || Sym.getShndx() == SHN_UNDEF) &&
|
||||
Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user