xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-xray/func-id-helper.cpp (revision 8bcb0991864975618c09697b1aca10683346d9f0)
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"
140b57cec5SDimitry Andric #include "llvm/Support/Path.h"
150b57cec5SDimitry Andric #include <sstream>
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric using namespace llvm;
180b57cec5SDimitry Andric using namespace xray;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric std::string FuncIdConversionHelper::SymbolOrNumber(int32_t FuncId) const {
210b57cec5SDimitry Andric   auto CacheIt = CachedNames.find(FuncId);
220b57cec5SDimitry Andric   if (CacheIt != CachedNames.end())
230b57cec5SDimitry Andric     return CacheIt->second;
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric   std::ostringstream F;
260b57cec5SDimitry Andric   auto It = FunctionAddresses.find(FuncId);
270b57cec5SDimitry Andric   if (It == FunctionAddresses.end()) {
280b57cec5SDimitry Andric     F << "#" << FuncId;
290b57cec5SDimitry Andric     return F.str();
300b57cec5SDimitry Andric   }
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   object::SectionedAddress ModuleAddress;
330b57cec5SDimitry Andric   ModuleAddress.Address = It->second;
340b57cec5SDimitry Andric   // TODO: set proper section index here.
350b57cec5SDimitry Andric   // object::SectionedAddress::UndefSection works for only absolute addresses.
360b57cec5SDimitry Andric   ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection;
370b57cec5SDimitry Andric   if (auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress)) {
380b57cec5SDimitry Andric     auto &DI = *ResOrErr;
39*8bcb0991SDimitry Andric     if (DI.FunctionName == DILineInfo::BadString)
400b57cec5SDimitry Andric       F << "@(" << std::hex << It->second << ")";
410b57cec5SDimitry Andric     else
420b57cec5SDimitry Andric       F << DI.FunctionName;
430b57cec5SDimitry Andric   } else
440b57cec5SDimitry Andric     handleAllErrors(ResOrErr.takeError(), [&](const ErrorInfoBase &) {
450b57cec5SDimitry Andric       F << "@(" << std::hex << It->second << ")";
460b57cec5SDimitry Andric     });
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   auto S = F.str();
490b57cec5SDimitry Andric   CachedNames[FuncId] = S;
500b57cec5SDimitry Andric   return S;
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric std::string FuncIdConversionHelper::FileLineAndColumn(int32_t FuncId) const {
540b57cec5SDimitry Andric   auto It = FunctionAddresses.find(FuncId);
550b57cec5SDimitry Andric   if (It == FunctionAddresses.end())
560b57cec5SDimitry Andric     return "(unknown)";
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   std::ostringstream F;
590b57cec5SDimitry Andric   object::SectionedAddress ModuleAddress;
600b57cec5SDimitry Andric   ModuleAddress.Address = It->second;
610b57cec5SDimitry Andric   // TODO: set proper section index here.
620b57cec5SDimitry Andric   // object::SectionedAddress::UndefSection works for only absolute addresses.
630b57cec5SDimitry Andric   ModuleAddress.SectionIndex = object::SectionedAddress::UndefSection;
640b57cec5SDimitry Andric   auto ResOrErr = Symbolizer.symbolizeCode(BinaryInstrMap, ModuleAddress);
650b57cec5SDimitry Andric   if (!ResOrErr) {
660b57cec5SDimitry Andric     consumeError(ResOrErr.takeError());
670b57cec5SDimitry Andric     return "(unknown)";
680b57cec5SDimitry Andric   }
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   auto &DI = *ResOrErr;
710b57cec5SDimitry Andric   F << sys::path::filename(DI.FileName).str() << ":" << DI.Line << ":"
720b57cec5SDimitry Andric     << DI.Column;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   return F.str();
750b57cec5SDimitry Andric }
76