libdwarf
Example getting .debug_ranges data

Example accessing ranges data.

If have_base_addr is false there is no die (as in reading the raw .debug_ranges section) or there is some serious data corruption somewhere.

*/
static
void functionusingrange(Dwarf_Signed i,Dwarf_Ranges *r,
Dwarf_Bool *have_base_addr,
Dwarf_Unsigned *baseaddr)
{
Dwarf_Unsigned base = *baseaddr;
printf("[%4ld] ",(signed long)i);
switch(r->dwr_type) {
case DW_RANGES_ENTRY:
printf(
"DW_RANGES_ENTRY: raw addr1 " PRX
" addr2 " PRX,
r->dwr_addr1,r->dwr_addr2);
if (r->dwr_addr1 == r->dwr_addr2) {
printf(" (empty range)");
}
printf("\n");
if (*have_base_addr) {
printf(" "
"DW_RANGES_ENTRY: cooked addr1 0x%08llx"
" addr2 " PRX "\n" ,
r->dwr_addr1+base,r->dwr_addr2+base);
}
break;
case DW_RANGES_ADDRESS_SELECTION:
printf(
"Base Address : " PRX "\n",
r->dwr_addr2);
*have_base_addr = TRUE;
*baseaddr = r->dwr_addr2;
break;
case DW_RANGES_END:
printf(
"DW_RANGES_END : 0,0\n");
*have_base_addr = FALSE;
*baseaddr = 0;
break;
default:
printf(
"ERROR : incorrect dwr_type is 0x%lx\n",
(unsigned long)r->dwr_type);
}
}
/* On call the rangesoffset is a default zero. */
int examplev(Dwarf_Debug dbg,Dwarf_Off rangesoffset_in,
Dwarf_Die die, Dwarf_Error*error)
{
Dwarf_Signed count = 0;
Dwarf_Off realoffset = 0;
Dwarf_Ranges *rangesbuf = 0;
Dwarf_Unsigned bytecount = 0;
int res = 0;
Dwarf_Unsigned base_address = 0;
Dwarf_Bool have_base_addr = FALSE;
Dwarf_Bool have_rangesoffset = FALSE;
Dwarf_Unsigned rangesoffset = (Dwarf_Unsigned)rangesoffset_in;
(void)have_rangesoffset;
if (die) {
/* Find the ranges for a specific DIE */
res = dwarf_get_ranges_baseaddress(dbg,die,&have_base_addr,
&base_address,&have_rangesoffset,&rangesoffset,error);
if (res == DW_DLV_ERROR) {
/* Just pretend not an error. */
dwarf_dealloc_error(dbg,*error);
*error = 0;
}
} else {
/* To test getting all ranges and no knowledge
of the base address (so cooked values
cannot be definitely known unless
the base is in the .debug_ranges entries
themselves */
}
res = dwarf_get_ranges_b(dbg,rangesoffset,die,
&realoffset,
&rangesbuf,&count,&bytecount,error);
if (res != DW_DLV_OK) {
if (res == DW_DLV_ERROR) {
printf("ERROR dwarf_get_ranges_b %s\n",
dwarf_errmsg(*error));
} else {
printf("NO_ENTRY dwarf_get_ranges_b\n");
}
return res;
}
{
Dwarf_Signed i = 0;
printf("Range group base address: " PRX
", offset in .debug_ranges:"
" 0x%08llx\n",
base_address, rangesoffset);
for ( i = 0; i < count; ++i ) {
Dwarf_Ranges *cur = rangesbuf+i;
/* Use cur. */
functionusingrange(i,cur,&have_base_addr,&base_address);
}
dwarf_dealloc_ranges(dbg,rangesbuf,count);
}
return DW_DLV_OK;
}
struct Dwarf_Debug_s * Dwarf_Debug
Definition: libdwarf.h:603
struct Dwarf_Die_s * Dwarf_Die
Definition: libdwarf.h:608
struct Dwarf_Error_s * Dwarf_Error
Definition: libdwarf.h:597
signed long long Dwarf_Signed
Definition: libdwarf.h:197
unsigned long long Dwarf_Unsigned
Definition: libdwarf.h:196
int Dwarf_Bool
Definition: libdwarf.h:202
unsigned long long Dwarf_Off
Definition: libdwarf.h:198
void dwarf_dealloc_error(Dwarf_Debug dw_dbg, Dwarf_Error dw_error)
Free (dealloc) an Dwarf_Error something created.
char * dwarf_errmsg(Dwarf_Error dw_error)
What message string is in the error?
int dwarf_get_ranges_baseaddress(Dwarf_Debug dw_dbg, Dwarf_Die dw_die, Dwarf_Bool *dw_known_base, Dwarf_Unsigned *dw_baseaddress, Dwarf_Bool *dw_at_ranges_offset_present, Dwarf_Unsigned *dw_at_ranges_offset, Dwarf_Error *dw_error)
Find ranges base address.
int dwarf_get_ranges_b(Dwarf_Debug dw_dbg, Dwarf_Off dw_rangesoffset, Dwarf_Die dw_die, Dwarf_Off *dw_return_realoffset, Dwarf_Ranges **dw_rangesbuf, Dwarf_Signed *dw_rangecount, Dwarf_Unsigned *dw_bytecount, Dwarf_Error *dw_error)
Access to code ranges from a CU or just reading through the raw .debug_ranges section.
void dwarf_dealloc_ranges(Dwarf_Debug dw_dbg, Dwarf_Ranges *dw_rangesbuf, Dwarf_Signed dw_rangecount)
Dealloc the array dw_rangesbuf.
Definition: libdwarf.h:469