//===- InstrProfilingPlatformROCm.cpp - Profile data ROCm platform -------===//
//
// 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
//
//===----------------------------------------------------------------------===//

extern "C" {
#include "InstrProfiling.h"
#include "InstrProfilingPort.h"
#include "InstrProfilingUtil.h"
}

#include "interception/interception.h"
// C library headers (not <cstdio> etc.): clang_rt.profile is built with
// -nostdinc++ and avoids the C++ standard library (see profile/CMakeLists.txt).
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <wchar.h>
#endif

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// windows.h needs to be included before tlhelp32.h.
#include <tlhelp32.h>
#else
#include <dlfcn.h>
#include <pthread.h>
#endif

#include "InstrProfilingPlatformROCmInternal.h"

// shortcut to shared helper names
using namespace __prof_rocm;

/* Serialize one-time HIP loader resolution and DynamicModules mutations.
 * Inline to avoid a sanitizer_common dependency. */
#ifdef _WIN32
static INIT_ONCE HipLoadedOnce = INIT_ONCE_STATIC_INIT;
static CRITICAL_SECTION DynamicModulesLock;
static INIT_ONCE DynamicModulesLockInit = INIT_ONCE_STATIC_INIT;
static BOOL CALLBACK initDynamicModulesLockCb(PINIT_ONCE, PVOID, PVOID *) {
  InitializeCriticalSection(&DynamicModulesLock);
  return TRUE;
}
static void lockDynamicModules(void) {
  InitOnceExecuteOnce(&DynamicModulesLockInit, initDynamicModulesLockCb, NULL,
                      NULL);
  EnterCriticalSection(&DynamicModulesLock);
}
static void unlockDynamicModules(void) {
  LeaveCriticalSection(&DynamicModulesLock);
}
#else
static pthread_once_t HipLoadedOnce = PTHREAD_ONCE_INIT;
static pthread_mutex_t DynamicModulesLock = PTHREAD_MUTEX_INITIALIZER;
static void lockDynamicModules(void) {
  pthread_mutex_lock(&DynamicModulesLock);
}
static void unlockDynamicModules(void) {
  pthread_mutex_unlock(&DynamicModulesLock);
}
#endif

int __prof_rocm::isVerboseMode() {
  static int IsVerbose = -1;
  if (IsVerbose == -1)
    IsVerbose = getenv("LLVM_PROFILE_VERBOSE") != nullptr;
  return IsVerbose;
}

/* -------------------------------------------------------------------------- */
/*  Dynamic loading of HIP runtime symbols                                   */
/* -------------------------------------------------------------------------- */

typedef int (*hipGetSymbolAddressTy)(void **, const void *);
typedef int (*hipGetSymbolSizeTy)(size_t *, const void *);
typedef int (*hipMemcpyTy)(void *, const void *, size_t, int);
typedef int (*hipModuleGetGlobalTy)(void **, size_t *, void *, const char *);
typedef int (*hipGetDeviceCountTy)(int *);
typedef int (*hipGetDeviceTy)(int *);
typedef int (*hipSetDeviceTy)(int);
#if defined(__linux__) && !defined(_WIN32)
typedef void *HipStream;
typedef int (*hipStreamGetDeviceTy)(HipStream, int *);
#endif

/* Minimal hipDeviceProp_t (HIP 6.x R0600): only gcnArchName at offset 1160
 * is read. Padded to 4096 to tolerate ABI growth. */
typedef struct {
  char padding[1160];
  char gcnArchName[256];
  char tail_padding[2680];
} HipDevicePropMinimal;
typedef int (*hipGetDevicePropertiesTy)(HipDevicePropMinimal *, int);

static hipGetSymbolAddressTy pHipGetSymbolAddress = nullptr;
static hipGetSymbolSizeTy pHipGetSymbolSize = nullptr;
static hipMemcpyTy pHipMemcpy = nullptr;
static hipModuleGetGlobalTy pHipModuleGetGlobal = nullptr;
static hipGetDeviceCountTy pHipGetDeviceCount = nullptr;
static hipGetDeviceTy pHipGetDevice = nullptr;
static hipSetDeviceTy pHipSetDevice = nullptr;
#if defined(__linux__) && !defined(_WIN32)
static hipStreamGetDeviceTy pHipStreamGetDevice = nullptr;
#endif
static hipGetDevicePropertiesTy pHipGetDeviceProperties = nullptr;

static int NumDevices = 0;
/* 256 matches hipDeviceProp_t::gcnArchName, the source field width. */
static char (*DeviceArchNames)[256] = nullptr;
#if defined(__linux__) && !defined(_WIN32)
static unsigned char *UsedDevices = nullptr;
static int AnyDeviceUsed = 0;
#endif

#ifdef _WIN32
static wchar_t toLowerAsciiW(wchar_t C) {
  return C >= L'A' && C <= L'Z' ? C - L'A' + L'a' : C;
}

static int wcsEqualNoCase(const wchar_t *A, const wchar_t *B) {
  while (*A && *B) {
    if (toLowerAsciiW(*A) != toLowerAsciiW(*B))
      return 0;
    ++A;
    ++B;
  }
  return *A == *B;
}

static int wcsStartsWithNoCase(const wchar_t *S, const wchar_t *Prefix) {
  while (*Prefix) {
    if (toLowerAsciiW(*S) != toLowerAsciiW(*Prefix))
      return 0;
    ++S;
    ++Prefix;
  }
  return 1;
}

static int wcsEndsWithNoCase(const wchar_t *S, const wchar_t *Suffix) {
  size_t SLen = wcslen(S);
  size_t SuffixLen = wcslen(Suffix);
  return SLen >= SuffixLen && wcsEqualNoCase(S + SLen - SuffixLen, Suffix);
}

static int isHipRuntimeModuleName(const wchar_t *Name) {
  return wcsEqualNoCase(Name, L"amdhip64.dll") ||
         (wcsStartsWithNoCase(Name, L"amdhip64_") &&
          wcsEndsWithNoCase(Name, L".dll"));
}

static void *findLoadedHipRuntime(void) {
  HMODULE Handle = GetModuleHandleW(L"amdhip64.dll");
  if (Handle)
    return (void *)Handle;

  HANDLE Snapshot = CreateToolhelp32Snapshot(
      TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetCurrentProcessId());
  if (Snapshot == INVALID_HANDLE_VALUE)
    return nullptr;

  MODULEENTRY32W Entry;
  Entry.dwSize = sizeof(Entry);
  if (Module32FirstW(Snapshot, &Entry)) {
    do {
      if (isHipRuntimeModuleName(Entry.szModule)) {
        Handle = Entry.hModule;
        break;
      }
    } while (Module32NextW(Snapshot, &Entry));
  }

  CloseHandle(Snapshot);
  return (void *)Handle;
}
#endif

/* -------------------------------------------------------------------------- */
/*  Device-to-host copies                                                     */
/*  Keep HIP-only to avoid an HSA dependency.                                 */
/* -------------------------------------------------------------------------- */

