xref: /freebsd-src/contrib/llvm-project/llvm/tools/llvm-xray/func-id-helper.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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 Andric std::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 Andric std::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