libdwarf
Reading .debug_macro data (DWARF5)

Example reading DWARF5 macro data.

This builds an list or some other data structure (not defined) to give an import somewhere to list the import offset and then later to enquire if the list has unexamined offsets. The code compiles but is not yet tested.

This example does not actually do the import at the correct time as this is just checking import offsets, not creating a proper full list (in the proper order) of the macros with the imports inserted. Here we find the macro context for a DIE, report those macro entries, noting any macro_import in a list loop extracting unchecked macro offsets from the list note any import in a list Of course some functions are not implemented here...

*/
int has_unchecked_import_in_list(void)
{
/* Do something */
return DW_DLV_OK;
}
Dwarf_Unsigned get_next_import_from_list(void)
{
/* Do something */
return 22;
}
void mark_this_offset_as_examined(
Dwarf_Unsigned macro_unit_offset)
{
/* do something */
/* avoid compiler warnings. */
(void)macro_unit_offset;
}
void add_offset_to_list(Dwarf_Unsigned offset)
{
/* do something */
/* avoid compiler warnings. */
(void)offset;;
}
int examplep5(Dwarf_Die cu_die,Dwarf_Error *error)
{
int lres = 0;
Dwarf_Unsigned version = 0;
Dwarf_Macro_Context macro_context = 0;
Dwarf_Unsigned macro_unit_offset = 0;
Dwarf_Unsigned number_of_ops = 0;
Dwarf_Unsigned ops_total_byte_len = 0;
Dwarf_Bool is_primary = TRUE;
/* Just call once each way to test both.
Really the second is just for imported units.*/
for ( ; ; ) {
if (is_primary) {
lres = dwarf_get_macro_context(cu_die,
&version,&macro_context,
&macro_unit_offset,
&number_of_ops,
&ops_total_byte_len,
error);
is_primary = FALSE;
} else {
if (has_unchecked_import_in_list()) {
macro_unit_offset = get_next_import_from_list();
} else {
/* We are done */
break;
}
macro_unit_offset,
&version,
&macro_context,
&number_of_ops,
&ops_total_byte_len,
error);
mark_this_offset_as_examined(macro_unit_offset);
}
if (lres == DW_DLV_ERROR) {
/* Something is wrong. */
return lres;
}
if (lres == DW_DLV_NO_ENTRY) {
/* We are done. */
break;
}
/* lres == DW_DLV_OK) */
for (k = 0; k < number_of_ops; ++k) {
Dwarf_Unsigned section_offset = 0;
Dwarf_Half macro_operator = 0;
Dwarf_Half forms_count = 0;
const Dwarf_Small *formcode_array = 0;
Dwarf_Unsigned line_number = 0;
Dwarf_Unsigned index = 0;
Dwarf_Unsigned offset =0;
const char * macro_string =0;
int lres2 = 0;
lres2 = dwarf_get_macro_op(macro_context,
k, &section_offset,&macro_operator,
&forms_count, &formcode_array,error);
if (lres2 != DW_DLV_OK) {
/* Some error. Deal with it */
return lres2;
}
switch(macro_operator) {
case 0:
/* Nothing to do. */
break;
case DW_MACRO_end_file:
/* Do something */
break;
case DW_MACRO_define:
case DW_MACRO_undef:
case DW_MACRO_define_strp:
case DW_MACRO_undef_strp:
case DW_MACRO_define_strx:
case DW_MACRO_undef_strx:
case DW_MACRO_define_sup:
case DW_MACRO_undef_sup: {
lres2 = dwarf_get_macro_defundef(macro_context,
k,
&line_number,
&index,
&offset,
&forms_count,
&macro_string,
error);
if (lres2 != DW_DLV_OK) {
/* Some error. Deal with it */
return lres2;
}
/* do something */
}
break;
case DW_MACRO_start_file: {
lres2 = dwarf_get_macro_startend_file(macro_context,
k,&line_number,
&index,
&macro_string,error);
if (lres2 != DW_DLV_OK) {
/* Some error. Deal with it */
return lres2;
}
/* do something */
}
break;
case DW_MACRO_import: {
lres2 = dwarf_get_macro_import(macro_context,
k,&offset,error);
if (lres2 != DW_DLV_OK) {
/* Some error. Deal with it */
return lres2;
}
add_offset_to_list(offset);
}
break;
case DW_MACRO_import_sup: {
lres2 = dwarf_get_macro_import(macro_context,
k,&offset,error);
if (lres2 != DW_DLV_OK) {
/* Some error. Deal with it */
return lres2;
}
/* do something */
}
break;
default:
/* This is an error or an omission
in the code here. We do not
know what to do.
Do something appropriate, print something?. */
break;
}
}
macro_context = 0;
}
return DW_DLV_OK;
}
/*
struct Dwarf_Die_s * Dwarf_Die
Definition: libdwarf.h:608
struct Dwarf_Error_s * Dwarf_Error
Definition: libdwarf.h:597
struct Dwarf_Macro_Context_s * Dwarf_Macro_Context
Definition: libdwarf.h:702
unsigned char Dwarf_Small
Definition: libdwarf.h:204
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_get_macro_context(Dwarf_Die dw_die, Dwarf_Unsigned *dw_version_out, Dwarf_Macro_Context *dw_macro_context, Dwarf_Unsigned *dw_macro_unit_offset_out, Dwarf_Unsigned *dw_macro_ops_count_out, Dwarf_Unsigned *dw_macro_ops_data_length_out, Dwarf_Error *dw_error)
DWARF5 .debug_macro access via Dwarf_Die.
int dwarf_get_macro_import(Dwarf_Macro_Context dw_macro_context, Dwarf_Unsigned dw_op_number, Dwarf_Unsigned *dw_target_offset, Dwarf_Error *dw_error)
Get Macro import.
int dwarf_get_macro_op(Dwarf_Macro_Context dw_macro_context, Dwarf_Unsigned dw_op_number, Dwarf_Unsigned *dw_op_start_section_offset, Dwarf_Half *dw_macro_operator, Dwarf_Half *dw_forms_count, const Dwarf_Small **dw_formcode_array, Dwarf_Error *dw_error)
Access macro operation details of a single operation.
int dwarf_get_macro_context_by_offset(Dwarf_Die dw_die, Dwarf_Unsigned dw_offset, Dwarf_Unsigned *dw_version_out, Dwarf_Macro_Context *dw_macro_context, Dwarf_Unsigned *dw_macro_ops_count_out, Dwarf_Unsigned *dw_macro_ops_data_length, Dwarf_Error *dw_error)
DWARF5 .debug_macro access via Dwarf_Die and an offset.
void dwarf_dealloc_macro_context(Dwarf_Macro_Context dw_mc)
Dealloc a macro context.
int dwarf_get_macro_startend_file(Dwarf_Macro_Context dw_macro_context, Dwarf_Unsigned dw_op_number, Dwarf_Unsigned *dw_line_number, Dwarf_Unsigned *dw_name_index_to_line_tab, const char **dw_src_file_name, Dwarf_Error *dw_error)
Get Macro start end.
int dwarf_get_macro_defundef(Dwarf_Macro_Context dw_macro_context, Dwarf_Unsigned dw_op_number, Dwarf_Unsigned *dw_line_number, Dwarf_Unsigned *dw_index, Dwarf_Unsigned *dw_offset, Dwarf_Half *dw_forms_count, const char **dw_macro_string, Dwarf_Error *dw_error)
Get Macro defundef.