From 970bebafebf088eb62117c810ae53e0e58420bd0 Mon Sep 17 00:00:00 2001 From: "Baraldi, Giovanni" Date: Thu, 13 Mar 2025 20:35:25 +0100 Subject: [PATCH] Update codeobj disassembly to use comgr va2fo API (#250) * Update codeobj disassembly to use comgr va2fo API * Format * Tidy fix * Tidy fix * Review comments --------- Co-authored-by: Giovanni Baraldi --- CHANGELOG.md | 1 + .../cxx/codeobj/code_printing.hpp | 8 +-- .../cxx/codeobj/disassembly.hpp | 69 +++++-------------- 3 files changed, 23 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0bd55eb53..a4506ac4c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -168,6 +168,7 @@ Full documentation for ROCprofiler-SDK is available at [rocm.docs.amd.com/projec ### Changed - SDK no longer creates a background thread when every tool returns a nullptr from `rocprofiler_configure`. +- Updated disassembly.hpp's vaddr-to-file-offset mapping to use the dedicated comgr API. ### Resolved issues diff --git a/source/include/rocprofiler-sdk/cxx/codeobj/code_printing.hpp b/source/include/rocprofiler-sdk/cxx/codeobj/code_printing.hpp index c408691a36..2bbe7344f4 100644 --- a/source/include/rocprofiler-sdk/cxx/codeobj/code_printing.hpp +++ b/source/include/rocprofiler-sdk/cxx/codeobj/code_printing.hpp @@ -22,6 +22,9 @@ #pragma once +#include "disassembly.hpp" +#include "segment.hpp" + #include #include @@ -35,9 +38,6 @@ #include #include -#include "disassembly.hpp" -#include "segment.hpp" - namespace rocprofiler { namespace sdk @@ -169,7 +169,7 @@ public: std::optional va2fo(uint64_t vaddr) const { if(disassembly) return disassembly->va2fo(vaddr); - return {}; + return std::nullopt; }; std::unique_ptr disassemble_instruction(uint64_t faddr, uint64_t vaddr) diff --git a/source/include/rocprofiler-sdk/cxx/codeobj/disassembly.hpp b/source/include/rocprofiler-sdk/cxx/codeobj/disassembly.hpp index 67dd55736f..c054143e62 100644 --- a/source/include/rocprofiler-sdk/cxx/codeobj/disassembly.hpp +++ b/source/include/rocprofiler-sdk/cxx/codeobj/disassembly.hpp @@ -23,13 +23,15 @@ #pragma once #include -#include #include + +#include #include #include #include #include +#include #include #include #include @@ -61,13 +63,6 @@ return AMD_COMGR_STATUS_ERROR; \ } -#define CHECK_VA2FO(x, msg) \ - if(!(x)) \ - { \ - std::cerr << __FILE__ << ' ' << __LINE__ << ' ' << msg << "\n"; \ - return std::nullopt; \ - } - namespace rocprofiler { namespace sdk @@ -285,54 +280,26 @@ public: instance.last_instruction = instruction; } - std::optional va2fo(uint64_t va) + std::optional va2fo(uint64_t va) const { - CHECK_VA2FO(buffer.size() > sizeof(Elf64_Ehdr), "buffer is not large enough"); + uint64_t offset = 0; + uint64_t slicesize = 0; + bool nobits = false; - uint8_t* e_ident = (uint8_t*) buffer.data(); - CHECK_VA2FO(e_ident, "e_ident is nullptr"); + auto status = amd_comgr_map_elf_virtual_address_to_code_object_offset( + data, va, &offset, &slicesize, &nobits); - CHECK_VA2FO(e_ident[EI_MAG0] == ELFMAG0 || e_ident[EI_MAG1] == ELFMAG1 || - e_ident[EI_MAG2] == ELFMAG2 || e_ident[EI_MAG3] == ELFMAG3, - "unexpected ei_mag"); - - CHECK_VA2FO(e_ident[EI_CLASS] == ELFCLASS64, "unexpected ei_class"); - CHECK_VA2FO(e_ident[EI_DATA] == ELFDATA2LSB, "unexpected ei_data"); - CHECK_VA2FO(e_ident[EI_VERSION] == EV_CURRENT, "unexpected ei_version"); - CHECK_VA2FO(e_ident[EI_OSABI] == 64, "unexpected ei_osabi"); // ELFOSABI_AMDGPU_HSA - - CHECK_VA2FO(e_ident[EI_ABIVERSION] == 2 || // ELFABIVERSION_AMDGPU_HSA_V4 - e_ident[EI_ABIVERSION] == 3 || // ELFABIVERSION_AMDGPU_HSA_V5 - e_ident[EI_ABIVERSION] == 4, // ELFABIVERSION_AMDGPU_HSA_V6 - "unexpected ei_abiversion"); - - Elf64_Ehdr* ehdr = (Elf64_Ehdr*) buffer.data(); - CHECK_VA2FO(ehdr, "ehdr is nullptr"); - CHECK_VA2FO(ehdr->e_type == ET_DYN, "unexpected e_type"); - CHECK_VA2FO(ehdr->e_machine == ELF::EM_AMDGPU, "unexpected e_machine"); - CHECK_VA2FO(ehdr->e_phoff != 0, "unexpected e_phoff"); - - CHECK_VA2FO(buffer.size() > ehdr->e_phoff + sizeof(Elf64_Phdr), - "buffer is not large enough"); - - Elf64_Phdr* phdr = (Elf64_Phdr*) ((uint8_t*) buffer.data() + ehdr->e_phoff); - CHECK_VA2FO(phdr, "phdr is nullptr"); - - for(uint16_t i = 0; i < ehdr->e_phnum; ++i) - { - if(phdr[i].p_type != PT_LOAD) continue; - if(va < phdr[i].p_vaddr || va >= (phdr[i].p_vaddr + phdr[i].p_memsz)) continue; - - return va + phdr[i].p_offset - phdr[i].p_vaddr; - } - return std::nullopt; + if(status != AMD_COMGR_STATUS_SUCCESS || nobits) + return std::nullopt; + else + return offset; } - std::vector buffer; - std::string last_instruction; - amd_comgr_disassembly_info_t info; - amd_comgr_data_t data; - std::map symbol_map; + std::vector buffer{}; + std::string last_instruction{}; + amd_comgr_disassembly_info_t info{}; + amd_comgr_data_t data{}; + std::map symbol_map{}; }; } // namespace disassembly