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