static void doEnsureHipLoaded(void) {
  if (!__interception::DynamicLoaderAvailable()) {
    if (isVerboseMode())
      PROF_NOTE("%s", "Dynamic library loading not available - "
                      "HIP profiling disabled\n");
    return;
  }

#ifdef _WIN32
  /* Use the app's loaded HIP runtime to avoid binding another ROCm version. */
  void *Handle = findLoadedHipRuntime();
#else
  const char *HipLibName = "libamdhip64.so";
  void *Handle = __interception::OpenLibrary(HipLibName);
#endif
  if (!Handle)
    return;

  pHipGetSymbolAddress = (hipGetSymbolAddressTy)__interception::LookupSymbol(
      Handle, "hipGetSymbolAddress");
  pHipGetSymbolSize = (hipGetSymbolSizeTy)__interception::LookupSymbol(
      Handle, "hipGetSymbolSize");
  pHipMemcpy = (hipMemcpyTy)__interception::LookupSymbol(Handle, "hipMemcpy");
  pHipModuleGetGlobal = (hipModuleGetGlobalTy)__interception::LookupSymbol(
      Handle, "hipModuleGetGlobal");
  pHipGetDeviceCount = (hipGetDeviceCountTy)__interception::LookupSymbol(
      Handle, "hipGetDeviceCount");
  pHipGetDevice =
      (hipGetDeviceTy)__interception::LookupSymbol(Handle, "hipGetDevice");
  pHipSetDevice =
      (hipSetDeviceTy)__interception::LookupSymbol(Handle, "hipSetDevice");
#if defined(__linux__) && !defined(_WIN32)
  pHipStreamGetDevice = (hipStreamGetDeviceTy)__interception::LookupSymbol(
      Handle, "hipStreamGetDevice");
#endif
  pHipGetDeviceProperties =
      (hipGetDevicePropertiesTy)__interception::LookupSymbol(
          Handle, "hipGetDevicePropertiesR0600");
  if (!pHipGetDeviceProperties)
    pHipGetDeviceProperties =
        (hipGetDevicePropertiesTy)__interception::LookupSymbol(
            Handle, "hipGetDeviceProperties");

  if (pHipGetDeviceCount && pHipGetDeviceProperties) {
    int Count = 0;
    if (pHipGetDeviceCount(&Count) == 0 && Count > 0) {
      DeviceArchNames = (char (*)[256])calloc(Count, sizeof(*DeviceArchNames));
      if (!DeviceArchNames) {
        PROF_ERR("%s\n", "failed to allocate device arch name table");
        return;
      }
#if defined(__linux__) && !defined(_WIN32)
      UsedDevices = (unsigned char *)calloc(Count, sizeof(*UsedDevices));
      if (!UsedDevices && isVerboseMode())
        PROF_NOTE("%s\n", "Device-use tracking disabled");
#endif
      HipDevicePropMinimal Prop;
      for (int i = 0; i < Count; ++i) {
        __builtin_memset(&Prop, 0, sizeof(Prop));
        if (pHipGetDeviceProperties(&Prop, i) == 0) {
          strncpy(DeviceArchNames[i], Prop.gcnArchName,
                  sizeof(DeviceArchNames[i]) - 1);
          DeviceArchNames[i][sizeof(DeviceArchNames[i]) - 1] = '\0';
          if (isVerboseMode())
            PROF_NOTE("Device %d arch: %s\n", i, DeviceArchNames[i]);
        }
      }
      NumDevices = Count;
    }
  }
}

#ifdef _WIN32
static BOOL CALLBACK ensureHipLoadedCb(PINIT_ONCE, PVOID, PVOID *) {
  doEnsureHipLoaded();
  return TRUE;
}
#endif

void __prof_rocm::ensureHipLoaded(void) {
#ifdef _WIN32
  InitOnceExecuteOnce(&HipLoadedOnce, ensureHipLoadedCb, NULL, NULL);
#else
  pthread_once(&HipLoadedOnce, doEnsureHipLoaded);
#endif
}

// Accessor for the HSA drain: true once the loaded HIP runtime exposes
// hipMemcpy. Kept here so pHipMemcpy stays file-private to this TU.
int __prof_rocm::hipMemcpyAvailable() { return pHipMemcpy != nullptr; }

/* -------------------------------------------------------------------------- */
/*  Public wrappers that forward to the loaded HIP symbols                   */
/* -------------------------------------------------------------------------- */

static int hipGetSymbolAddress(void **devPtr, const void *symbol) {
  ensureHipLoaded();
  return pHipGetSymbolAddress ? pHipGetSymbolAddress(devPtr, symbol) : -1;
}

static int hipGetSymbolSize(size_t *size, const void *symbol) {
  ensureHipLoaded();
  return pHipGetSymbolSize ? pHipGetSymbolSize(size, symbol) : -1;
}

static int hipMemcpy(void *dest, const void *src, size_t len,
                     int kind /*2=DToH*/) {
  ensureHipLoaded();
  return pHipMemcpy ? pHipMemcpy(dest, src, len, kind) : -1;
}

/* Device section symbols must be registered with CLR first; otherwise
 * hipMemcpy may take a CPU path and crash. */
int __prof_rocm::memcpyDeviceToHost(void *Dst, const void *Src, size_t Size) {
  return hipMemcpy(Dst, Src, Size, 2 /* DToH */);
}

[[maybe_unused]]
static int hipModuleGetGlobal(void **DevPtr, size_t *Bytes, void *Module,
                              const char *Name) {
  ensureHipLoaded();
  return pHipModuleGetGlobal ? pHipModuleGetGlobal(DevPtr, Bytes, Module, Name)
                             : -1;
}

static int hipGetDevice(int *DeviceId) {
  ensureHipLoaded();
  return pHipGetDevice ? pHipGetDevice(DeviceId) : -1;
}

static int hipSetDevice(int DeviceId) {
  ensureHipLoaded();
  return pHipSetDevice ? pHipSetDevice(DeviceId) : -1;
}

#if defined(__linux__) && !defined(_WIN32)
static int hipStreamGetDevice(HipStream Stream, int *DeviceId) {
  ensureHipLoaded();
  return pHipStreamGetDevice ? pHipStreamGetDevice(Stream, DeviceId) : -1;
}

static void markDeviceUsed(int DeviceId) {
  if (DeviceId < 0 || DeviceId >= NumDevices || !UsedDevices)
    return;
  __atomic_store_n(&UsedDevices[DeviceId], 1, __ATOMIC_RELAXED);
  __atomic_store_n(&AnyDeviceUsed, 1, __ATOMIC_RELEASE);
}

static void markCurrentDeviceUsed(void) {
  int DeviceId = -1;
  if (hipGetDevice(&DeviceId) == 0)
    markDeviceUsed(DeviceId);
}

static void markLaunchStreamDeviceUsed(HipStream Stream) {
  int DeviceId = -1;
  if (Stream && hipStreamGetDevice(Stream, &DeviceId) == 0) {
    markDeviceUsed(DeviceId);
    return;
  }
  markCurrentDeviceUsed();
}

static int shouldCollectDevice(int DeviceId) {
  if (UsedDevices && __atomic_load_n(&AnyDeviceUsed, __ATOMIC_ACQUIRE) &&
      !__atomic_load_n(&UsedDevices[DeviceId], __ATOMIC_RELAXED))
    return 0;
  return 1;
}
#else
static int shouldCollectDevice(int) { return 1; }
#endif

static const char *getDeviceArchName(int DeviceId) {
  if (DeviceId < 0 || DeviceId >= NumDevices || !DeviceArchNames[DeviceId][0])
    return "amdgpu";
  return DeviceArchNames[DeviceId];
}

/* -------------------------------------------------------------------------- */
/*  Dynamic module tracking                                                   */
/* -------------------------------------------------------------------------- */

/* Per-TU profile entry inside a dynamic module.
 * A single dynamic module may contain multiple TUs (e.g. -fgpu-rdc). */
typedef struct {
  void *DeviceVar; /* device address of __llvm_profile_sections_<CUID> */
  int Processed;   /* 0 = not yet collected, 1 = data already copied   */
} OffloadDynamicTUInfo;

/* One entry per hipModuleLoad call. */
typedef struct {
  void *ModulePtr;           /* hipModule_t handle                        */
  OffloadDynamicTUInfo *TUs; /* array of per-TU entries                 */
  int NumTUs;
  int CapTUs;
} OffloadDynamicModuleInfo;

static OffloadDynamicModuleInfo *DynamicModules = nullptr;
static int NumDynamicModules = 0;
static int CapDynamicModules = 0;

/* -------------------------------------------------------------------------- */
/*  ELF symbol enumeration (manual parse: compiler-rt cannot link LLVM Support)
 */
/* -------------------------------------------------------------------------- */

#if __has_include(<elf.h>)
#include <elf.h>

/* Callback invoked for every matching symbol name found in the ELF image.
 * Return 0 to continue iteration, non-zero to stop. */
typedef int (*SymbolCallback)(const char *Name, void *UserData);

/* If Image is a clang offload bundle, return a pointer to the first embedded
 * ELF. Returns Image if not a bundle, nullptr if a bundle holds no ELF. */
