QByteArray DwarfDie::attributeName(Dwarf_Half attributeType) { const char* attrName; const auto res = dwarf_get_AT_name(attributeType, &attrName); if (res != DW_DLV_OK) return QByteArray("Unknown attribute ") + QByteArray::number(attributeType); return QByteArray::fromRawData(attrName, strlen(attrName)); }
int main(int argc, char **argv) { unsigned u = 0; unsigned int num = 0; int input_eof = 0; unsigned table_rows = 0; unsigned table_columns = 0; unsigned current_row = 0; FILE * fileInp = 0; FILE * fileOut = 0; const char *aname = 0; unsigned int index = 0; print_version_details(argv[0],FALSE); process_args(argc,argv); print_args(argc,argv); if (!input_name ) { fprintf(stderr,"Input name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileInp = fopen(input_name,"r"); if (!fileInp) { fprintf(stderr,"Invalid input filename, could not open '%s'\n", input_name); print_usage_message(argv[0],usage); exit(FAILED); } if (!output_name ) { fprintf(stderr,"Output name required, not supplied.\n"); print_usage_message(argv[0],usage); exit(FAILED); } fileOut = fopen(output_name,"w"); if (!fileOut) { fprintf(stderr,"Invalid output filename, could not open: '%s'\n", output_name); print_usage_message(argv[0],usage); exit(FAILED); } if ((standard_flag && extended_flag) || (!standard_flag && !extended_flag)) { fprintf(stderr,"Invalid table type\n"); fprintf(stderr,"Choose -e or -s .\n"); print_usage_message(argv[0],usage); exit(FAILED); } if (standard_flag) { table_rows = STD_ATTR_TABLE_ROWS; table_columns = STD_ATTR_TABLE_COLUMNS; } else { table_rows = EXT_ATTR_TABLE_ROWS; table_columns = EXT_ATTR_TABLE_COLS; } input_eof = read_value(&num,fileInp); /* 0xffffffff */ if (IS_EOF == input_eof) { bad_line_input("Empty input file"); } if (num != MAGIC_TOKEN_VALUE) { bad_line_input("Expected 0xffffffff"); } /* Generate main header, regardless of contents */ fprintf(fileOut,"/* Generated code, do not edit. */\n"); fprintf(fileOut,"/* Generated on %s %s */\n",__DATE__,__TIME__); fprintf(fileOut,"\n/* BEGIN FILE */\n\n"); #ifdef HAVE_USAGE_TAG_ATTR /* Generate the data type to record the usage of the pairs tag-attr */ if (standard_flag) { fprintf(fileOut,"#ifndef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#define HAVE_USAGE_TAG_ATTR 1\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); fprintf(fileOut,"#ifdef HAVE_USAGE_TAG_ATTR\n"); fprintf(fileOut,"#include \"dwarf.h\"\n"); fprintf(fileOut,"#include \"libdwarf.h\"\n\n"); fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," unsigned int count; /* Attribute count */\n"); fprintf(fileOut," Dwarf_Half attr; /* Attribute value */\n"); fprintf(fileOut,"} Usage_Tag_Attr;\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ while (!feof(stdin)) { unsigned int tag; unsigned int curcol = 0; unsigned int cur_attr = 0; unsigned int attr; input_eof = read_value(&tag,fileInp); if (IS_EOF == input_eof) { /* Reached normal eof */ break; } if (standard_flag) { if (tag >= table_rows ) { bad_line_input("tag %d exceeds standard table size",tag); } } else { if (current_row >= table_rows) { bad_line_input("too many extended table rows."); } tag_attr_combination_table[current_row][0] = tag; } input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly.."); } curcol = 1; cur_attr = 1; #ifdef HAVE_USAGE_TAG_ATTR /* Check if we have duplicated tags */ if (standard_flag) { if (tag_parents[tag]) { bad_line_input("tag 0x%02x value already defined",tag); } tag_parents[tag] = tag; /* Clear out the working attribute vector */ memset(tag_attr_vector,0,DW_AT_last * sizeof(Dwarf_Half)); } #endif /* HAVE_USAGE_TAG_ATTR */ while (num != MAGIC_TOKEN_VALUE) { if (standard_flag) { unsigned idx = num / BITS_PER_WORD; unsigned bit = num % BITS_PER_WORD; if (idx >= table_columns) { char msg[200]; snprintf(msg, sizeof(msg), "too many attributes a: table incomplete " "index %d cols %d.",idx,table_columns); bad_line_input(msg); } tag_attr_combination_table[tag][idx] |= (1 << bit); } else { if (curcol >= table_columns) { char msg[200]; snprintf(msg, sizeof(msg), "too many attributes b: table incomplete " "index %d cols %d.",curcol,table_columns); bad_line_input(msg); } tag_attr_combination_table[current_row][curcol] = num; curcol++; } #ifdef HAVE_USAGE_TAG_ATTR /* Record the usage only for standard tables */ if (standard_flag) { /* Add attribute to current tag */ if (cur_attr >= DW_AT_last) { char msg[200]; snprintf(msg, sizeof(msg), "too many attributes c: table incomplete " "index %d cols %d.",cur_attr,DW_AT_last); bad_line_input(msg); } /* Check for duplicated entries */ if (tag_attr_vector[cur_attr]) { bad_line_input("duplicated attributes: table incomplete."); } tag_attr_vector[cur_attr] = num; cur_attr++; } #endif /* HAVE_USAGE_TAG_ATTR */ input_eof = read_value(&num,fileInp); if (IS_EOF == input_eof) { bad_line_input("Not terminated correctly."); } } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the tag-attributes vector for current tag */ if (standard_flag) { if (tag >= DW_TAG_last) { bad_line_input("tag 0x%02x exceeds standard table size",tag); } if (tag_children[tag]) { bad_line_input("tag 0x%02x already defined",tag); } tag_children[tag] = tag; /* Generate reference vector */ aname = 0; dwarf_get_TAG_name(tag,&aname); fprintf(fileOut,"/* 0x%02x - %s */\n",tag,aname); fprintf(fileOut, "static Usage_Tag_Attr tag_attr_%02x[] = {\n",tag); for (index = 1; index < cur_attr; ++index) { attr = tag_attr_vector[index]; dwarf_get_AT_name(attr,&aname); fprintf(fileOut," {/* 0x%02x */ 0, %s},\n",attr,aname); } fprintf(fileOut," {/* %4s */ 0, 0}\n};\n\n"," "); /* Record allowed number of attributes */ tag_attr_legal[tag] = cur_attr - 1; } #endif /* HAVE_USAGE_TAG_ATTR */ ++current_row; } #ifdef HAVE_USAGE_TAG_ATTR /* Generate the parent of the individual vectors */ if (standard_flag) { unsigned int tag; unsigned int legal; fprintf(fileOut, "static Usage_Tag_Attr *usage_tag_attr[] = {\n"); for (index = 0; index < DW_TAG_last; ++index) { tag = tag_children[index]; if (tag) { aname = 0; dwarf_get_TAG_name(tag,&aname); fprintf(fileOut, " tag_attr_%02x, /* 0x%02x - %s */\n",tag,tag,aname); } else { fprintf(fileOut," 0,\n"); } } fprintf(fileOut," 0\n};\n\n"); /* Generate table with allowed number of attributes */ fprintf(fileOut,"typedef struct {\n"); fprintf(fileOut," Dwarf_Small legal; /* Legal attributes */\n"); fprintf(fileOut," Dwarf_Small found; /* Found attributes */\n"); fprintf(fileOut,"} Rate_Tag_Attr;\n\n"); fprintf(fileOut, "static Rate_Tag_Attr rate_tag_attr[] = {\n"); for (tag = 0; tag < DW_TAG_last; ++tag) { if (tag_children[tag]) { legal = tag_attr_legal[tag]; aname = 0; dwarf_get_TAG_name(tag,&aname); fprintf(fileOut, " {%2d, 0, /* 0x%02x - %s */},\n",legal,tag,aname); } else { fprintf(fileOut," {0, 0},\n"); } } fprintf(fileOut," {0, 0}\n};\n\n"); fprintf(fileOut,"#endif /* HAVE_USAGE_TAG_ATTR */\n\n"); } #endif /* HAVE_USAGE_TAG_ATTR */ if (standard_flag) { fprintf(fileOut,"#define ATTR_TREE_ROW_COUNT %d\n\n",table_rows); fprintf(fileOut,"#define ATTR_TREE_COLUMN_COUNT %d\n\n",table_columns); fprintf(fileOut, "static unsigned int tag_attr_combination_table" "[ATTR_TREE_ROW_COUNT][ATTR_TREE_COLUMN_COUNT] = {\n"); } else { fprintf(fileOut,"/* Common extensions */\n"); fprintf(fileOut,"#define ATTR_TREE_EXT_ROW_COUNT %d\n\n",table_rows); fprintf(fileOut,"#define ATTR_TREE_EXT_COLUMN_COUNT %d\n\n", table_columns); fprintf(fileOut, "static unsigned int tag_attr_combination_ext_table" "[ATTR_TREE_EXT_ROW_COUNT][ATTR_TREE_EXT_COLUMN_COUNT] = {\n"); } for (u = 0; u < table_rows; u++) { unsigned j = 0; const char *name = 0; if (standard_flag) { dwarf_get_TAG_name(u,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",u,name); } else { unsigned k = tag_attr_combination_table[u][0]; dwarf_get_TAG_name(k,&name); fprintf(fileOut,"/* 0x%02x - %-37s*/\n",k,name); } fprintf(fileOut," { "); for (j = 0; j < table_columns; ++j ) { fprintf(fileOut,"0x%08x,",tag_attr_combination_table[u][j]); } fprintf(fileOut,"},\n"); } fprintf(fileOut,"};\n"); fprintf(fileOut,"\n/* END FILE */\n"); fclose(fileInp); fclose(fileOut); return (0); }
const char * get_AT_name(unsigned int val_in,int printonerr) { const char *v = 0; int res = dwarf_get_AT_name(val_in,&v); return ellipname(res,val_in,v,"AT",printonerr); }
static void _dwarf_attr(Dwarf_Die die) { Dwarf_Attribute at; Dwarf_Bool has_attr; Dwarf_Half attr; Dwarf_Error de; const char *attr_name; int i, r; for (i = 0; i < attr_array_size; i++) { if (dwarf_hasattr(die, attr_array[i], &has_attr, &de) != DW_DLV_OK) { tet_printf("dwarf_hasattr failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(has_attr); if (has_attr) { if (dwarf_get_AT_name(attr_array[i], &attr_name) != DW_DLV_OK) { tet_printf("dwarf_get_AT_name failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; continue; } if (attr_name == NULL) { tet_infoline("dwarf_get_AT_name returned " "DW_DLV_OK but didn't return string"); result = TET_FAIL; continue; } TS_CHECK_STRING(attr_name); tet_printf("DIE #%d has attribute '%s'\n", die_cnt, attr_name); r = dwarf_attr(die, attr_array[i], &at, &de); if (r == DW_DLV_ERROR) { tet_printf("dwarf_attr failed: %s", dwarf_errmsg(de)); result = TET_FAIL; continue; } else if (r == DW_DLV_NO_ENTRY) { tet_infoline("dwarf_hasattr returned true for " "attribute '%s', while dwarf_attr returned" " DW_DLV_NO_ENTRY for the same attr"); result = TET_FAIL; continue; } if (dwarf_whatattr(at, &attr, &de) != DW_DLV_OK) { tet_printf("dwarf_whatattr failed: %s", dwarf_errmsg(de)); result = TET_FAIL; continue; } if (attr != attr_array[i]) { tet_infoline("attr returned by dwarf_whatattr" " != attr_array[i]"); result = TET_FAIL; continue; } } } }
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); } }