summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwarf-extract-struct.c169
1 files changed, 90 insertions, 79 deletions
diff --git a/dwarf-extract-struct.c b/dwarf-extract-struct.c
index 1ade375..dfd373b 100644
--- a/dwarf-extract-struct.c
+++ b/dwarf-extract-struct.c
@@ -23,15 +23,16 @@ 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 find_fields(Dwarf_Debug dbg, Dwarf_Die struct_die, 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[]) {
- fprintf(stderr, "%s debug_file struct_name field [field...]\n",
+ fprintf(stderr, "%s debug_file struct_name [field [field...]]\n",
argv[0]);
}
@@ -45,7 +46,7 @@ int main(int argc, const char *argv[]) {
Dwarf_Handler errhand = 0;
Dwarf_Ptr errarg = 0;
- if(argc < 4) {
+ if(argc < 3) {
usage(argv);
exit(1);
}
@@ -171,8 +172,9 @@ 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_fields(dbg, next, struct_name, field_names,
- field_count, level + 1);
+ find_fields(dbg, die, 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);
@@ -201,79 +203,6 @@ 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) {
- Dwarf_Die next;
- Dwarf_Error err;
- int rc, i, printed_count = 0;
-
- printf("struct %s {\n\tunion {\n",
- struct_name);
-
- do {
- char *name;
- const char *tag_name;
- Dwarf_Half tag;
-
- rc = dwarf_diename(die, &name, &err);
- if (rc == DW_DLV_NO_ENTRY) {
- name = NULL;
- } else if (rc != DW_DLV_OK) {
- 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) {
- 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) {
- 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>");
- }
-
- 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)
- dwarf_dealloc(dbg, name, DW_DLA_STRING);
-
- if (rc != DW_DLV_OK)
- break;
-
- die = next;
- } while (die);
-}
-
-
static int dwarf_get_offset(Dwarf_Debug dbg, Dwarf_Die die,
int *poffset, Dwarf_Error *perr) {
Dwarf_Attribute attr;
@@ -412,6 +341,88 @@ static int deref_type(Dwarf_Debug dbg, Dwarf_Die type_die,
return rc;
}
+static void find_fields(Dwarf_Debug dbg, Dwarf_Die struct_die, 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;
+ int size;
+
+ printf("struct %s {\n\tunion {\n",
+ struct_name);
+
+ rc = dwarf_get_size(dbg, struct_die, &size, &err);
+ if (rc != DW_DLV_OK) {
+ fprintf(stderr, "could not get size for struct %s: %s\n",
+ struct_name, dwarf_errmsg(err));
+ exit(1);
+ }
+ printf("\t\tchar whole_struct[%d];\n", size);
+
+ do {
+ char *name;
+ const char *tag_name;
+ Dwarf_Half tag;
+
+ rc = dwarf_diename(die, &name, &err);
+ if (rc == DW_DLV_NO_ENTRY) {
+ name = NULL;
+ } else if (rc != DW_DLV_OK) {
+ 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) {
+ 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) {
+ 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>");
+ }
+
+ 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)
+ dwarf_dealloc(dbg, name, DW_DLA_STRING);
+
+ if (rc != DW_DLV_OK)
+ break;
+
+ die = next;
+ } while (die);
+}
+
static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name,
int padnum) {
Dwarf_Attribute attr;