[llvm-objdump] Match GNU objdump on symbol types shown in disassembly

output.

STT_OBJECT and STT_COMMON are dumped as data, not disassembled.

https://bugs.llvm.org/show_bug.cgi?id=41947

Differential Revision: https://reviews.llvm.org/D62964

llvm-svn: 364211
This commit is contained in:
Yuanfang Chen 2019-06-24 17:47:56 +00:00
parent 9c01eaff6a
commit 6e04b92c89
2 changed files with 62 additions and 16 deletions

View File

@ -22,9 +22,25 @@
# STATIC-EMPTY: # STATIC-EMPTY:
# STATIC-NEXT: 0000000000001002 only_static: # STATIC-NEXT: 0000000000001002 only_static:
# CHECK-NEXT: 1002: # CHECK-NEXT: 1002:
# DYN-EMPTY:
# DYN-NEXT: 0000000000001003 object:
# CHECK-NEXT: 1003: # CHECK-NEXT: 1003:
# DYN-EMPTY:
# DYN-NEXT: 0000000000001004 zero_sized:
# CHECK-NEXT: 1004: # CHECK-NEXT: 1004:
# CHECK-NEXT: 1005:{{.*}} # DYN-EMPTY:
# DYN-NEXT: 0000000000001005 common:
# CHECK-NEXT: 1005:
# DYN-EMPTY:
# DYN-NEXT: 0000000000001006 loos:
# CHECK-NEXT: 1006:
# DYN-EMPTY:
# DYN-NEXT: 0000000000001007 loproc:
# CHECK-NEXT: 1007:
# CHECK-NEXT: 1008:
# CHECK-NEXT: 1009:
# CHECK-NEXT: 100a:
# CHECK-NEXT: 100b:{{.*}}
# CHECK-NOT: {{.}} # CHECK-NOT: {{.}}
--- !ELF --- !ELF
@ -38,7 +54,7 @@ Sections:
Type: SHT_PROGBITS Type: SHT_PROGBITS
Flags: [SHF_ALLOC, SHF_EXECINSTR] Flags: [SHF_ALLOC, SHF_EXECINSTR]
Address: 0x1000 Address: 0x1000
Content: 909090909090 Content: 909090909090909090909090
ProgramHeaders: ProgramHeaders:
- Type: PT_LOAD - Type: PT_LOAD
VAddr: 0x1000 VAddr: 0x1000
@ -64,14 +80,12 @@ DynamicSymbols:
Value: 0x1001 Value: 0x1001
Section: .text Section: .text
Size: 1 Size: 1
Type: STT_FUNC Type: STT_NOTYPE
Binding: STB_GLOBAL Binding: STB_GLOBAL
## The rest of the dynamic symbols won't be used for various reasons. - Name: object
## FIXME: the first two symbols here should be dumped.
## See https://bugs.llvm.org/show_bug.cgi?id=41947
- Name: not_func
Value: 0x1003 Value: 0x1003
Section: .text Section: .text
Size: 1
Type: STT_OBJECT Type: STT_OBJECT
Binding: STB_GLOBAL Binding: STB_GLOBAL
- Name: zero_sized - Name: zero_sized
@ -79,20 +93,45 @@ DynamicSymbols:
Section: .text Section: .text
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
- Name: '' # No name - Name: common
Value: 0x1005 Value: 0x1005
Section: .text Section: .text
Size: 1 Size: 1
Type: STT_COMMON
Binding: STB_GLOBAL
- Name: loos
Value: 0x1006
Section: .text
Size: 1
Type: 10
Binding: STB_GLOBAL
- Name: loproc
Value: 0x1007
Section: .text
Size: 1
Type: 13
Binding: STB_GLOBAL
## The rest of the dynamic symbols won't be used for various reasons.
- Name: section
Value: 0x1008
Section: .text
Size: 1
Type: STT_SECTION
Binding: STB_GLOBAL
- Name: '' # No name
Value: 0x1009
Section: .text
Size: 1
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
- Name: absolute - Name: absolute
Value: 0x1005 Value: 0x100a
Index: SHN_ABS Index: SHN_ABS
Size: 1 Size: 1
Type: STT_FUNC Type: STT_FUNC
Binding: STB_GLOBAL Binding: STB_GLOBAL
- Name: undefined - Name: undefined
Value: 0x1005 Value: 0x100b
Index: SHN_UNDEF Index: SHN_UNDEF
Size: 1 Size: 1
Type: STT_FUNC Type: STT_FUNC

View File

@ -857,10 +857,15 @@ addDynamicElfSymbols(const ELFObjectFile<ELFT> *Obj,
std::map<SectionRef, SectionSymbolsTy> &AllSymbols) { std::map<SectionRef, SectionSymbolsTy> &AllSymbols) {
for (auto Symbol : Obj->getDynamicSymbolIterators()) { for (auto Symbol : Obj->getDynamicSymbolIterators()) {
uint8_t SymbolType = Symbol.getELFType(); uint8_t SymbolType = Symbol.getELFType();
if (SymbolType != ELF::STT_FUNC || Symbol.getSize() == 0) if (SymbolType == ELF::STT_SECTION)
continue; continue;
uint64_t Address = unwrapOrError(Symbol.getAddress(), Obj->getFileName()); uint64_t Address = unwrapOrError(Symbol.getAddress(), Obj->getFileName());
// ELFSymbolRef::getAddress() returns size instead of value for common
// symbols which is not desirable for disassembly output. Overriding.
if (SymbolType == ELF::STT_COMMON)
Address = Obj->getSymbol(Symbol.getRawDataRefImpl())->st_value;
StringRef Name = unwrapOrError(Symbol.getName(), Obj->getFileName()); StringRef Name = unwrapOrError(Symbol.getName(), Obj->getFileName());
if (Name.empty()) if (Name.empty())
continue; continue;
@ -1289,14 +1294,16 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
if (SectionAddr < StartAddress) if (SectionAddr < StartAddress)
Index = std::max<uint64_t>(Index, StartAddress - SectionAddr); Index = std::max<uint64_t>(Index, StartAddress - SectionAddr);
// If there is a data symbol inside an ELF text section and we are // If there is a data/common symbol inside an ELF text section and we are
// only disassembling text (applicable all architectures), we are in a // only disassembling text (applicable all architectures), we are in a
// situation where we must print the data and not disassemble it. // situation where we must print the data and not disassemble it.
if (Obj->isELF() && std::get<2>(Symbols[SI]) == ELF::STT_OBJECT && if (Obj->isELF() && !DisassembleAll && Section.isText()) {
!DisassembleAll && Section.isText()) { uint8_t SymTy = std::get<2>(Symbols[SI]);
if (SymTy == ELF::STT_OBJECT || SymTy == ELF::STT_COMMON) {
dumpELFData(SectionAddr, Index, End, Bytes); dumpELFData(SectionAddr, Index, End, Bytes);
Index = End; Index = End;
} }
}
bool CheckARMELFData = hasMappingSymbols(Obj) && bool CheckARMELFData = hasMappingSymbols(Obj) &&
std::get<2>(Symbols[SI]) != ELF::STT_OBJECT && std::get<2>(Symbols[SI]) != ELF::STT_OBJECT &&