Browse Source

Prepare for better DIE parsing (broken)

master
A.Olokhtonov 3 years ago
parent
commit
8d962976cf
  1. 2
      build.sh
  2. 2
      src/command.c
  3. 19
      src/common.h
  4. 47
      src/dwarf.c
  5. 19
      src/util.c
  6. 2
      test/test_main.c

2
build.sh

@ -39,7 +39,7 @@ elif [[ $1 = "tests" ]]; then
elif [[ $1 = "clean" ]]; then elif [[ $1 = "clean" ]]; then
rm build/* rm build/*
else else
echo "No such target '$1'" echo "No such target '$1'. Try one of: [empty], examples, tests, clean"
fi fi
echo "Leaving project directory" echo "Leaving project directory"

2
src/command.c

@ -155,8 +155,6 @@ command_print(struct mi_process proc, char *name, int name_length)
u64 address = cfa + variable->location; u64 address = cfa + variable->location;
u64 raw_value = ptrace(PTRACE_PEEKDATA, proc.pid, address, NULL); u64 raw_value = ptrace(PTRACE_PEEKDATA, proc.pid, address, NULL);
printf("\"%s\", %ld\n", type.name, variable->location);
u8 raw_value1; u8 raw_value1;
u16 raw_value2; u16 raw_value2;
u32 raw_value4; u32 raw_value4;

19
src/common.h

@ -1,3 +1,5 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -10,14 +12,14 @@
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/uio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/user.h> #include <sys/user.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h> // mmap, munmap
#include <sys/personality.h> #include <sys/personality.h> // syscall(SYS_personality, ADDR_NO_RANDOMIZE)
#include <sys/uio.h> // process_vm_readv
typedef uint8_t u8; typedef uint8_t u8;
typedef uint16_t u16; typedef uint16_t u16;
@ -42,6 +44,12 @@ enum mi_type_encoding {
MI_UNSIGNED MI_UNSIGNED
}; };
enum mi_type_decorator {
MI_POINTER = 0x01,
MI_CONST = 0x02,
MI_RESTRICT = 0x04,
};
struct mi_buffer { struct mi_buffer {
u8 *data; u8 *data;
u64 size; u64 size;
@ -64,6 +72,11 @@ struct mi_type {
char *name; char *name;
int size; int size;
enum mi_type_encoding encoding; 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 // used during parsing so that variables (which only have offsets) could find their
// corresponding parsed type record // corresponding parsed type record

47
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_variable *variable = dest->variables + dest->var_count;
struct mi_type *type = dest->types + dest->type_count; struct mi_type *type = dest->types + dest->type_count;
struct mi_type *parent_type = 0;
comp_unit->functions_from = dest->func_count; comp_unit->functions_from = dest->func_count;
for (;;) { for (;;) {
@ -804,6 +806,32 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest,
++depth; ++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; u32 attribute, form;
do { do {
@ -838,6 +866,15 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest,
} else if (attribute == DW_AT_type) { } else if (attribute == DW_AT_type) {
variable->type = value; 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) { } else if (tag == DW_TAG_base_type) {
type->_offset = record_offset; type->_offset = record_offset;
if (attribute == DW_AT_name) { 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); } 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) { if (tag == DW_TAG_subprogram) {
func->high_pc = func->low_pc + func->high_pc; func->high_pc = func->low_pc + func->high_pc;
func->variables_from = dest->var_count; 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; ++dest->var_count;
++variable; ++variable;
} else if (tag == DW_TAG_base_type) { } else if (tag == DW_TAG_base_type) {
++parent_type->children_count;
++dest->type_count; ++dest->type_count;
++type; ++type;
} else if (tag == DW_TAG_structure_type) {
parent_type = type;
parent_type->children_from = dest->type_count;
++type;
} }
#endif
} }
// Resolve types // Resolve types

19
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); regset = eh_frame_find_pc(fde, regset, pc);
return(regset.cfa); 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);
} }

2
test/test_main.c

@ -161,6 +161,8 @@ test_print(char *path, int steps, char *name, char *type, int location)
int int
main(void) main(void)
{ {
freopen("/dev/null", "wb", stdout);
DO_TEST("start 001-simple", test_start("res/001-simple")); 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 002-compilation-units", test_start("res/002-compilation-units"));
DO_TEST("start 003-recursion", test_start("res/003-recursion")); DO_TEST("start 003-recursion", test_start("res/003-recursion"));

Loading…
Cancel
Save