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