static const void *unwrapOffloadBundle(const void *Image) {
  static const char BundleMagic[] = "__CLANG_OFFLOAD_BUNDLE__";
  if (memcmp(Image, BundleMagic, sizeof(BundleMagic) - 1) != 0)
    return Image; /* Not a bundle, return as-is. */

  const char *Buf = (const char *)Image;
  uint64_t NumEntries;
  __builtin_memcpy(&NumEntries, Buf + sizeof(BundleMagic) - 1,
                   sizeof(uint64_t));

  /* Walk the entry table (starts at offset 32). */
  const char *Cursor = Buf + 32;
  for (uint64_t I = 0; I < NumEntries; ++I) {
    uint64_t EntryOffset, EntrySize, IDSize;
    __builtin_memcpy(&EntryOffset, Cursor, sizeof(EntryOffset));
    Cursor += sizeof(EntryOffset);
    __builtin_memcpy(&EntrySize, Cursor, sizeof(EntrySize));
    Cursor += sizeof(EntrySize);
    __builtin_memcpy(&IDSize, Cursor, sizeof(IDSize));
    Cursor += sizeof(IDSize);
    Cursor += IDSize; /* skip entry ID */

    if (EntrySize >= sizeof(Elf64_Ehdr)) {
      const Elf64_Ehdr *E = (const Elf64_Ehdr *)(Buf + EntryOffset);
      if (E->e_ident[EI_MAG0] == ELFMAG0 && E->e_ident[EI_MAG1] == ELFMAG1 &&
          E->e_ident[EI_MAG2] == ELFMAG2 && E->e_ident[EI_MAG3] == ELFMAG3) {
        return (const void *)(Buf + EntryOffset);
      }
    }
  }

  PROF_WARN("%s", "offload bundle contains no valid ELF entries\n");
  return nullptr;
}

/* Invoke CB for every global symbol in Image (an AMDGPU ELF or offload bundle)
 * whose name starts with PREFIX. Image may be null. */
static void enumerateElfSymbols(const void *Image, const char *Prefix,
                                SymbolCallback CB, void *UserData) {
  if (!Image)
    return;

  Image = unwrapOffloadBundle(Image);
  if (!Image)
    return;

  const Elf64_Ehdr *Ehdr = (const Elf64_Ehdr *)Image;
  if (Ehdr->e_ident[EI_MAG0] != ELFMAG0 || Ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
      Ehdr->e_ident[EI_MAG2] != ELFMAG2 || Ehdr->e_ident[EI_MAG3] != ELFMAG3) {
    if (isVerboseMode())
      PROF_NOTE("%s", "Image is not a valid ELF, skipping enumeration\n");
    return;
  }

  size_t PrefixLen = strlen(Prefix);
  const char *Base = (const char *)Image;
  const Elf64_Shdr *Shdrs = (const Elf64_Shdr *)(Base + Ehdr->e_shoff);

  for (int i = 0; i < Ehdr->e_shnum; ++i) {
    if (Shdrs[i].sh_type != SHT_SYMTAB)
      continue;

    const Elf64_Sym *Syms = (const Elf64_Sym *)(Base + Shdrs[i].sh_offset);
    int NumSyms = Shdrs[i].sh_size / sizeof(Elf64_Sym);
    /* String table is the section referenced by sh_link. */
    const char *StrTab = Base + Shdrs[Shdrs[i].sh_link].sh_offset;

    for (int j = 0; j < NumSyms; ++j) {
      if (Syms[j].st_name == 0)
        continue;
      const char *Name = StrTab + Syms[j].st_name;
      if (strncmp(Name, Prefix, PrefixLen) == 0) {
        if (CB(Name, UserData))
          return;
      }
    }
  }
}

/* State passed through the enumeration callback. */
typedef struct {
  void *Module; /* hipModule_t */
  OffloadDynamicModuleInfo *ModInfo;
} EnumState;

/* Register one __llvm_profile_sections_<CUID> symbol on the module entry.
 * hipModuleGetGlobal also registers the device address with CLR so hipMemcpy
 * can copy from it later. */
static int registerPrfSymbol(const char *Name, void *UserData) {
  EnumState *S = (EnumState *)UserData;
  OffloadDynamicModuleInfo *MI = S->ModInfo;

  /* The symbol is the per-TU sections struct itself, not a pointer
   * indirection, so this address is the hipMemcpy source. */
  void *DeviceVar = nullptr;
  size_t Bytes = 0;
  if (hipModuleGetGlobal(&DeviceVar, &Bytes, S->Module, Name) != 0) {
    PROF_WARN("failed to get symbol %s for module %p\n", Name, S->Module);
    return 0; /* continue */
  }

  if (growArray((void **)&MI->TUs, &MI->CapTUs, MI->NumTUs + 1, 4,
                sizeof(*MI->TUs))) {
    PROF_ERR("%s\n", "failed to grow TU array");
    return 0;
  }
  OffloadDynamicTUInfo *TU = &MI->TUs[MI->NumTUs++];
  TU->DeviceVar = DeviceVar;
  TU->Processed = 0;

  (void)Name;
  return 0; /* continue enumeration */
}

#endif /* __has_include(<elf.h>) */

/* -------------------------------------------------------------------------- */
/*  Registration / un-registration helpers                                   */
/* -------------------------------------------------------------------------- */

extern "C" void
__llvm_profile_offload_register_dynamic_module(int ModuleLoadRc, void **Ptr,
                                               const void *Image) {
  if (ModuleLoadRc)
    return;

  lockDynamicModules();

  if (isVerboseMode())
    PROF_NOTE("Registering loaded module %d: rc=%d, module=%p, image=%p\n",
              NumDynamicModules, ModuleLoadRc, *Ptr, Image);

  if (growArray((void **)&DynamicModules, &CapDynamicModules,
                NumDynamicModules + 1, 64, sizeof(*DynamicModules))) {
    unlockDynamicModules();
    return;
  }

  OffloadDynamicModuleInfo *MI = &DynamicModules[NumDynamicModules++];
  MI->ModulePtr = *Ptr;
  MI->TUs = nullptr;
  MI->NumTUs = 0;
  MI->CapTUs = 0;

  /* Dynamic-module profiling needs ELF parsing for symbol enumeration. */
#if __has_include(<elf.h>)
  EnumState State = {*Ptr, MI};
  enumerateElfSymbols(Image, "__llvm_profile_sections_", registerPrfSymbol,
                      &State);
#else
  (void)Image;
  if (isVerboseMode())
    PROF_NOTE("%s",
              "Dynamic module profiling not supported on this platform\n");
#endif

  if (MI->NumTUs == 0) {
    PROF_WARN("no __llvm_profile_sections_* symbols found in module %p\n",
              *Ptr);
  } else if (isVerboseMode()) {
    PROF_NOTE("Module %p: registered %d TU(s)\n", *Ptr, MI->NumTUs);
  }

  unlockDynamicModules();
}

extern "C" void __llvm_profile_offload_unregister_dynamic_module(void *Ptr) {
  lockDynamicModules();
  for (int i = 0; i < NumDynamicModules; ++i) {
    OffloadDynamicModuleInfo *MI = &DynamicModules[i];

    /* HIP recycles hipModule_t addresses; drained slots are cleared so a
     * recycled handle finds the new slot, not the dead one. */
    if (MI->ModulePtr != Ptr)
      continue;

    if (isVerboseMode())
      PROF_NOTE("Unregistering module %p (%d TUs)\n", MI->ModulePtr,
                MI->NumTUs);

    static int NextTUIndex = 0;
    for (int t = 0; t < MI->NumTUs; ++t) {
      OffloadDynamicTUInfo *TU = &MI->TUs[t];
      if (TU->Processed) {
        if (isVerboseMode())
          PROF_NOTE("Module %p TU %d already processed, skipping\n", Ptr, t);
        continue;
      }
      int TUIndex = __atomic_fetch_add(&NextTUIndex, 1, __ATOMIC_RELAXED);
      if (TU->DeviceVar) {
        int CurDev = 0;
        hipGetDevice(&CurDev);
        const char *ArchName = getDeviceArchName(CurDev);
        /* Encode TUIndex in Target so each drain writes a distinct profraw;
         * otherwise back-to-back drains overwrite the same file. */
        char TargetWithTU[64];
        snprintf(TargetWithTU, sizeof(TargetWithTU), "%s.%d", ArchName,
                 TUIndex);
        if (processDeviceOffloadPrf(TU->DeviceVar, TargetWithTU, nullptr) == 0)
          TU->Processed = 1;
        else
          PROF_WARN("failed to process profile data for module %p TU %d\n", Ptr,
                    t);
      }
    }
    MI->ModulePtr = nullptr;
    unlockDynamicModules();
    return;
  }

  if (isVerboseMode())
    PROF_WARN("unregister called for unknown module %p\n", Ptr);
  unlockDynamicModules();
}

