mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-03 20:27:58 +03:00
Debugger: Support FUNC debug information
It is used to print function names in backtrace.
This commit is contained in:
@@ -41,12 +41,21 @@ typedef struct {
|
||||
Mapping *mappings;
|
||||
} SrcInfo;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int page;
|
||||
int addr;
|
||||
boolean is_local;
|
||||
} FuncInfo;
|
||||
|
||||
struct debug_symbols {
|
||||
int version;
|
||||
int nr_srcs;
|
||||
SrcInfo *srcs;
|
||||
int nr_vars;
|
||||
char **variables;
|
||||
int nr_funcs;
|
||||
FuncInfo *functions;
|
||||
};
|
||||
|
||||
const char *fget4cc(FILE *fp) {
|
||||
@@ -161,6 +170,21 @@ static boolean load_vari(struct debug_symbols *dsym, char *buf) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean load_func(struct debug_symbols *dsym, char *buf) {
|
||||
dsym->nr_funcs = LittleEndian_getDW(buf, 0);
|
||||
dsym->functions = calloc(dsym->nr_funcs, sizeof(FuncInfo));
|
||||
char *p = buf + 4;
|
||||
for (int i = 0; i < dsym->nr_funcs; i++) {
|
||||
dsym->functions[i].name = p;
|
||||
p += strlen(p) + 1;
|
||||
dsym->functions[i].page = LittleEndian_getW(p, 0);
|
||||
dsym->functions[i].addr = LittleEndian_getDW(p, 2);
|
||||
dsym->functions[i].is_local = p[6];
|
||||
p += 7;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct debug_symbols *dsym_load(const char *path) {
|
||||
FILE *fp = fopen(path, "rb");
|
||||
if (!fp) {
|
||||
@@ -206,6 +230,8 @@ struct debug_symbols *dsym_load(const char *path) {
|
||||
ok = load_line(dsym, section_content);
|
||||
} else if (!strcmp(tag, "VARI")) {
|
||||
ok = load_vari(dsym, section_content);
|
||||
} else if (!strcmp(tag, "FUNC")) {
|
||||
ok = load_func(dsym, section_content);
|
||||
} else {
|
||||
WARNING("%s: unrecognized section %s\n", path, tag);
|
||||
}
|
||||
@@ -304,3 +330,26 @@ int dsym_lookup_variable(struct debug_symbols *dsym, const char *name) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *dsym_addr2func(struct debug_symbols *dsym, int page, int addr) {
|
||||
if (!dsym)
|
||||
return NULL;
|
||||
|
||||
// Binary search.
|
||||
int left = 0, right = dsym->nr_funcs;
|
||||
while (left < right) {
|
||||
int mid = (left + right) / 2;
|
||||
FuncInfo *f = &dsym->functions[mid];
|
||||
if (f->page < page || (f->page == page && f->addr <= addr))
|
||||
left = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
}
|
||||
if (left == 0)
|
||||
return NULL;
|
||||
FuncInfo *f = &dsym->functions[left - 1];
|
||||
if (f->page != page)
|
||||
return NULL;
|
||||
assert(f->addr <= addr);
|
||||
return f->name;
|
||||
}
|
||||
|
||||
@@ -31,5 +31,6 @@ int dsym_line2addr(struct debug_symbols *dsym, int page, int line);
|
||||
int dsym_addr2line(struct debug_symbols *dsym, int page, int addr);
|
||||
const char *dsym_source_line(struct debug_symbols *dsym, int page, int line);
|
||||
int dsym_lookup_variable(struct debug_symbols *dsym, const char *name);
|
||||
const char *dsym_addr2func(struct debug_symbols *dsym, int page, int addr);
|
||||
|
||||
#endif // __DEBUG_SYMBOL_H__
|
||||
|
||||
+11
-6
@@ -53,17 +53,22 @@ static Breakpoint *internal_breakpoint;
|
||||
static const char whitespaces[] = " \t\r\n";
|
||||
|
||||
static const char *format_address(int page, int addr, boolean is_return_addr) {
|
||||
static char buf[120];
|
||||
static char buf[100];
|
||||
const char *src = dsym_page2src(symbols, page);
|
||||
|
||||
// For return addresses, search with (addr - 1) so that the function call's
|
||||
// line number will be printed.
|
||||
int line = dsym_addr2line(symbols, page, is_return_addr ? addr - 1 : addr);
|
||||
const char *func = dsym_addr2func(symbols, page, is_return_addr ? addr - 1 : addr);
|
||||
|
||||
if (src && line > 0)
|
||||
sprintf(buf, "%.100s:%d", src, line); // TODO: print function name
|
||||
else
|
||||
sprintf(buf, "%d:0x%x", page, addr);
|
||||
if (src && line > 0) {
|
||||
if (func)
|
||||
snprintf(buf, sizeof(buf), "%s:%d in %s", src, line, func);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%s:%d", src, line);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%d:0x%x", page, addr);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -364,7 +369,7 @@ void dbg_repl(void) {
|
||||
}
|
||||
|
||||
char buf[256];
|
||||
while (printf("dbg> "), fgets(buf, sizeof(buf), stdin)) {
|
||||
while (printf("dbg> "), fflush(stdout), fgets(buf, sizeof(buf), stdin)) {
|
||||
char *cmd = strtok(buf, whitespaces);
|
||||
if (!cmd) {
|
||||
// TODO: repeat last command
|
||||
|
||||
Reference in New Issue
Block a user