[XRay][tools] Add option to llvm-xray extract to symbolize functions

Summary:
This allows us to, if the symbol names are available in the binary, be
able to provide the function name in the YAML output.

Reviewers: dblaikie, pelikan

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D32153

llvm-svn: 300624
This commit is contained in:
Dean Michael Berris 2017-04-18 23:23:54 +00:00
parent 94b2bde631
commit 918802bed4
3 changed files with 32 additions and 3 deletions

View File

@ -59,6 +59,7 @@ struct YAMLXRaySledEntry {
yaml::Hex64 Function; yaml::Hex64 Function;
SledEntry::FunctionKinds Kind; SledEntry::FunctionKinds Kind;
bool AlwaysInstrument; bool AlwaysInstrument;
std::string FunctionName;
}; };
/// The InstrumentationMap represents the computed function id's and indicated /// The InstrumentationMap represents the computed function id's and indicated
@ -115,6 +116,7 @@ template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
IO.mapRequired("function", Entry.Function); IO.mapRequired("function", Entry.Function);
IO.mapRequired("kind", Entry.Kind); IO.mapRequired("kind", Entry.Kind);
IO.mapRequired("always-instrument", Entry.AlwaysInstrument); IO.mapRequired("always-instrument", Entry.AlwaysInstrument);
IO.mapOptional("function-name", Entry.FunctionName);
} }
static constexpr bool flow = true; static constexpr bool flow = true;

View File

@ -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: ...

View File

@ -16,6 +16,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "func-id-helper.h"
#include "xray-registry.h" #include "xray-registry.h"
#include "llvm/Object/ELF.h" #include "llvm/Object/ELF.h"
#include "llvm/Object/ObjectFile.h" #include "llvm/Object/ObjectFile.h"
@ -45,10 +46,18 @@ static cl::opt<std::string>
static cl::alias ExtractOutput2("o", cl::aliasopt(ExtractOutput), static cl::alias ExtractOutput2("o", cl::aliasopt(ExtractOutput),
cl::desc("Alias for -output"), cl::desc("Alias for -output"),
cl::sub(Extract)); cl::sub(Extract));
static cl::opt<bool> 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 { 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. // First we translate the sleds into the YAMLXRaySledEntry objects in a deque.
std::vector<YAMLXRaySledEntry> YAMLSleds; std::vector<YAMLXRaySledEntry> YAMLSleds;
auto Sleds = Map.sleds(); auto Sleds = Map.sleds();
@ -58,7 +67,8 @@ void exportAsYAML(const InstrumentationMap &Map, raw_ostream &OS) {
if (!FuncId) if (!FuncId)
return; return;
YAMLSleds.push_back({*FuncId, Sled.Address, Sled.Function, Sled.Kind, YAMLSleds.push_back({*FuncId, Sled.Address, Sled.Function, Sled.Kind,
Sled.AlwaysInstrument}); Sled.AlwaysInstrument,
ExtractSymbolize ? FH.SymbolOrNumber(*FuncId) : ""});
} }
Output Out(OS, nullptr, 0); Output Out(OS, nullptr, 0);
Out << YAMLSleds; Out << YAMLSleds;
@ -80,6 +90,13 @@ static CommandRegistration Unused(&Extract, []() -> Error {
if (EC) if (EC)
return make_error<StringError>( return make_error<StringError>(
Twine("Cannot open file '") + ExtractOutput + "' for writing.", EC); 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(); return Error::success();
}); });