static void **OffloadShadowVariables = nullptr;
static int NumShadowVariables = 0;
static int CapShadowVariables = 0;

struct OffloadSectionShadow {
  void *Data;
  void *Counters;
  void *UniformCounters;
  void *Names;
};

struct OffloadSectionShadowGroup {
  OffloadSectionShadow *Shadows;
  int NumShadows;
  int CapShadows;
  int NumSections;
};

static OffloadSectionShadowGroup *OffloadSectionShadowGroups = nullptr;
static int CapSectionShadowGroups = 0;

static int ensureSectionShadowGroupCapacity(void) {
  return growArray((void **)&OffloadSectionShadowGroups,
                   &CapSectionShadowGroups, CapShadowVariables,
                   CapShadowVariables, sizeof(*OffloadSectionShadowGroups));
}

static int ensureSectionShadowCapacity(OffloadSectionShadowGroup *Group,
                                       int MinCapacity) {
  return growArray((void **)&Group->Shadows, &Group->CapShadows, MinCapacity, 4,
                   sizeof(*Group->Shadows));
}

extern "C" void __llvm_profile_offload_register_shadow_variable(void *ptr) {
  if (growArray((void **)&OffloadShadowVariables, &CapShadowVariables,
                NumShadowVariables + 1, 64, sizeof(*OffloadShadowVariables)))
    return;
  if (ensureSectionShadowGroupCapacity())
    return;
  int Index = NumShadowVariables++;
  OffloadShadowVariables[Index] = ptr;
  __builtin_memset(&OffloadSectionShadowGroups[Index], 0,
                   sizeof(OffloadSectionShadowGroups[Index]));
}

extern "C" void
__llvm_profile_offload_register_section_shadow_variable(void *ptr) {
  if (NumShadowVariables == 0)
    return;

  /* Match CGCUDANV.cpp: data, counters, uniform counters, then names for each
   * kernel. */
  OffloadSectionShadowGroup *Group =
      &OffloadSectionShadowGroups[NumShadowVariables - 1];
  int ShadowIndex = Group->NumSections / 4;
  if (ensureSectionShadowCapacity(Group, ShadowIndex + 1))
    return;
  if (ShadowIndex >= Group->NumShadows)
    Group->NumShadows = ShadowIndex + 1;

  OffloadSectionShadow *Shadow = &Group->Shadows[ShadowIndex];
  switch (Group->NumSections % 4) {
  case 0:
    Shadow->Data = ptr;
    break;
  case 1:
    Shadow->Counters = ptr;
    break;
  case 2:
    Shadow->UniformCounters = ptr;
    break;
  case 3:
    Shadow->Names = ptr;
    break;
  }
  ++Group->NumSections;
}

namespace {

struct ProfileSectionCopy {
  const char *Name;
  const void *DevBegin;
  size_t Size;
  const void *&CachedDevBegin;
  char *&CachedHost;
  size_t &CachedSize;
  UniqueFree Owner;
  char *HostBegin = nullptr;
  bool Reused = false;

  ProfileSectionCopy(const char *Name, const void *DevBegin, size_t Size,
                     const void *&CachedDevBegin, char *&CachedHost,
                     size_t &CachedSize)
      : Name(Name), DevBegin(DevBegin), Size(Size),
        CachedDevBegin(CachedDevBegin), CachedHost(CachedHost),
        CachedSize(CachedSize) {}

  ProfileSectionCopy(const ProfileSectionCopy &) = delete;
  ProfileSectionCopy &operator=(const ProfileSectionCopy &) = delete;

  int prepare() {
    if (Size == 0)
      return 0;
    if (DevBegin == CachedDevBegin && Size == CachedSize) {
      HostBegin = CachedHost;
      Reused = true;
      if (isVerboseMode())
        PROF_NOTE("Reusing cached %s section (%zu bytes)\n", Name, Size);
    } else {
      HostBegin = static_cast<char *>(malloc(Size));
      Owner.reset(HostBegin);
    }
    return HostBegin ? 0 : -1;
  }

  int copy() {
    if (Size == 0 || Reused)
      return 0;
    return memcpyDeviceToHost(HostBegin, DevBegin, Size);
  }

  void commitCache() {
    if (Reused || Size == 0)
      return;
    CachedDevBegin = DevBegin;
    CachedHost = HostBegin;
    CachedSize = Size;
    Owner.release();
  }
};

} // namespace

static int getRegisteredSectionBounds(void *Shadow, void **DevicePtr,
                                      size_t *Size) {
  *DevicePtr = nullptr;
  *Size = 0;
  int AddrRc = hipGetSymbolAddress(DevicePtr, Shadow);
  int SizeRc = hipGetSymbolSize(Size, Shadow);
  return AddrRc == 0 && SizeRc == 0 && *DevicePtr && *Size > 0 ? 0 : -1;
}

struct RegisteredSectionRange {
  const void *Data;
  const void *Counters;
  const void *UniformCounters;
  const void *Names;
  size_t DataSize;
  size_t CountersSize;
  size_t UniformCountersSize;
  size_t NamesSize;
  size_t DataOffset;
  size_t CountersOffset;
  size_t UniformCountersOffset;
  size_t NamesOffset;
};

static int
hasCompleteSectionShadows(const OffloadSectionShadowGroup *Sections) {
  if (!Sections || Sections->NumShadows == 0 || Sections->NumSections % 4 != 0)
    return 0;
  for (int I = 0; I < Sections->NumShadows; ++I) {
    if (!Sections->Shadows[I].Data || !Sections->Shadows[I].Counters ||
        !Sections->Shadows[I].UniformCounters || !Sections->Shadows[I].Names)
      return 0;
  }
  return 1;
}

