DWARF stuff...
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

191 lines
4.8 KiB

static u64
get_address_of_subroutine(struct mi_process proc, char *sr)
{
for (int i = 0; i < proc.debug.func_count; ++i) {
struct mi_function *func = proc.debug.functions + i;
if (0 == strcmp(func->name, sr)) {
return(func->offset);
}
}
return(0);
}
static struct mi_sourcepoint *
pc_to_sourcepoint(struct mi_process proc, u64 pc)
{
// NOTE: find first point BIGGER that pc, return the sourcepoint just before that
// TODO: binary search
for (int i = 0; i < proc.debug.sp_count; ++i) {
struct mi_sourcepoint *point = proc.debug.sp_table + i;
if (point->pc > pc) {
return(proc.debug.sp_table + i - 1);
}
}
return(0);
}
static void
print_word_at_address(int child, u64 address)
{
long word = ptrace(PTRACE_PEEKDATA, child, address, NULL);
u8 nb[4];
memcpy(nb, &word, 4);
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
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;
char full_path[512] = { 0 };
snprintf(full_path, 511, "%s/%s", dir, filename);
struct mi_buffer file = read_file_mmap(full_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) {
if (current_line == sp->line) {
int len = 0;
int start = 0;
int leading = 1;
for (u32 j = i; j < size; ++j) {
if (leading && (source[j] == '\t' || source[j] == ' ')) {
++start;
} else {
leading = 0;
}
if (source[j] == '\n') {
break;
}
++len;
}
printf("%.*s\n", len - start, source + i + start);
return;
}
if (source[i] == '\n') {
current_line++;
}
}
}
static struct mi_process
process_create(char *path)
{
struct mi_process result = { 0 };
/* disable ASLR */
syscall(SYS_personality, ADDR_NO_RANDOMIZE);
pid_t pid = fork();
if (pid == -1) {
DIE("fork error\n");
}
if (pid == 0) {
int rt = ptrace(PTRACE_TRACEME, 0, 0, 0);
assert(rt == 0);
char *args[] = { path, NULL };
rt = execvp(path, args);
if (rt == -1) {
DIE("exevp error\n");
}
}
struct mi_buffer file = read_file_mmap(path);
result.elf = file.data;
result.elf_size = file.size;
result.pid = pid;
return(result);
}
static struct mi_registers
get_process_registers(struct mi_process proc)
{
struct user_regs_struct regs = { 0 };
struct iovec iov = { &regs, sizeof(regs) };
struct mi_registers result = { 0 };
ptrace(PTRACE_GETREGSET, proc.pid, NT_PRSTATUS, &iov);
result.rax = regs.rax;
result.rip = regs.rip;
result.rbp = regs.rbp;
result.rbx = regs.rbx;
result.rcx = regs.rcx;
result.rdx = regs.rdx;
result.rsi = regs.rsi;
result.rdi = regs.rdi;
result.rsp = regs.rsp;
result._sys = regs;
return(result);
}
static void
set_process_registers(struct mi_process proc, struct mi_registers regs)
{
struct iovec iov = { &regs._sys, sizeof(regs._sys) };
ptrace(PTRACE_GETREGSET, proc.pid, NT_PRSTATUS, &iov);
}
static void
print_current_instruction(struct mi_process proc)
{
struct mi_registers regs = get_process_registers(proc);
long wordb = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip - 4, NULL);
long word = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip, NULL);
long worda = ptrace(PTRACE_PEEKDATA, proc.pid, regs.rip + 4, NULL);
u8 nb[12];
memcpy(nb, &wordb, 4);
memcpy(nb + 4, &word, 4);
memcpy(nb + 8, &worda, 4);
printf("PC = %#018lx: %x %x %x %x [%x] %x %x %x %x %x %x %x\n", regs.rip,
nb[0], nb[1], nb[2], nb[3], nb[4], nb[5], nb[6], nb[7],
nb[8], nb[9], nb[10], nb[11]);
}