diff options
Diffstat (limited to 'dwarf.c')
-rw-r--r-- | dwarf.c | 124 |
1 files changed, 117 insertions, 7 deletions
@@ -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); } |