int __prof_rocm::processDeviceOffloadPrf(
    void *DeviceOffloadPrf, const char *Target,
    const OffloadSectionShadowGroup *Sections) {
  __llvm_profile_gpu_sections HostSections;

  if (hipMemcpy(&HostSections, DeviceOffloadPrf, sizeof(HostSections),
                2 /*DToH*/) != 0) {
    PROF_ERR("%s\n", "failed to copy offload prf structure from device");
    return -1;
  }

  const void *DevCntsBegin = HostSections.CountersStart;
  const void *DevDataBegin = HostSections.DataStart;
  const void *DevNamesBegin = HostSections.NamesStart;
  const void *DevUniformCntsBegin = HostSections.UniformCountersStart;
  const void *DevCntsEnd = HostSections.CountersStop;
  const void *DevDataEnd = HostSections.DataStop;
  const void *DevNamesEnd = HostSections.NamesStop;
  const void *DevUniformCntsEnd = HostSections.UniformCountersStop;

  size_t CountersSize = (const char *)DevCntsEnd - (const char *)DevCntsBegin;
  size_t DataSize = (const char *)DevDataEnd - (const char *)DevDataBegin;
  size_t NamesSize = (const char *)DevNamesEnd - (const char *)DevNamesBegin;
  size_t UniformCountersSize =
      (const char *)DevUniformCntsEnd - (const char *)DevUniformCntsBegin;

  int UseRegisteredSections = hasCompleteSectionShadows(Sections);
  RegisteredSectionRange *RegisteredRanges = nullptr;
  int NumRegisteredRanges = 0;

  if (isVerboseMode())
    PROF_NOTE("Section pointers: Cnts=[%p,%p]=%zu Data=[%p,%p]=%zu "
              "Names=[%p,%p]=%zu UCnts=[%p,%p]=%zu\n",
              DevCntsBegin, DevCntsEnd, CountersSize, DevDataBegin, DevDataEnd,
              DataSize, DevNamesBegin, DevNamesEnd, NamesSize,
              DevUniformCntsBegin, DevUniformCntsEnd, UniformCountersSize);

  if (CountersSize == 0 || DataSize == 0)
    return 0;

  int ret = -1;

  /* Sections using linker-defined __start_/__stop_ bounds are shared across
     TU structs in RDC mode. Deduplicate by caching the last copied range. */
  static const void *CachedDevNamesBegin = nullptr;
  static char *CachedHostNames = nullptr;
  static size_t CachedNamesSize = 0;

  static const void *CachedDevCntsBegin = nullptr;
  static char *CachedHostCnts = nullptr;
  static size_t CachedCntsSize = 0;

  static const void *CachedDevDataBegin = nullptr;
  static char *CachedHostData = nullptr;
  static size_t CachedDataSize = 0;

  static const void *CachedDevUCntsBegin = nullptr;
  static char *CachedHostUCnts = nullptr;
  static size_t CachedUCntsSize = 0;

  ProfileSectionCopy Cnts("counters", DevCntsBegin, CountersSize,
                          CachedDevCntsBegin, CachedHostCnts, CachedCntsSize);
  ProfileSectionCopy Data("data", DevDataBegin, DataSize, CachedDevDataBegin,
                          CachedHostData, CachedDataSize);
  ProfileSectionCopy Names("names", DevNamesBegin, NamesSize,
                           CachedDevNamesBegin, CachedHostNames,
                           CachedNamesSize);
  ProfileSectionCopy UCnts("ucnts", DevUniformCntsBegin, UniformCountersSize,
                           CachedDevUCntsBegin, CachedHostUCnts,
                           CachedUCntsSize);

  UniqueFree RegisteredRangeOwner;

  if (UseRegisteredSections) {
    NumRegisteredRanges = Sections->NumShadows;
    RegisteredRangeOwner.reset(
        malloc(NumRegisteredRanges * sizeof(RegisteredSectionRange)));
    RegisteredRanges = (RegisteredSectionRange *)RegisteredRangeOwner.get();
    if (!RegisteredRanges) {
      PROF_ERR("%s\n", "failed to allocate registered section table");
      return -1;
    }
    __builtin_memset(RegisteredRanges, 0,
                     NumRegisteredRanges * sizeof(*RegisteredRanges));

    size_t RegisteredDataSize = 0;
    size_t RegisteredCountersSize = 0;
    size_t RegisteredUniformCountersSize = 0;
    size_t RegisteredNamesSize = 0;
    for (int I = 0; I < NumRegisteredRanges; ++I) {
      void *Data = nullptr;
      void *Counters = nullptr;
      void *UniformCounters = nullptr;
      void *Names = nullptr;
      size_t ThisDataSize = 0;
      size_t ThisCountersSize = 0;
      size_t ThisUniformCountersSize = 0;
      size_t ThisNamesSize = 0;
      OffloadSectionShadow *Shadow = &Sections->Shadows[I];
      if (getRegisteredSectionBounds(Shadow->Data, &Data, &ThisDataSize) != 0 ||
          getRegisteredSectionBounds(Shadow->Counters, &Counters,
                                     &ThisCountersSize) != 0 ||
          getRegisteredSectionBounds(Shadow->UniformCounters, &UniformCounters,
                                     &ThisUniformCountersSize) != 0 ||
          getRegisteredSectionBounds(Shadow->Names, &Names, &ThisNamesSize) !=
              0) {
        PROF_ERR("%s\n", "failed to get registered section bounds");
        return -1;
      }

      RegisteredRanges[I].Data = Data;
      RegisteredRanges[I].Counters = Counters;
      RegisteredRanges[I].UniformCounters = UniformCounters;
      RegisteredRanges[I].Names = Names;
      RegisteredRanges[I].DataSize = ThisDataSize;
      RegisteredRanges[I].CountersSize = ThisCountersSize;
      RegisteredRanges[I].UniformCountersSize = ThisUniformCountersSize;
      RegisteredRanges[I].NamesSize = ThisNamesSize;
      RegisteredRanges[I].DataOffset = RegisteredDataSize;
      RegisteredRanges[I].CountersOffset = RegisteredCountersSize;
      RegisteredRanges[I].UniformCountersOffset = RegisteredUniformCountersSize;
      RegisteredDataSize += ThisDataSize;
      RegisteredCountersSize += ThisCountersSize;
      RegisteredUniformCountersSize += ThisUniformCountersSize;

      int ReuseNames = 0;
      for (int J = 0; J < I; ++J) {
        if (RegisteredRanges[J].Names == Names &&
            RegisteredRanges[J].NamesSize == ThisNamesSize) {
          RegisteredRanges[I].NamesOffset = RegisteredRanges[J].NamesOffset;
          ReuseNames = 1;
          break;
        }
      }
      if (!ReuseNames) {
        RegisteredRanges[I].NamesOffset = RegisteredNamesSize;
        RegisteredNamesSize += ThisNamesSize;
      }
    }

    DataSize = RegisteredDataSize;
    CountersSize = RegisteredCountersSize;
    UniformCountersSize = RegisteredUniformCountersSize;
    NamesSize = RegisteredNamesSize;
    Data.HostBegin = DataSize ? (char *)malloc(DataSize) : nullptr;
    Cnts.HostBegin = CountersSize ? (char *)malloc(CountersSize) : nullptr;
    UCnts.HostBegin =
        UniformCountersSize ? (char *)malloc(UniformCountersSize) : nullptr;
    Names.HostBegin = NamesSize ? (char *)malloc(NamesSize) : nullptr;
    Data.Owner.reset(Data.HostBegin);
    Cnts.Owner.reset(Cnts.HostBegin);
    UCnts.Owner.reset(UCnts.HostBegin);
    Names.Owner.reset(Names.HostBegin);
    if ((DataSize > 0 && !Data.HostBegin) ||
        (CountersSize > 0 && !Cnts.HostBegin) ||
        (UniformCountersSize > 0 && !UCnts.HostBegin) ||
        (NamesSize > 0 && !Names.HostBegin)) {
      PROF_ERR("%s\n", "failed to allocate host memory for device sections");
      return -1;
    }

    for (int I = 0; I < NumRegisteredRanges; ++I) {
      RegisteredSectionRange *R = &RegisteredRanges[I];
      if (memcpyDeviceToHost(Data.HostBegin + R->DataOffset, R->Data,
                             R->DataSize) != 0 ||
          memcpyDeviceToHost(Cnts.HostBegin + R->CountersOffset, R->Counters,
                             R->CountersSize) != 0 ||
          memcpyDeviceToHost(UCnts.HostBegin + R->UniformCountersOffset,
                             R->UniformCounters, R->UniformCountersSize) != 0) {
        PROF_ERR("%s\n", "failed to copy profile sections from device");
        return -1;
      }

      int CopyNames = 1;
      for (int J = 0; J < I; ++J) {
        if (RegisteredRanges[J].Names == R->Names &&
            RegisteredRanges[J].NamesSize == R->NamesSize) {
          CopyNames = 0;
          break;
        }
      }
      if (CopyNames && R->NamesSize > 0 &&
          memcpyDeviceToHost(Names.HostBegin + R->NamesOffset, R->Names,
                             R->NamesSize) != 0) {
        PROF_ERR("%s\n", "failed to copy profile sections from device");
        return -1;
      }
    }
  } else {
    if (Cnts.prepare() != 0 || Data.prepare() != 0 || Names.prepare() != 0 ||
        UCnts.prepare() != 0) {
      PROF_ERR("%s\n", "failed to allocate host memory for device sections");
      return -1;
    }

    if (Data.copy() != 0 || Cnts.copy() != 0 || Names.copy() != 0 ||
        UCnts.copy() != 0) {
      PROF_ERR("%s\n", "failed to copy profile sections from device");
      return -1;
    }

    /* Cache buffers so RDC-mode multi-shadow drains can reuse them.
     * release() prevents the scope guards from freeing what the cache owns. */
    Cnts.commitCache();
    Data.commitCache();
    Names.commitCache();
    UCnts.commitCache();
  }

  if (isVerboseMode())
    PROF_NOTE("Copied device sections: Counters=%zu, Data=%zu, Names=%zu, "
              "UniformCounters=%zu\n",
              CountersSize, DataSize, NamesSize, UniformCountersSize);

  // Arrange buffer as [Data][Padding][Counters][Names] to match the layout
  // expected by lprofWriteDataImpl (CountersDelta = CountersBegin - DataBegin).
  const uint64_t NumData = DataSize / sizeof(__llvm_profile_data);
  const uint64_t NumBitmapBytes = 0;
  const uint64_t NumUniformCounters = UniformCountersSize / sizeof(uint64_t);
  const uint64_t VTableSectionSize = 0;
  const uint64_t VNamesSize = 0;
  uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
      PaddingBytesAfterBitmapBytes, PaddingBytesAfterUniformCounters,
      PaddingBytesAfterNames, PaddingBytesAfterVTable, PaddingBytesAfterVNames;

  if (__llvm_profile_get_padding_sizes_for_counters(
          DataSize, CountersSize, NumBitmapBytes, NumUniformCounters, NamesSize,
          VTableSectionSize, VNamesSize, &PaddingBytesBeforeCounters,
          &PaddingBytesAfterCounters, &PaddingBytesAfterBitmapBytes,
          &PaddingBytesAfterUniformCounters, &PaddingBytesAfterNames,
          &PaddingBytesAfterVTable, &PaddingBytesAfterVNames) != 0) {
    PROF_ERR("%s\n", "failed to get padding sizes");
    return -1;
  }

  size_t ContiguousBufferSize =
      DataSize + PaddingBytesBeforeCounters + CountersSize + NamesSize;
  UniqueFree ContiguousBuf(malloc(ContiguousBufferSize));
  if (!ContiguousBuf.get()) {
    PROF_ERR("%s\n", "failed to allocate contiguous buffer");
    return -1;
  }
  char *ContiguousBuffer = ContiguousBuf.get();
  __builtin_memset(ContiguousBuffer, 0, ContiguousBufferSize);

  char *BufDataBegin = ContiguousBuffer;
  char *BufCountersBegin =
      ContiguousBuffer + DataSize + PaddingBytesBeforeCounters;
  char *BufNamesBegin = BufCountersBegin + CountersSize;

  __builtin_memcpy(BufDataBegin, Data.HostBegin, DataSize);
  __builtin_memcpy(BufCountersBegin, Cnts.HostBegin, CountersSize);
  __builtin_memcpy(BufNamesBegin, Names.HostBegin, NamesSize);

  // CounterPtr and UniformCounterPtr are device-relative offsets; relocate
  // them for the file layout where the Data section precedes the Counters and
  // UniformCounters sections. Uniform counters are copied in linker (section)
  // order and located via their relative pointer, exactly like the regular
  // counters: llvm-profdata reads them through UniformCounterPtr (decrementing
  // UniformCountersDelta per record, just like CountersDelta) and does not
  // assume data-record order, so no reordering is needed.
  ptrdiff_t UCFileOffset = DataSize + PaddingBytesBeforeCounters +
                           CountersSize + PaddingBytesAfterCounters +
                           NumBitmapBytes + PaddingBytesAfterBitmapBytes;
  __llvm_profile_data *RelocatedData = (__llvm_profile_data *)BufDataBegin;
  for (uint64_t i = 0; i < NumData; ++i) {
    size_t DataRecordOffset = i * sizeof(__llvm_profile_data);
    const char *RangeDevDataBegin = (const char *)DevDataBegin;
    const char *RangeDevCountersBegin = (const char *)DevCntsBegin;
    const char *RangeDevUCntsBegin = (const char *)DevUniformCntsBegin;
    size_t RangeCountersOffset = 0;
    size_t RangeUCntsOffset = 0;
    if (UseRegisteredSections) {
      int FoundRange = 0;
      for (int R = 0; R < NumRegisteredRanges; ++R) {
        RegisteredSectionRange *Range = &RegisteredRanges[R];
        if (DataRecordOffset < Range->DataOffset ||
            DataRecordOffset >= Range->DataOffset + Range->DataSize)
          continue;
        RangeDevDataBegin = (const char *)Range->Data;
        RangeDevCountersBegin = (const char *)Range->Counters;
        RangeDevUCntsBegin = (const char *)Range->UniformCounters;
        RangeCountersOffset = Range->CountersOffset;
        RangeUCntsOffset = Range->UniformCountersOffset;
        DataRecordOffset -= Range->DataOffset;
        FoundRange = 1;
        break;
      }
      if (!FoundRange) {
        PROF_ERR("%s\n", "failed to locate profile data record range");
        return -1;
      }
    }
    const char *DeviceDataStructAddr = RangeDevDataBegin + DataRecordOffset;
    if (RelocatedData[i].CounterPtr) {
      const char *DeviceCountersAddr =
          DeviceDataStructAddr + (ptrdiff_t)RelocatedData[i].CounterPtr;
      ptrdiff_t OffsetIntoCountersSection =
          DeviceCountersAddr - RangeDevCountersBegin;
      ptrdiff_t NewRelativeOffset =
          DataSize + PaddingBytesBeforeCounters + RangeCountersOffset +
          OffsetIntoCountersSection - (i * sizeof(__llvm_profile_data));
      __builtin_memcpy((char *)RelocatedData + i * sizeof(__llvm_profile_data) +
                           offsetof(__llvm_profile_data, CounterPtr),
                       &NewRelativeOffset, sizeof(NewRelativeOffset));
    }
    if (UCnts.HostBegin && RelocatedData[i].UniformCounterPtr) {
      const char *DeviceUCAddr =
          DeviceDataStructAddr + (ptrdiff_t)RelocatedData[i].UniformCounterPtr;
      ptrdiff_t OffsetIntoUCSection = DeviceUCAddr - RangeDevUCntsBegin;
      ptrdiff_t NewUCRelativeOffset = UCFileOffset + RangeUCntsOffset +
                                      OffsetIntoUCSection -
                                      (i * sizeof(__llvm_profile_data));
      __builtin_memcpy((char *)RelocatedData + i * sizeof(__llvm_profile_data) +
                           offsetof(__llvm_profile_data, UniformCounterPtr),
                       &NewUCRelativeOffset, sizeof(NewUCRelativeOffset));
    } else {
      __builtin_memset((char *)RelocatedData + i * sizeof(__llvm_profile_data) +
                           offsetof(__llvm_profile_data, UniformCounterPtr),
                       0, sizeof(RelocatedData[i].UniformCounterPtr));
    }
    __builtin_memset((char *)RelocatedData + i * sizeof(__llvm_profile_data) +
                         offsetof(__llvm_profile_data, BitmapPtr),
                     0,
                     sizeof(RelocatedData[i].BitmapPtr) +
                         sizeof(RelocatedData[i].FunctionPointer) +
                         sizeof(RelocatedData[i].Values));
  }

  ret = __llvm_write_custom_profile(
      Target, (__llvm_profile_data *)BufDataBegin,
      (__llvm_profile_data *)(BufDataBegin + DataSize), BufCountersBegin,
      BufCountersBegin + CountersSize, UCnts.HostBegin,
      UCnts.HostBegin ? UCnts.HostBegin + UniformCountersSize : nullptr,
      BufNamesBegin, BufNamesBegin + NamesSize, nullptr);

  if (ret != 0) {
    PROF_ERR("%s\n", "failed to write device profile using shared API");
  } else {
#if defined(__linux__) && !defined(_WIN32)
    // Dedup against the supplemental HSA pass: this section is now drained, so
    // the HSA walk must not drain the same device code object again.
    profRecordDrainedBounds(DevDataBegin, DevCntsBegin, DevNamesBegin);
#endif
    if (isVerboseMode())
      PROF_NOTE("%s\n", "Successfully wrote device profile using shared API");
  }

  return ret;
}

