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