libdwarf
Using dwarf_discr_list()

Example using dwarf_discr_list, dwarf_formblock.

An example calling dwarf_get_form_class, dwarf_discr_list, and dwarf_formblock. and the dwarf_deallocs applicable.

See also
dwarf_discr_list
dwarf_get_form_class
dwarf_formblock
Parameters
dw_dbgThe applicable Dwarf_Debug
dw_dieThe applicable Dwarf_Die
dw_attrThe applicable Dwarf_Attribute
dw_attrnum,Theattribute number passed in to shorten this example a bit.
dw_isunsigned,Theattribute number passed in to shorten this example a bit.
dw_theform,Theform number passed in to shorten this example a bit.
dw_errorThe usual error pointer.
Returns
Returns DW_DLV_OK etc
*/
int example_discr_list(Dwarf_Debug dbg,
Dwarf_Die die,
Dwarf_Half attrnum,
Dwarf_Bool isunsigned,
Dwarf_Half theform,
Dwarf_Error *error)
{
/* The example here assumes that
attribute attr is a DW_AT_discr_list.
isunsigned should be set from the signedness
of the parent of 'die' per DWARF rules for
DW_AT_discr_list. */
enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN;
Dwarf_Half version = 0;
Dwarf_Half offset_size = 0;
int wres = 0;
wres = dwarf_get_version_of_die(die,&version,&offset_size);
if (wres != DW_DLV_OK) {
/* FAIL */
return wres;
}
fc = dwarf_get_form_class(version,attrnum,offset_size,theform);
if (fc == DW_FORM_CLASS_BLOCK) {
int fres = 0;
Dwarf_Block *tempb = 0;
fres = dwarf_formblock(attr, &tempb, error);
if (fres == DW_DLV_OK) {
Dwarf_Unsigned arraycount = 0;
int sres = 0;
sres = dwarf_discr_list(dbg,
(Dwarf_Small *)tempb->bl_data,
tempb->bl_len,
&h,&arraycount,error);
if (sres == DW_DLV_NO_ENTRY) {
/* Nothing here. */
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return sres;
}
if (sres == DW_DLV_ERROR) {
/* FAIL . */
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return sres ;
}
for (u = 0; u < arraycount; u++) {
int u2res = 0;
Dwarf_Half dtype = 0;
Dwarf_Signed dlow = 0;
Dwarf_Signed dhigh = 0;
Dwarf_Unsigned ulow = 0;
Dwarf_Unsigned uhigh = 0;
if (isunsigned) {
u2res = dwarf_discr_entry_u(h,u,
&dtype,&ulow,&uhigh,error);
} else {
u2res = dwarf_discr_entry_s(h,u,
&dtype,&dlow,&dhigh,error);
}
if (u2res == DW_DLV_ERROR) {
/* Something wrong */
dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD);
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return u2res ;
}
if (u2res == DW_DLV_NO_ENTRY) {
/* Impossible. u < arraycount. */
dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD);
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return u2res;
}
/* Do something with dtype, and whichever
of ulow, uhigh,dlow,dhigh got set.
Probably save the values somewhere.
Simple casting of dlow to ulow (or vice versa)
will not get the right value due to the nature
of LEB values. Similarly for uhigh, dhigh.
One must use the right call. */
}
dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD);
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
}
}
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
struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head
Definition: libdwarf.h:363
struct Dwarf_Attribute_s * Dwarf_Attribute
Definition: libdwarf.h:658
enum Dwarf_Form_Class dwarf_get_form_class(Dwarf_Half dw_version, Dwarf_Half dw_attrnum, Dwarf_Half dw_offset_size, Dwarf_Half dw_form)
Return the FORM_CLASS applicable. Four pieces of information are necessary to get the correct FORM_CL...
int dwarf_discr_list(Dwarf_Debug dw_dbg, Dwarf_Small *dw_blockpointer, Dwarf_Unsigned dw_blocklen, Dwarf_Dsc_Head *dw_dsc_head_out, Dwarf_Unsigned *dw_dsc_array_length_out, Dwarf_Error *dw_error)
Return an array of discriminant values.
int dwarf_formblock(Dwarf_Attribute dw_attr, Dwarf_Block **dw_returned_block, Dwarf_Error *dw_error)
Return an allocated filled-in Form_Block.
int dwarf_discr_entry_s(Dwarf_Dsc_Head dw_dsc, Dwarf_Unsigned dw_entrynum, Dwarf_Half *dw_out_type, Dwarf_Signed *dw_out_discr_low, Dwarf_Signed *dw_out_discr_high, Dwarf_Error *dw_error)
Access to a single signed discriminant list entry.
int dwarf_discr_entry_u(Dwarf_Dsc_Head dw_dsc, Dwarf_Unsigned dw_entrynum, Dwarf_Half *dw_out_type, Dwarf_Unsigned *dw_out_discr_low, Dwarf_Unsigned *dw_out_discr_high, Dwarf_Error *dw_error)
Access a single unsigned discriminant list entry.
unsigned char Dwarf_Small
Definition: libdwarf.h:204
signed long long Dwarf_Signed
Definition: libdwarf.h:197
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_version_of_die(Dwarf_Die dw_die, Dwarf_Half *dw_version, Dwarf_Half *dw_offset_size)
Get the version and offset size.
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,...
Dwarf_Form_Class
Definition: libdwarf.h:269
Definition: libdwarf.h:330