//===-- xray_interface.cpp --------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of XRay, a dynamic runtime instrumentation system.
//
// Implementation of the API functions.
//
//===----------------------------------------------------------------------===//

#include "xray_interface_internal.h"

#include <cinttypes>
#include <cstdio>
#include <errno.h>
#include <limits>
#include <string.h>
#include <sys/mman.h>

#if SANITIZER_FUCHSIA
#include <zircon/process.h>
#include <zircon/sanitizer.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#endif

#include "sanitizer_common/sanitizer_addrhashmap.h"
#include "sanitizer_common/sanitizer_common.h"

#include "xray_defs.h"
#include "xray_flags.h"

extern __sanitizer::SpinMutex XRayInstrMapMutex;
extern __sanitizer::atomic_uint8_t XRayInitialized;
extern __xray::XRaySledMap *XRayInstrMaps;
extern __sanitizer::atomic_uint32_t XRayNumObjects;

namespace __xray {

#if defined(__x86_64__)
static const int16_t cSledLength = 12;
#elif defined(__aarch64__)
static const int16_t cSledLength = 32;
#elif defined(__arm__)
static const int16_t cSledLength = 28;
#elif SANITIZER_LOONGARCH64
static const int16_t cSledLength = 48;
#elif SANITIZER_MIPS32
static const int16_t cSledLength = 48;
#elif SANITIZER_MIPS64
static const int16_t cSledLength = 64;
#elif defined(__powerpc64__)
static const int16_t cSledLength = 8;
#elif defined(__hexagon__)
static const int16_t cSledLength = 20;
#elif defined(__riscv) && (__riscv_xlen == 64)
static const int16_t cSledLength = 68;
#elif defined(__riscv) && (__riscv_xlen == 32)
static const int16_t cSledLength = 52;
#elif defined(__s390x__)
static const int16_t cSledLength = 18;
#else
#error "Unsupported CPU Architecture"
#endif /* CPU architecture */

// This is the function to call when we encounter the entry or exit sleds.
atomic_uintptr_t XRayPatchedFunction SANITIZER_INTERFACE_ATTRIBUTE{0};

// This is the function to call from the arg1-enabled sleds/trampolines.
atomic_uintptr_t XRayArgLogger SANITIZER_INTERFACE_ATTRIBUTE{0};

// This is the function to call when we encounter a custom event log call.
atomic_uintptr_t XRayPatchedCustomEvent SANITIZER_INTERFACE_ATTRIBUTE{0};

// This is the function to call when we encounter a typed event log call.
atomic_uintptr_t XRayPatchedTypedEvent SANITIZER_INTERFACE_ATTRIBUTE{0};

// This is the global status to determine whether we are currently
// patching/unpatching.
atomic_uint8_t XRayPatching{0};

struct TypeDescription {
  uint32_t type_id;
  std::size_t description_string_length;
};

using TypeDescriptorMapType = AddrHashMap<TypeDescription, 11>;
// An address map from immutable descriptors to type ids.
TypeDescriptorMapType TypeDescriptorAddressMap{};

atomic_uint32_t TypeEventDescriptorCounter{0};

// MProtectHelper is an RAII wrapper for calls to mprotect(...) that will
// undo any successful mprotect(...) changes. This is used to make a page
// writeable and executable, and upon destruction if it was successful in
// doing so returns the page into a read-only and executable page.
//
// This is only used specifically for runtime-patching of the XRay
// instrumentation points. This assumes that the executable pages are
// originally read-and-execute only.
class MProtectHelper {
  void *PageAlignedAddr;
  std::size_t MProtectLen;
  bool MustCleanup;

public:
  explicit MProtectHelper(void *PageAlignedAddr,
                          std::size_t MProtectLen,
                          std::size_t PageSize) XRAY_NEVER_INSTRUMENT
      : PageAlignedAddr(PageAlignedAddr),
        MProtectLen(MProtectLen),
        MustCleanup(false) {
#if SANITIZER_FUCHSIA
    MProtectLen = RoundUpTo(MProtectLen, PageSize);
#endif
  }

  int MakeWriteable() XRAY_NEVER_INSTRUMENT {
#if SANITIZER_FUCHSIA
    auto R = __sanitizer_change_code_protection(
        reinterpret_cast<uintptr_t>(PageAlignedAddr), MProtectLen, true);
    if (R != ZX_OK) {
      Report("XRay: cannot change code protection: %s\n",
             _zx_status_get_string(R));
      return -1;
    }
    MustCleanup = true;
    return 0;
#else
    auto R = mprotect(PageAlignedAddr, MProtectLen,
                      PROT_READ | PROT_WRITE | PROT_EXEC);
    if (R != -1)
      MustCleanup = true;
    return R;
#endif
  }

