From 8d962976cf90f5fb8a8634b2441144c86ce2f312 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Fri, 30 Jul 2021 17:44:09 +0300 Subject: [PATCH] Prepare for better DIE parsing (broken) --- build.sh | 2 +- src/command.c | 2 -- src/common.h | 19 ++++++++++++++++--- src/dwarf.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- src/util.c | 19 +++++++++++++++++++ test/test_main.c | 2 ++ 6 files changed, 84 insertions(+), 7 deletions(-) diff --git a/build.sh b/build.sh index 8b411e8..9ab8fac 100755 --- a/build.sh +++ b/build.sh @@ -39,7 +39,7 @@ elif [[ $1 = "tests" ]]; then elif [[ $1 = "clean" ]]; then rm build/* else - echo "No such target '$1'" + echo "No such target '$1'. Try one of: [empty], examples, tests, clean" fi echo "Leaving project directory" diff --git a/src/command.c b/src/command.c index 17ffd68..a1841fd 100644 --- a/src/command.c +++ b/src/command.c @@ -155,8 +155,6 @@ command_print(struct mi_process proc, char *name, int name_length) u64 address = cfa + variable->location; u64 raw_value = ptrace(PTRACE_PEEKDATA, proc.pid, address, NULL); - printf("\"%s\", %ld\n", type.name, variable->location); - u8 raw_value1; u16 raw_value2; u32 raw_value4; diff --git a/src/common.h b/src/common.h index 667d21c..8999e63 100644 --- a/src/common.h +++ b/src/common.h @@ -1,3 +1,5 @@ +#define _GNU_SOURCE + #include #include #include @@ -10,14 +12,14 @@ #include #include -#include #include #include #include #include #include -#include -#include +#include // mmap, munmap +#include // syscall(SYS_personality, ADDR_NO_RANDOMIZE) +#include // process_vm_readv typedef uint8_t u8; typedef uint16_t u16; @@ -42,6 +44,12 @@ enum mi_type_encoding { MI_UNSIGNED }; +enum mi_type_decorator { + MI_POINTER = 0x01, + MI_CONST = 0x02, + MI_RESTRICT = 0x04, +}; + struct mi_buffer { u8 *data; u64 size; @@ -64,6 +72,11 @@ struct mi_type { char *name; int size; enum mi_type_encoding encoding; + u32 flags; + + // For structures + u32 children_from; + u32 children_count; // used during parsing so that variables (which only have offsets) could find their // corresponding parsed type record diff --git a/src/dwarf.c b/src/dwarf.c index d549740..90aae52 100644 --- a/src/dwarf.c +++ b/src/dwarf.c @@ -777,6 +777,8 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, struct mi_variable *variable = dest->variables + dest->var_count; struct mi_type *type = dest->types + dest->type_count; + struct mi_type *parent_type = 0; + comp_unit->functions_from = dest->func_count; for (;;) { @@ -804,6 +806,32 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, ++depth; } + switch (tag) { + case DW_TAG_compile_unit: { + break; + } + + case DW_TAG_subprogram: { + break; + } + + case DW_TAG_variable: { + break; + } + + case DW_TAG_structure_type: { + break; + } + + case DW_TAG_member: { + break; + } + + case DW_TAG_base_type: { + break; + } + } +#if 0 u32 attribute, form; do { @@ -838,6 +866,15 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, } else if (attribute == DW_AT_type) { variable->type = value; } + } else if (tag == DW_TAG_structure_type) { + type->_offset = record_offset; + if (attribute == DW_AT_name) { + type->name = (char *) value; + } else if (attribute == DW_AT_byte_size) { + type->size = value; + } + } else if (tag == DW_TAG_member) { + } else if (tag == DW_TAG_base_type) { type->_offset = record_offset; if (attribute == DW_AT_name) { @@ -882,7 +919,7 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, } } while (attribute != 0 || form != 0); - // NOTE(aolo2): DIE completely processed, finish it up + // NOTE(aolo2): DIE completely processed, finish it ??uploads?? if (tag == DW_TAG_subprogram) { func->high_pc = func->low_pc + func->high_pc; func->variables_from = dest->var_count; @@ -895,9 +932,17 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, ++dest->var_count; ++variable; } else if (tag == DW_TAG_base_type) { + ++parent_type->children_count; ++dest->type_count; ++type; + } else if (tag == DW_TAG_structure_type) { + parent_type = type; + parent_type->children_from = dest->type_count; + ++type; } +#endif + + } // Resolve types diff --git a/src/util.c b/src/util.c index 22a987b..dd1c585 100644 --- a/src/util.c +++ b/src/util.c @@ -326,4 +326,23 @@ get_cfa_at_pc(struct mi_process proc, u64 pc) regset = eh_frame_find_pc(fde, regset, pc); return(regset.cfa); +} + +static void +read_process_memory(struct mi_process proc, u64 at, u64 size) +{ + struct iovec local = { 0 }; + struct iovec remote = { 0 }; + + u8 *data = malloc(size); + + local.iov_base = data; + local.iov_len = size; + + remote.iov_base = (void *) at; + remote.iov_len = size; + + u64 read = process_vm_readv(proc.pid, &local, 1, &remote, 1, 0); + + assert(read == size); } \ No newline at end of file diff --git a/test/test_main.c b/test/test_main.c index 20743fe..aa8e681 100644 --- a/test/test_main.c +++ b/test/test_main.c @@ -161,6 +161,8 @@ test_print(char *path, int steps, char *name, char *type, int location) int main(void) { + freopen("/dev/null", "wb", stdout); + DO_TEST("start 001-simple", test_start("res/001-simple")); DO_TEST("start 002-compilation-units", test_start("res/002-compilation-units")); DO_TEST("start 003-recursion", test_start("res/003-recursion"));