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