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