diff --git a/llvm/test/tools/llvm-objdump/X86/elf-disassemble-dynamic-symbols.test b/llvm/test/tools/llvm-objdump/X86/elf-disassemble-dynamic-symbols.test --- a/llvm/test/tools/llvm-objdump/X86/elf-disassemble-dynamic-symbols.test +++ b/llvm/test/tools/llvm-objdump/X86/elf-disassemble-dynamic-symbols.test @@ -13,18 +13,35 @@ # CHECK: Disassembly of section .text: # CHECK-EMPTY: # STATIC-NEXT: 0000000000001000 .text: -# DYN-NEXT: 0000000000001000 only_dyn: +# DYN-NEXT: 0000000000001000 notype_dyn: # CHECK-NEXT: 1000: # CHECK-EMPTY: # STATIC-NEXT: 0000000000001001 both_static: -# DYN-NEXT: 0000000000001001 both_dyn: +# DYN-NEXT: 0000000000001001 object_dyn: # CHECK-NEXT: 1001: -# STATIC-EMPTY: +# CHECK-EMPTY: # STATIC-NEXT: 0000000000001002 only_static: +# DYN-NEXT: 0000000000001002 func_dyn: # CHECK-NEXT: 1002: +# DYN-EMPTY: +# DYN-NEXT: 0000000000001003 both_func_dyn: # CHECK-NEXT: 1003: +# DYN-EMPTY: +# DYN-NEXT: 0000000000001004 zero_sized_func_dyn: # CHECK-NEXT: 1004: -# CHECK-NEXT: 1005:{{.*}} +# DYN-EMPTY: +# DYN-NEXT: 0000000000001005 common_dyn: +# CHECK-NEXT: 1005: +# DYN-EMPTY: +# DYN-NEXT: 0000000000001006 loos_dyn: +# CHECK-NEXT: 1006: +# DYN-EMPTY: +# DYN-NEXT: 0000000000001007 loproc_dyn: +# CHECK-NEXT: 1007: +# CHECK-NEXT: 1008: +# CHECK-NEXT: 1009: +# CHECK-NEXT: 100a: +# CHECK-NEXT: 100b:{{.*}} # CHECK-NOT: {{.}} --- !ELF @@ -38,7 +55,7 @@ Type: SHT_PROGBITS Flags: [SHF_ALLOC, SHF_EXECINSTR] Address: 0x1000 - Content: 909090909090 + Content: 909090909090909090909090 ProgramHeaders: - Type: PT_LOAD VAddr: 0x1000 @@ -54,45 +71,73 @@ Section: .text Binding: STB_GLOBAL DynamicSymbols: - - Name: only_dyn + - Name: notype_dyn Value: 0x1000 Section: .text Size: 1 - Type: STT_FUNC + Type: STT_NOTYPE Binding: STB_GLOBAL - - Name: both_dyn + - Name: object_dyn Value: 0x1001 Section: .text + Type: STT_OBJECT + Binding: STB_GLOBAL + - Name: func_dyn + Value: 0x1002 + Section: .text Size: 1 Type: STT_FUNC Binding: STB_GLOBAL - ## The rest of the dynamic symbols won't be used for various reasons. - ## FIXME: the first two symbols here should be dumped. - ## See https://bugs.llvm.org/show_bug.cgi?id=41947 - - Name: not_func + - Name: both_func_dyn Value: 0x1003 Section: .text - Type: STT_OBJECT + Size: 1 + Type: STT_FUNC Binding: STB_GLOBAL - - Name: zero_sized + - Name: zero_sized_func_dyn Value: 0x1004 Section: .text Type: STT_FUNC Binding: STB_GLOBAL - - Name: '' # No name + - Name: common_dyn Value: 0x1005 Section: .text Size: 1 + Type: STT_COMMON + Binding: STB_GLOBAL + - Name: loos_dyn + Value: 0x1006 + Section: .text + Size: 1 + Type: 10 + Binding: STB_GLOBAL + - Name: loproc_dyn + 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_dyn + Value: 0x1008 + Section: .text + Size: 1 + Type: STT_SECTION + Binding: STB_GLOBAL + - Name: '' # No name + Value: 0x1009 + Section: .text + Size: 1 Type: STT_FUNC Binding: STB_GLOBAL - Name: absolute - Value: 0x1005 + Value: 0x100a Index: SHN_ABS Size: 1 Type: STT_FUNC Binding: STB_GLOBAL - Name: undefined - Value: 0x1005 + Value: 0x100b Index: SHN_UNDEF Size: 1 Type: STT_FUNC diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -846,10 +846,15 @@ std::map &AllSymbols) { for (auto Symbol : Obj->getDynamicSymbolIterators()) { uint8_t SymbolType = Symbol.getELFType(); - if (SymbolType != ELF::STT_FUNC || Symbol.getSize() == 0) + if (SymbolType == ELF::STT_SECTION) continue; 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()); if (Name.empty()) continue; @@ -1261,13 +1266,15 @@ if (SectionAddr < StartAddress) Index = std::max(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 // situation where we must print the data and not disassemble it. - if (Obj->isELF() && std::get<2>(Symbols[SI]) == ELF::STT_OBJECT && - !DisassembleAll && Section.isText()) { - dumpELFData(SectionAddr, Index, End, Bytes); - Index = End; + if (Obj->isELF() && !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); + Index = End; + } } bool CheckARMELFData = isArmElf(Obj) &&