10b57cec5SDimitry Andric //===- xray-fc-account.cpp: XRay Function Call Accounting Tool ------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Implementation of the helper tools dealing with XRay-generated function ids. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "func-id-helper.h" 14*81ad6265SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 150b57cec5SDimitry Andric #include "llvm/Support/Path.h" 160b57cec5SDimitry Andric #include <sstream> 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace llvm; 190b57cec5SDimitry Andric using namespace xray; 200b57cec5SDimitry Andric SymbolOrNumber(int32_t FuncId) const210b57cec5SDimitry Andricstd::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const { 220b57cec5SDimitry Andric auto CacheIt = CachedNames.find(FuncId); 230b57cec5SDimitry Andric if (CacheIt != CachedNames.end()) 240b57cec5SDimitry Andric return CacheIt->second; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric std::ostringstream F; 270b57cec5SDimitry Andric auto It = FunctionAddresses.find(FuncId); 280b57cec5SDimitry Andric if (It == FunctionAddresses.end()) { 290b57cec5SDimitry Andric F << "#" << FuncId; 300b57cec5SDimitry Andric return F.str(); 310b57cec5SDimitry Andric } 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric object::SectionedAddress ModuleAddress; 340b57cec5SDimitry Andric ModuleAddress.Address = It->second; 350b57cec5SDimitry Andric // TODO: set proper section index here. 360b57cec5SDimitry Andric // object::SectionedAddress::UndefSection works for only absolute addresses. 370b57cec5SDimitry Andric ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 380b57cec5SDimitry Andric if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) { 390b57cec5SDimitry Andric auto &DI = *ResOrErr; 408bcb0991SDimitry Andric if (DI.FunctionName == DILineInfo::BadString) 410b57cec5SDimitry Andric F << "@(" << std::hex << It->second << ")"; 420b57cec5SDimitry Andric else 430b57cec5SDimitry Andric F << DI.FunctionName; 440b57cec5SDimitry Andric } else 450b57cec5SDimitry Andric handleAllErrors(ResOrErr.takeError(), [&](const ErrorInfoBase &) { 460b57cec5SDimitry Andric F << "@(" << std::hex << It->second << ")"; 470b57cec5SDimitry Andric }); 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric auto S = F.str(); 500b57cec5SDimitry Andric CachedNames[FuncId] = S; 510b57cec5SDimitry Andric return S; 520b57cec5SDimitry Andric } 530b57cec5SDimitry Andric FileLineAndColumn(int32_t FuncId) const540b57cec5SDimitry Andricstd::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const { 550b57cec5SDimitry Andric auto It = FunctionAddresses.find(FuncId); 560b57cec5SDimitry Andric if (It == FunctionAddresses.end()) 570b57cec5SDimitry Andric return "(unknown)"; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric std::ostringstream F; 600b57cec5SDimitry Andric object::SectionedAddress ModuleAddress; 610b57cec5SDimitry Andric ModuleAddress.Address = It->second; 620b57cec5SDimitry Andric // TODO: set proper section index here. 630b57cec5SDimitry Andric // object::SectionedAddress::UndefSection works for only absolute addresses. 640b57cec5SDimitry Andric ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection; 650b57cec5SDimitry Andric auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress); 660b57cec5SDimitry Andric if (!ResOrErr) { 670b57cec5SDimitry Andric consumeError(ResOrErr.takeError()); 680b57cec5SDimitry Andric return "(unknown)"; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric auto &DI = *ResOrErr; 720b57cec5SDimitry Andric F << sys::path::filename(DI.FileName).str() << ":" << DI.Line << ":" 730b57cec5SDimitry Andric << DI.Column; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric return F.str(); 760b57cec5SDimitry Andric } 77