2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit c9249c22 authored by Micha Müller's avatar Micha Müller
Browse files

Caliper-service rework WIP3

parent 669e5303
......@@ -105,6 +105,7 @@ class DcdbPusher {
typedef struct {
uintptr_t start_addr;
uintptr_t end_addr;
uintptr_t offset; // offset as parsed from /proc//maps
size_t fsym_offset; // Offset in bytes from the address of this struct
// to the beginning of the associated symbol section
size_t fsym_count; // Number of symbols in this address range
......@@ -138,6 +139,7 @@ private:
* addr_data[addr_count]
* addr_count * (fsym_data[addr_data.fsym_count])
*/
//TODO close shm file at end
void* shm; // pointer to shared memory object
size_t shm_size; // size of shm in bytes
int shm_file; // fd of the underlying shared memory file
......@@ -166,6 +168,7 @@ private:
size_t write_function_symbols(const char* const filename,
const uintptr_t start_addr,
const uintptr_t end_addr,
const uintptr_t offset,
fsym_data*& dest_ptr,
Channel* chn) {
Elf *elf;
......@@ -216,6 +219,7 @@ private:
int status = -1;
fsym_data symdat;
//TODO sym.st_name == STN_UNDEF?
symstr = elf_strptr(elf, shdr.sh_link, sym.st_name);
/* Demangle if necessary. Require GNU v3 ABI by the "_Z" prefix. */
......@@ -230,25 +234,58 @@ private:
strncpy(symdat.name, symstr, 512);
}
symdat.name[511] = '\0';
symdat.start_addr = sym.st_value;
symdat.end_addr = sym.st_value + sym.st_size;
//TODO determine if symbol address relative and if so add offset
if ((symdat.start_addr >= start_addr &&
symdat.start_addr <= end_addr) ||
(symdat.end_addr >= start_addr &&
symdat.end_addr <= end_addr)) {
//TODO calculated symbol addresses must be wrong...
//see example: https://wiki.osdev.org/ELF_Tutorial#Accessing_the_Value_of_a_Symbol
if (sym.st_shndx == SHN_UNDEF) {
//external symbol
//look up should not be necessary as we also parse all other
//mapped files...
continue;
} else if (sym.st_shndx == SHN_ABS) {
//absolute symbol
symdat.start_addr = sym.st_value;
} else {
//internally defined symbol
Elf_Scn *tmp_scn;
GElf_Shdr tmp_shdr;
tmp_scn = elf_getscn(elf, sym.st_shndx);
//debug
if (tmp_scn == NULL) {
printf("Symbol %s has invalid section!\n", symdat.name);
continue;
}
gelf_getshdr(tmp_scn, &tmp_shdr);
//debug
// printf("Symbol %s: start %llx; sh_offset %llx; value %llx)\n", symdat.name,
// (start_addr-offset),
// tmp_shdr.sh_offset,
// sym.st_value);
symdat.start_addr = (start_addr - offset) + tmp_shdr.sh_offset + sym.st_value;
}
symdat.end_addr = symdat.start_addr + sym.st_size;
if (symdat.start_addr >= start_addr &&
symdat.start_addr <= end_addr) {
//debug
// printf("Symbol %s in mem range (%llx-%llx, size %llx)\n", symdat.name,
// symdat.start_addr,
// symdat.end_addr,
// sym.st_size);
memcpy(dest_ptr, &symdat, sizeof(addr_data));
++dest_ptr;
++entryCnt;
} else {
printf("Symbol %s out of mem range (%llx-%llx, size %llx)\n", symdat.name,
symdat.start_addr,
symdat.end_addr,
sym.st_size);
// printf("Symbol %s out of mem range (%llx-%llx, size %llx)\n", symdat.name,
// symdat.start_addr,
// symdat.end_addr,
// sym.st_size);
}
//TODO update size entry in output file
}
}
......@@ -259,7 +296,7 @@ private:
/**
* Set up address data in shm. Parse all address ranges and their pathnames
* which are marked as executable from /proc/self/maps.
* which are marked as executable from /proc//maps.
* Address ranges associated to a binary ELF file will be enriched with
* symbol data.
* TODO demangle different languages? (C, C++, Fortran, other?)
......@@ -285,11 +322,15 @@ private:
}
//read one line = one address range
while(fscanf(file, "%llx-%llx %*2c%1c%*s%*s%*s%*s%4096[^\n]",
while(fscanf(file, "%llx-%llx %*2c%1c%*s%llx%*s%*s%4096[^\n]",
&(addr.start_addr),
&(addr.end_addr),
&exec,
buf) == 4) {
&(addr.offset),
buf) == 5) {
//debug
//printf("%llx-%llx %c %llx %s\n", addr.start_addr, addr.end_addr, exec, addr.offset, buf);
//Only executable memory ranges are interesting. If the program counter
//ever points in a non-executable section --> HCF
......@@ -323,10 +364,12 @@ private:
for(size_t i = 0; i < addr_cnt; ++i) {
addr_ptr->fsym_offset = fsym_offset;
if (addr_ptr->pathname[0] == '/') {
printf("Parsing symbols for %s (%llx-%llx)\n", addr_ptr->pathname, addr_ptr->start_addr, addr_ptr->end_addr);
//debug
// printf("Parsing symbols for %s (%llx-%llx; %llx)\n", addr_ptr->pathname, addr_ptr->start_addr, addr_ptr->end_addr, addr_ptr->offset);
addr_ptr->fsym_count = write_function_symbols(addr_ptr->pathname,
addr_ptr->start_addr,
addr_ptr->end_addr,
addr_ptr->offset,
fsym_ptr,
chn);
fsym_offset += addr_ptr->fsym_count * sizeof(fsym_data);
......@@ -365,6 +408,9 @@ private:
printf("\n");
++addr_ptr;
}
//debug
printf("Shm: %p, fsym_ptr:%p\n", shm, (void*) fsym_ptr);
}
void post_init_cb(Caliper* c, Channel* chn) {
......@@ -530,7 +576,7 @@ private:
DcdbPusher(Caliper* c, Channel* chn) :
shm(NULL),
shm_size(2 * 1024 * 1024),
shm_size(64 * 1024 * 1024),
shm_file(-1),
sock(-1),
initialized(false) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment