Return a file URI for elf images in shared objects
Iterate the loaded shared objects to see if the given elf image binary is part of a loaded segment. Change-Id: I074cacd99eb5b59f883f4ce2bd901e0e35a660b8
This commit is contained in:
committed by
Laurent Morichetti
parent
6d5781bb14
commit
5f783494f1
@@ -42,14 +42,18 @@
|
||||
|
||||
#include "executable.hpp"
|
||||
|
||||
#include <libelf.h>
|
||||
#include <limits.h>
|
||||
#include <link.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <atomic>
|
||||
#include <fstream>
|
||||
#include <libelf.h>
|
||||
#include <unistd.h>
|
||||
#include "inc/amd_hsa_elf.h"
|
||||
#include "inc/amd_hsa_kernel_code.h"
|
||||
#include "core/inc/amd_hsa_code.hpp"
|
||||
@@ -1859,9 +1863,65 @@ hsa_status_t ExecutableImpl::Freeze(const char *options) {
|
||||
std::stringstream ss;
|
||||
uint64_t elf_begin = lco->getElfData();
|
||||
uint64_t elf_size = lco->getElfSize();
|
||||
ss << "file:///proc/" << getpid() << "/mem#"
|
||||
<< "offset=" << std::hex << std::showbase << elf_begin << "&"
|
||||
<< "size=" << elf_size;
|
||||
|
||||
struct args {
|
||||
ElfW(Addr) mem_addr;
|
||||
size_t callback_num;
|
||||
const char *file_name;
|
||||
size_t file_offset;
|
||||
} data{ elf_begin, 0 };
|
||||
|
||||
// Iterate the loaded shared objects program headers to see if the elf binary
|
||||
// is allocated in a mapped file.
|
||||
if (dl_iterate_phdr([](struct dl_phdr_info *info, size_t size, void *ptr) -> int {
|
||||
struct args *data = (struct args *) ptr;
|
||||
const ElfW(Addr) reladdr = data->mem_addr - info->dlpi_addr;
|
||||
|
||||
int n = info->dlpi_phnum;
|
||||
while (--n >= 0) {
|
||||
if (info->dlpi_phdr[n].p_type == PT_LOAD
|
||||
&& reladdr - info->dlpi_phdr[n].p_vaddr >= 0
|
||||
&& reladdr - info->dlpi_phdr[n].p_vaddr < info->dlpi_phdr[n].p_memsz) {
|
||||
// The first callback is always the program executable.
|
||||
if (!info->dlpi_name[0] && data->callback_num == 0) {
|
||||
static char argv0[PATH_MAX] = {0};
|
||||
if (!argv0[0] && readlink("/proc/self/exe", argv0, sizeof(argv0)) == -1)
|
||||
return 0;
|
||||
data->file_name = argv0;
|
||||
} else {
|
||||
data->file_name = info->dlpi_name;
|
||||
}
|
||||
|
||||
data->file_offset = reladdr - info->dlpi_phdr[n].p_vaddr + info->dlpi_phdr[n].p_offset;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
++data->callback_num;
|
||||
return 0;
|
||||
}, &data)) {
|
||||
unsigned char c;
|
||||
|
||||
ss.fill('0');
|
||||
ss << "file://";
|
||||
|
||||
while ((c = *data.file_name++) != '\0') {
|
||||
// %-encode the file name
|
||||
if (isalnum(c) || c == '/' || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
ss << c;
|
||||
} else {
|
||||
ss << std::uppercase;
|
||||
ss << '%' << std::hex << std::setw(2) << static_cast<int>(c);
|
||||
ss << std::nouppercase;
|
||||
}
|
||||
}
|
||||
ss << "#offset=" << std::dec << data.file_offset
|
||||
<< "&size=" << std::dec << elf_size;
|
||||
} else {
|
||||
ss << "file:///proc/" << getpid() << "/mem#"
|
||||
<< "offset=" << std::hex << std::showbase << elf_begin << "&"
|
||||
<< "size=" << std::dec << elf_size;
|
||||
}
|
||||
lco->r_debug_info.l_addr = lco->getDelta();
|
||||
lco->r_debug_info.l_name = strdup(ss.str().c_str());
|
||||
lco->r_debug_info.l_prev = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user