1a0e3ae4cSDean Michael Berris //===- xray-fc-account.cpp: XRay Function Call Accounting Tool ------------===// 2a0e3ae4cSDean Michael Berris // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a0e3ae4cSDean Michael Berris // 7a0e3ae4cSDean Michael Berris //===----------------------------------------------------------------------===// 8a0e3ae4cSDean Michael Berris // 9a0e3ae4cSDean Michael Berris // Implementation of the helper tools dealing with XRay-generated function ids. 10a0e3ae4cSDean Michael Berris // 11a0e3ae4cSDean Michael Berris //===----------------------------------------------------------------------===// 12a0e3ae4cSDean Michael Berris 13a0e3ae4cSDean Michael Berris #include "func-id-helper.h" 14*e72c195fSserge-sans-paille #include "llvm/Support/MemoryBuffer.h" 15a0e3ae4cSDean Michael Berris #include "llvm/Support/Path.h" 16a0e3ae4cSDean Michael Berris #include <sstream> 17a0e3ae4cSDean Michael Berris 18a0e3ae4cSDean Michael Berris using namespace llvm; 19a0e3ae4cSDean Michael Berris using namespace xray; 20a0e3ae4cSDean Michael Berris SymbolOrNumber(int32_t FuncId) const21a0e3ae4cSDean Michael Berrisstd::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const { 22a0e3ae4cSDean Michael Berris auto CacheIt = CachedNames.find(FuncId); 23a0e3ae4cSDean Michael Berris if (CacheIt != CachedNames.end()) 24a0e3ae4cSDean Michael Berris return CacheIt->second; 25a0e3ae4cSDean Michael Berris 26a0e3ae4cSDean Michael Berris std::ostringstream F; 27a0e3ae4cSDean Michael Berris auto It = FunctionAddresses.find(FuncId); 28a0e3ae4cSDean Michael Berris if (It == FunctionAddresses.end()) { 29a0e3ae4cSDean Michael Berris F << "#" << FuncId; 30a0e3ae4cSDean Michael Berris return F.str(); 31a0e3ae4cSDean Michael Berris } 32a0e3ae4cSDean Michael Berris 3377fc1f60SAlexey Lapshin object::SectionedAddress ModuleAddress; 3477fc1f60SAlexey Lapshin ModuleAddress.Address = It->second; 3577fc1f60SAlexey Lapshin // TODO: set proper section index here. 3677fc1f60SAlexey Lapshin // object::SectionedAddress::UndefSection works for only absolute addresses. 3777fc1f60SAlexey Lapshin ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 3877fc1f60SAlexey Lapshin if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) { 39a0e3ae4cSDean Michael Berris auto &DI = *ResOrErr; 409abf668cSMichael Pozulp if (DI.FunctionName == DILineInfo::BadString) 41a0e3ae4cSDean Michael Berris F << "@(" << std::hex << It->second << ")"; 42a0e3ae4cSDean Michael Berris else 43a0e3ae4cSDean Michael Berris F << DI.FunctionName; 44a0e3ae4cSDean Michael Berris } else 45a0e3ae4cSDean Michael Berris handleAllErrors(ResOrErr.takeError(), [&](const ErrorInfoBase &) { 46a0e3ae4cSDean Michael Berris F << "@(" << std::hex << It->second << ")"; 47a0e3ae4cSDean Michael Berris }); 48a0e3ae4cSDean Michael Berris 49a0e3ae4cSDean Michael Berris auto S = F.str(); 50a0e3ae4cSDean Michael Berris CachedNames[FuncId] = S; 51a0e3ae4cSDean Michael Berris return S; 52a0e3ae4cSDean Michael Berris } 53a0e3ae4cSDean Michael Berris FileLineAndColumn(int32_t FuncId) const54a0e3ae4cSDean Michael Berrisstd::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const { 55a0e3ae4cSDean Michael Berris auto It = FunctionAddresses.find(FuncId); 56a0e3ae4cSDean Michael Berris if (It == FunctionAddresses.end()) 57a0e3ae4cSDean Michael Berris return "(unknown)"; 58a0e3ae4cSDean Michael Berris 59a0e3ae4cSDean Michael Berris std::ostringstream F; 6077fc1f60SAlexey Lapshin object::SectionedAddress ModuleAddress; 6177fc1f60SAlexey Lapshin ModuleAddress.Address = It->second; 6277fc1f60SAlexey Lapshin // TODO: set proper section index here. 6377fc1f60SAlexey Lapshin // object::SectionedAddress::UndefSection works for only absolute addresses. 6477fc1f60SAlexey Lapshin ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 6577fc1f60SAlexey Lapshin auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress); 66a0e3ae4cSDean Michael Berris if (!ResOrErr) { 67a0e3ae4cSDean Michael Berris consumeError(ResOrErr.takeError()); 68a0e3ae4cSDean Michael Berris return "(unknown)"; 69a0e3ae4cSDean Michael Berris } 70a0e3ae4cSDean Michael Berris 71a0e3ae4cSDean Michael Berris auto &DI = *ResOrErr; 72a0e3ae4cSDean Michael Berris F << sys::path::filename(DI.FileName).str() << ":" << DI.Line << ":" 73a0e3ae4cSDean Michael Berris << DI.Column; 74a0e3ae4cSDean Michael Berris 75a0e3ae4cSDean Michael Berris return F.str(); 76a0e3ae4cSDean Michael Berris } 77