Skip to content

Instantly share code, notes, and snippets.

@devilholk
Created May 26, 2020 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save devilholk/7cdf7cb65b2dc91ed1159f6942fab67d to your computer and use it in GitHub Desktop.
Save devilholk/7cdf7cb65b2dc91ed1159f6942fab67d to your computer and use it in GitHub Desktop.
An incomplete attempt at enumerating DW_TAG_variable from DWARF data in ELF using libdw.
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <elfutils/libdwelf.h>
#include <dwarf.h>
/*
Bottom part of `objdump -Wi t3.o´ is:
<1><d5>: Abbrev Number: 9 (DW_TAG_variable)
<d6> DW_AT_name : (indirect string, offset: 0x15e): stuff
<da> DW_AT_decl_file : 2
<db> DW_AT_decl_line : 3
<dc> DW_AT_decl_column : 5
<dd> DW_AT_type : <0x47>
<e1> DW_AT_external : 1
<e1> DW_AT_location : 9 byte block: 3 0 0 0 0 0 0 0 0 (DW_OP_addr: 0)
<1><eb>: Abbrev Number: 9 (DW_TAG_variable)
<ec> DW_AT_name : (indirect string, offset: 0xc0): test_var
<f0> DW_AT_decl_file : 2
<f1> DW_AT_decl_line : 4
<f2> DW_AT_decl_column : 16
<f3> DW_AT_type : <0x76>
<f7> DW_AT_external : 1
<f7> DW_AT_location : 9 byte block: 3 20 0 0 0 0 0 0 0 (DW_OP_addr: 20)
<1><101>: Abbrev Number: 0
Using dwarf_getstring with the offsets 0x15e and 0xc0 I do get the DW_AT_name for the two DW_TAG_variable
But I am unable to figure out how to get those offsets from the attributes when iterating through the DIEs.
I am also unsure that I am actually iterating through them but I do hit DW_TAG_variable twice which is correct
but I am unable to verify I am not getting the same data twice.
*/
int main(void) {
int fd = open("t3.o", 0);
Dwarf* dbgdata = dwarf_begin(fd, DWARF_C_READ);
if (!dbgdata) {
int eno = dwarf_errno();
printf("Failed to load dwarf %i - %s\n", eno, dwarf_errmsg(eno));
} else {
Dwarf_Off off = 0;
size_t cuhl;
Dwarf_Off noff;
//Go through CU (compilation units?) (one found)
while (dwarf_nextcu (dbgdata, off, &noff, &cuhl, NULL, NULL, NULL) == 0) {
Dwarf_Die die_mem;
Dwarf_Die *die = dwarf_offdie (dbgdata, off + cuhl, &die_mem);
Dwarf_Die iter_mem;
Dwarf_Die *iter = &iter_mem;
dwarf_child (die, &iter_mem);
//Go through children in top DIE of the CU (or at least so I think)
while (1) {
if (dwarf_tag (iter) == DW_TAG_variable) {
Dwarf_Attribute atr_mem;
Dwarf_Attribute* atr = &atr_mem;
if (dwarf_attr(iter, DW_AT_name, &atr_mem) == 0) {
printf("Failed to atr\n");
} else {
printf("We have the attr but.. how do we get the offset in .debug_str section for DW_AT_name of this DW_TAG_variable? \n");
}
}
if (dwarf_siblingof (iter, &iter_mem) != 0) {
break;
}
}
off = noff;
}
dwarf_end(dbgdata);
}
close(fd);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment