diff --git a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test --- a/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test +++ b/llvm/test/tools/llvm-readobj/ELF/bb-addr-map.test @@ -17,6 +17,7 @@ # LLVM: BBAddrMap [ # LLVM-NEXT: Function { # LLVM-NEXT: At: [[ADDR]] +# LLVM-NEXT: Name: ? # LLVM-NEXT: BB entries [ # LLVM-NEXT: { # LLVM-NEXT: Offset: 0x0 @@ -38,6 +39,7 @@ # LLVM-NEXT: } # LLVM-NEXT: Function { # LLVM-NEXT: At: 0x22222 +# LLVM-NEXT: Name: foo # LLVM-NEXT: BB entries [ # LLVM-NEXT: { # LLVM-NEXT: Offset: 0x6 @@ -53,6 +55,7 @@ # LLVM-NEXT: BBAddrMap [ # LLVM-NEXT: Function { # LLVM-NEXT: At: 0x33333 +# LLVM-NEXT: Name: bar # LLVM-NEXT: BB entries [ # LLVM-NEXT: { # LLVM-NEXT: Offset: 0x9 @@ -69,14 +72,15 @@ # GNU: GNUStyle::printBBAddrMaps not implemented # TRUNCATED: BBAddrMap [ -# TRUNCATED-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 1: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end +# TRUNCATED-NEXT: warning: '[[FILE]]': unable to dump SHT_LLVM_BB_ADDR_MAP section with index 3: unable to decode LEB128 at offset [[OFFSET]]: malformed uleb128, extends past end # TRUNCATED-NEXT: ] ## Check that the other valid section is properly dumped. # TRUNCATED-NEXT: BBAddrMap [ # TRUNCATED-NEXT: Function { -# TRUNCATED-NEXT: At: 0x33333 -# TRUNCATED-NEXT: BB entries [ -# TRUNCATED-NEXT: { +# TRUNCATED-NEXT: At: 0x33333 +# TRUNCATED-NEXT: Name: bar +# TRUNCATED-NEXT: BB entries [ +# TRUNCATED-NEXT: { # TRUNCATED-NEXT: Offset: 0x9 # TRUNCATED-NEXT: Size: 0xA # TRUNCATED-NEXT: HasReturn: Yes @@ -94,9 +98,16 @@ Data: ELFDATA2LSB Type: ET_EXEC Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [SHF_ALLOC] + - Name: .text.bar + Type: SHT_PROGBITS + Flags: [SHF_ALLOC] - Name: bb_addr_map_1 Type: SHT_LLVM_BB_ADDR_MAP ShSize: [[SIZE=]] + Link: .text Entries: - Address: [[ADDR=0x11111]] BBEntries: @@ -116,9 +127,19 @@ Size: 16 - Name: bb_addr_map_2 Type: SHT_LLVM_BB_ADDR_MAP + Link: .text.bar Entries: - Address: 0x33333 BBEntries: - AddressOffset: 0x9 Size: 0xa Metadata: 0xb +Symbols: + - Name: foo + Section: .text + Type: STT_FUNC + Value: 0x22222 + - Name: bar + Section: .text.bar + Type: STT_FUNC + Value: 0x33333 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -298,6 +298,13 @@ std::vector getGroups(); + // Returns the function symbol index for the given address. Matches the + // symbol's section with FunctionSec when specified. + // Returns None if no function symbol can be found for the address or in case + // it is not defined in the specified section. + Optional + getFunctionSymbolIndex(uint64_t SymValue, + Optional FunctionSec); bool printFunctionStackSize(uint64_t SymValue, Optional FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, @@ -5701,10 +5708,8 @@ } template -bool ELFDumper::printFunctionStackSize( - uint64_t SymValue, Optional FunctionSec, - const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { - uint32_t FuncSymIndex = 0; +Optional ELFDumper::getFunctionSymbolIndex( + uint64_t SymValue, Optional FunctionSec) { if (this->DotSymtabSec) { if (Expected SymsOrError = Obj.symbols(this->DotSymtabSec)) { uint32_t Index = (uint32_t)-1; @@ -5722,7 +5727,7 @@ std::string Name = this->getStaticSymbolName(Index); reportUniqueWarning("unable to get address of symbol '" + Name + "': " + toString(SymAddrOrErr.takeError())); - break; + return None; } // Check if the symbol is in the right section. FunctionSec == None @@ -5739,26 +5744,33 @@ // untested. reportUniqueWarning("unable to get section of symbol '" + Name + "': " + toString(SecOrErr.takeError())); - break; + return None; } } - FuncSymIndex = Index; - break; + return Index; } } else { reportUniqueWarning("unable to read the symbol table: " + toString(SymsOrError.takeError())); } } + return None; +} +template +bool ELFDumper::printFunctionStackSize( + uint64_t SymValue, Optional FunctionSec, + const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { + Optional FuncSymIndex = + this->getFunctionSymbolIndex(SymValue, FunctionSec); std::string FuncName = "?"; if (!FuncSymIndex) reportUniqueWarning( "could not identify function symbol for stack size entry in " + describe(StackSizeSec)); else - FuncName = this->getStaticSymbolName(FuncSymIndex); + FuncName = this->getStaticSymbolName(*FuncSymIndex); // Extract the size. The expectation is that Offset is pointing to the right // place, i.e. past the function address. @@ -6694,9 +6706,14 @@ } template void LLVMELFDumper::printBBAddrMaps() { + bool IsRelocatable = this->Obj.getHeader().e_type == ELF::ET_REL; for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { if (Sec.sh_type != SHT_LLVM_BB_ADDR_MAP) continue; + Optional FunctionSec = None; + if (IsRelocatable) + FunctionSec = + unwrapOrError(this->FileName, this->Obj.getSection(Sec.sh_link)); ListScope L(W, "BBAddrMap"); Expected> BBAddrMapOrErr = this->Obj.decodeBBAddrMap(Sec); @@ -6708,6 +6725,17 @@ for (const Elf_BBAddrMap &AM : *BBAddrMapOrErr) { DictScope D(W, "Function"); W.printHex("At", AM.Addr); + Optional FuncSymIndex = + this->getFunctionSymbolIndex(AM.Addr, FunctionSec); + std::string FuncName = "?"; + if (FuncSymIndex == None) + this->reportUniqueWarning( + "could not identify function symbol for address (0x" + + Twine::utohexstr(AM.Addr) + ") in " + this->describe(Sec)); + else + FuncName = this->getStaticSymbolName(*FuncSymIndex); + W.printString("Name", FuncName); + ListScope L(W, "BB entries"); for (const typename Elf_BBAddrMap::BBEntry &BBE : AM.BBEntries) { DictScope L(W);