1 //===- xray-fc-account.cpp: XRay Function Call Accounting Tool ------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Implementation of the helper tools dealing with XRay-generated function ids. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "func-id-helper.h" 14 #include "llvm/Support/Path.h" 15 #include <sstream> 16 17 using namespace llvm; 18 using namespace xray; 19 20 std::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const { 21 auto CacheIt = CachedNames.find(FuncId); 22 if (CacheIt != CachedNames.end()) 23 return CacheIt->second; 24 25 std::ostringstream F; 26 auto It = FunctionAddresses.find(FuncId); 27 if (It == FunctionAddresses.end()) { 28 F << "#" << FuncId; 29 return F.str(); 30 } 31 32 object::SectionedAddress ModuleAddress; 33 ModuleAddress.Address = It->second; 34 // TODO: set proper section index here. 35 // object::SectionedAddress::UndefSection works for only absolute addresses. 36 ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 37 if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) { 38 auto &DI = *ResOrErr; 39 if (DI.FunctionName == DILineInfo::BadString) 40 F << "@(" << std::hex << It->second << ")"; 41 else 42 F << DI.FunctionName; 43 } else 44 handleAllErrors(ResOrErr.takeError(), [&](const ErrorInfoBase &) { 45 F << "@(" << std::hex << It->second << ")"; 46 }); 47 48 auto S = F.str(); 49 CachedNames[FuncId] = S; 50 return S; 51 } 52 53 std::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const { 54 auto It = FunctionAddresses.find(FuncId); 55 if (It == FunctionAddresses.end()) 56 return "(unknown)"; 57 58 std::ostringstream F; 59 object::SectionedAddress ModuleAddress; 60 ModuleAddress.Address = It->second; 61 // TODO: set proper section index here. 62 // object::SectionedAddress::UndefSection works for only absolute addresses. 63 ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 64 auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress); 65 if (!ResOrErr) { 66 consumeError(ResOrErr.takeError()); 67 return "(unknown)"; 68 } 69 70 auto &DI = *ResOrErr; 71 F << sys::path::filename(DI.FileName).str() << ":" << DI.Line << ":" 72 << DI.Column; 73 74 return F.str(); 75 } 76