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 25namespace llvm { 26 27namespace xray { 28 29// Forward declare to make a friend. 30class InstrumentationMap; 31 32/// Loads the instrumentation map from |Filename|. This auto-deduces the type of 33/// the instrumentation map. 34Expected<InstrumentationMap> loadInstrumentationMap(StringRef Filename); 35 36/// Represents an XRay instrumentation sled entry from an object file. 37struct 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 55struct 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/// 72class InstrumentationMap { 73public: 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 78private: 79 SledContainer Sleds; 80 FunctionAddressMap FunctionAddresses; 81 FunctionAddressReverseMap FunctionIds; 82 83 friend Expected<InstrumentationMap> loadInstrumentationMap(StringRef); 84 85public: 86 /// Provides a raw accessor to the unordered map of function addresses. 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. 96 const SledContainer &sleds() const { return Sleds; }; 97}; 98 99} // end namespace xray 100 101namespace yaml { 102 103template <> 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 115template <> 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 132LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRaySledEntry) 133 134#endif // LLVM_XRAY_INSTRUMENTATION_MAP_H 135