@@ -5490,12 +5490,27 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCallGraphInfo() {
54905490 return ;
54915491 using FunctionCallgraphInfo =
54925492 ::FunctionCallgraphInfoImpl<typename ELFT::uint>;
5493- OS << " Call graph information:: \n " ;
5493+
5494+ auto GetFunctionName = [&](typename ELFT::uint EntryPc){
5495+ SmallVector<uint32_t > FuncSymIndexes =
5496+ this ->getSymbolIndexesForFunctionAddress (EntryPc, std::nullopt );
5497+ if (FuncSymIndexes.empty ())
5498+ return std::string (" " );
5499+
5500+ SmallVector<std::string> FuncSymNames;
5501+ for (uint32_t Index : FuncSymIndexes)
5502+ FuncSymNames.push_back (this ->getStaticSymbolName (Index));
5503+ return join (FuncSymNames, " , " );
5504+ };
5505+
5506+ OS << " Per-function call graph information:: \n " ;
54945507 for (const auto &El : this ->FuncCGInfos ) {
54955508 typename ELFT::uint FuncEntryPc = El.first ;
54965509 FunctionCallgraphInfo CGInfo = El.second ;
5497- OS << " \n Function PC:: 0x"
5498- << format (" %lx" , FuncEntryPc); // TODO: Print function name
5510+ std::string FuncSymNames = GetFunctionName (FuncEntryPc);
5511+ if (!FuncSymNames.empty ())
5512+ OS << " \n Function:: " << FuncSymNames;
5513+ OS << " \n Function PC:: " << format (" 0x%lx" , FuncEntryPc);
54995514 OS << " \n FormatVersionNumber:: " << CGInfo.FormatVersionNumber ;
55005515 OS << " \n Function Kind:: " << GetFuntionKindString (CGInfo.Kind );
55015516 if (CGInfo.Kind == FunctionKind::INDIRECT_TARGET_KNOWN_TID)
@@ -5517,9 +5532,15 @@ template <class ELFT> void GNUELFDumper<ELFT>::printCallGraphInfo() {
55175532 if (CGInfo.DirectCallees .size () > 0 ) {
55185533 OS << " \n {" ;
55195534 for (auto CalleePC : CGInfo.DirectCallees ) {
5535+ std::string FuncSymNames = GetFunctionName (CalleePC);
5536+ if (!FuncSymNames.empty ()) {
5537+ OS << " \n " ;
5538+ OS.PadToColumn (2 );
5539+ OS << " Callee:: " << FuncSymNames;
5540+ }
55205541 OS << " \n " ;
55215542 OS.PadToColumn (2 );
5522- OS << " 0x" << format (" %lx" , CalleePC);
5543+ OS << " CalleePC:: 0x" << format (" %lx" , CalleePC);
55235544 }
55245545 OS << " \n }" ;
55255546 }
@@ -8361,22 +8382,41 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCGProfile() {
83618382template <class ELFT > void LLVMELFDumper<ELFT>::printCallGraphInfo() {
83628383 if (!this ->processCallGraphSection ())
83638384 return ;
8385+ if (this ->FuncCGInfos .size () == 0 )
8386+ return ;
8387+ using FunctionCallgraphInfo =
8388+ ::FunctionCallgraphInfoImpl<typename ELFT::uint>;
8389+
8390+ auto GetFunctionName = [&](typename ELFT::uint EntryPc){
8391+ SmallVector<uint32_t > FuncSymIndexes =
8392+ this ->getSymbolIndexesForFunctionAddress (EntryPc, std::nullopt );
8393+ if (FuncSymIndexes.empty ())
8394+ return std::string (" " );
8395+
8396+ SmallVector<std::string> FuncSymNames;
8397+ for (uint32_t Index : FuncSymIndexes)
8398+ FuncSymNames.push_back (this ->getStaticSymbolName (Index));
8399+ return join (FuncSymNames, " , " );
8400+ };
83648401
83658402 DictScope D (this ->W , " callgraph_info" );
83668403
8367- using FunctionCallgraphInfo =
8368- ::FunctionCallgraphInfoImpl<typename ELFT::uint>;
83698404 for (const auto &El : this ->FuncCGInfos ) {
83708405 typename ELFT::uint FuncEntryPc = El.first ;
8371- FunctionCallgraphInfo CGInfo = El.second ;
8372- std::string FuncPCStr = std::to_string (FuncEntryPc);
8373- DictScope FuncScope (this ->W , FuncPCStr); // TODO: Print function name
8406+ FunctionCallgraphInfo CGInfo = El.second ;
8407+ std::string FuncPCStr;
8408+ raw_string_ostream OS (FuncPCStr);
8409+ OS << format (" 0x%lx" , FuncEntryPc);
8410+ DictScope FuncScope (this ->W , OS.str ());
8411+ std::string FuncSymName = GetFunctionName (FuncEntryPc);
8412+ if (!FuncSymName.empty ())
8413+ this ->W .printString (" Name" , FuncSymName);
8414+
83748415 this ->W .printNumber (" FormatVersionNumber" , CGInfo.FormatVersionNumber );
8375- this ->W .printNumber (
8376- " Kind" , (uint64_t )CGInfo.Kind ); // TODO: Print Function Kind String
8377- // GetFuntionKindString(El.second.Kind);
8416+ this ->W .printString (" KindStr" , GetFuntionKindString (CGInfo.Kind ));
8417+ this ->W .printNumber (" Kind" , (uint64_t )CGInfo.Kind );
83788418 if (CGInfo.Kind == FunctionKind::INDIRECT_TARGET_KNOWN_TID)
8379- this ->W .printNumber (" TypeId" , CGInfo.FunctionTypeId );
8419+ this ->W .printHex (" TypeId" , CGInfo.FunctionTypeId );
83808420 this ->W .printNumber (" NumIndirectCallSites" ,
83818421 CGInfo.IndirectCallsites .size ());
83828422 if (CGInfo.IndirectCallsites .size () > 0 ) {
@@ -8388,8 +8428,15 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printCallGraphInfo() {
83888428 }
83898429 }
83908430 this ->W .printNumber (" NumDirectCallSites" , CGInfo.DirectCallees .size ());
8391- if (CGInfo.DirectCallees .size () > 0 )
8392- this ->W .printHexList (" direct_callees" , CGInfo.DirectCallees );
8431+ if (CGInfo.DirectCallees .size () > 0 ) {
8432+ ListScope ICT (this ->W , " direct_callees" );
8433+ for (auto CalleePC : CGInfo.DirectCallees ) {
8434+ this ->W .printHex (" calleePC" , CalleePC);
8435+ std::string CalleeSymName = GetFunctionName (CalleePC);
8436+ if (!CalleeSymName.empty ())
8437+ this ->W .printString (" Name" , CalleeSymName);
8438+ }
8439+ }
83938440 }
83948441}
83958442
0 commit comments