Browse Source

Load files on demand, support multiple source files

master
A.Olokhtonov 3 years ago
parent
commit
be498d6d52
  1. 6
      command.c
  2. 12
      common.h
  3. 39
      dwarf.c
  4. 6
      main.c
  5. 70
      util.c

6
command.c

@ -22,7 +22,7 @@ command_step(struct mi_process proc)
print_current_instruction(proc); print_current_instruction(proc);
struct mi_registers regs = get_process_registers(proc); struct mi_registers regs = get_process_registers(proc);
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address); struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address);
print_current_line(proc, sp->line); print_sourcepoint(proc, sp);
#endif #endif
} }
@ -68,7 +68,7 @@ command_next(struct mi_process proc)
// TODO: skip call, repXXX, etc // TODO: skip call, repXXX, etc
} while (next_sp->line == sp->line); } while (next_sp->line == sp->line);
print_current_line(proc, next_sp->line); print_sourcepoint(proc, next_sp);
} }
static void static void
@ -76,7 +76,7 @@ command_list(struct mi_process proc)
{ {
struct mi_registers regs = get_process_registers(proc); struct mi_registers regs = get_process_registers(proc);
struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address); struct mi_sourcepoint *sp = pc_to_sourcepoint(proc, regs.rip - proc.base_address);
print_current_line(proc, sp->line); print_sourcepoint(proc, sp);
} }
static void static void

12
common.h

