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 @@ -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"

2
src/command.c

@ -155,8 +155,6 @@ command_print(struct mi_process proc, char *name, int name_length) @@ -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;

19
src/common.h

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -10,14 +12,14 @@ @@ -10,14 +12,14 @@
#include <assert.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/personality.h>
#include <sys/mman.h> // mmap, munmap
#include <sys/personality.h> // syscall(SYS_personality, ADDR_NO_RANDOMIZE)
#include <sys/uio.h> // process_vm_readv
typedef uint8_t u8;
typedef uint16_t u16;
@ -42,6 +44,12 @@ enum mi_type_encoding { @@ -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 { @@ -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

47
src/dwarf.c

@ -777,6 +777,8 @@ read_debug_info_for_compilation_unit(u8 *file, struct mi_debuginfo *dest, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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

19
src/util.c

@ -326,4 +326,23 @@ get_cfa_at_pc(struct mi_process proc, u64 pc) @@ -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);
}

2
test/test_main.c

@ -161,6 +161,8 @@ test_print(char *path, int steps, char *name, char *type, int location) @@ -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"));

Loading…
Cancel
Save