Index: include/llvm/XRay/InstrumentationMap.h =================================================================== --- include/llvm/XRay/InstrumentationMap.h +++ include/llvm/XRay/InstrumentationMap.h @@ -59,6 +59,7 @@ yaml::Hex64 Function; SledEntry::FunctionKinds Kind; bool AlwaysInstrument; + std::string FunctionName; }; /// The InstrumentationMap represents the computed function id's and indicated @@ -115,6 +116,7 @@ IO.mapRequired("function", Entry.Function); IO.mapRequired("kind", Entry.Kind); IO.mapRequired("always-instrument", Entry.AlwaysInstrument); + IO.mapOptional("function-name", Entry.FunctionName); } static constexpr bool flow = true; Index: test/tools/llvm-xray/X86/extract-instrmap-symbolize.ll =================================================================== --- /dev/null +++ test/tools/llvm-xray/X86/extract-instrmap-symbolize.ll @@ -0,0 +1,10 @@ +; This tests that we can extract the instrumentation map and symbolize the +; function addresses. +; RUN: llvm-xray extract %S/Inputs/elf64-example.bin -s | FileCheck %s + +; CHECK: --- +; CHECK-NEXT: - { id: 1, address: 0x000000000041C900, function: 0x000000000041C900, kind: function-enter, always-instrument: true, function-name: {{.*foo.*}} } +; CHECK-NEXT: - { id: 1, address: 0x000000000041C912, function: 0x000000000041C900, kind: function-exit, always-instrument: true, function-name: {{.*foo.*}} } +; CHECK-NEXT: - { id: 2, address: 0x000000000041C930, function: 0x000000000041C930, kind: function-enter, always-instrument: true, function-name: {{.*bar.*}} } +; CHECK-NEXT: - { id: 2, address: 0x000000000041C946, function: 0x000000000041C930, kind: function-exit, always-instrument: true, function-name: {{.*bar.*}} } +; CHECK-NEXT: ... Index: tools/llvm-xray/xray-extract.cc =================================================================== --- tools/llvm-xray/xray-extract.cc +++ tools/llvm-xray/xray-extract.cc @@ -16,6 +16,7 @@ #include #include +#include "func-id-helper.h" #include "xray-registry.h" #include "llvm/Object/ELF.h" #include "llvm/Object/ObjectFile.h" @@ -45,10 +46,18 @@ static cl::alias ExtractOutput2("o", cl::aliasopt(ExtractOutput), cl::desc("Alias for -output"), cl::sub(Extract)); +static cl::opt ExtractSymbolize("symbolize", cl::value_desc("symbolize"), + cl::init(false), + cl::desc("symbolize functions"), + cl::sub(Extract)); +static cl::alias ExtractSymbolize2("s", cl::aliasopt(ExtractSymbolize), + cl::desc("alias for -symbolize"), + cl::sub(Extract)); namespace { -void exportAsYAML(const InstrumentationMap &Map, raw_ostream &OS) { +void exportAsYAML(const InstrumentationMap &Map, raw_ostream &OS, + FuncIdConversionHelper &FH) { // First we translate the sleds into the YAMLXRaySledEntry objects in a deque. std::vector YAMLSleds; auto Sleds = Map.sleds(); @@ -58,7 +67,8 @@ if (!FuncId) return; YAMLSleds.push_back({*FuncId, Sled.Address, Sled.Function, Sled.Kind, - Sled.AlwaysInstrument}); + Sled.AlwaysInstrument, + ExtractSymbolize ? FH.SymbolOrNumber(*FuncId) : ""}); } Output Out(OS, nullptr, 0); Out << YAMLSleds; @@ -80,6 +90,13 @@ if (EC) return make_error( Twine("Cannot open file '") + ExtractOutput + "' for writing.", EC); - exportAsYAML(*InstrumentationMapOrError, OS); + const auto &FunctionAddresses = + InstrumentationMapOrError->getFunctionAddresses(); + symbolize::LLVMSymbolizer::Options Opts( + symbolize::FunctionNameKind::LinkageName, true, true, false, ""); + symbolize::LLVMSymbolizer Symbolizer(Opts); + llvm::xray::FuncIdConversionHelper FuncIdHelper(ExtractInput, Symbolizer, + FunctionAddresses); + exportAsYAML(*InstrumentationMapOrError, OS, FuncIdHelper); return Error::success(); });