summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwarf.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/dwarf.c b/dwarf.c
index d18c74b..51dbe6c 100644
--- a/dwarf.c
+++ b/dwarf.c
@@ -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);
}