diff --git a/Makefile b/Makefile index 4b004a8..a352be0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc CFLAGS=-MD -MP -ggdb -I./mujs -LDFLAGS=-lm +LDFLAGS=-lm -lelf SRCS=debugus.c linenoise.c hash.c pmparser.c OBJS=$(patsubst %.c,%.o,$(SRCS)) DEPS=$(patsubst %.c,%.d,$(SRCS)) diff --git a/da.h b/da.h new file mode 100644 index 0000000..f666a47 --- /dev/null +++ b/da.h @@ -0,0 +1,27 @@ +#ifndef DA_H_ +#define DA_H_ + +#include + +#define da_append(da, item) \ + do { \ + if ((da)->count == 0) { \ + (da)->capacity = 1; \ + (da)->items = malloc(sizeof(item)*sizeof((da)->capacity)); \ + } else { \ + if ((da)->count == (da)->capacity) { \ + (da)->capacity *= 2; \ + (da)->items = realloc((da)->items, (da)->capacity * sizeof((item))); \ + } \ + } \ + (da)->items[(da)->count++] = (item); \ + } while(0) + +#define da_deinit(da) \ + do { \ + if ((da)->count > 0) { \ + free((da)->items); \ + } \ + } while(0) + +#endif // DA_H_ diff --git a/debugus.c b/debugus.c index 82d873d..52dd2bc 100644 --- a/debugus.c +++ b/debugus.c @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -16,6 +19,7 @@ #include "mujs.h" #include "hash.h" #include "pmparser.h" +#include "da.h" #define LOG_ERR(fmt, ...) fprintf(stderr, "Error: " fmt, ##__VA_ARGS__) #define LOG_INF(fmt, ...) fprintf(stdout, "Info: " fmt, ##__VA_ARGS__) @@ -139,12 +143,23 @@ void brk_disable(Brk *brk) brk->enabled = false; } +typedef struct { + const char *name; + uintptr_t addr; +} Symbol; + +typedef struct { + Symbol *items; + size_t count, capacity; +} Symbols; + typedef struct { const char *file; pid_t pid; js_State *js; HashTable brks; uintptr_t program_load_offset; + Symbols symbols; } Dbg; void dbg_wait(Dbg *dbg) @@ -395,6 +410,16 @@ void dbg_js_mem_write(js_State *js) js_pushundefined(js); } +void dbg_js_list_syms(js_State *js) +{ + Dbg *dbg = getdbg(); + for (int i = 0; i < dbg->symbols.count; i++) { + Symbol *sym = &dbg->symbols.items[i]; + LOG_INF("Symbol %s at %"PRIxPTR"\n", sym->name, sym->addr); + } + js_pushundefined(js); +} + void dbg_init_js(Dbg *dbg) { dbg->js = js_newstate(NULL, NULL, JS_STRICT); @@ -420,6 +445,7 @@ void dbg_init_js(Dbg *dbg) make_js_func(set_reg, 2 /* reg name, value*/); make_js_func(mem_read, 1 /*addr*/); make_js_func(mem_write, 2 /*addr, value*/); + make_js_func(list_syms, 0); #undef make_js_func } @@ -459,9 +485,65 @@ void dbg_load_script(Dbg *dbg, const char *script_path) js_dostring(dbg->js, script_buf); + free(script_buf); fclose(script); } +void dbg_load_symbols(Dbg *dbg) +{ + FILE *bin = fopen(dbg->file, "rb"); + if (bin == NULL) { + LOG_ERR("Cannot load symbols from file\n"); + return; + } + + Elf *elf; + Elf_Scn *scn = NULL; + GElf_Shdr shdr; + Elf_Data *data; + GElf_Sym sym; + + elf_version(EV_CURRENT); + + elf = elf_begin(fileno(bin), ELF_C_READ, NULL); + if (elf == NULL) { + LOG_ERR("Could not parse elf\n"); + fclose(bin); + return; + } + + while ((scn = elf_nextscn(elf, scn)) != NULL) { + gelf_getshdr(scn, &shdr); + if (shdr.sh_type == SHT_SYMTAB) { + break; + } + } + + data = elf_getdata(scn, NULL); + int count = shdr.sh_size / shdr.sh_entsize; + + for (int i = 0; i < count; i++) { + gelf_getsym(data, i, &sym); + if (sym.st_info != 2 /*func*/) { + char *name = elf_strptr(elf, shdr.sh_link, sym.st_name); + size_t len = strlen(name); + if (len == 0 || sym.st_value == 0x0) { + continue; + } + + char *n = malloc(len+1); + strcpy(n, name); + n[len] = '\0'; + + Symbol symbol = { .name = name, .addr = dbg->program_load_offset + (uintptr_t)sym.st_value }; + da_append(&dbg->symbols, symbol); + } + } + + elf_end(elf); + fclose(bin); +} + void dbg_init(Dbg *dbg, const char *file, pid_t pid) { memset(dbg, 0, sizeof(*dbg)); @@ -470,7 +552,7 @@ void dbg_init(Dbg *dbg, const char *file, pid_t pid) dbg_init_js(dbg); dbg_init_load_offset(dbg); hashtable_init(&dbg->brks, MAX_BRKS); - + dbg_load_symbols(dbg); dbg_load_script(dbg, INIT_SCRIPT); } @@ -478,6 +560,7 @@ void dbg_deinit(Dbg *dbg) { js_freestate(dbg->js); hashtable_deinit(&dbg->brks); + da_deinit(&dbg->symbols); } void dbg_loop(Dbg *dbg)