Files
TheRock/rocm-systems/projects/clr/rocclr/device/rocm/rocurilocator.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

142 lines
5.0 KiB
C++

/*
* Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
*
* SPDX-License-Identifier: MIT
*/
#if defined(__clang__)
#if __has_feature(address_sanitizer)
#include "rocurilocator.hpp"
#include <sstream>
namespace amd::roc {
std::vector<UriLocator::UriRange>& UriLocator::table() {
static auto* t = new std::vector<UriRange>();
return *t;
}
std::mutex& UriLocator::tableMutex() {
static auto* m = new std::mutex();
return *m;
}
void UriLocator::recordCodeObjects(hsa_executable_t exec) {
hsa_ven_amd_loader_1_03_pfn_t fn_table;
if (Hsa::system_get_major_extension_table(HSA_EXTENSION_AMD_LOADER, 1, sizeof(fn_table),
&fn_table) != HSA_STATUS_SUCCESS ||
fn_table.hsa_ven_amd_loader_executable_iterate_loaded_code_objects == nullptr) {
return;
}
struct CbArgs {
hsa_ven_amd_loader_1_03_pfn_t* fn;
std::vector<UriRange> ranges;
} args{&fn_table, {}};
fn_table.hsa_ven_amd_loader_executable_iterate_loaded_code_objects(
exec,
[](hsa_executable_t, hsa_loaded_code_object_t lcobj, void* data) -> hsa_status_t {
auto* a = static_cast<CbArgs*>(data);
auto get = a->fn->hsa_ven_amd_loader_loaded_code_object_get_info;
if (get == nullptr) return HSA_STATUS_ERROR;
uint64_t base = 0, size = 0;
int64_t delta = 0;
uint32_t uriLen = 0;
if (get(lcobj, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_BASE, &base) !=
HSA_STATUS_SUCCESS ||
get(lcobj, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_SIZE, &size) !=
HSA_STATUS_SUCCESS ||
get(lcobj, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_LOAD_DELTA, &delta) !=
HSA_STATUS_SUCCESS ||
get(lcobj, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI_LENGTH, &uriLen) !=
HSA_STATUS_SUCCESS) {
return HSA_STATUS_SUCCESS;
}
std::string uri(uriLen, '\0');
if (get(lcobj, HSA_VEN_AMD_LOADER_LOADED_CODE_OBJECT_INFO_URI, uri.data()) !=
HSA_STATUS_SUCCESS) {
return HSA_STATUS_SUCCESS;
}
a->ranges.push_back(UriRange{base, base + size - 1, delta, std::move(uri)});
return HSA_STATUS_SUCCESS;
},
&args);
if (!args.ranges.empty()) {
std::lock_guard<std::mutex> lock(tableMutex());
auto& tab = table();
tab.insert(tab.end(), std::make_move_iterator(args.ranges.begin()),
std::make_move_iterator(args.ranges.end()));
}
}
// Encoding of uniform-resource-identifier(URI) is detailed in
// https://llvm.org/docs/AMDGPUUsage.html#loaded-code-object-path-uniform-resource-identifier-uri
std::pair<uint64_t, uint64_t> UriLocator::decodeUriAndGetFd(UriInfo& uri,
amd::Os::FileDesc* uri_fd) {
std::ostringstream ss;
char cur;
uint64_t offset = 0, size = 0;
if (uri.uriPath.size() == 0) return {0, 0};
auto pos = uri.uriPath.find("//");
if (pos == std::string::npos) {
uri.uriPath = "";
return {0, 0};
}
auto rspos = uri.uriPath.find('#');
if (rspos != std::string::npos) {
// parse range specifier
std::string offprefix = "offset=", sizeprefix = "size=";
auto sbeg = uri.uriPath.find('&', rspos);
auto offbeg = rspos + offprefix.size() + 1;
std::string offstr = uri.uriPath.substr(offbeg, sbeg - offbeg);
auto sizebeg = sbeg + sizeprefix.size() + 1;
std::string sizestr = uri.uriPath.substr(sizebeg, uri.uriPath.size() - sizebeg);
offset = std::stoull(offstr, nullptr, 0);
size = std::stoull(sizestr, nullptr, 0);
rspos -= 1;
} else {
rspos = uri.uriPath.size() - 1;
}
if (uri.uriPath.substr(0, pos) == "file:") {
pos += 2;
// decode filepath
for (auto i = pos; i <= rspos;) {
cur = uri.uriPath[i];
if (isalnum(cur) || cur == '/' || cur == '-' || cur == '_' || cur == '.' || cur == '~') {
ss << cur;
i++;
} else {
// characters prefix with '%' char
char tbits = uri.uriPath[i + 1], lbits = uri.uriPath[i + 2];
uint8_t t = (tbits < 58) ? (tbits - 48) : ((tbits - 65) + 10);
uint8_t l = (lbits < 58) ? (lbits - 48) : ((lbits - 65) + 10);
ss << (char)(((0b00000000 | t) << 4) | l);
i += 3;
}
}
uri.uriPath = ss.str();
size_t fd_size;
(void)amd::Os::GetFileHandle(uri.uriPath.c_str(), uri_fd, &fd_size);
// As per URI locator syntax, range_specifier is optional
// if range_specifier is absent return total size of the file
// and set offset to begin at 0.
if (size == 0) size = fd_size;
}
return {offset, size};
}
UriLocator::UriInfo UriLocator::lookUpUri(uint64_t device_pc) {
std::lock_guard<std::mutex> lock(tableMutex());
// Reverse order so that if an address range was reused, the most recent load wins.
auto& tab = table();
for (auto it = tab.rbegin(); it != tab.rend(); ++it)
if (it->startAddr_ <= device_pc && device_pc <= it->endAddr_)
return UriInfo{it->Uri_.c_str(), it->elfDelta_};
return UriInfo{"", 0};
}
} // namespace amd::roc
#endif
#endif