From a506edf4f27f422452213f730211dd6d74409e17 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sat, 17 Jul 2021 14:15:29 +0300 Subject: [PATCH] Parse and use the directory table from .debug_line --- common.h | 11 +++++++++-- dwarf.c | 26 +++++++++++++++++++++----- main.c | 10 ++++++---- util.c | 13 +++++++------ 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/common.h b/common.h index 1ebf049..7f78f4a 100644 --- a/common.h +++ b/common.h @@ -58,6 +58,12 @@ struct mi_debuginfo { char *comp_dir; }; +struct mi_sourcefile { + char *filename; + char *dir; + struct mi_buffer file; +}; + struct mi_process { pid_t pid; @@ -69,9 +75,10 @@ struct mi_process { struct mi_debuginfo debug; - char **source_file_names; - struct mi_buffer *source_files; int source_file_count; + int source_dirs_count; + struct mi_sourcefile *source_files; + char **source_directories; }; struct mi_registers { diff --git a/dwarf.c b/dwarf.c index c3d5a91..c47b9a6 100644 --- a/dwarf.c +++ b/dwarf.c @@ -314,7 +314,9 @@ parse_debug_info(u8 *file, struct mi_debuginfo *dest) } static void -parse_debug_line(u8 *file, struct mi_sourcepoint *dest, char **dest_files, int *dest_size, int *dest_files_size) +parse_debug_line(u8 *file, + struct mi_sourcepoint *dest, struct mi_sourcefile *dest_files, char **dest_directories, + int *dest_size, int *dest_files_size, int *dest_directories_size) { u64 dl_offset = get_section_offset(file, ".debug_line"); @@ -336,7 +338,12 @@ is followed by a single null byte." */ u8 *p = file + dl_offset; while (*p != 0) { + if (dest_directories) { + dest_directories[ndirs] = (char *) p; + } + ++ndirs; + while (*p != 0) { ++p; } @@ -352,11 +359,9 @@ is followed by a single null byte." */ while (*p != 0) { /* null-terminated string */ if (dest_files) { - dest_files[nfiles] = (char *) p; + dest_files[nfiles].filename = (char *) p; } - ++nfiles; - while (*p != 0) { ++p; } @@ -364,12 +369,19 @@ is followed by a single null byte." */ ++p; u64 offset = 0; + u32 dir_index = 0; u32 dummy = 0; - offset += decode_leb128(p, &dummy); + offset += decode_leb128(p, &dir_index); offset += decode_leb128(p, &dummy); offset += decode_leb128(p, &dummy); + if (dest_files) { + dest_files[nfiles].dir = dest_directories[dir_index - 1]; + } + + ++nfiles; + p += offset; } @@ -619,6 +631,10 @@ is followed by a single null byte." */ if (dest_size) { *dest_size = pc_count; } + + if (dest_directories_size) { + *dest_directories_size = ndirs; + } } static u64 diff --git a/main.c b/main.c index 6d1985b..1e1c849 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,8 @@ #include "util.c" #include "command.c" +// TODO: read the directory table, get full path as comp_dir + directory_table (can be ".." or w/e) + filename + int main(int argc, char *argv[]) { @@ -31,11 +33,11 @@ main(int argc, char *argv[]) printf("> "); fflush(stdout); - parse_debug_line(process.elf, 0, 0, &process.debug.sp_count, &process.source_file_count); + parse_debug_line(process.elf, 0, 0, 0, &process.debug.sp_count, &process.source_file_count, &process.source_dirs_count); process.debug.sp_table = malloc(process.debug.sp_count * sizeof(struct mi_sourcepoint)); - process.source_file_names = malloc(process.source_file_count * sizeof(char *)); - process.source_files = malloc(process.source_file_count * sizeof(char *)); - parse_debug_line(process.elf, process.debug.sp_table, process.source_file_names, 0, 0); + process.source_directories = malloc(process.source_dirs_count * sizeof(char *)); + process.source_files = malloc(process.source_file_count * sizeof(struct mi_sourcefile)); + parse_debug_line(process.elf, process.debug.sp_table, process.source_files, process.source_directories, 0, 0, 0); while ((command_length = getline(&command, &max_command_length, stdin))) { if (command_length == 1) { diff --git a/util.c b/util.c index a2e25bd..690c675 100644 --- a/util.c +++ b/util.c @@ -59,18 +59,19 @@ static void print_sourcepoint(struct mi_process proc, struct mi_sourcepoint *sp) { // NOTE: sourcepoint file indices are 1-based - if (proc.source_files[sp->file - 1].data == 0) { - char *filename = proc.source_file_names[sp->file - 1]; - char *dir = proc.debug.comp_dir; + if (proc.source_files[sp->file - 1].file.data == 0) { + char *file_filename = proc.source_files[sp->file - 1].filename; + char *file_dirname = proc.source_files[sp->file - 1].dir; + char *comp_dir = proc.debug.comp_dir; char full_path[512] = { 0 }; - snprintf(full_path, 511, "%s/%s", dir, filename); + snprintf(full_path, 511, "%s/%s/%s", comp_dir, file_dirname, file_filename); struct mi_buffer file = read_file_mmap(full_path); - proc.source_files[sp->file - 1] = file; + proc.source_files[sp->file - 1].file = file; } - struct mi_buffer file = proc.source_files[sp->file - 1]; + struct mi_buffer file = proc.source_files[sp->file - 1].file; char *source = (char *) file.data; u64 size = file.size;