Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 32 additions & 8 deletions projects/clr/hipamd/src/hip_fatbin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,19 +204,35 @@ static std::string TargetToGeneric(std::string input) {
return generic_name;
}

static bool IsCodeObjectUncompressed(const void* image) {
static bool IsCodeObjectUncompressed(const void* image, size_t image_size) {
constexpr size_t kMagicSize = sizeof(symbols::kOffloadBundleUncompressedMagicStr) - 1;
if (image_size < kMagicSize) {
return false;
}
return std::memcmp(image,
reinterpret_cast<const void*>(symbols::kOffloadBundleUncompressedMagicStr),
sizeof(symbols::kOffloadBundleUncompressedMagicStr) - 1) == 0;
kMagicSize) == 0;
}

static bool IsCodeObjectCompressed(const void* image) {
static bool IsCodeObjectCompressed(const void* image, size_t image_size) {
constexpr size_t kMagicSize = sizeof(symbols::kOffloadBundleCompressedMagicStr) - 1;
if (image_size < kMagicSize) {
return false;
}
return std::memcmp(image,
reinterpret_cast<const void*>(symbols::kOffloadBundleCompressedMagicStr),
sizeof(symbols::kOffloadBundleCompressedMagicStr) - 1) == 0;
kMagicSize) == 0;
}

static bool IsCodeObjectElf(const void* image) {
static bool IsCodeObjectElf(const void* image, size_t image_size) {
if (image_size < sizeof(amd::Elf64_Ehdr)) {
return false;
}
// Verify 4-byte ELF magic before accessing deeper header fields
static constexpr unsigned char kElfMagic[] = {0x7f, 'E', 'L', 'F'};
if (std::memcmp(image, kElfMagic, sizeof(kElfMagic)) != 0) {
return false;
}
const amd::Elf64_Ehdr* ehdr = reinterpret_cast<const amd::Elf64_Ehdr*>(image);
return ehdr->e_machine == EM_AMDGPU && ehdr->e_ident[EI_OSABI] == ELFOSABI_AMDGPU_HSA;
}
Expand Down Expand Up @@ -450,12 +466,20 @@ hipError_t FatBinaryInfo::ExtractFatBinaryUsingCOMGR(const std::vector<hip::Devi
guarantee(image_ != nullptr, "Image cannot be nullptr, file:%s did not map for some reason",
fname_.c_str());

bool is_compressed = IsCodeObjectCompressed(image_),
is_uncompressed = IsCodeObjectUncompressed(image_);
// Determine image size for bounds checking in magic string comparisons.
// For file-mapped images use the known file size; for direct-pointer images
// (compiler-embedded or user-provided) the size is not tracked, so use SIZE_MAX
// to allow the checks to proceed (caller is responsible for valid data).
const size_t image_size = (image_mapped_ && ufd_)
? (ufd_->fsize_ - foffset_)
: SIZE_MAX;
Comment on lines +469 to +475
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image_size falls back to SIZE_MAX when the buffer size is unknown, but this file doesn’t include a header that guarantees SIZE_MAX is defined on all toolchains. Also, other code in this repo typically uses std::numeric_limits<size_t>::max() (e.g. projects/clr/hipamd/src/hip_memory.cpp) instead of SIZE_MAX. Consider switching to std::numeric_limits<size_t>::max() (and including <limits>), or explicitly including the header that defines SIZE_MAX.

Copilot uses AI. Check for mistakes.

bool is_compressed = IsCodeObjectCompressed(image_, image_size),
is_uncompressed = IsCodeObjectUncompressed(image_, image_size);

// It better be elf if its neither compressed nor uncompressed
if (!is_compressed && !is_uncompressed) {
if (IsCodeObjectElf(image_)) {
if (IsCodeObjectElf(image_, image_size)) {
// Load the binary directly
auto elf_size = amd::Elf::getElfSize(image_);
for (size_t i = 0; i < devices.size(); i++) {
Expand Down
Loading