1//===- InstrumentationMap.h - XRay Instrumentation Map ----------*- C++ -*-===//
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// Defines the interface for extracting the instrumentation map from an
10// XRay-instrumented binary.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_XRAY_INSTRUMENTATION_MAP_H
15#define LLVM_XRAY_INSTRUMENTATION_MAP_H
16
17#include "llvm/ADT/Optional.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/Error.h"
20#include "llvm/Support/YAMLTraits.h"
21#include <cstdint>
22#include <unordered_map>
23#include <vector>
24
25namespace llvm {
26
27namespace xray {
28
29// Forward declare to make a friend.
30class InstrumentationMap;
31
32/// Loads the instrumentation map from |Filename|. This auto-deduces the type of
33/// the instrumentation map.
34Expected<InstrumentationMap> loadInstrumentationMap(StringRef Filename);
35
36/// Represents an XRay instrumentation sled entry from an object file.
37struct SledEntry {
38  /// Each entry here represents the kinds of supported instrumentation map
39  /// entries.
40  enum class FunctionKinds { ENTRY, EXIT, TAIL, LOG_ARGS_ENTER, CUSTOM_EVENT };
41
42  /// The address of the sled.
43  uint64_t Address;
44
45  /// The address of the function.
46  uint64_t Function;
47
48  /// The kind of sled.
49  FunctionKinds Kind;
50
51  /// Whether the sled was annotated to always be instrumented.
52  bool AlwaysInstrument;
53};
54
55struct YAMLXRaySledEntry {
56  int32_t FuncId;
57  yaml::Hex64 Address;
58  yaml::Hex64 Function;
59  SledEntry::FunctionKinds Kind;
60  bool AlwaysInstrument;
61  std::string FunctionName;
62};
63
64/// The InstrumentationMap represents the computed function id's and indicated
65/// function addresses from an object file (or a YAML file). This provides an
66/// interface to just the mapping between the function id, and the function
67/// address.
68///
69/// We also provide raw access to the actual instrumentation map entries we find
70/// associated with a particular object file.
71///
72class InstrumentationMap {
73public:
74  using FunctionAddressMap = std::unordered_map<int32_t, uint64_t>;
75  using FunctionAddressReverseMap = std::unordered_map<uint64_t, int32_t>;
76  using SledContainer = std::vector<SledEntry>;
77
78private:
79  SledContainer Sleds;
80  FunctionAddressMap FunctionAddresses;
81  FunctionAddressReverseMap FunctionIds;
82
83  friend Expected<InstrumentationMap> loadInstrumentationMap(StringRef);
84
85public:
86  /// Provides a raw accessor to the unordered map of function addresses.
87  const FunctionAddressMap &getFunctionAddresses() { return FunctionAddresses; }
88
89  /// Returns an XRay computed function id, provided a function address.
90  Optional<int32_t> getFunctionId(uint64_t Addr) const;
91
92  /// Returns the function address for a function id.
93  Optional<uint64_t> getFunctionAddr(int32_t FuncId) const;
94
95  /// Provide read-only access to the entries of the instrumentation map.
96  const SledContainer &sleds() const { return Sleds; };
97};
98
99} // end namespace xray
100
101namespace yaml {
102
103template <> struct ScalarEnumerationTraits<xray::SledEntry::FunctionKinds> {
104  static void enumeration(IO &IO, xray::SledEntry::FunctionKinds &Kind) {
105    IO.enumCase(Kind, "function-enter", xray::SledEntry::FunctionKinds::ENTRY);
106    IO.enumCase(Kind, "function-exit", xray::SledEntry::FunctionKinds::EXIT);
107    IO.enumCase(Kind, "tail-exit", xray::SledEntry::FunctionKinds::TAIL);
108    IO.enumCase(Kind, "log-args-enter",
109                xray::SledEntry::FunctionKinds::LOG_ARGS_ENTER);
110    IO.enumCase(Kind, "custom-event",
111                xray::SledEntry::FunctionKinds::CUSTOM_EVENT);
112  }
113};
114
115template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
116  static void mapping(IO &IO, xray::YAMLXRaySledEntry &Entry) {
117    IO.mapRequired("id", Entry.FuncId);
118    IO.mapRequired("address", Entry.Address);
119    IO.mapRequired("function", Entry.Function);
120    IO.mapRequired("kind", Entry.Kind);
121    IO.mapRequired("always-instrument", Entry.AlwaysInstrument);
122    IO.mapOptional("function-name", Entry.FunctionName);
123  }
124
125  static constexpr bool flow = true;
126};
127
128} // end namespace yaml
129
130} // end namespace llvm
131
132LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRaySledEntry)
133
134#endif // LLVM_XRAY_INSTRUMENTATION_MAP_H
135