static int processShadowVariable(int Index, const char *Target) {
  void *ShadowVar = OffloadShadowVariables[Index];
  void *DeviceSections = nullptr;
  if (hipGetSymbolAddress(&DeviceSections, ShadowVar) != 0) {
    PROF_WARN("failed to get symbol address for shadow variable %p\n",
              ShadowVar);
    return -1;
  }
  /* DeviceSections points at the per-TU sections struct itself. */
  const OffloadSectionShadowGroup *Sections = nullptr;
  if (Index < CapSectionShadowGroups)
    Sections = &OffloadSectionShadowGroups[Index];
  if (!hasCompleteSectionShadows(Sections))
    return 0;
  return processDeviceOffloadPrf(DeviceSections, Target, Sections);
}

static int isHipAvailable(void) {
  ensureHipLoaded();
  return pHipMemcpy != nullptr && pHipGetSymbolAddress != nullptr;
}

/* -------------------------------------------------------------------------- */
/*  Collect device-side profile data                                          */
/* -------------------------------------------------------------------------- */

/* Host-shadow drain: static-linked kernels (host __hipRegisterVar shadows) and
 * intercepted dynamic modules. The caller gates this on
 * (NumShadowVariables || NumDynamicModules) && isHipAvailable(); pure
 * device-linked programs (RCCL) are handled by the supplemental HSA pass. */
