diff options
author | Dominique Martinet <asmadeus@codewreck.org> | 2017-10-03 16:18:27 +0900 |
---|---|---|
committer | Dominique Martinet <asmadeus@codewreck.org> | 2017-10-03 16:18:27 +0900 |
commit | 8b079fca9d7726ebc860434350240d3a8d91a43a (patch) | |
tree | 1ebc9ae7435e5c4073b933c575045580d9c2148c | |
parent | f365e7a74546efb8601592ff5acc96a5cf040098 (diff) |
print whole struct at a time
-rw-r--r-- | dwarf.c | 77 |
1 files changed, 41 insertions, 36 deletions
@@ -10,22 +10,22 @@ #include "libdwarf.h" -static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, const char *field_name); -static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, const char *field_name, int level); -static void find_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, int level); -static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name); +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(char *argv[]) { - printf("%s file struct field\n", argv[0]); + printf("%s debug_file struct_name field [field...]\n", argv[0]); } int main(int argc, char *argv[]) { Dwarf_Debug dbg = 0; int fd = -1; const char *filepath; - const char *struct_name, *field_name; + const char *struct_name, **field_names; int res = DW_DLV_ERROR; Dwarf_Error error; Dwarf_Handler errhand = 0; @@ -38,7 +38,7 @@ int main(int argc, char *argv[]) { filepath = argv[1]; struct_name = argv[2]; - field_name = argv[3]; + field_names = argv + 3; fd = open(filepath,O_RDONLY); if(fd < 0) { @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) { exit(1); } - parse_dwarf(dbg, struct_name, field_name); + parse_dwarf(dbg, struct_name, field_names, argc - 3); res = dwarf_finish(dbg,&error); if(res != DW_DLV_OK) { @@ -61,7 +61,7 @@ int main(int argc, char *argv[]) { } static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, - const char *field_name) { + const char *field_names[], int field_count) { Dwarf_Bool is_info = 1; Dwarf_Unsigned cu_length; Dwarf_Half cu_version; @@ -98,14 +98,14 @@ static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, exit(1); } - find_struct(dbg, die, struct_name, field_name, 0); + find_struct(dbg, die, struct_name, field_names, field_count, 0); } printf("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_name, 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; @@ -150,12 +150,16 @@ static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, if (rc == DW_DLV_OK) { if (tag == DW_TAG_structure_type && name && strcasecmp(name, struct_name) == 0) { - find_field(dbg, next, field_name, level + 1); - printf("Found struct %s but it had no member %s!\n", - struct_name, field_name); + 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", + struct_name); + for (rc = 0; rc < field_count; rc++) { + if (field_names[rc]) + printf("%s\n", field_names[rc]); + } exit(3); } - find_struct(dbg, next, struct_name, field_name, level + 1); + find_struct(dbg, next, struct_name, field_names, field_count, level + 1); dwarf_dealloc(dbg, next, DW_DLA_DIE); } @@ -172,13 +176,13 @@ static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, } while (die); } -static void find_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, 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; + int rc, i, printed_count = 0; - if (level > 2) - return; + printf("struct %s {\n\tunion {\n", + struct_name); do { char *name; @@ -209,23 +213,23 @@ static void find_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, i printf("<%d> %p <%d> %s: %s\n", level, die, tag, tag_name, name ? name : "<no name>"); } - if (tag == DW_TAG_member && name - && strcasecmp(name, field_name) == 0) { - print_field(dbg, die, field_name); - exit(0); - } - - rc = dwarf_child(die, &next, &err); - if (rc == DW_DLV_ERROR) { - printf("dwarf_child error: %d %s\n", rc, dwarf_errmsg(err)); - exit(1); - } - if (rc == DW_DLV_OK) { - find_field(dbg, next, field_name, level + 1); - dwarf_dealloc(dbg, next, DW_DLA_DIE); + if (tag == DW_TAG_member && name) { + for (i = 0; i < field_count; i++) { + if (!field_names[i]) + continue; + if (strcasecmp(name, field_names[i]) == 0) { + print_field(dbg, die, field_names[i], printed_count); + field_names[i] = NULL; + printed_count++; + break; + } + } + if (printed_count == field_count) { + printf("\t};\n};\n"); + exit(0); + } } - rc = dwarf_siblingof(dbg, die, &next, &err); dwarf_dealloc(dbg, die, DW_DLA_DIE); if (name) @@ -238,7 +242,7 @@ static void find_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, i } while (die); } -static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name) { +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; @@ -394,7 +398,8 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name) dwarf_dealloc(dbg, type_die, DW_DLA_DIE); } - printf("union {\n\tchar padding[%u]\n\t%s %s\n};\n", + printf("\t\tstruct {\n\t\t\tchar padding%i[%u]\n\t\t\t%s %s\n\t\t};\n", + padnum, (unsigned int) offset, type_buf, field_name); } |