static void DC_resolve_type(Dwarf_Die v, DC_type *t){ /*TODO: Error Handling*/ Dwarf_Error error; Dwarf_Attribute type; Dwarf_Off off; Dwarf_Die typeDie; Dwarf_Half tag = 0; /* * Start with the variable, not its type. The loop * unwraps all the types. */ dwarf_attr(v, DW_AT_type, &type, &error); dwarf_formref(type, &off, &error); DC_get_die_from_CU_relative_offset(v, off, &typeDie); int points = 0; int arrs = 0; while( 1 ){ Dwarf_Bool has; dwarf_hasattr(typeDie,DW_AT_type,&has,&error); if(!has){ /*We've reached a base or structure type*/ dwarf_diename(typeDie,&(t->name),&error); Dwarf_Attribute bsize; dwarf_attr(typeDie,DW_AT_byte_size,&bsize,&error); dwarf_formudata(bsize,(Dwarf_Unsigned*)(&t->byteSize),&error); t->indirectionLevel = points; t->arrayLevel = arrs; return; /*Note: I am assuming this must happen eventually. can there * be mutually referencing types?*/ } /*Otherwise: this type has a type, so it is a pointer or a typedef * or an array type. For now, we're only going to correctly * handle pointer types.(TODO:) */ dwarf_tag(typeDie,&tag,&error); if(tag == DW_TAG_pointer_type){ points++; } if(tag == DW_TAG_array_type){ arrs++; } dwarf_attr(typeDie, DW_AT_type, &type, &error); dwarf_formref(type, &off, &error); /*Note, the next line uses v, because it can use anything in the CU*/ DC_get_die_from_CU_relative_offset(v, off, &typeDie); } }
static Dwarf_Off die_attr_ref(dwarf_t *dw, Dwarf_Die die, Dwarf_Half name) { Dwarf_Attribute attr; Dwarf_Off off; attr = die_attr(dw, die, name, DW_ATTR_REQ); if (dwarf_formref(attr, &off, &dw->dw_err) != DW_DLV_OK) { terminate("die %llu: failed to get ref (form 0x%x)\n", die_off(dw, die), die_attr_form(dw, attr)); } dwarf_dealloc(dw->dw_dw, attr, DW_DLA_ATTR); return (off); }
Dwarf_Off DieHolder::get_ref_from_attr(int attr) { Dwarf_Off offset = 0; Dwarf_Half form = 0; Dwarf_Error err = NULL; Dwarf_Attribute attrib = get_attr(attr); CHECK_DWERR2(attrib == NULL, NULL, "cannot find DIE attribute %d\n", attr); CHECK_DWERR(dwarf_whatform(attrib, &form, &err), err, "cannot get form of the DIE attribute %d", attr); switch(form) { case DW_FORM_ref_addr: CHECK_DWERR(dwarf_global_formref(attrib, &offset, &err), err, "cannot get global reference address"); break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: { Dwarf_Off cu_offset = 0; Dwarf_Off cu_length = 0; CHECK_DWERR(dwarf_formref(attrib, &offset, &err), err, "cannot get reference address"); cu_offset = get_CU_offset_range(&cu_length); offset += cu_offset; } break; default: THROW_DWERR("unknown reference form=%d\n", form); break; } return offset; }
static void show_all_attrs(Dwarf_Die die, unsigned long level, void *ndata){ Dwarf_Error error; Dwarf_Half tag; dwarf_tag(die,&tag,&error); const char *stag; dwarf_get_TAG_name(tag,&stag); Dwarf_Off off = 0x0; dwarf_die_CU_offset(die,&off,&error); fprintf(stderr,"[%u]<%x>%s\n",level,off,stag); char **sourceFiles; Dwarf_Signed num; int res; if( (res = dwarf_srcfiles(die,&sourceFiles,&num,&error)) == DW_DLV_OK){ fprintf(stderr,"Source Files Referenced:\n"); int i; for(i = 0; i < num; i++){ fprintf(stderr,"%s\n",sourceFiles[i]); dwarf_dealloc(d, sourceFiles[i],DW_DLA_STRING); } dwarf_dealloc(d, sourceFiles,DW_DLA_LIST); } Dwarf_Unsigned atcnt; Dwarf_Attribute *atlist; int errv; if((errv = dwarf_attrlist(die, &atlist, &atcnt, &error)) == DW_DLV_OK){ int i; for(i = 0; i < atcnt; i++){ Dwarf_Half attr; if(dwarf_whatattr(atlist[i],&attr,&error) == DW_DLV_OK){ const char *sattr; dwarf_get_AT_name(attr,&sattr); fprintf(stderr,"\t%s => ",sattr); }else{ fprintf(stderr,"\tCouldn't Get Attr Type!\n"); continue; } Dwarf_Half form; if(dwarf_whatform(atlist[i],&form,&error) == DW_DLV_OK){ //const char *formname; //dwarf_get_FORM_name(form,&formname); //fprintf(stderr,"[%s] ",formname); switch(form){ case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: {Dwarf_Off offset; dwarf_formref(atlist[i],&offset,&error); fprintf(stderr,"%x\n",offset);} break; case DW_FORM_ref_addr: {Dwarf_Off offset; dwarf_global_formref(atlist[i],&offset,&error); fprintf(stderr,"%x\n",offset);} break; case DW_FORM_addr: {Dwarf_Addr addr; dwarf_formaddr(atlist[i],&addr,&error); fprintf(stderr,"%x\n",addr);} break; case DW_FORM_flag: {Dwarf_Bool flag; dwarf_formflag(atlist[i],&flag,&error); fprintf(stderr,"%s\n",flag ? "True" : "False");} break; case DW_FORM_udata: case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: {Dwarf_Unsigned val; dwarf_formudata(atlist[i],&val,&error); fprintf(stderr,"%u\n",val);} break; case DW_FORM_sdata: {Dwarf_Signed val; dwarf_formsdata(atlist[i],&val,&error); fprintf(stderr,"%d\n",val);} break; case DW_FORM_block: case DW_FORM_block1: if(attr == DW_AT_location || attr == DW_AT_data_member_location || attr == DW_AT_vtable_elem_location || attr == DW_AT_string_length || attr == DW_AT_use_location || attr == DW_AT_return_addr){ /* Dwarf_Locdesc *locationList; Dwarf_Signed listLength; int ret = dwarf_loclist( atlist[i], &locationList, &listLength, &error ); int frameRel = 0; long offset = 0; decode_location(locationList,listLength,&offset,NULL,&frameRel); int i; for( i = 0; i < listLength; ++i){ dwarf_dealloc(d,locationList[i].ld_s,DW_DLA_LOC_BLOCK); } dwarf_dealloc(d,locationList,DW_DLA_LOCDESC); */ DC_location dcl; DC_get_location_attr_value(atlist[i],&dcl); fprintf(stderr," %s:",dcl.isFrameOffset ? "FP Offset" : "Address"); fprintf(stderr," %ld\n",dcl.offset); }else{ fprintf(stderr,"UNSUPPORTED ATTRIBUTE TYPE\n"); } break; case DW_FORM_string: {char *val; dwarf_formstring(atlist[i],&val,&error); fprintf(stderr,"%s\n",val);} break; case DW_FORM_strp: {char *str; if( (dwarf_formstring(atlist[i],&str,&error) == DW_DLV_OK) ){ fprintf(stderr,"%s\n",str); } } break; default: fprintf(stderr,"Unhandled Attribute Form!\n"); break; }; } dwarf_dealloc(d, atlist[i], DW_DLA_ATTR); } dwarf_dealloc(d, atlist, DW_DLA_LIST); } }