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