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