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
18using namespace llvm;
19using namespace xray;
20
21std::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const {
22 auto CacheIt = CachedNames.find(Val: FuncId);
23 if (CacheIt != CachedNames.end())
24 return CacheIt->second;
25
26 std::ostringstream F;
27 auto It = FunctionAddresses.find(x: 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(ModuleName: BinaryInstrMap, ModuleOffset: 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(E: ResOrErr.takeError(), Handlers: [&](const ErrorInfoBase &) {
46 F << "@(" << std::hex << It->second << ")";
47 });
48
49 auto S = F.str();
50 CachedNames[FuncId] = S;
51 return S;
52}
53
54std::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const {
55 auto It = FunctionAddresses.find(x: 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(ModuleName: BinaryInstrMap, ModuleOffset: ModuleAddress);
66 if (!ResOrErr) {
67 consumeError(Err: ResOrErr.takeError());
68 return "(unknown)";
69 }
70
71 auto &DI = *ResOrErr;
72 F << sys::path::filename(path: DI.FileName).str() << ":" << DI.Line << ":"
73 << DI.Column;
74
75 return F.str();
76}
77