Home | History | Annotate | Download | only in XRay
      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.
     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.
     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