SWDEV-432445: ATT continuous mode update part2. Added codeobj tracking.
Change-Id: I1b58af70d221bbeb9b4cab960d26357a504045dd
[ROCm/rocprofiler commit: edf93d48ab]
Šī revīzija ir iekļauta:
revīziju iesūtīja
Giovanni Baraldi
vecāks
34fd4840d1
revīzija
f275cdd602
@@ -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;
|
||||
};
|
||||
|
||||
Atsaukties uz šo jaunā problēmā
Block a user