SWDEV-432445: ATT continuous mode update part2. Added codeobj tracking.

Change-Id: I1b58af70d221bbeb9b4cab960d26357a504045dd


[ROCm/rocprofiler commit: edf93d48ab]
Šī revīzija ir iekļauta:
Giovanni LB
2023-11-30 14:16:29 -03:00
revīziju iesūtīja Giovanni Baraldi
vecāks 34fd4840d1
revīzija f275cdd602
18 mainīti faili ar 731 papildinājumiem un 289 dzēšanām
@@ -30,13 +30,15 @@
#include <unordered_map>
#include "disassembly.hpp"
#include "segment.hpp"
class code_object_decoder_t {
class CodeObjDecoderComponent
{
public:
std::optional<SymbolInfo> find_symbol(uint64_t address);
code_object_decoder_t(const char* codeobj_data, uint64_t codeobj_size);
~code_object_decoder_t();
CodeObjDecoderComponent(const char* codeobj_data, uint64_t codeobj_size);
~CodeObjDecoderComponent();
std::pair<instruction_instance_t, size_t>
disassemble_instruction(uint64_t faddr, uint64_t vaddr);
@@ -50,44 +52,133 @@ public:
std::map<uint64_t, SymbolInfo> m_symbol_map{};
std::string m_uri;
std::vector<char> buffer;
std::vector<instruction_instance_t> instructions{};
std::unique_ptr<DisassemblyInstance> disassembly{};
};
class CodeobjService
typedef struct {
const char* inst;
const char* cpp;
size_t size;
} instruction_info_t;
class CodeobjDecoder
{
public:
CodeobjService(const char* filepath, uint64_t load_base);
bool decode_single(uint64_t vaddr, uint64_t faddr);
CodeobjDecoder(const char* filepath, uint64_t loadbase, uint64_t memsize);
bool decode_single(uint64_t vaddr);
bool decode_single_at_offset(uint64_t vaddr, uint64_t voffset);
bool add_to_map(uint64_t faddr, uint64_t vaddr, uint64_t voffset);
std::pair<instruction_instance_t, size_t>& getDecoded(uint64_t addr);
const char* getInstruction(uint64_t addr) { return getDecoded(addr).first.instruction; }
const char* getCppref(uint64_t addr) { return getDecoded(addr).first.cpp_reference; }
size_t getSize(uint64_t addr) { return getDecoded(addr).second; }
uint64_t size() const {
if (!decoder) return 0;
return decoder->buffer.size();
instruction_info_t get(uint64_t addr) {
auto& inst = getDecoded(addr);
return {inst.first.instruction, inst.first.cpp_reference, inst.second};
}
uint64_t begin() const { return load_base; };
uint64_t end() const { return begin() + size(); }
uint64_t begin() const { return loadbase; };
uint64_t end() const { return load_end; }
uint64_t size() const { return load_end-loadbase; }
bool inrange(uint64_t addr) const { return addr >= begin() && addr < end(); }
const char* getSymbolName(uint64_t addr) const {
if (!decoder) return nullptr;
auto it = decoder->m_symbol_map.find(addr-load_base);
auto it = decoder->m_symbol_map.find(addr-loadbase);
if (it != decoder->m_symbol_map.end())
return it->second.name.data();
return nullptr;
}
std::vector<std::pair<uint64_t, uint64_t>> elf_segments{};
private:
const uint64_t load_base;
const uint64_t loadbase;
uint64_t load_end = 0;
std::unordered_map<uint64_t, std::pair<instruction_instance_t, size_t>> decoded_map;
std::unique_ptr<code_object_decoder_t> decoder{nullptr};
bool bNotElfFILE = false;
std::unique_ptr<CodeObjDecoderComponent> decoder{nullptr};
};
/**
* @brief Maps ID and offsets into instructions
*/
class CodeobjList
{
public:
CodeobjList() = default;
virtual void addDecoder(const char* filepath, uint32_t id, uint64_t loadbase, uint64_t memsize)
{
decoders[id] = std::make_shared<CodeobjDecoder>(filepath, loadbase, memsize);
}
virtual bool removeDecoder(uint32_t id)
{
return decoders.erase(id) != 0;
}
instruction_info_t get(uint32_t id, uint64_t offset)
{
auto& decoder = decoders.at(id);
auto& inst = decoder->getDecoded(decoder->begin() + offset);
return {inst.first.instruction, inst.first.cpp_reference, inst.second};
}
const char* getSymbolName(uint32_t id, uint64_t offset)
{
auto& decoder = decoders.at(id);
uint64_t vaddr = decoder->begin() + offset;
if (decoder->inrange(vaddr))
return decoder->getSymbolName(vaddr);
return nullptr;
}
protected:
std::unordered_map<uint32_t, std::shared_ptr<CodeobjDecoder>> decoders{};
};
/**
* @brief Translates virtual addresses to elf file offsets
*/
class CodeobjTableTranslation : protected CodeobjList
{
using Super = CodeobjList;
public:
CodeobjTableTranslation() = default;
void addDecoder(const char* filepath, uint32_t id, uint64_t loadbase, uint64_t memsize) override
{
this->Super::addDecoder(filepath, id, loadbase, memsize);
auto ptr = decoders.at(id);
table.insert({ptr->begin(), static_cast<uint32_t>(ptr->size()), id, 0});
}
virtual bool removeDecoder(uint32_t id, uint64_t loadbase)
{
return table.remove(loadbase) && this->Super::removeDecoder(id);
}
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);
}
instruction_info_t get(uint32_t id, uint64_t offset) { return this->Super::get(id, offset); }
const char* getSymbolName(uint64_t vaddr)
{
for (auto& [_, decoder] : decoders)
{
if (!decoder->inrange(vaddr)) continue;
return decoder->getSymbolName(vaddr);
}
return nullptr;
}
private:
CodeobjTableTranslator table;
};