  ~MProtectHelper() XRAY_NEVER_INSTRUMENT {
    if (MustCleanup) {
#if SANITIZER_FUCHSIA
      auto R = __sanitizer_change_code_protection(
          reinterpret_cast<uintptr_t>(PageAlignedAddr), MProtectLen, false);
      if (R != ZX_OK) {
        Report("XRay: cannot change code protection: %s\n",
               _zx_status_get_string(R));
      }
#else
      mprotect(PageAlignedAddr, MProtectLen, PROT_READ | PROT_EXEC);
#endif
    }
  }
};

namespace {

bool isObjectLoaded(int32_t ObjId) {
  SpinMutexLock Guard(&XRayInstrMapMutex);
  if (ObjId < 0 || static_cast<uint32_t>(ObjId) >=
                       atomic_load(&XRayNumObjects, memory_order_acquire)) {
    return false;
  }
  return XRayInstrMaps[ObjId].Loaded;
}

bool patchSled(const XRaySledEntry &Sled, bool Enable, int32_t FuncId,
               const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT {
  bool Success = false;
  switch (Sled.Kind) {
  case XRayEntryType::ENTRY:
    Success = patchFunctionEntry(Enable, FuncId, Sled, Trampolines,
                                 /*LogArgs=*/false);
    break;
  case XRayEntryType::EXIT:
    Success = patchFunctionExit(Enable, FuncId, Sled, Trampolines);
    break;
  case XRayEntryType::TAIL:
    Success = patchFunctionTailExit(Enable, FuncId, Sled, Trampolines);
    break;
  case XRayEntryType::LOG_ARGS_ENTRY:
    Success = patchFunctionEntry(Enable, FuncId, Sled, Trampolines,
                                 /*LogArgs=*/true);
    break;
  case XRayEntryType::CUSTOM_EVENT:
    Success = patchCustomEvent(Enable, FuncId, Sled);
    break;
  case XRayEntryType::TYPED_EVENT:
    Success = patchTypedEvent(Enable, FuncId, Sled);
    break;
  default:
    Report("Unsupported sled kind '%" PRIu64 "' @%04x\n", Sled.Address,
           int(Sled.Kind));
    return false;
  }
  return Success;
}

const XRayFunctionSledIndex
findFunctionSleds(int32_t FuncId,
                  const XRaySledMap &InstrMap) XRAY_NEVER_INSTRUMENT {
  int32_t CurFn = 0;
  uint64_t LastFnAddr = 0;
  XRayFunctionSledIndex Index = {nullptr, 0};

  for (std::size_t I = 0; I < InstrMap.Entries && CurFn <= FuncId; I++) {
    const auto &Sled = InstrMap.Sleds[I];
    const auto Function = Sled.function();
    if (Function != LastFnAddr) {
      CurFn++;
      LastFnAddr = Function;
    }

    if (CurFn == FuncId) {
      if (Index.Begin == nullptr)
        Index.Begin = &Sled;
      Index.Size = &Sled - Index.Begin + 1;
    }
  }

  return Index;
}

XRayPatchingStatus patchFunction(int32_t FuncId, int32_t ObjId,
                                 bool Enable) XRAY_NEVER_INSTRUMENT {
  if (!atomic_load(&XRayInitialized, memory_order_acquire))
    return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.

  uint8_t NotPatching = false;
  if (!atomic_compare_exchange_strong(
          &XRayPatching, &NotPatching, true, memory_order_acq_rel))
    return XRayPatchingStatus::ONGOING; // Already patching.

  // Next, we look for the function index.
  XRaySledMap InstrMap;
  {
    SpinMutexLock Guard(&XRayInstrMapMutex);
    if (ObjId < 0 || static_cast<uint32_t>(ObjId) >=
                         atomic_load(&XRayNumObjects, memory_order_acquire)) {
      Report("Unable to patch function: invalid sled map index: %d", ObjId);
      return XRayPatchingStatus::FAILED;
    }
    InstrMap = XRayInstrMaps[ObjId];
  }

  // If we don't have an index, we can't patch individual functions.
  if (InstrMap.Functions == 0)
    return XRayPatchingStatus::NOT_INITIALIZED;

  // Check if the corresponding DSO has been unloaded.
  if (!InstrMap.Loaded) {
    Report("Invalid function id provided: %d\n", FuncId);
    return XRayPatchingStatus::NOT_INITIALIZED;
  }

  // FuncId must be a positive number, less than the number of functions
  // instrumented.
  if (FuncId <= 0 || static_cast<size_t>(FuncId) > InstrMap.Functions) {
    Report("Invalid function id provided: %d\n", FuncId);
    return XRayPatchingStatus::FAILED;
  }

  auto PackedId = __xray::MakePackedId(FuncId, ObjId);

  // Now we patch ths sleds for this specific function.
  XRayFunctionSledIndex SledRange;
  if (InstrMap.SledsIndex) {
    SledRange = {InstrMap.SledsIndex[FuncId - 1].fromPCRelative(),
                 InstrMap.SledsIndex[FuncId - 1].Size};
  } else {
    SledRange = findFunctionSleds(FuncId, InstrMap);
  }

  auto *f = SledRange.Begin;
  bool SucceedOnce = false;
  for (size_t i = 0; i != SledRange.Size; ++i)
    SucceedOnce |= patchSled(f[i], Enable, PackedId, InstrMap.Trampolines);

  atomic_store(&XRayPatching, false, memory_order_release);

  if (!SucceedOnce) {
    Report("Failed patching any sled for function '%d'.", FuncId);
    return XRayPatchingStatus::FAILED;
  }

  return XRayPatchingStatus::SUCCESS;
}

// controlPatching implements the common internals of the patching/unpatching
// implementation. |Enable| defines whether we're enabling or disabling the
// runtime XRay instrumentation.
// This function should only be called after ensuring that XRay is initialized
// and no other thread is currently patching.
XRayPatchingStatus controlPatchingObjectUnchecked(bool Enable, int32_t ObjId) {
  XRaySledMap InstrMap;
  {
    SpinMutexLock Guard(&XRayInstrMapMutex);
    if (ObjId < 0 || static_cast<uint32_t>(ObjId) >=
                         atomic_load(&XRayNumObjects, memory_order_acquire)) {
      Report("Unable to patch functions: invalid sled map index: %d\n", ObjId);
      return XRayPatchingStatus::FAILED;
    }
    InstrMap = XRayInstrMaps[ObjId];
  }
  if (InstrMap.Entries == 0)
    return XRayPatchingStatus::NOT_INITIALIZED;

  if (Verbosity())
    Report("Patching object %d with %d functions.\n", ObjId, InstrMap.Entries);

  // Check if the corresponding DSO has been unloaded.
  if (!InstrMap.Loaded) {
    Report("Object is not loaded at index: %d\n", ObjId);
    return XRayPatchingStatus::FAILED;
  }

  uint32_t FuncId = 1;
  uint64_t CurFun = 0;

  // First we want to find the bounds for which we have instrumentation points,
  // and try to get as few calls to mprotect(...) as possible. We're assuming
  // that all the sleds for the instrumentation map are contiguous as a single
  // set of pages. When we do support dynamic shared object instrumentation,
  // we'll need to do this for each set of page load offsets per DSO loaded. For
  // now we're assuming we can mprotect the whole section of text between the
  // minimum sled address and the maximum sled address (+ the largest sled
  // size).
  auto *MinSled = &InstrMap.Sleds[0];
  auto *MaxSled = &InstrMap.Sleds[InstrMap.Entries - 1];
  for (std::size_t I = 0; I < InstrMap.Entries; I++) {
    const auto &Sled = InstrMap.Sleds[I];
    if (Sled.address() < MinSled->address())
      MinSled = &Sled;
    if (Sled.address() > MaxSled->address())
      MaxSled = &Sled;
  }

  const size_t PageSize = flags()->xray_page_size_override > 0
                              ? flags()->xray_page_size_override
                              : GetPageSizeCached();
  if ((PageSize == 0) || ((PageSize & (PageSize - 1)) != 0)) {
    Report("System page size is not a power of two: %zu\n", PageSize);
    return XRayPatchingStatus::FAILED;
  }

  void *PageAlignedAddr =
      reinterpret_cast<void *>(MinSled->address() & ~(PageSize - 1));
  size_t MProtectLen =
      (MaxSled->address() - reinterpret_cast<uptr>(PageAlignedAddr)) +
      cSledLength;
  MProtectHelper Protector(PageAlignedAddr, MProtectLen, PageSize);
  if (Protector.MakeWriteable() == -1) {
    Report("Failed mprotect: %d\n", errno);
    return XRayPatchingStatus::FAILED;
  }

  for (std::size_t I = 0; I < InstrMap.Entries; ++I) {
    auto &Sled = InstrMap.Sleds[I];
    auto F = Sled.function();
    if (CurFun == 0)
      CurFun = F;
    if (F != CurFun) {
      ++FuncId;
      CurFun = F;
    }
    auto PackedId = __xray::MakePackedId(FuncId, ObjId);
    patchSled(Sled, Enable, PackedId, InstrMap.Trampolines);
  }
  atomic_store(&XRayPatching, false, memory_order_release);
  return XRayPatchingStatus::SUCCESS;
}

// Controls patching for all registered objects.
// Returns: SUCCESS, if patching succeeds for all objects.
//          NOT_INITIALIZED, if one or more objects returned NOT_INITIALIZED
//             but none failed.
//          FAILED, if patching of one or more objects failed.
XRayPatchingStatus controlPatching(bool Enable) XRAY_NEVER_INSTRUMENT {
  if (!atomic_load(&XRayInitialized, memory_order_acquire))
    return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.

  uint8_t NotPatching = false;
  if (!atomic_compare_exchange_strong(&XRayPatching, &NotPatching, true,
                                      memory_order_acq_rel))
    return XRayPatchingStatus::ONGOING; // Already patching.

  auto XRayPatchingStatusResetter = at_scope_exit(
      [] { atomic_store(&XRayPatching, false, memory_order_release); });

  unsigned NumObjects = __xray_num_objects();

  XRayPatchingStatus CombinedStatus{NOT_INITIALIZED};
  for (unsigned I = 0; I < NumObjects; ++I) {
    if (!isObjectLoaded(I))
      continue;
    auto LastStatus = controlPatchingObjectUnchecked(Enable, I);
    switch (LastStatus) {
    case SUCCESS:
      if (CombinedStatus == NOT_INITIALIZED)
        CombinedStatus = SUCCESS;
      break;
    case FAILED:
      // Report failure, but try to patch the remaining objects
      CombinedStatus = FAILED;
      break;
    case NOT_INITIALIZED:
      // XRay has been initialized but there are no sleds available for this
      // object. Try to patch remaining objects.
      if (CombinedStatus != FAILED)
        CombinedStatus = NOT_INITIALIZED;
      break;
    case ONGOING:
      UNREACHABLE("Status ONGOING should not appear at this point");
    }
  }
  return CombinedStatus;
}

// Controls patching for one object.
XRayPatchingStatus controlPatching(bool Enable,
                                   int32_t ObjId) XRAY_NEVER_INSTRUMENT {

  if (!atomic_load(&XRayInitialized, memory_order_acquire))
    return XRayPatchingStatus::NOT_INITIALIZED; // Not initialized.

  uint8_t NotPatching = false;
  if (!atomic_compare_exchange_strong(&XRayPatching, &NotPatching, true,
                                      memory_order_acq_rel))
    return XRayPatchingStatus::ONGOING; // Already patching.

  auto XRayPatchingStatusResetter = at_scope_exit(
      [] { atomic_store(&XRayPatching, false, memory_order_release); });

  return controlPatchingObjectUnchecked(Enable, ObjId);
}

XRayPatchingStatus mprotectAndPatchFunction(int32_t FuncId, int32_t ObjId,
                                            bool Enable) XRAY_NEVER_INSTRUMENT {
  XRaySledMap InstrMap;
  {
    SpinMutexLock Guard(&XRayInstrMapMutex);
    if (ObjId < 0 || static_cast<uint32_t>(ObjId) >=
                         atomic_load(&XRayNumObjects, memory_order_acquire)) {
      Report("Unable to patch function: invalid sled map index: %d\n", ObjId);
      return XRayPatchingStatus::FAILED;
    }
    InstrMap = XRayInstrMaps[ObjId];
  }

  // Check if the corresponding DSO has been unloaded.
  if (!InstrMap.Loaded) {
    Report("Object is not loaded at index: %d\n", ObjId);
    return XRayPatchingStatus::FAILED;
  }

  // FuncId must be a positive number, less than the number of functions
  // instrumented.
  if (FuncId <= 0 || static_cast<size_t>(FuncId) > InstrMap.Functions) {
    Report("Invalid function id provided: %d\n", FuncId);
    return XRayPatchingStatus::FAILED;
  }

  const size_t PageSize = flags()->xray_page_size_override > 0
                              ? flags()->xray_page_size_override
                              : GetPageSizeCached();
  if ((PageSize == 0) || ((PageSize & (PageSize - 1)) != 0)) {
    Report("Provided page size is not a power of two: %zu\n", PageSize);
    return XRayPatchingStatus::FAILED;
  }

  // Here we compute the minimum sled and maximum sled associated with a
  // particular function ID.
  XRayFunctionSledIndex SledRange;
  if (InstrMap.SledsIndex) {
    SledRange = {InstrMap.SledsIndex[FuncId - 1].fromPCRelative(),
                 InstrMap.SledsIndex[FuncId - 1].Size};
  } else {
    SledRange = findFunctionSleds(FuncId, InstrMap);
  }
  auto *f = SledRange.Begin;
  auto *e = SledRange.Begin + SledRange.Size;
  auto *MinSled = f;
  auto *MaxSled = e - 1;
  while (f != e) {
    if (f->address() < MinSled->address())
      MinSled = f;
    if (f->address() > MaxSled->address())
      MaxSled = f;
    ++f;
  }

  void *PageAlignedAddr =
      reinterpret_cast<void *>(MinSled->address() & ~(PageSize - 1));
  size_t MProtectLen =
      (MaxSled->address() - reinterpret_cast<uptr>(PageAlignedAddr)) +
      cSledLength;
  MProtectHelper Protector(PageAlignedAddr, MProtectLen, PageSize);
  if (Protector.MakeWriteable() == -1) {
    Report("Failed mprotect: %d\n", errno);
    return XRayPatchingStatus::FAILED;
  }
  return patchFunction(FuncId, ObjId, Enable);
}

} // namespace

} // namespace __xray

using namespace __xray;

// The following functions are declared `extern "C" {...}` in the header, hence
// they're defined in the global namespace.

int __xray_set_handler(void (*entry)(int32_t,
                                     XRayEntryType)) XRAY_NEVER_INSTRUMENT {
  if (atomic_load(&XRayInitialized, memory_order_acquire)) {

    atomic_store(&__xray::XRayPatchedFunction,
                 reinterpret_cast<uintptr_t>(entry), memory_order_release);
    return 1;
  }
  return 0;
}

int __xray_set_customevent_handler(void (*entry)(void *, size_t))
    XRAY_NEVER_INSTRUMENT {
  if (atomic_load(&XRayInitialized, memory_order_acquire)) {
    atomic_store(&__xray::XRayPatchedCustomEvent,
                 reinterpret_cast<uintptr_t>(entry), memory_order_release);
    return 1;
  }
  return 0;
}

int __xray_set_typedevent_handler(void (*entry)(size_t, const void *,
                                                size_t)) XRAY_NEVER_INSTRUMENT {
  if (atomic_load(&XRayInitialized, memory_order_acquire)) {
    atomic_store(&__xray::XRayPatchedTypedEvent,
                 reinterpret_cast<uintptr_t>(entry), memory_order_release);
    return 1;
  }
  return 0;
}

int __xray_remove_handler() XRAY_NEVER_INSTRUMENT {
  return __xray_set_handler(nullptr);
}

int __xray_remove_customevent_handler() XRAY_NEVER_INSTRUMENT {
  return __xray_set_customevent_handler(nullptr);
}

int __xray_remove_typedevent_handler() XRAY_NEVER_INSTRUMENT {
  return __xray_set_typedevent_handler(nullptr);
}

uint16_t __xray_register_event_type(
    const char *const event_type) XRAY_NEVER_INSTRUMENT {
  TypeDescriptorMapType::Handle h(&TypeDescriptorAddressMap, (uptr)event_type);
  if (h.created()) {
    h->type_id = atomic_fetch_add(
        &TypeEventDescriptorCounter, 1, memory_order_acq_rel);
    h->description_string_length = strnlen(event_type, 1024);
  }
  return h->type_id;
}

XRayPatchingStatus __xray_patch() XRAY_NEVER_INSTRUMENT {
  return controlPatching(true);
}

XRayPatchingStatus __xray_patch_object(int32_t ObjId) XRAY_NEVER_INSTRUMENT {
  return controlPatching(true, ObjId);
}

XRayPatchingStatus __xray_unpatch() XRAY_NEVER_INSTRUMENT {
  return controlPatching(false);
}

XRayPatchingStatus __xray_unpatch_object(int32_t ObjId) XRAY_NEVER_INSTRUMENT {
  return controlPatching(false, ObjId);
}

XRayPatchingStatus __xray_patch_function(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
  auto Ids = __xray::UnpackId(FuncId);
  auto ObjId = Ids.first;
  auto FnId = Ids.second;
  return mprotectAndPatchFunction(FnId, ObjId, true);
}

XRayPatchingStatus
__xray_patch_function_in_object(int32_t FuncId,
                                int32_t ObjId) XRAY_NEVER_INSTRUMENT {
  return mprotectAndPatchFunction(FuncId, ObjId, true);
}

XRayPatchingStatus
__xray_unpatch_function(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
  auto Ids = __xray::UnpackId(FuncId);
  auto ObjId = Ids.first;
  auto FnId = Ids.second;
  return mprotectAndPatchFunction(FnId, ObjId, false);
}

XRayPatchingStatus
__xray_unpatch_function_in_object(int32_t FuncId,
                                  int32_t ObjId) XRAY_NEVER_INSTRUMENT {
  return mprotectAndPatchFunction(FuncId, ObjId, false);
}

int __xray_set_handler_arg1(void (*entry)(int32_t, XRayEntryType, uint64_t)) {
  if (!atomic_load(&XRayInitialized, memory_order_acquire))
    return 0;

  // A relaxed write might not be visible even if the current thread gets
  // scheduled on a different CPU/NUMA node.  We need to wait for everyone to
  // have this handler installed for consistency of collected data across CPUs.
  atomic_store(&XRayArgLogger, reinterpret_cast<uint64_t>(entry),
               memory_order_release);
  return 1;
}

int __xray_remove_handler_arg1() { return __xray_set_handler_arg1(nullptr); }

uintptr_t
__xray_function_address(int32_t CombinedFuncId) XRAY_NEVER_INSTRUMENT {
  auto Ids = __xray::UnpackId(CombinedFuncId);
  return __xray_function_address_in_object(Ids.second, Ids.first);
}

uintptr_t __xray_function_address_in_object(int32_t FuncId, int32_t ObjId)
    XRAY_NEVER_INSTRUMENT {
  XRaySledMap InstrMap;
  {
    SpinMutexLock Guard(&XRayInstrMapMutex);
    auto count = atomic_load(&XRayNumObjects, memory_order_acquire);
    if (ObjId < 0 || static_cast<uint32_t>(ObjId) >= count) {
      Report("Unable to determine function address: invalid sled map index %d "
             "(size is %d)\n",
             ObjId, (int)count);
      return 0;
    }
    InstrMap = XRayInstrMaps[ObjId];
  }

  if (FuncId <= 0 || static_cast<size_t>(FuncId) > InstrMap.Functions)
    return 0;
  const XRaySledEntry *Sled =
      InstrMap.SledsIndex ? InstrMap.SledsIndex[FuncId - 1].fromPCRelative()
                          : findFunctionSleds(FuncId, InstrMap).Begin;
  return Sled->function()
// On PPC, function entries are always aligned to 16 bytes. The beginning of a
// sled might be a local entry, which is always +8 based on the global entry.
// Always return the global entry.
#ifdef __PPC__
         & ~0xf
#endif
      ;
}

size_t __xray_max_function_id() XRAY_NEVER_INSTRUMENT {
  return __xray_max_function_id_in_object(0);
}

size_t __xray_max_function_id_in_object(int32_t ObjId) XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayInstrMapMutex);
  if (ObjId < 0 || static_cast<uint32_t>(ObjId) >=
                       atomic_load(&XRayNumObjects, memory_order_acquire))
    return 0;
  return XRayInstrMaps[ObjId].Functions;
}

size_t __xray_num_objects() XRAY_NEVER_INSTRUMENT {
  SpinMutexLock Guard(&XRayInstrMapMutex);
  return atomic_load(&XRayNumObjects, memory_order_acquire);
}

int32_t __xray_unpack_function_id(int32_t PackedId) {
  return __xray::UnpackId(PackedId).second;
}

int32_t __xray_unpack_object_id(int32_t PackedId) {
  return __xray::UnpackId(PackedId).first;
}

int32_t __xray_pack_id(int32_t FuncId, int32_t ObjId) {
  return __xray::MakePackedId(FuncId, ObjId);
}