static int collectHostShadowData(void) {
  int Ret = 0;

  /* Shadow variables (static-linked kernels): drain from every device. */
  if (NumShadowVariables > 0) {
    int OrigDevice = -1;
    hipGetDevice(&OrigDevice);

    for (int Dev = 0; Dev < NumDevices; ++Dev) {
      if (!shouldCollectDevice(Dev)) {
        if (isVerboseMode())
          PROF_NOTE("Skipping unused device %d\n", Dev);
        continue;
      }
#if defined(__linux__) && !defined(_WIN32)
      /* When no kernel launch was tracked at all, shouldCollectDevice() falls
       * back to collect-all, which can fault/hang reading a non-resident
       * device's sections on a multi-GPU host. On Linux the supplemental HSA
       * drain covers those cases safely. */
      if (!__atomic_load_n(&AnyDeviceUsed, __ATOMIC_ACQUIRE)) {
        if (isVerboseMode())
          PROF_NOTE("No tracked launch; deferring device %d to HSA drain\n",
                    Dev);
        continue;
      }
#endif
      if (hipSetDevice(Dev) != 0) {
        if (isVerboseMode())
          PROF_NOTE("Failed to set device %d, skipping\n", Dev);
        continue;
      }
      const char *ArchName = getDeviceArchName(Dev);
      if (isVerboseMode())
        PROF_NOTE("Collecting static profile data from device %d (%s)\n", Dev,
                  ArchName);
      for (int i = 0; i < NumShadowVariables; ++i) {
        /* Stable name per shadow so a repeated drain (explicit collect plus the
         * atexit drain) overwrites its own profraw rather than emitting a
         * second one: bare arch for a single TU, arch.<i> for RDC multi-TU. */
        const char *Target = ArchName;
        char TargetWithIdx[64];
        if (NumShadowVariables > 1) {
          snprintf(TargetWithIdx, sizeof(TargetWithIdx), "%s.%d", ArchName, i);
          Target = TargetWithIdx;
        }
        if (processShadowVariable(i, Target) != 0)
          Ret = -1;
      }
    }

    if (OrigDevice >= 0)
      hipSetDevice(OrigDevice);
  }

  /* Warn about unprocessed TUs; skip cleared slots (already drained). */
  lockDynamicModules();
  for (int i = 0; i < NumDynamicModules; ++i) {
    OffloadDynamicModuleInfo *MI = &DynamicModules[i];
    if (!MI->ModulePtr)
      continue;
    for (int t = 0; t < MI->NumTUs; ++t) {
      if (!MI->TUs[t].Processed) {
        PROF_WARN("dynamic module %p TU %d was not processed before exit\n",
                  MI->ModulePtr, t);
        Ret = -1;
      }
    }
  }
  unlockDynamicModules();

  return Ret;
}

extern "C" int __llvm_profile_hip_collect_device_data(void) {
  int Ret = 0;

  if ((NumShadowVariables != 0 || NumDynamicModules != 0) && isHipAvailable() &&
      collectHostShadowData() != 0)
    Ret = -1;

#if defined(__linux__) && !defined(_WIN32)
  /* Supplemental HSA-introspection drain */
  if (drainDevicesViaHsa() != 0)
    Ret = -1;
#endif

  if (Ret != 0)
    PROF_WARN("%s\n", "failed to collect device profile data");
  return Ret;
}

/* Linux HIP interceptors. */

#if defined(__linux__) && !defined(_WIN32)

typedef struct {
  unsigned int x;
  unsigned int y;
  unsigned int z;
} HipDim3;

typedef struct {
  void *Func;
  HipDim3 GridDim;
  HipDim3 BlockDim;
  void **Args;
  size_t SharedMem;
  HipStream Stream;
} HipLaunchParams;

typedef struct {
  HipDim3 GridDim;
  HipDim3 BlockDim;
  size_t DynamicSmemBytes;
  HipStream Stream;
  void *Attrs;
  unsigned NumAttrs;
} HipLaunchConfig;

typedef void *HipFunction;
typedef void *HipEvent;
typedef void *HipGraphExec;

static int recordHipLaunchResult(int Rc, HipStream Stream) {
  if (Rc == 0)
    markLaunchStreamDeviceUsed(Stream);
  return Rc;
}

static int recordHipMultiDeviceLaunchResult(int Rc,
                                            HipLaunchParams *LaunchParams,
                                            int NumLaunches) {
  if (Rc != 0 || !LaunchParams || NumLaunches <= 0)
    return Rc;
  for (int I = 0; I < NumLaunches; ++I)
    markLaunchStreamDeviceUsed(LaunchParams[I].Stream);
  return Rc;
}

// interceptors must have external linkage
// NOLINTBEGIN(misc-use-internal-linkage)
INTERCEPTOR(int, hipLaunchKernel, const void *Function, HipDim3 GridDim,
            HipDim3 BlockDim, void **Args, size_t SharedMemBytes,
            HipStream Stream) {
  return recordHipLaunchResult(REAL(hipLaunchKernel)(Function, GridDim,
                                                     BlockDim, Args,
                                                     SharedMemBytes, Stream),
                               Stream);
}

INTERCEPTOR(int, hipLaunchKernel_spt, const void *Function, HipDim3 GridDim,
            HipDim3 BlockDim, void **Args, size_t SharedMemBytes,
            HipStream Stream) {
  return recordHipLaunchResult(
      REAL(hipLaunchKernel_spt)(Function, GridDim, BlockDim, Args,
                                SharedMemBytes, Stream),
      Stream);
}

INTERCEPTOR(int, hipExtLaunchKernel, const void *Function, HipDim3 GridDim,
            HipDim3 BlockDim, void **Args, size_t SharedMemBytes,
            HipStream Stream, HipEvent StartEvent, HipEvent StopEvent,
            int Flags) {
  return recordHipLaunchResult(
      REAL(hipExtLaunchKernel)(Function, GridDim, BlockDim, Args,
                               SharedMemBytes, Stream, StartEvent, StopEvent,
                               Flags),
      Stream);
}

INTERCEPTOR(int, hipLaunchKernelExC, const HipLaunchConfig *Config,
            const void *Function, void **Args) {
  int Rc = REAL(hipLaunchKernelExC)(Config, Function, Args);
  return recordHipLaunchResult(Rc, Config ? Config->Stream : nullptr);
}

