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