diff options
-rw-r--r-- | dwarf-extract-struct.c | 177 |
1 files changed, 117 insertions, 60 deletions
diff --git a/dwarf-extract-struct.c b/dwarf-extract-struct.c index 7e9bb2c..1007a5c 100644 --- a/dwarf-extract-struct.c +++ b/dwarf-extract-struct.c @@ -4,6 +4,7 @@ * Author: Dominique Martinet <dominique.martinet@cea.fr> * License: WTFPLv2 * + * Canonical source: http://cgit.notk.org/asmadeus/dwarf-extract-struct.git */ #include <sys/types.h> @@ -18,15 +19,20 @@ #include "libdwarf/libdwarf.h" -static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, const char *field_names[], int field_count); -static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, const char *field_names[], int field_count, int level); -static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, const char *field_names[], int field_count, int level); -static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, int pad_num); +static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, + const char *field_names[], int field_count); +static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, + const char *field_names[], int field_count, int level); +static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, + const char *field_names[], int field_count, int level); +static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, + int pad_num); int debug = 0; void usage(const char *argv[]) { - printf("%s debug_file struct_name field [field...]\n", argv[0]); + fprintf(stderr, "%s debug_file struct_name field [field...]\n", + argv[0]); } int main(int argc, const char *argv[]) { @@ -49,11 +55,11 @@ int main(int argc, const char *argv[]) { fd = open(filepath,O_RDONLY); if(fd < 0) { - printf("Failure attempting to open %s\n",filepath); + fprintf(stderr, "Failure attempting to open %s\n",filepath); } res = dwarf_init(fd, DW_DLC_READ, errhand, errarg, &dbg, &error); if(res != DW_DLV_OK) { - printf("Giving up, cannot do DWARF processing\n"); + fprintf(stderr, "Giving up, cannot do DWARF processing\n"); exit(1); } @@ -61,7 +67,7 @@ int main(int argc, const char *argv[]) { res = dwarf_finish(dbg,&error); if(res != DW_DLV_OK) { - printf("dwarf_finish failed!\n"); + fprintf(stderr, "dwarf_finish failed!\n"); } close(fd); return 0; @@ -94,25 +100,28 @@ static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, if (rc == DW_DLV_NO_ENTRY) break; if (rc != DW_DLV_OK) { - printf("error dwarf_next_cu_header_c: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "error dwarf_next_cu_header_c: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } rc = dwarf_siblingof(dbg, NULL, &die, &err); if (rc != DW_DLV_OK) { - printf("first dwarf_siblingof failed: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "first dwarf_siblingof failed: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } find_struct(dbg, die, struct_name, field_names, field_count, 0); } - printf("struct %s not found\n", struct_name); + fprintf(stderr, "struct %s not found\n", struct_name); exit(2); } -static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, const char *field_names[], int field_count, int level) { +static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, + const char *field_names[], int field_count, int level) { Dwarf_Die next; Dwarf_Error err; int rc; @@ -129,44 +138,53 @@ static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, if (rc == DW_DLV_NO_ENTRY) { name = NULL; } else if (rc != DW_DLV_OK) { - printf("dwarf_diename error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_diename error: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } rc = dwarf_tag(die, &tag, &err); if (rc != DW_DLV_OK) { - printf("dwarf_tag error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_tag error: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } if (debug) { rc = dwarf_get_TAG_name(tag, &tag_name); if (rc != DW_DLV_OK) { - printf("dwarf_get_TAG_name error: %d\n", rc); + fprintf(stderr, + "dwarf_get_TAG_name error: %d\n", rc); exit(1); } - printf("<%d> %p <%d> %s: %s\n", level, die, tag, tag_name, name ? name : "<no name>"); + printf("<%d> %p <%d> %s: %s\n", level, die, tag, + tag_name, name ? name : "<no name>"); } rc = dwarf_child(die, &next, &err); if (rc == DW_DLV_ERROR) { - printf("dwarf_child error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_child error: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } if (rc == DW_DLV_OK) { if (tag == DW_TAG_structure_type && name && strcasecmp(name, struct_name) == 0) { - find_fields(dbg, next, struct_name, field_names, field_count, level + 1); - printf("Found struct %s but it did not have all members given!\nMissing:\n", + find_fields(dbg, next, struct_name, field_names, + field_count, level + 1); + fprintf(stderr, + "Found struct %s but it did not have all members given!\nMissing:\n", struct_name); for (rc = 0; rc < field_count; rc++) { if (field_names[rc]) - printf("%s\n", field_names[rc]); + fprintf(stderr, "%s\n", + field_names[rc]); } exit(3); } - find_struct(dbg, next, struct_name, field_names, field_count, level + 1); + find_struct(dbg, next, struct_name, field_names, + field_count, level + 1); dwarf_dealloc(dbg, next, DW_DLA_DIE); } @@ -183,7 +201,8 @@ static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, } while (die); } -static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, const char *field_names[], int field_count, int level) { +static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, + const char *field_names[], int field_count, int level) { Dwarf_Die next; Dwarf_Error err; int rc, i, printed_count = 0; @@ -200,24 +219,28 @@ static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, if (rc == DW_DLV_NO_ENTRY) { name = NULL; } else if (rc != DW_DLV_OK) { - printf("dwarf_diename error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_diename error: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } rc = dwarf_tag(die, &tag, &err); if (rc != DW_DLV_OK) { - printf("dwarf_tag error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_tag error: %d %s\n", + rc, dwarf_errmsg(err)); exit(1); } if (debug) { rc = dwarf_get_TAG_name(tag, &tag_name); if (rc != DW_DLV_OK) { - printf("dwarf_get_TAG_name error: %d\n", rc); + fprintf(stderr, + "dwarf_get_TAG_name error: %d\n", rc); exit(1); } - printf("<%d> %p <%d> %s: %s\n", level, die, tag, tag_name, name ? name : "<no name>"); + printf("<%d> %p <%d> %s: %s\n", level, die, tag, + tag_name, name ? name : "<no name>"); } if (tag == DW_TAG_member && name) { @@ -225,7 +248,8 @@ static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, if (!field_names[i]) continue; if (strcasecmp(name, field_names[i]) == 0) { - print_field(dbg, die, field_names[i], printed_count); + print_field(dbg, die, field_names[i], + printed_count); field_names[i] = NULL; printed_count++; break; @@ -249,7 +273,8 @@ static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, } while (die); } -static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, int padnum) { +static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, + int padnum) { Dwarf_Attribute attr; Dwarf_Error err; Dwarf_Unsigned offset = 0; @@ -258,15 +283,18 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, rc = dwarf_attr(die, DW_AT_data_member_location, &attr, &err); if (rc == DW_DLV_NO_ENTRY) { - printf("Found %s but no offset, assuming 0\n", field_name); + fprintf(stderr, "Found %s but no offset, assuming 0\n", + field_name); } else if (rc != DW_DLV_OK) { - printf("Error getting dwarf attr offset: %s\n", dwarf_errmsg(err)); + fprintf(stderr, "Error getting dwarf attr offset: %s\n", + dwarf_errmsg(err)); exit(4); } else { Dwarf_Half form; rc = dwarf_whatform(attr, &form, &err); if (rc != DW_DLV_OK) { - printf("Error getting whatform: %s\n", dwarf_errmsg(err)); + fprintf(stderr, "Error getting whatform: %s\n", + dwarf_errmsg(err)); exit(5); } if (form == DW_FORM_data1 || form == DW_FORM_data2 @@ -277,22 +305,26 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, Dwarf_Signed soffset; dwarf_formsdata(attr, &soffset, 0); if (soffset < 0) { - printf("unsupported negative offset\n"); - /* FAIL */ + fprintf(stderr, + "unsupported negative offset\n"); + exit(5); } offset = (Dwarf_Unsigned) soffset; } else { Dwarf_Locdesc **locdescs; Dwarf_Signed len; - if (dwarf_loclist_n(attr, &locdescs, &len, &err) == DW_DLV_ERROR) { - printf("unsupported member offset\n"); - /* FAIL */ + if (dwarf_loclist_n(attr, &locdescs, &len, &err) + == DW_DLV_ERROR) { + fprintf(stderr, "unsupported member offset\n"); + exit(5); } if (len != 1 - || locdescs[0]->ld_cents != 1 - || (locdescs[0]->ld_s[0]).lr_atom != DW_OP_plus_uconst) { - printf("unsupported location expression\n"); - /* FAIL */ + || locdescs[0]->ld_cents != 1 + || (locdescs[0]->ld_s[0]).lr_atom + != DW_OP_plus_uconst) { + fprintf(stderr, + "unsupported location expression\n"); + exit(5); } offset = (locdescs[0]->ld_s[0]).lr_number; } @@ -301,10 +333,13 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, rc = dwarf_attr(die, DW_AT_type, &attr, &err); if (rc == DW_DLV_NO_ENTRY) { - printf("Found %s but no type, can't assume that one out..\n", field_name); + fprintf(stderr, + "Found %s but no type, can't assume that one out..\n", + field_name); exit(6); } else if (rc != DW_DLV_OK) { - printf("Error getting dwarf attrlist: %s\n", dwarf_errmsg(err)); + fprintf(stderr, "Error getting dwarf attrlist: %s\n", + dwarf_errmsg(err)); exit(6); } else { Dwarf_Die type_die; @@ -315,19 +350,24 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, rc = dwarf_global_formref(attr, &type_off, &err); if (rc != DW_DLV_OK) { - printf("Error getting ref offset for type: %s\n", dwarf_errmsg(err)); + fprintf(stderr, + "Error getting ref offset for type: %s\n", + dwarf_errmsg(err)); exit(7); } rc = dwarf_offdie_b(dbg, type_off, 1, &type_die, &err); if (rc != DW_DLV_OK) { - printf("Error getting die from offset for type: %s\n", dwarf_errmsg(err)); + fprintf(stderr, + "Error getting die from offset for type: %s\n", + dwarf_errmsg(err)); exit(7); } rc = dwarf_tag(type_die, &type_tag, &err); if (rc != DW_DLV_OK) { - printf("dwarf_tag error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_tag error: %d %s\n", + rc, dwarf_errmsg(err)); exit(7); } @@ -336,21 +376,30 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, Dwarf_Off pointer_off; Dwarf_Die pointer_die; - rc = dwarf_attr(type_die, DW_AT_type, &pointer_attr, &err); + rc = dwarf_attr(type_die, DW_AT_type, &pointer_attr, + &err); if (rc != DW_DLV_OK) { - printf("Error getting pointer attr for type: %s\n", dwarf_errmsg(err)); + fprintf(stderr, + "Error getting pointer attr for type: %s\n", + dwarf_errmsg(err)); exit(7); } - rc = dwarf_global_formref(pointer_attr, &pointer_off, &err); + rc = dwarf_global_formref(pointer_attr, &pointer_off, + &err); if (rc != DW_DLV_OK) { - printf("Error getting pointer ref offset for type: %s\n", dwarf_errmsg(err)); + fprintf(stderr, + "Error getting pointer ref offset for type: %s\n", + dwarf_errmsg(err)); exit(7); } - rc = dwarf_offdie_b(dbg, pointer_off, 1, &pointer_die, &err); + rc = dwarf_offdie_b(dbg, pointer_off, 1, &pointer_die, + &err); if (rc != DW_DLV_OK) { - printf("Error getting pointer die from offset for type: %s\n", dwarf_errmsg(err)); + fprintf(stderr, + "Error getting pointer die from offset for type: %s\n", + dwarf_errmsg(err)); exit(7); } @@ -362,29 +411,35 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, rc = dwarf_tag(type_die, &type_tag, &err); if (rc != DW_DLV_OK) { - printf("dwarf_tag error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_tag error: %d %s\n", + rc, dwarf_errmsg(err)); exit(7); } } rc = dwarf_diename(type_die, &type_name, &err); if (rc != DW_DLV_OK) { - printf("dwarf_diename error: %d %s\n", rc, dwarf_errmsg(err)); + fprintf(stderr, "dwarf_diename error: %d %s\n", + rc, dwarf_errmsg(err)); const char *tag_name; rc = dwarf_get_TAG_name(type_tag, &tag_name); if (rc != DW_DLV_OK) { - printf("dwarf_get_TAG_name error: %d\n", rc); + fprintf(stderr, + "dwarf_get_TAG_name error: %d\n", + rc); } - printf("Bad tag %s (%d)?\n", tag_name, type_tag); + fprintf(stderr, "Bad tag %s (%d)?\n", + tag_name, type_tag); exit(7); } if (type_tag == DW_TAG_structure_type) { - snprintf(type_buf, 1024, "struct %s%s", pointer ? "*" : "", - type_name); - } else if (type_tag == DW_TAG_base_type || type_tag == DW_TAG_typedef) { + snprintf(type_buf, 1024, "struct %s%s", + pointer ? "*" : "", type_name); + } else if (type_tag == DW_TAG_base_type + || type_tag == DW_TAG_typedef) { snprintf(type_buf, 1024, "%s%s", pointer ? "*" : "", type_name); } else { @@ -392,10 +447,12 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, rc = dwarf_get_TAG_name(type_tag, &tag_name); if (rc != DW_DLV_OK) { - printf("dwarf_get_TAG_name error: %d\n", rc); + fprintf(stderr, + "dwarf_get_TAG_name error: %d\n", rc); } - printf("Type tag %s (%d) is not implemented, please add it\n", + fprintf(stderr, + "Type tag %s (%d) is not implemented, please add it\n", tag_name, type_tag); exit(7); } |