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/MemoryBuffer.h" 15 #include "llvm/Support/Path.h" 16 #include <sstream> 17 18 using namespace llvm; 19 using namespace xray; 20 21 std::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const { 22 auto CacheIt = CachedNames.find(FuncId); 23 if (CacheIt != CachedNames.end()) 24 return CacheIt->second; 25 26 std::ostringstream F; 27 auto It = FunctionAddresses.find(FuncId); 28 if (It == FunctionAddresses.end()) { 29 F << "#" << FuncId; 30 return F.str(); 31 } 32 33 object::SectionedAddress ModuleAddress; 34 ModuleAddress.Address = It->second; 35 // TODO: set proper section index here. 36 // object::SectionedAddress::UndefSection works for only absolute addresses. 37 ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 38 if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) { 39 auto &DI = *ResOrErr; 40 if (DI.FunctionName == DILineInfo::BadString) 41 F << "@(" << std::hex << It->second << ")"; 42 else 43 F << DI.FunctionName; 44 } else 45 handleAllErrors(ResOrErr.takeError(), [&](const ErrorInfoBase &) { 46 F << "@(" << std::hex << It->second << ")"; 47 }); 48 49 auto S = F.str(); 50 CachedNames[FuncId] = S; 51 return S; 52 } 53 54 std::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const { 55 auto It = FunctionAddresses.find(FuncId); 56 if (It == FunctionAddresses.end()) 57 return "(unknown)"; 58 59 std::ostringstream F; 60 object::SectionedAddress ModuleAddress; 61 ModuleAddress.Address = It->second; 62 // TODO: set proper section index here. 63 // object::SectionedAddress::UndefSection works for only absolute addresses. 64 ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 65 auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress); 66 if (!ResOrErr) { 67 consumeError(ResOrErr.takeError()); 68 return "(unknown)"; 69 } 70 71 auto &DI = *ResOrErr; 72 F << sys::path::filename(DI.FileName).str() << ":" << DI.Line << ":" 73 << DI.Column; 74 75 return F.str(); 76 } 77