libdwarf
Loading...
Searching...
No Matches
Example walking CUs(e)

Example examining CUs looking for specific items(e).

Example examining CUs looking for specific items(e).

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.

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 examplecuhdre() will know what to retrieve (when we return DW_DLV_OK from examplecuhdree() 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_data,
{
/* do somthing */
/* avoid compiler warnings */
(void)myrecords_data;
(void)d;
}
int my_needed_data_exists(struct myrecords_struct *myrecords_data)
{
/* do something */
/* avoid compiler warnings */
(void)myrecords_data;
return DW_DLV_OK;
}
/* Loop on DIE tree. */
static void
record_die_and_siblings_e(Dwarf_Debug dbg, Dwarf_Die in_die,
int is_info, int in_level,
struct myrecords_struct *myrec,
Dwarf_Error *error)
{
int res = DW_DLV_OK;
Dwarf_Die cur_die=in_die;
Dwarf_Die child = 0;
myrecord_data_for_die(myrec,in_die);
/* Loop on a list of siblings */
for (;;) {
Dwarf_Die sib_die = 0;
/* Depending on your goals, the in_level,
and the DW_TAG of cur_die, you may want
to skip the dwarf_child call. We descend
the DWARF-standard way of depth-first. */
res = dwarf_child(cur_die,&child,error);
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_siblings_e(dbg,child,is_info,
in_level+1,myrec,error);
/* No longer need 'child' die. */
dwarf_dealloc(dbg,child,DW_DLA_DIE);
child = 0;
}
/* res == DW_DLV_NO_ENTRY or DW_DLV_OK */
res = dwarf_siblingof_c(cur_die,&sib_die,error);
if (res == DW_DLV_ERROR) {
exit(EXIT_FAILURE);
}
if (res == DW_DLV_NO_ENTRY) {
/* Done at this level. */
break;
}
/* res == DW_DLV_OK */
if (cur_die != in_die) {
dwarf_dealloc(dbg,cur_die,DW_DLA_DIE);
cur_die = 0;
}
cur_die = sib_die;
myrecord_data_for_die(myrec,sib_die);
}
return;
}
/* Assuming records properly initialized for your use. */
int examplecuhdre(Dwarf_Debug dbg,
struct myrecords_struct *myrec,
Dwarf_Error *error)
{
Dwarf_Unsigned abbrev_offset = 0;
Dwarf_Half address_size = 0;
Dwarf_Half version_stamp = 0;
Dwarf_Half offset_size = 0;
Dwarf_Half extension_size = 0;
Dwarf_Sig8 signature;
Dwarf_Unsigned typeoffset = 0;
Dwarf_Unsigned next_cu_header = 0;
Dwarf_Half header_cu_type = 0;
Dwarf_Bool is_info = TRUE;
int res = 0;
while(!my_needed_data_exists(myrec)) {
Dwarf_Die cu_die = 0;
Dwarf_Unsigned cu_header_length = 0;
memset(&signature,0, sizeof(signature));
res = dwarf_next_cu_header_e(dbg,is_info,
&cu_die,
&cu_header_length,
&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) {
/* Done with .debug_info, now check for
.debug_types. */
is_info = FALSE;
continue;
}
/* No more CUs to read! Never found
what we were looking for in either
.debug_info or .debug_types. */
return res;
}
/* We have the cu_die .
New in v0.9.0 because the connection of
the CU_DIE to the CU header is clear
in the argument list.
/
record_die_and_siblings_e(dbg,cu_die,is_info,
0, myrec,error);
dwarf_dealloc_die(cu_die);
}
/* Found what we looked for */
return DW_DLV_OK;
}
struct Dwarf_Debug_s * Dwarf_Debug
Definition libdwarf.h:603
struct Dwarf_Die_s * Dwarf_Die
Definition libdwarf.h:613
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
DW_API int dwarf_next_cu_header_e(Dwarf_Debug dw_dbg, Dwarf_Bool dw_is_info, Dwarf_Die *dw_cu_die, 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(e).
DW_API 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.
DW_API int dwarf_siblingof_c(Dwarf_Die dw_die, Dwarf_Die *dw_return_siblingdie, Dwarf_Error *dw_error)
Return the next sibling DIE.
DW_API 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