SWDEV-432445: ATT continuous mode update part2. Added codeobj tracking.
Change-Id: I1b58af70d221bbeb9b4cab960d26357a504045dd
[ROCm/rocprofiler commit: edf93d48ab]
Cette révision appartient à :
révisé par
Giovanni Baraldi
Parent
34fd4840d1
révision
f275cdd602
@@ -122,58 +122,65 @@ CodeObjectBinary::CodeObjectBinary(const std::string& uri) : m_uri(uri) {
|
||||
});
|
||||
|
||||
buffer = std::vector<char>{};
|
||||
try {
|
||||
size_t offset{0}, size{0};
|
||||
size_t offset{0}, size{0};
|
||||
|
||||
if (auto offset_it = params.find("offset"); offset_it != params.end()) {
|
||||
offset = std::stoul(offset_it->second, nullptr, 0);
|
||||
}
|
||||
|
||||
if (auto size_it = params.find("size"); size_it != params.end()) {
|
||||
if (!(size = std::stoul(size_it->second, nullptr, 0))) return;
|
||||
}
|
||||
|
||||
if (protocol != "file") throw protocol + " protocol not supported!";
|
||||
|
||||
std::ifstream file(decoded_path, std::ios::in | std::ios::binary);
|
||||
if (!file || !file.is_open()) throw "could not open " + decoded_path;
|
||||
|
||||
if (!size) {
|
||||
file.ignore(std::numeric_limits<std::streamsize>::max());
|
||||
size_t bytes = file.gcount();
|
||||
file.clear();
|
||||
|
||||
if (bytes < offset)
|
||||
throw "invalid uri " + decoded_path + " (file size < offset)";
|
||||
|
||||
size = bytes - offset;
|
||||
}
|
||||
|
||||
file.seekg(offset, std::ios_base::beg);
|
||||
buffer.resize(size);
|
||||
file.read(&buffer[0], size);
|
||||
} catch (...) {
|
||||
if (auto offset_it = params.find("offset"); offset_it != params.end()) {
|
||||
offset = std::stoul(offset_it->second, nullptr, 0);
|
||||
}
|
||||
|
||||
if (auto size_it = params.find("size"); size_it != params.end()) {
|
||||
if (!(size = std::stoul(size_it->second, nullptr, 0))) return;
|
||||
}
|
||||
|
||||
if (protocol != "file") throw protocol + " protocol not supported!";
|
||||
|
||||
std::ifstream file(decoded_path, std::ios::in | std::ios::binary);
|
||||
if (!file || !file.is_open()) throw "could not open " + decoded_path;
|
||||
|
||||
if (!size) {
|
||||
file.ignore(std::numeric_limits<std::streamsize>::max());
|
||||
size_t bytes = file.gcount();
|
||||
file.clear();
|
||||
|
||||
if (bytes < offset)
|
||||
throw "invalid uri " + decoded_path + " (file size < offset)";
|
||||
|
||||
size = bytes - offset;
|
||||
}
|
||||
|
||||
file.seekg(offset, std::ios_base::beg);
|
||||
buffer.resize(size);
|
||||
file.read(&buffer[0], size);
|
||||
}
|
||||
|
||||
DisassemblyInstance::DisassemblyInstance(code_object_decoder_t& decoder)
|
||||
: buffer(reinterpret_cast<void*>(decoder.buffer.data())),
|
||||
size(decoder.buffer.size())
|
||||
DisassemblyInstance::DisassemblyInstance(
|
||||
const char* codeobj_data,
|
||||
uint64_t codeobj_size,
|
||||
std::optional<std::string> input_isa
|
||||
)
|
||||
{
|
||||
THROW_COMGR(amd_comgr_create_data(AMD_COMGR_DATA_KIND_EXECUTABLE, &data));
|
||||
THROW_COMGR(amd_comgr_set_data(data, size, decoder.buffer.data()));
|
||||
buffer = std::vector<char>(codeobj_size, 0);
|
||||
std::memcpy(buffer.data(), codeobj_data, codeobj_size);
|
||||
|
||||
/*std::cout << "checking isa" << std::endl;
|
||||
char isa_name[128];
|
||||
size_t isa_size = sizeof(isa_name);
|
||||
CHECK_COMGR(amd_comgr_get_data_isa_name(data, &isa_size, isa_name));
|
||||
std::cout << isa_name << std::endl; */
|
||||
const char* isa_name = "amdgcn-amd-amdhsa--gfx1100";
|
||||
THROW_COMGR(amd_comgr_create_data(AMD_COMGR_DATA_KIND_EXECUTABLE, &data));
|
||||
THROW_COMGR(amd_comgr_set_data(data, buffer.size(), buffer.data()));
|
||||
if (!input_isa)
|
||||
{
|
||||
input_isa = "amdgcn-amd-amdhsa--gfx1100";
|
||||
}
|
||||
if (!input_isa)
|
||||
{
|
||||
input_isa = std::string();
|
||||
input_isa->resize(128);
|
||||
size_t isa_size = sizeof(input_isa->size());
|
||||
THROW_COMGR(amd_comgr_get_data_isa_name(data, &isa_size, input_isa->data()));
|
||||
}
|
||||
|
||||
THROW_COMGR(amd_comgr_create_disassembly_info(
|
||||
isa_name,
|
||||
input_isa->data(),
|
||||
&DisassemblyInstance::memory_callback, &DisassemblyInstance::inst_callback,
|
||||
[](uint64_t address, void* user_data) {}, &info));
|
||||
|
||||
}
|
||||
|
||||
static bool IsKernelType(amd_comgr_symbol_type_t type)
|
||||
@@ -208,7 +215,7 @@ amd_comgr_status_t DisassemblyInstance::symbol_callback(amd_comgr_symbol_t symbo
|
||||
RETURN_COMGR(amd_comgr_symbol_get_info(symbol, AMD_COMGR_SYMBOL_INFO_NAME, name.data()));
|
||||
|
||||
DisassemblyInstance& instance = *static_cast<DisassemblyInstance*>(user_data);
|
||||
std::optional<uint64_t> faddr = va2fo(instance.buffer, vaddr);
|
||||
std::optional<uint64_t> faddr = instance.va2fo(vaddr);
|
||||
|
||||
if (faddr)
|
||||
instance.symbol_map[vaddr] = {name, *faddr, mem_size};
|
||||
@@ -230,7 +237,7 @@ DisassemblyInstance::~DisassemblyInstance() {
|
||||
uint64_t DisassemblyInstance::ReadInstruction(uint64_t faddr, uint64_t vaddr, const char* cpp_line)
|
||||
{
|
||||
uint64_t size_read;
|
||||
uint64_t addr_in_buffer = reinterpret_cast<uint64_t>(buffer) + faddr;
|
||||
uint64_t addr_in_buffer = reinterpret_cast<uint64_t>(buffer.data()) + faddr;
|
||||
|
||||
THROW_COMGR(amd_comgr_disassemble_instruction(info, addr_in_buffer, (void*)this, &size_read));
|
||||
|
||||
@@ -242,7 +249,8 @@ uint64_t DisassemblyInstance::ReadInstruction(uint64_t faddr, uint64_t vaddr, co
|
||||
uint64_t DisassemblyInstance::memory_callback(uint64_t from, char* to, uint64_t size,
|
||||
void* user_data) {
|
||||
DisassemblyInstance& instance = *static_cast<DisassemblyInstance*>(user_data);
|
||||
int64_t copysize = reinterpret_cast<int64_t>(instance.buffer) + instance.size - (int64_t)from;
|
||||
int64_t copysize = reinterpret_cast<int64_t>(instance.buffer.data())
|
||||
+ instance.buffer.size() - static_cast<int64_t>(from);
|
||||
copysize = std::min<int64_t>(size, copysize);
|
||||
std::memcpy(to, (char*)from, copysize);
|
||||
return copysize;
|
||||
@@ -261,11 +269,11 @@ void DisassemblyInstance::inst_callback(const char* instruction, void* user_data
|
||||
// mem - input argument, start of the elf
|
||||
// va - input argument, virtual address
|
||||
// return file offset, if found
|
||||
std::optional<uint64_t> DisassemblyInstance::va2fo(void *mem, uint64_t va)
|
||||
std::optional<uint64_t> DisassemblyInstance::va2fo(uint64_t va)
|
||||
{
|
||||
CHECK_VA2FO(mem, "mem is nullptr");
|
||||
/*CHECK_VA2FO(buffer.size(), "buffer is not large enough");
|
||||
|
||||
uint8_t *e_ident = (uint8_t*)mem;
|
||||
uint8_t *e_ident = (uint8_t*)buffer.data();
|
||||
CHECK_VA2FO(e_ident, "e_ident is nullptr");
|
||||
|
||||
CHECK_VA2FO(
|
||||
@@ -277,20 +285,25 @@ std::optional<uint64_t> DisassemblyInstance::va2fo(void *mem, uint64_t va)
|
||||
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 /*ELFOSABI_AMDGPU_HSA*/, "unexpected ei_osabi");
|
||||
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*/ , "unexpected ei_abiversion");
|
||||
e_ident[EI_ABIVERSION] == 2 || // ELFABIVERSION_AMDGPU_HSA_V4
|
||||
e_ident[EI_ABIVERSION] == 3, "unexpected ei_abiversion"); // ELFABIVERSION_AMDGPU_HSA_V5
|
||||
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)mem;
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)buffer.data();
|
||||
CHECK_VA2FO(buffer.size() > ehdr->e_phoff + sizeof(Elf64_Ehdr), "buffer is not large enough");
|
||||
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_machine == ELF::EM_AMDGPU, "unexpected e_machine"); */
|
||||
|
||||
CHECK_VA2FO(buffer.size() > sizeof(Elf64_Ehdr), "buffer is not large enough");
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)buffer.data();
|
||||
CHECK_VA2FO(ehdr->e_phoff != 0, "unexpected e_phoff");
|
||||
|
||||
Elf64_Phdr *phdr = (Elf64_Phdr*)((uint8_t*)mem + ehdr->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)
|
||||
@@ -304,3 +317,58 @@ std::optional<uint64_t> DisassemblyInstance::va2fo(void *mem, uint64_t va)
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#undef CHECK_VA2FO
|
||||
#define CHECK_VA2FO(x, msg) if (!(x)) { \
|
||||
std::cerr << __FILE__ << ' ' << __LINE__ << ' ' << msg << std::endl; \
|
||||
return {}; \
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint64_t, uint64_t>> DisassemblyInstance::getSegments()
|
||||
{
|
||||
/*CHECK_VA2FO(buffer.size(), "buffer is not large enough");
|
||||
|
||||
uint8_t *e_ident = (uint8_t*)buffer.data();
|
||||
CHECK_VA2FO(e_ident, "e_ident is nullptr");
|
||||
|
||||
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, "unexpected ei_abiversion"); // ELFABIVERSION_AMDGPU_HSA_V5
|
||||
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)buffer.data();
|
||||
CHECK_VA2FO(buffer.size() > ehdr->e_phoff + sizeof(Elf64_Ehdr), "buffer is not large enough");
|
||||
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(buffer.size() > sizeof(Elf64_Ehdr), "buffer is not large enough");
|
||||
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)buffer.data();
|
||||
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");
|
||||
|
||||
std::vector<std::pair<uint64_t, uint64_t>> segments;
|
||||
for (Elf64_Half i = 0; i < ehdr->e_phnum; ++i)
|
||||
{
|
||||
if (phdr[i].p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
segments.push_back({phdr[i].p_vaddr - phdr[i].p_offset, phdr[i].p_memsz});
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
Référencer dans un nouveau ticket
Bloquer un utilisateur