|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <syscall.h>
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#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>
|
|
|
|
|
|
|
|
typedef uint8_t u8;
|
|
|
|
typedef uint16_t u16;
|
|
|
|
typedef uint32_t u32;
|
|
|
|
typedef uint64_t u64;
|
|
|
|
|
|
|
|
typedef int8_t s8;
|
|
|
|
typedef int16_t s16;
|
|
|
|
typedef int32_t s32;
|
|
|
|
typedef int64_t s64;
|
|
|
|
|
|
|
|
typedef float f32;
|
|
|
|
typedef double f64;
|
|
|
|
|
|
|
|
#include "elf_dwarf.h"
|
|
|
|
|
|
|
|
enum mi_type_encoding {
|
|
|
|
MI_ADDRESS,
|
|
|
|
MI_BOOLEAN,
|
|
|
|
MI_FLOAT,
|
|
|
|
MI_SIGNED,
|
|
|
|
MI_UNSIGNED
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_buffer {
|
|
|
|
u8 *data;
|
|
|
|
u64 size;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_sourcepoint {
|
|
|
|
u64 pc;
|
|
|
|
int line;
|
|
|
|
int column;
|
|
|
|
int file;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_sourcefile {
|
|
|
|
char *filename;
|
|
|
|
char *dir;
|
|
|
|
struct mi_buffer file;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_type {
|
|
|
|
char *name;
|
|
|
|
int size;
|
|
|
|
enum mi_type_encoding encoding;
|
|
|
|
|
|
|
|
// used during parsing so that variables (which only have offsets) could find their
|
|
|
|
// corresponding parsed type record
|
|
|
|
s64 _offset;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_variable {
|
|
|
|
char *name;
|
|
|
|
s64 location;
|
|
|
|
int type;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_function {
|
|
|
|
u64 low_pc;
|
|
|
|
u64 high_pc;
|
|
|
|
char *name;
|
|
|
|
int variables_from;
|
|
|
|
int variables_count;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_sourceinfo {
|
|
|
|
struct mi_sourcepoint *sp_table;
|
|
|
|
int sp_count;
|
|
|
|
|
|
|
|
int source_file_count;
|
|
|
|
struct mi_sourcefile *source_files;
|
|
|
|
|
|
|
|
char **source_directories;
|
|
|
|
int source_dirs_count;
|
|
|
|
|
|
|
|
char *comp_dir;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_compunit {
|
|
|
|
u64 low_pc;
|
|
|
|
u64 high_pc;
|
|
|
|
|
|
|
|
struct mi_sourceinfo source;
|
|
|
|
|
|
|
|
int functions_from;
|
|
|
|
int functions_count;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_debuginfo {
|
|
|
|
struct mi_compunit compilation_units[16];
|
|
|
|
struct mi_function functions[64];
|
|
|
|
struct mi_variable variables[64];
|
|
|
|
struct mi_type types[64];
|
|
|
|
|
|
|
|
int cu_count;
|
|
|
|
int func_count;
|
|
|
|
int var_count;
|
|
|
|
int type_count;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_process {
|
|
|
|
pid_t pid;
|
|
|
|
|
|
|
|
u8 *elf;
|
|
|
|
u64 elf_size;
|
|
|
|
|
|
|
|
u64 base_address;
|
|
|
|
u64 main_address;
|
|
|
|
|
|
|
|
struct mi_debuginfo debug;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct mi_registers {
|
|
|
|
u64 rbp;
|
|
|
|
u64 rbx;
|
|
|
|
u64 rax;
|
|
|
|
u64 rcx;
|
|
|
|
u64 rdx;
|
|
|
|
u64 rsi;
|
|
|
|
u64 rdi;
|
|
|
|
u64 rip;
|
|
|
|
u64 rsp;
|
|
|
|
|
|
|
|
struct user_regs_struct _sys;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define NT_PRSTATUS 1
|
|
|
|
#define DIE(string) do { fprintf(stderr, string); exit(1); } while (0)
|
|
|
|
#define ABS(v) ((v) < 0 ? -(v) : (v))
|