INTERCEPTOR(int, hipLaunchCooperativeKernel, const void *Function,
            HipDim3 GridDim, HipDim3 BlockDim, void **KernelParams,
            unsigned SharedMemBytes, HipStream Stream) {
  return recordHipLaunchResult(
      REAL(hipLaunchCooperativeKernel)(Function, GridDim, BlockDim,
                                       KernelParams, SharedMemBytes, Stream),
      Stream);
}

INTERCEPTOR(int, hipLaunchCooperativeKernel_spt, const void *Function,
            HipDim3 GridDim, HipDim3 BlockDim, void **KernelParams,
            unsigned SharedMemBytes, HipStream Stream) {
  return recordHipLaunchResult(
      REAL(hipLaunchCooperativeKernel_spt)(
          Function, GridDim, BlockDim, KernelParams, SharedMemBytes, Stream),
      Stream);
}

INTERCEPTOR(int, hipLaunchCooperativeKernelMultiDevice,
            HipLaunchParams *LaunchParams, int NumDevices, unsigned Flags) {
  return recordHipMultiDeviceLaunchResult(
      REAL(hipLaunchCooperativeKernelMultiDevice)(LaunchParams, NumDevices,
                                                  Flags),
      LaunchParams, NumDevices);
}

INTERCEPTOR(int, hipExtLaunchMultiKernelMultiDevice,
            HipLaunchParams *LaunchParams, int NumDevices, unsigned Flags) {
  return recordHipMultiDeviceLaunchResult(
      REAL(hipExtLaunchMultiKernelMultiDevice)(LaunchParams, NumDevices, Flags),
      LaunchParams, NumDevices);
}

INTERCEPTOR(int, hipModuleLaunchKernel, HipFunction Function, unsigned GridDimX,
            unsigned GridDimY, unsigned GridDimZ, unsigned BlockDimX,
            unsigned BlockDimY, unsigned BlockDimZ, unsigned SharedMemBytes,
            HipStream Stream, void **KernelParams, void **Extra) {
  return recordHipLaunchResult(
      REAL(hipModuleLaunchKernel)(Function, GridDimX, GridDimY, GridDimZ,
                                  BlockDimX, BlockDimY, BlockDimZ,
                                  SharedMemBytes, Stream, KernelParams, Extra),
      Stream);
}

INTERCEPTOR(int, hipExtModuleLaunchKernel, HipFunction Function,
            unsigned GridDimX, unsigned GridDimY, unsigned GridDimZ,
            unsigned BlockDimX, unsigned BlockDimY, unsigned BlockDimZ,
            size_t SharedMemBytes, HipStream Stream, void **KernelParams,
            void **Extra, HipEvent StartEvent, HipEvent StopEvent,
            unsigned Flags) {
  return recordHipLaunchResult(
      REAL(hipExtModuleLaunchKernel)(Function, GridDimX, GridDimY, GridDimZ,
                                     BlockDimX, BlockDimY, BlockDimZ,
                                     SharedMemBytes, Stream, KernelParams,
                                     Extra, StartEvent, StopEvent, Flags),
      Stream);
}

INTERCEPTOR(int, hipGraphLaunch, HipGraphExec GraphExec, HipStream Stream) {
  return recordHipLaunchResult(REAL(hipGraphLaunch)(GraphExec, Stream), Stream);
}

INTERCEPTOR(int, hipGraphLaunch_spt, HipGraphExec GraphExec, HipStream Stream) {
  return recordHipLaunchResult(REAL(hipGraphLaunch_spt)(GraphExec, Stream),
                               Stream);
}

static void registerDynamicModuleFromFile(int Rc, void **Module,
                                          const char *Filename) {
  if (Rc)
    return;

  FILE *File = fopen(Filename, "rb");
  if (!File) {
    PROF_WARN("failed to open dynamic module file %s\n", Filename);
    return;
  }

  if (fseek(File, 0, SEEK_END) != 0) {
    PROF_WARN("failed to seek dynamic module file %s\n", Filename);
    fclose(File);
    return;
  }
  long FileSize = ftell(File);
  if (FileSize <= 0 || fseek(File, 0, SEEK_SET) != 0) {
    PROF_WARN("failed to get size of dynamic module file %s\n", Filename);
    fclose(File);
    return;
  }

  ManagedMemory Image;
  lprofGetFileContentBuffer(File, (uint64_t)FileSize, &Image);
  fclose(File);
  if (Image.Status == MS_INVALID) {
    PROF_WARN("failed to read dynamic module file %s\n", Filename);
    return;
  }

  __llvm_profile_offload_register_dynamic_module(Rc, Module, Image.Addr);
  lprofReleaseBuffer(&Image, (size_t)FileSize);
}

INTERCEPTOR(int, hipModuleLoad, void **module, const char *fname) {
  int rc = REAL(hipModuleLoad)(module, fname);
  registerDynamicModuleFromFile(rc, module, fname);
  return rc;
}

INTERCEPTOR(int, hipModuleLoadData, void **module, const void *image) {
  int rc = REAL(hipModuleLoadData)(module, image);
  __llvm_profile_offload_register_dynamic_module(rc, module, image);
  return rc;
}

INTERCEPTOR(int, hipModuleLoadDataEx, void **module, const void *image,
            unsigned numOptions, void **options, void **optionValues) {
  int rc = REAL(hipModuleLoadDataEx)(module, image, numOptions, options,
                                     optionValues);
  __llvm_profile_offload_register_dynamic_module(rc, module, image);
  return rc;
}

INTERCEPTOR(int, hipModuleUnload, void *module) {
  /* Drain counters before the module is destroyed; device addresses
   * captured at register time are invalid after unload. */
  __llvm_profile_offload_unregister_dynamic_module(module);
  return REAL(hipModuleUnload)(module);
}
// NOLINTEND(misc-use-internal-linkage)

__attribute__((constructor)) static void installHipInterceptors() {
  /* Avoid interception unless the HIP runtime is already loaded. */
  int HasModuleLoad = dlsym(RTLD_DEFAULT, "hipModuleLoad") != nullptr;
  int InstalledLaunch = 0;
#define TRY_INTERCEPT_LAUNCH(Name)                                             \
  do {                                                                         \
    if (dlsym(RTLD_DEFAULT, #Name))                                            \
      InstalledLaunch |= INTERCEPT_FUNCTION(Name);                             \
  } while (0)
  TRY_INTERCEPT_LAUNCH(hipLaunchKernel);
  TRY_INTERCEPT_LAUNCH(hipLaunchKernel_spt);
  TRY_INTERCEPT_LAUNCH(hipExtLaunchKernel);
  TRY_INTERCEPT_LAUNCH(hipLaunchKernelExC);
  TRY_INTERCEPT_LAUNCH(hipLaunchCooperativeKernel);
  TRY_INTERCEPT_LAUNCH(hipLaunchCooperativeKernel_spt);
  TRY_INTERCEPT_LAUNCH(hipLaunchCooperativeKernelMultiDevice);
  TRY_INTERCEPT_LAUNCH(hipExtLaunchMultiKernelMultiDevice);
  TRY_INTERCEPT_LAUNCH(hipModuleLaunchKernel);
  TRY_INTERCEPT_LAUNCH(hipExtModuleLaunchKernel);
  TRY_INTERCEPT_LAUNCH(hipGraphLaunch);
  TRY_INTERCEPT_LAUNCH(hipGraphLaunch_spt);
#undef TRY_INTERCEPT_LAUNCH
  int InstalledAny = InstalledLaunch;
  if (HasModuleLoad) {
    HasModuleLoad = INTERCEPT_FUNCTION(hipModuleLoad);
    InstalledAny |= HasModuleLoad;
  }
  if (!InstalledAny)
    return;
  if (isVerboseMode())
    PROF_NOTE("%s", "Installing HIP interceptors\n");
  if (HasModuleLoad) {
    INTERCEPT_FUNCTION(hipModuleLoadData);
    INTERCEPT_FUNCTION(hipModuleLoadDataEx);
    INTERCEPT_FUNCTION(hipModuleUnload);
  }
}

#endif /* __linux__ */