@ -31,6 +31,11 @@ typedef int64_t s64;
#include "elf_dwarf.h" #include "elf_dwarf.h"
struct mi_buffer {
u8 *data;
u64 size;
};
struct mi_sourcepoint { struct mi_sourcepoint {
u64 pc; u64 pc;
int line; int line;
@ -41,9 +46,6 @@ struct mi_sourcepoint {
struct mi_process { struct mi_process {
pid_t pid; pid_t pid;
char *source;
u64 source_size;
u8 *elf; u8 *elf;
u64 elf_size; u64 elf_size;
@ -52,6 +54,10 @@ struct mi_process {
struct mi_sourcepoint *sp_table; struct mi_sourcepoint *sp_table;
int sp_count; int sp_count;
char **source_file_names;
struct mi_buffer *source_files;
int source_file_count;
}; };
struct mi_registers { struct mi_registers {

39
dwarf.c

@ -295,7 +295,7 @@ find_subroutine_offset(u8 *file, u64 header_size, u8 address_size,
} }
static void static void
construct_line_number_table(u8 *file, struct mi_sourcepoint *dest, int *dest_size) construct_line_number_table(u8 *file, struct mi_sourcepoint *dest, char **dest_files, int *dest_size, int *dest_files_size)
{ {
u64 dl_offset = get_section_offset(file, ".debug_line"); u64 dl_offset = get_section_offset(file, ".debug_line");
@ -331,9 +331,13 @@ is followed by a single null byte." */
p = file + dl_offset; p = file + dl_offset;
while (*p != 0) { while (*p != 0) {
/* null-terminated string */
if (dest_files) {
dest_files[nfiles] = (char *) p;
}
++nfiles; ++nfiles;
/* null-terminated string */
while (*p != 0) { while (*p != 0) {
++p; ++p;
} }
@ -350,33 +354,8 @@ is followed by a single null byte." */
p += offset; p += offset;
} }
header.files = malloc(nfiles * sizeof(struct dwarf_debug_line_file_info)); if (dest_files_size) {
header.nfiles = nfiles; *dest_files_size = nfiles;
struct dwarf_debug_line_file_info *f = header.files;
p = file + dl_offset;
while (*p != 0) {
/* null-terminated string */
f->name = (char *) p;
while (*p != 0) {
++p;
}
++p;
u64 offset = 0;
u32 dummy = 0;
offset += decode_leb128(p, &f->directory_index);
offset += decode_leb128(p, &f->time_modified);
offset += decode_leb128(p, &f->file_size);
p += offset;
++f;
} }
dl_offset = p - file + 1; dl_offset = p - file + 1;
@ -618,7 +597,7 @@ is followed by a single null byte." */
} while (opcode_extended != DW_LNE_end_sequence); } while (opcode_extended != DW_LNE_end_sequence);
if (!dest) { if (dest_size) {
*dest_size = pc_count; *dest_size = pc_count;
} }
} }

6
main.c

@ -28,9 +28,11 @@ main(int argc, char *argv[])
printf("> "); printf("> ");
fflush(stdout); fflush(stdout);
construct_line_number_table(process.elf, 0, &process.sp_count); construct_line_number_table(process.elf, 0, 0, &process.sp_count, &process.source_file_count);
process.sp_table = malloc(process.sp_count * sizeof(struct mi_sourcepoint)); process.sp_table = malloc(process.sp_count * sizeof(struct mi_sourcepoint));
construct_line_number_table(process.elf, process.sp_table, 0); process.source_file_names = malloc(process.source_file_count * sizeof(char *));
process.source_files = malloc(process.source_file_count * sizeof(char *));
construct_line_number_table(process.elf, process.sp_table, process.source_file_names, 0, 0);
while ((command_length = getline(&command, &max_command_length, stdin))) { while ((command_length = getline(&command, &max_command_length, stdin))) {
if (0 == strncmp(command, "exit\n", command_length) || 0 == strncmp(command, "q\n", command_length)) { if (0 == strncmp(command, "exit\n", command_length) || 0 == strncmp(command, "q\n", command_length)) {

70
util.c

@ -22,15 +22,44 @@ print_word_at_address(int child, u64 address)
printf("word at %#018lx: {%x %x %x %x}\n", address, nb[0], nb[1], nb[2], nb[3]); printf("word at %#018lx: {%x %x %x %x}\n", address, nb[0], nb[1], nb[2], nb[3]);
} }
static struct mi_buffer
read_file_mmap(char *path)
{
struct mi_buffer result = { 0 };
struct stat s;
int fd = open(path, O_RDONLY);
assert(fd != -1);
fstat(fd, &s);
result.data = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
result.size = s.st_size;
printf("mmap()-ed %ld bytes (%s)\n", result.size, path);
close(fd);
return(result);
}
static void static void
print_current_line(struct mi_process proc, u64 line) print_sourcepoint(struct mi_process proc, struct mi_sourcepoint *sp)
{ {
char *source = proc.source; // NOTE: sourcepoint file indices are 1-based
u64 size = proc.source_size; if (proc.source_files[sp->file - 1].data == 0) {
u64 current_line = 1; char *path = proc.source_file_names[sp->file - 1];
struct mi_buffer file = read_file_mmap(path);
proc.source_files[sp->file - 1] = file;
}
struct mi_buffer file = proc.source_files[sp->file - 1];
char *source = (char *) file.data;
u64 size = file.size;
int current_line = 1;
for (u32 i = 0; i < size; ++i) { for (u32 i = 0; i < size; ++i) {
if (current_line == line) { if (current_line == sp->line) {
int len = 0; int len = 0;
int start = 0; int start = 0;
int leading = 1; int leading = 1;
@ -84,35 +113,10 @@ process_create(char *path)
} }
} }
u64 source_size; struct mi_buffer file = read_file_mmap(path);
u64 elf_size;
u8 *elf;
char *source;
struct stat s;
int fd;
{
fd = open(path, O_RDONLY);
assert(fd != -1);
fstat(fd, &s);
elf_size = s.st_size;
elf = mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
}
{
fd = open("/code/trace-test/traceme.c", O_RDONLY); // TODO
assert(fd != -1);
fstat(fd, &s);
source_size = s.st_size;
source = mmap(0, source_size, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
}
result.elf = elf; result.elf = file.data;
result.elf_size = elf_size; result.elf_size = file.size;
result.source = source;
result.source_size = source_size;
result.pid = pid; result.pid = pid;
return(result); return(result);

Loading…
Cancel
Save