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

Change-Id: I1b58af70d221bbeb9b4cab960d26357a504045dd


[ROCm/rocprofiler commit: edf93d48ab]
Cette révision appartient à :
Giovanni LB
2023-11-30 14:16:29 -03:00
révisé par Giovanni Baraldi
Parent 34fd4840d1
révision f275cdd602
18 fichiers modifiés avec 731 ajouts et 289 suppressions
+122 -54
Voir le fichier
@@ -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;
}