From 614f092da80cbaae2abd5fcb952270e34121d2b4 Mon Sep 17 00:00:00 2001 From: Giovanni Baraldi Date: Thu, 6 Mar 2025 18:12:00 +0100 Subject: [PATCH 1/5] Adding AMDGPU_HSA_V6 --- plugin/att/disassembly.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin/att/disassembly.cpp b/plugin/att/disassembly.cpp index 657c8b94..7def5703 100644 --- a/plugin/att/disassembly.cpp +++ b/plugin/att/disassembly.cpp @@ -303,7 +303,8 @@ std::optional DisassemblyInstance::va2fo(uint64_t va) CHECK_VA2FO( e_ident[EI_ABIVERSION] == 2 || // ELFABIVERSION_AMDGPU_HSA_V4 - e_ident[EI_ABIVERSION] == 3, "unexpected ei_abiversion"); // ELFABIVERSION_AMDGPU_HSA_V5 + e_ident[EI_ABIVERSION] == 3 || // ELFABIVERSION_AMDGPU_HSA_V5 + e_ident[EI_ABIVERSION] == 4, "unexpected ei_abiversion"); // ELFABIVERSION_AMDGPU_HSA_V6 Elf64_Ehdr *ehdr = (Elf64_Ehdr*)buffer.data(); CHECK_VA2FO(ehdr, "ehdr is nullptr"); From 4af7359cb01449bd1cd508f963fc6ad6ca033680 Mon Sep 17 00:00:00 2001 From: Giovanni Baraldi Date: Thu, 6 Mar 2025 18:57:02 +0100 Subject: [PATCH 2/5] Fix segment --- plugin/att/segment.hpp | 157 +++++++++++------------------------------ 1 file changed, 40 insertions(+), 117 deletions(-) diff --git a/plugin/att/segment.hpp b/plugin/att/segment.hpp index 3a2cc3ad..781da83c 100644 --- a/plugin/att/segment.hpp +++ b/plugin/att/segment.hpp @@ -23,132 +23,55 @@ #include #include #include -#include +#include #include -template -class ordered_vector : public std::vector +struct address_range_t { - using Super = std::vector; -public: - void insert(const Type& elem) - { - size_t loc = lower_bound(elem.begin()); - if (this->size() && get(loc).begin() < elem.begin()) - loc ++; - this->Super::insert(this->begin()+loc, elem); - } - bool remove(const Type& elem) - { - if (!this->size()) return false; - size_t loc = lower_bound(elem.begin()); - if (get(loc) != elem) return false; - - this->Super::erase(this->begin()+loc); - return true; - } - bool remove(uint64_t elem_begin) - { - if (!this->size()) return false; - size_t loc = lower_bound(elem_begin); - if (get(loc).begin() != elem_begin) return false; - - this->Super::erase(this->begin()+loc); - return true; - } - size_t lower_bound(size_t addr) const - { - if (!this->size()) return 0; - return binary_search(addr, 0, this->size()-1); - } - - size_t binary_search(size_t addr, size_t s, size_t e) const - { - if (s >= e) - return s; - else if (s+1 == e) - return (get(e).begin() <= addr) ? e : s; - - size_t mid = (s+e)/2; - if (get(mid).begin() <= addr) - return binary_search(addr, mid, e); - else - return binary_search(addr, s, mid); - } - const Type& get(size_t i) const { return this->operator[](i); } + uint64_t addr{0}; + uint64_t size{0}; + uint64_t id{0}; + + bool operator==(const address_range_t& other) const + { + return (addr >= other.addr && addr < other.addr + other.size) || + (other.addr >= addr && other.addr < addr + size); + } + bool operator<(const address_range_t& other) const + { + if(*this == other) return false; + return addr < other.addr; + } + bool inrange(uint64_t _addr) const { return addr <= _addr && addr + size > _addr; }; }; /** * @brief Finds a candidate codeobj for the given vaddr -*/ -template -class cached_ordered_vector : public ordered_vector + */ +class CodeobjTableTranslator : public std::set { - using Super = ordered_vector; -public: - cached_ordered_vector() { reset(); } - - const Type& find_obj(uint64_t addr) - { - if (testCache(addr)) - return get(cached_segment); - - size_t lb = this->lower_bound(addr); - if (lb >= this->size() || !get(lb).inrange(addr)) - throw std::string("segment addr out of range"); - - cached_segment = lb; - return get(cached_segment); - } - - uint64_t find_addr(uint64_t addr) { - return find_obj(addr).begin(); - } - - bool testCache(uint64_t addr) const { - return this->cached_segment < this->size() && get(cached_segment).inrange(addr); - } - - const Type& get(size_t index) const { return this->data()[index]; } - - void insert(const Type& elem) { this->Super::insert(elem); } - void insert_list(std::vector arange) - { - for (auto& elem : arange) push_back(elem); - std::sort( - this->begin(), - this->end(), - [](const Type& a, const Type& b) { return a.begin() < b.begin(); } - ); - }; + using Super = std::set; - void reset() { cached_segment = ~0; } - void clear() { reset(); this->Super::clear(); } - bool remove(uint64_t addr) { reset(); return this->Super::remove(addr); } +public: + address_range_t find_codeobj_in_range(uint64_t addr) + { + if(!cached_segment.inrange(addr)) + { + auto it = this->find(address_range_t{addr, 0, 0}); + if(it == this->end()) throw std::exception(); + cached_segment = *it; + } + return cached_segment; + } + + void clear_cache() { cached_segment = {}; } + bool remove(const address_range_t& range) + { + clear_cache(); + return this->erase(range) != 0; + } + bool remove(uint64_t addr) { return remove(address_range_t{addr, 0, 0}); } private: - size_t cached_segment = ~0; -}; - - -struct address_range_t -{ - uint64_t vbegin; - uint32_t size; - uint32_t id; - uint32_t offset; - - bool operator<(const address_range_t& other) const { return vbegin < other.vbegin; } - bool inrange(uint64_t addr) const { return addr >= vbegin && addr < vbegin+size; }; - uint64_t begin() const { return vbegin; } -}; - - -/** - * @brief Finds a candidate codeobj for the given vaddr -*/ -class CodeobjTableTranslator : public cached_ordered_vector -{ - public: - const address_range_t& find_codeobj_in_range(uint64_t addr) { return this->find_obj(addr); } + address_range_t cached_segment{}; }; From 9757b033a418669b63a789f7a0bd3f728c62a82b Mon Sep 17 00:00:00 2001 From: Giovanni Baraldi Date: Thu, 6 Mar 2025 19:24:44 +0100 Subject: [PATCH 3/5] Fix conflicts --- plugin/att/code_printing.cpp | 39 ++++++++++++++++++------------------ plugin/att/code_printing.hpp | 8 ++++---- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/plugin/att/code_printing.cpp b/plugin/att/code_printing.cpp index 0550e5fa..cd89f66b 100644 --- a/plugin/att/code_printing.cpp +++ b/plugin/att/code_printing.cpp @@ -119,7 +119,7 @@ CodeObjDecoderComponent::CodeObjDecoderComponent( Dwarf_Off cu_offset{0}, next_offset; size_t header_size; - std::unordered_set used_addrs; + std::map used_addrs; while (!dwarf_nextcu(dbg.get(), cu_offset, &next_offset, &header_size, nullptr, nullptr, nullptr)) { @@ -142,32 +142,33 @@ CodeObjDecoderComponent::CodeObjDecoderComponent( if (used_addrs.find(addr) != used_addrs.end()) { - size_t pos = m_line_number_map.lower_bound(addr); - m_line_number_map.data()[pos].str += ' ' + dwarf_line; + used_addrs.at(addr) += ' ' + dwarf_line; continue; } - used_addrs.insert(addr); - m_line_number_map.insert(DSourceLine{addr, 0, std::move(dwarf_line)}); + used_addrs.emplace(addr, std::move(dwarf_line)); } } cu_offset = next_offset; } - } - // Can throw - disassembly = std::make_unique(codeobj_data, codeobj_size, gpu_id); - if (m_line_number_map.size()) - { - size_t total_size = 0; - for (size_t i=0; ifirst - it->first; + auto segment = address_range_t{it->first, delta, 0}; + m_line_number_map.emplace(segment, std::move(it->second)); + it++; + } + auto segment = address_range_t{it->first, codeobj_size - it->first, 0}; + m_line_number_map.emplace(segment, std::move(it->second)); } - m_line_number_map.back().size = std::max(total_size, codeobj_size) - total_size; } + + // Can throw + disassembly = std::make_unique(codeobj_data, codeobj_size, gpu_id); try { m_symbol_map = disassembly->GetKernelMap(); // Can throw } catch(...) {} @@ -209,10 +210,8 @@ CodeObjDecoderComponent::disassemble_instruction(uint64_t faddr, uint64_t vaddr) const char* cpp_line = nullptr; - try { - const DSourceLine& it = m_line_number_map.find_obj(vaddr); - cpp_line = it.str.data(); - } catch(...) {} + auto it = m_line_number_map.find({vaddr, 0, 0}); + if(it != m_line_number_map.end()) cpp_line = it->second.data(); size_t size = disassembly->ReadInstruction(faddr, vaddr, cpp_line); return {disassembly->last_instruction, size}; diff --git a/plugin/att/code_printing.hpp b/plugin/att/code_printing.hpp index 2c34cee2..53178257 100644 --- a/plugin/att/code_printing.hpp +++ b/plugin/att/code_printing.hpp @@ -57,7 +57,7 @@ class CodeObjDecoderComponent int m_fd; - cached_ordered_vector m_line_number_map; + std::map m_line_number_map{}; std::map m_symbol_map{}; std::string m_uri; @@ -176,7 +176,7 @@ class CodeobjTableTranslation : protected CodeobjList { this->Super::addDecoder(filepath, id, loadbase, memsize, gpu_id); auto ptr = decoders.at(id); - table.insert({ptr->begin(), static_cast(ptr->size()), id, 0}); + table.insert(address_range_t{ptr->begin(), static_cast(ptr->size()), id}); } virtual bool removeDecoder(uint32_t id, uint64_t loadbase) @@ -186,8 +186,8 @@ class CodeobjTableTranslation : protected CodeobjList instruction_info_t get(uint64_t vaddr) { - auto& addr_range = table.find_codeobj_in_range(vaddr); - return get(addr_range.id, vaddr - addr_range.vbegin); + auto addr_range = table.find_codeobj_in_range(vaddr); + return get(addr_range.id, vaddr - addr_range.addr); } instruction_info_t get(uint32_t id, uint64_t offset) { return this->Super::get(id, offset); } From b8fa18996e9acef9e8194494abbbedbe226611c9 Mon Sep 17 00:00:00 2001 From: Giovanni Baraldi Date: Fri, 7 Mar 2025 01:03:47 +0100 Subject: [PATCH 4/5] ident fix --- plugin/att/stitch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/att/stitch.py b/plugin/att/stitch.py index 546f0786..75bfec21 100644 --- a/plugin/att/stitch.py +++ b/plugin/att/stitch.py @@ -155,7 +155,7 @@ def try_match_swapped(self, i, line, increment): class PCTranslator: def __init__(self, insts, code, raw_code, reverse_map, codeservice): self.codeservice = codeservice - + self.insts = insts self.addrmap = {c[-3] : (c, self.codeservice.GetInstruction(c[-3])[3]) for c in code if c[-3] > 0} From 0a153f7f4f5802f2799fb77243df93545a95f144 Mon Sep 17 00:00:00 2001 From: Giovanni Baraldi Date: Wed, 26 Mar 2025 10:09:59 -0500 Subject: [PATCH 5/5] Symbol lookup fix --- plugin/att/disassembly.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin/att/disassembly.cpp b/plugin/att/disassembly.cpp index 7def5703..b5707489 100644 --- a/plugin/att/disassembly.cpp +++ b/plugin/att/disassembly.cpp @@ -357,7 +357,8 @@ std::vector> DisassemblyInstance::getSegments() CHECK_VA2FO( e_ident[EI_ABIVERSION] == 2 || // ELFABIVERSION_AMDGPU_HSA_V4 - e_ident[EI_ABIVERSION] == 3, "unexpected ei_abiversion"); // ELFABIVERSION_AMDGPU_HSA_V5 + e_ident[EI_ABIVERSION] == 3 || // ELFABIVERSION_AMDGPU_HSA_V5 + e_ident[EI_ABIVERSION] == 4, "unexpected ei_abiversion"); // ELFABIVERSION_AMDGPU_HSA_V6 Elf64_Ehdr *ehdr = (Elf64_Ehdr*)buffer.data(); CHECK_VA2FO(ehdr, "ehdr is nullptr");