Example accessing all CUs looking for specific items(d).
Loops through as many CUs as needed, stops and returns once a CU provides the desired data.
Assumes certain functions you write to remember the aspect of CUs that matter to you so once found in a cu my_needed_data_exists() or some other function of yours can identify the correct record. (Possibly a DIE global offset. Remember to note if each DIE has is_info TRUE or FALSE so libdwarf can find the DIE properly.)
Depending on your goals in examining the DIE tree it may be helpful to maintain a DIE stack of active DIEs, pushing and popping as you make your way throught the DIE levels.
We assume that on a serious error we will give up (for simplicity here).
We assume the caller to examplecuhdrd() will know what to retrieve (when we return DW_DLV_OK from examplecuhdrd() and that myrecords points to a record with all the data needed by my_needed_data_exists() and recorded by myrecord_data_for_die().
*/
struct myrecords_struct *myrecords;
void myrecord_data_for_die(struct myrecords_struct *myrecords,
int my_needed_data_exists(struct myrecords_struct *myrecords);
static void
int is_info, int in_level,
struct myrecords_struct *myrec,
{
int res = DW_DLV_OK;
myrecord_data_for_die(myrec,in_die);
for (;;) {
if (res == DW_DLV_ERROR) {
printf("Error in dwarf_child , level %d \n",in_level);
exit(EXIT_FAILURE);
}
if (res == DW_DLV_OK) {
record_die_and_siblingsd(dbg,child,is_info,
in_level+1,myrec,error);
child = 0;
}
if (res == DW_DLV_ERROR) {
exit(EXIT_FAILURE);
}
if (res == DW_DLV_NO_ENTRY) {
break;
}
if (cur_die != in_die) {
cur_die = 0;
}
cur_die = sib_die;
myrecord_data_for_die(myrec,sib_die);
}
return;
}
struct myrecords_struct *myrec,
{
int res = 0;
while(!my_needed_data_exists(myrec)) {
memset(&signature,0, sizeof(signature));
&version_stamp, &abbrev_offset,
&address_size, &offset_size,
&extension_size,&signature,
&typeoffset, &next_cu_header,
&header_cu_type,error);
if (res == DW_DLV_ERROR) {
return res;
}
if (res == DW_DLV_NO_ENTRY) {
if (is_info == TRUE) {
is_info = FALSE;
continue;
}
return res;
}
&cu_die,error);
if (res == DW_DLV_ERROR) {
return res;
}
if (res == DW_DLV_NO_ENTRY) {
exit(EXIT_FAILURE);
}
record_die_and_siblingsd(dbg,cu_die,is_info,
0, myrec,error);
}
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
unsigned short Dwarf_Half
Definition: libdwarf.h:203
unsigned long long Dwarf_Unsigned
Definition: libdwarf.h:196
int Dwarf_Bool
Definition: libdwarf.h:202
int dwarf_next_cu_header_d(Dwarf_Debug dw_dbg, Dwarf_Bool dw_is_info, Dwarf_Unsigned *dw_cu_header_length, Dwarf_Half *dw_version_stamp, Dwarf_Off *dw_abbrev_offset, Dwarf_Half *dw_address_size, Dwarf_Half *dw_length_size, Dwarf_Half *dw_extension_size, Dwarf_Sig8 *dw_type_signature, Dwarf_Unsigned *dw_typeoffset, Dwarf_Unsigned *dw_next_cu_header_offset, Dwarf_Half *dw_header_cu_type, Dwarf_Error *dw_error)
Return information on the next CU header(d)
void dwarf_dealloc_die(Dwarf_Die dw_die)
Deallocate (free) a DIE.
int dwarf_child(Dwarf_Die dw_die, Dwarf_Die *dw_return_childdie, Dwarf_Error *dw_error)
Return the child DIE, if any. The child may be the first of a list of sibling DIEs.
int dwarf_siblingof_b(Dwarf_Debug dw_dbg, Dwarf_Die dw_die, Dwarf_Bool dw_is_info, Dwarf_Die *dw_return_siblingdie, Dwarf_Error *dw_error)
Return the first DIE or the next sibling DIE.
void dwarf_dealloc(Dwarf_Debug dw_dbg, void *dw_space, Dwarf_Unsigned dw_type)
The generic dealloc (free) function. It requires you know the correct DW_DLA value to pass in,...
Definition: libdwarf.h:313