Skip to content

Commit

Permalink
Flesh out working version of dump_loc_ids_brief()
Browse files Browse the repository at this point in the history
  • Loading branch information
gapisback committed May 2, 2024
1 parent 3a11577 commit 685ce90
Showing 1 changed file with 56 additions and 7 deletions.
63 changes: 56 additions & 7 deletions src/loc-elf-id-decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <getopt.h> // For getopt_long()
#include <libelf.h> // For ELF apis: elf_begin(), elf_kind() etc.
#include <gelf.h> // For ELF apis: GElf_Shdr{}, gelf_getshdr() etc.
#include <assert.h>

// Define the struct location
struct location
Expand Down Expand Up @@ -79,18 +80,20 @@ struct option Long_options[] = {
// { "brief" , required_argument , NULL, 'f'},
{ "program-binary", required_argument , NULL, 'p'}
, { "brief" , no_argument , NULL, 'b'}
, { "brief-map" , no_argument , NULL, 'm'}
, { "dump-rodata" , no_argument , NULL, 'r'}
, { "dump-loc-ids" , no_argument , NULL, 'l'}
, { "debug" , no_argument , NULL, 'd'}
, { "help" , no_argument , NULL, 'h'}
, { NULL, 0, NULL, 0} // End of options
};

const char * Options_str = "p:bldh";
const char * Options_str = "p:bdhlm";

typedef struct args {
const char * binary;
_Bool brief;
_Bool brief_map;
_Bool dump_rodata;
_Bool dump_loc_ids;
_Bool debug;
Expand All @@ -109,6 +112,10 @@ void dump_loc_ids(_Bool dump_loc_ids, struct location *loc_id_ref,
uint32_t count, const char *rodata_buf,
const size_t rodata_addr, uint64_t sh_addr);

void dump_loc_ids_brief(_Bool brief_map, struct location *loc_id_ref,
uint32_t count,
const char *rodata_buf, const size_t rodata_addr);

void prGElf_Shdr(const GElf_Shdr *shdr, Elf_Scn *scn, const char *name);

void prSection_details(const char *name, Elf_Scn *scn, GElf_Shdr *shdr);
Expand Down Expand Up @@ -178,9 +185,13 @@ main(const int argc, char *argv[])
GElf_Shdr shdr;
Elf_Scn *scn = NULL;
char *rodata_buf = NULL;
struct location *loc_ids = NULL;
size_t rodata_addr = 0;
char *name = NULL;

// Variables to track info about loc_ids section data
struct location *loc_ids = NULL;
uint32_t nloc_id_entries = 0;

while ((scn = elf_nextscn(elf, scn)) != NULL) {

// Get ELF section's header.
Expand All @@ -207,7 +218,6 @@ main(const int argc, char *argv[])
}
} else if (IS_REQD_SECTION(name)) {

uint32_t nloc_id_entries = 0;
// Account for alignment bytes left in GElf_Shdr
nloc_id_entries = ((shdr.sh_size - shdr.sh_addralign)
/ sizeof(struct location));
Expand All @@ -232,6 +242,12 @@ main(const int argc, char *argv[])
}
}

if ((args->brief || args->brief_map) && loc_ids) {
assert(nloc_id_entries > 0);
dump_loc_ids_brief(args->brief_map, loc_ids, nloc_id_entries,
rodata_buf, rodata_addr);
}

// Cleanup.
if (loc_ids) {
free(loc_ids);
Expand Down Expand Up @@ -277,6 +293,10 @@ parse_arguments(const int argc, char *argv[], ArgStruct *args)
args->brief = true;
break;

case 'm':
args->brief_map = true;
break;

case 'r':
args->dump_rodata = true;
break;
Expand Down Expand Up @@ -488,8 +508,8 @@ void hexdump(const void* data, size_t size, size_t sh_addr) {
* │
* file_offset (start of file-name)
*
* Empirically, it appears that &Loc_id_ref will be higher than the struct location{}
* of each such location stashed in this section.
* Empirically, it appears that &Loc_id_ref will be higher than the
* struct location{} of each such location stashed in this section.
* *****************************************************************************
*/
void
Expand All @@ -503,12 +523,12 @@ dump_loc_ids(_Bool dump_loc_ids, struct location *loc_id_ref, uint32_t count,
printf("Index\t\tFunction\tFile\t\tLine\n");
}

for (size_t i = 0; i < count; ++i) {
for (uint32_t i = 0; i < count; i++) {
size_t func_offset = (intptr_t) loc_id_ref[i].fn;
size_t file_offset = (intptr_t) loc_id_ref[i].file;

if (dump_loc_ids) {
printf("%zu (0x%lx) \tfn=0x%lx, \tfile=0x%lx, \tline=%u",
printf("%u (0x%lx) \tfn=0x%lx, \tfile=0x%lx, \tline=%u",
i, sh_addr, // &loc_id_ref[i],
func_offset, file_offset, loc_id_ref[i].line);
}
Expand All @@ -528,3 +548,32 @@ dump_loc_ids(_Bool dump_loc_ids, struct location *loc_id_ref, uint32_t count,
sh_addr += sizeof(*loc_id_ref);
}
}

/**
* *****************************************************************************
* dump_loc_ids_brief() - Unpack the Loc_id_ref[] structures from the named
* section. Print them out in a form that can be consumed by external scripts.
* *****************************************************************************
*/
void
dump_loc_ids_brief(_Bool brief_map, struct location *loc_id_ref, uint32_t count,
const char *rodata_buf, const size_t rodata_addr)
{
for (uint32_t i = 0; i < count; i++) {
size_t func_offset = (intptr_t) loc_id_ref[i].fn;
size_t file_offset = (intptr_t) loc_id_ref[i].file;

if (brief_map) {
printf("-%lu %s:%d::%s()\n",
((count - i) * sizeof(*loc_id_ref)),
(rodata_buf + (file_offset - rodata_addr)),
loc_id_ref[i].line,
(rodata_buf + (func_offset - rodata_addr)));
} else {
printf("%s:%d::%s()\n",
(rodata_buf + (file_offset - rodata_addr)),
loc_id_ref[i].line,
(rodata_buf + (func_offset - rodata_addr)));
}
}
}

0 comments on commit 685ce90

Please sign in to comment.