summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwarf.c124
1 files changed, 117 insertions, 7 deletions
diff --git a/dwarf.c b/dwarf.c
index cf6506f..4e7539f 100644
--- a/dwarf.c
+++ b/dwarf.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
+#include <strings.h>
#include <errno.h>
#include "dwarf.h"
#include "libdwarf.h"
@@ -76,7 +77,7 @@ static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name,
while (1) {
- Dwarf_Die die, next;
+ Dwarf_Die die;
rc = dwarf_next_cu_header_c(dbg, is_info, &cu_length,
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
@@ -100,7 +101,7 @@ static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name,
find_struct(dbg, die, struct_name, field_name, 0);
}
- printf("struct %s not found\n", struct_name, field_name);
+ printf("struct %s not found\n", struct_name);
exit(2);
}
@@ -241,15 +242,15 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name)
Dwarf_Attribute attr;
Dwarf_Error err;
Dwarf_Unsigned offset = 0;
- int rc, i;
+ int rc;
printf("Found %s\n", field_name);
rc = dwarf_attr(die, DW_AT_data_member_location, &attr, &err);
if (rc == DW_DLV_NO_ENTRY) {
- printf("Found %s but no offest, assuming 0\n", field_name);
+ printf("Found %s but no offset, assuming 0\n", field_name);
} else if (rc != DW_DLV_OK) {
- printf("Error getting dwarf attrlist: %s\n", dwarf_errmsg(err));
+ printf("Error getting dwarf attr offset: %s\n", dwarf_errmsg(err));
exit(4);
} else {
Dwarf_Half form;
@@ -271,7 +272,7 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name)
}
offset = (Dwarf_Unsigned) soffset;
} else {
- Dwarf_Locdesc **locdescs;
+ Dwarf_Locdesc **locdescs;
Dwarf_Signed len;
if (dwarf_loclist_n(attr, &locdescs, &len, &err) == DW_DLV_ERROR) {
printf("unsupported member offset\n");
@@ -285,6 +286,115 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name)
}
offset = (locdescs[0]->ld_s[0]).lr_number;
}
+ dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+ }
+ printf("offset %u\n", (unsigned int)offset);
+
+ 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);
+ exit(6);
+ } else if (rc != DW_DLV_OK) {
+ printf("Error getting dwarf attrlist: %s\n", dwarf_errmsg(err));
+ exit(6);
+ } else {
+ Dwarf_Die type_die;
+ Dwarf_Off type_off;
+ Dwarf_Half type_tag;
+ char *type_name;
+ char type_buf[1024];
+ int pointer = 0;
+
+ 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));
+ 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));
+ 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));
+ exit(7);
+ }
+
+ if (type_tag == DW_TAG_pointer_type) {
+ Dwarf_Attribute pointer_attr;
+ Dwarf_Off pointer_off;
+ Dwarf_Die pointer_die;
+
+ 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));
+ exit(7);
+ }
+
+ 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));
+ exit(7);
+ }
+
+ 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));
+ exit(7);
+ }
+
+ dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+ dwarf_dealloc(dbg, type_die, DW_DLA_DIE);
+ attr = pointer_attr;
+ type_die = pointer_die;
+ pointer++;
+
+ rc = dwarf_tag(type_die, &type_tag, &err);
+ if (rc != DW_DLV_OK) {
+ printf("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));
+ 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);
+ }
+
+ printf("Bad tag %s (%d)?\n", tag_name, type_tag);
+ exit(7);
+ }
+
+ if (type_tag == DW_TAG_structure_type) {
+ sprintf(type_buf, "struct %s%s", pointer ? "*" : "",
+ type_name);
+ } else if (type_tag == DW_TAG_base_type || type_tag == DW_TAG_typedef) {
+ sprintf(type_buf, "%s%s", pointer ? "*" : "",
+ type_name);
+ } else {
+ 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);
+ }
+
+ printf("Type tag %s (%d) is not implemented, please add it\n",
+ tag_name, type_tag);
+ exit(7);
+ }
+ printf("type name %s\n", type_buf);
+
+ dwarf_dealloc(dbg, type_name, DW_DLA_STRING);
+ dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+ dwarf_dealloc(dbg, type_die, DW_DLA_DIE);
}
- printf("offset %u\n", offset);
}