Skip to content

Commit

Permalink
Treat local and non-local symbols differently
Browse files Browse the repository at this point in the history
  • Loading branch information
LIJI32 committed Jul 29, 2023
1 parent d209628 commit 29becc2
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 45 deletions.
68 changes: 34 additions & 34 deletions Core/debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ static inline void switch_banking_state(GB_gameboy_t *gb, uint16_t bank)
}
}

static const char *value_to_string(GB_gameboy_t *gb, uint16_t value, bool prefer_name)
static const char *value_to_string(GB_gameboy_t *gb, uint16_t value, bool prefer_name, bool prefer_local)
{
static __thread char output[256];
const GB_bank_symbol_t *symbol = GB_debugger_find_symbol(gb, value);
const GB_bank_symbol_t *symbol = GB_debugger_find_symbol(gb, value, prefer_local);

if (symbol && (value - symbol->addr > 0x1000 || symbol->addr == 0) ) {
symbol = NULL;
Expand Down Expand Up @@ -167,12 +167,12 @@ static GB_symbol_map_t *get_symbol_map(GB_gameboy_t *gb, uint16_t bank)
return gb->bank_symbols[bank];
}

static const char *debugger_value_to_string(GB_gameboy_t *gb, value_t value, bool prefer_name)
static const char *debugger_value_to_string(GB_gameboy_t *gb, value_t value, bool prefer_name, bool prefer_local)
{
if (!value.has_bank) return value_to_string(gb, value.value, prefer_name);
if (!value.has_bank) return value_to_string(gb, value.value, prefer_name, prefer_local);

static __thread char output[256];
const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, value.bank), value.value);
const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, value.bank), value.value, prefer_local);

if (symbol && (value.value - symbol->addr > 0x1000 || symbol->addr == 0) ) {
symbol = NULL;
Expand Down Expand Up @@ -890,11 +890,11 @@ static bool registers(GB_gameboy_t *gb, char *arguments, char *modifiers, const
(gb->f & GB_HALF_CARRY_FLAG)? 'H' : '-',
(gb->f & GB_SUBTRACT_FLAG)? 'N' : '-',
(gb->f & GB_ZERO_FLAG)? 'Z' : '-');
GB_log(gb, "BC = %s\n", value_to_string(gb, gb->bc, false));
GB_log(gb, "DE = %s\n", value_to_string(gb, gb->de, false));
GB_log(gb, "HL = %s\n", value_to_string(gb, gb->hl, false));
GB_log(gb, "SP = %s\n", value_to_string(gb, gb->sp, false));
GB_log(gb, "PC = %s\n", value_to_string(gb, gb->pc, false));
GB_log(gb, "BC = %s\n", value_to_string(gb, gb->bc, false, false));
GB_log(gb, "DE = %s\n", value_to_string(gb, gb->de, false, false));
GB_log(gb, "HL = %s\n", value_to_string(gb, gb->hl, false, false));
GB_log(gb, "SP = %s\n", value_to_string(gb, gb->sp, false, false));
GB_log(gb, "PC = %s\n", value_to_string(gb, gb->pc, false, false));
GB_log(gb, "IME = %s\n", gb->ime? "Enabled" : "Disabled");
return true;
}
Expand Down Expand Up @@ -1067,9 +1067,9 @@ static bool breakpoint(GB_gameboy_t *gb, char *arguments, char *modifiers, const
gb->has_jump_to_breakpoints = true;
}

GB_log(gb, "Breakpoint %u set at %s", id, debugger_value_to_string(gb, result, true));
GB_log(gb, "Breakpoint %u set at %s", id, debugger_value_to_string(gb, result, true, false));
if (length) {
GB_log(gb, " - %s\n", debugger_value_to_string(gb, end, true));
GB_log(gb, " - %s\n", debugger_value_to_string(gb, end, true, true));
}
else {
GB_log(gb, "\n");
Expand Down Expand Up @@ -1124,7 +1124,7 @@ static bool delete(GB_gameboy_t *gb, char *arguments, char *modifiers, const deb

value_t addr = (value_t){gb->breakpoints[i].bank != (uint16_t)-1, gb->breakpoints[i].bank, gb->breakpoints[i].addr};

GB_log(gb, "Breakpoint %u removed from %s\n", id, debugger_value_to_string(gb, addr, addr.has_bank));
GB_log(gb, "Breakpoint %u removed from %s\n", id, debugger_value_to_string(gb, addr, addr.has_bank, false));
return true;
}

Expand Down Expand Up @@ -1239,9 +1239,9 @@ static bool watch(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
.length = length,
};

GB_log(gb, "Watchpoint %u set at %s", id, debugger_value_to_string(gb, result, true));
GB_log(gb, "Watchpoint %u set at %s", id, debugger_value_to_string(gb, result, true, false));
if (length) {
GB_log(gb, " - %s\n", debugger_value_to_string(gb, end, true));
GB_log(gb, " - %s\n", debugger_value_to_string(gb, end, true, true));
}
else {
GB_log(gb, "\n");
Expand Down Expand Up @@ -1284,7 +1284,7 @@ static bool unwatch(GB_gameboy_t *gb, char *arguments, char *modifiers, const de

value_t addr = (value_t){gb->watchpoints[i].bank != (uint16_t)-1, gb->watchpoints[i].bank, gb->watchpoints[i].addr};

GB_log(gb, "Watchpoint %u removed from %s\n", id, debugger_value_to_string(gb, addr, addr.has_bank));
GB_log(gb, "Watchpoint %u removed from %s\n", id, debugger_value_to_string(gb, addr, addr.has_bank, false));
return true;
}

Expand All @@ -1311,19 +1311,19 @@ static bool list(GB_gameboy_t *gb, char *arguments, char *modifiers, const debug
if (gb->breakpoints[i].length) {
value_t end = addr;
end.value += gb->breakpoints[i].length + 1;
end_string = strdup(debugger_value_to_string(gb, end, addr.has_bank));
end_string = strdup(debugger_value_to_string(gb, end, addr.has_bank, true));
}
if (gb->breakpoints[i].condition) {
GB_log(gb, " %d. %s%s%s (%sCondition: %s)\n", gb->breakpoints[i].id,
debugger_value_to_string(gb, addr, addr.has_bank),
debugger_value_to_string(gb, addr, addr.has_bank, false),
end_string? " - " : "",
end_string ?: "",
gb->breakpoints[i].is_jump_to? "Jump to, ": "",
gb->breakpoints[i].condition);
}
else {
GB_log(gb, " %d. %s%s%s%s\n", gb->breakpoints[i].id,
debugger_value_to_string(gb, addr, addr.has_bank),
debugger_value_to_string(gb, addr, addr.has_bank, false),
end_string? " - " : "",
end_string ?: "",
gb->breakpoints[i].is_jump_to? " (Jump to)" : "");
Expand All @@ -1345,17 +1345,17 @@ static bool list(GB_gameboy_t *gb, char *arguments, char *modifiers, const debug
if (gb->watchpoints[i].length) {
value_t end = addr;
end.value += gb->watchpoints[i].length + 1;
end_string = strdup(debugger_value_to_string(gb, end, addr.has_bank));
end_string = strdup(debugger_value_to_string(gb, end, addr.has_bank, true));
}
if (gb->watchpoints[i].condition) {
GB_log(gb, " %d. %s%s%s (%c%c, Condition: %s)\n", gb->watchpoints[i].id, debugger_value_to_string(gb, addr, addr.has_bank),
GB_log(gb, " %d. %s%s%s (%c%c, Condition: %s)\n", gb->watchpoints[i].id, debugger_value_to_string(gb, addr, addr.has_bank, false),
end_string? " - " : "", end_string ?: "",
(gb->watchpoints[i].flags & WATCHPOINT_READ)? 'r' : '-',
(gb->watchpoints[i].flags & WATCHPOINT_WRITE)? 'w' : '-',
gb->watchpoints[i].condition);
}
else {
GB_log(gb, " %d. %s%s%s (%c%c)\n", gb->watchpoints[i].id, debugger_value_to_string(gb, addr, addr.has_bank),
GB_log(gb, " %d. %s%s%s (%c%c)\n", gb->watchpoints[i].id, debugger_value_to_string(gb, addr, addr.has_bank, false),
end_string? " - " : "", end_string ?: "",
(gb->watchpoints[i].flags & WATCHPOINT_READ)? 'r' : '-',
(gb->watchpoints[i].flags & WATCHPOINT_WRITE)? 'w' : '-');
Expand Down Expand Up @@ -1427,7 +1427,7 @@ static bool print(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu
if (!error) {
switch (modifiers[0]) {
case 'a':
GB_log(gb, "=%s\n", debugger_value_to_string(gb, result, false));
GB_log(gb, "=%s\n", debugger_value_to_string(gb, result, false, false));
break;
case 'd':
GB_log(gb, "=%d\n", result.value);
Expand Down Expand Up @@ -1634,9 +1634,9 @@ static bool backtrace(GB_gameboy_t *gb, char *arguments, char *modifiers, const
return true;
}

GB_log(gb, " 1. %s\n", debugger_value_to_string(gb, (value_t){true, bank_for_addr(gb, gb->pc), gb->pc}, true));
GB_log(gb, " 1. %s\n", debugger_value_to_string(gb, (value_t){true, bank_for_addr(gb, gb->pc), gb->pc}, true, false));
for (unsigned i = gb->backtrace_size; i--;) {
GB_log(gb, "%3d. %s\n", gb->backtrace_size - i + 1, debugger_value_to_string(gb, (value_t){true, gb->backtrace_returns[i].bank, gb->backtrace_returns[i].addr}, true));
GB_log(gb, "%3d. %s\n", gb->backtrace_size - i + 1, debugger_value_to_string(gb, (value_t){true, gb->backtrace_returns[i].bank, gb->backtrace_returns[i].addr}, true, false));
}

return true;
Expand Down Expand Up @@ -2224,10 +2224,10 @@ static void test_watchpoint(GB_gameboy_t *gb, uint16_t addr, uint8_t flags, uint
condition_ok:
GB_debugger_break(gb);
if (flags == WATCHPOINT_READ) {
GB_log(gb, "Watchpoint %u: [%s]\n", watchpoint->id, value_to_string(gb, addr, true));
GB_log(gb, "Watchpoint %u: [%s]\n", watchpoint->id, value_to_string(gb, addr, true, false));
}
else {
GB_log(gb, "Watchpoint %u: [%s] = $%02x\n", watchpoint->id, value_to_string(gb, addr, true), value);
GB_log(gb, "Watchpoint %u: [%s] = $%02x\n", watchpoint->id, value_to_string(gb, addr, true, false), value);
}
return;
}
Expand Down Expand Up @@ -2417,7 +2417,7 @@ static void noinline debugger_run(GB_gameboy_t *gb)
unsigned breakpoint_id = 0;
if (gb->breakpoints && !gb->debug_stopped && (breakpoint_id = should_break(gb, gb->pc, false))) {
GB_debugger_break(gb);
GB_log(gb, "Breakpoint %u: PC = %s\n", breakpoint_id, value_to_string(gb, gb->pc, true));
GB_log(gb, "Breakpoint %u: PC = %s\n", breakpoint_id, value_to_string(gb, gb->pc, true, false));
GB_cpu_disassemble(gb, gb->pc, 5);
}

Expand All @@ -2428,7 +2428,7 @@ static void noinline debugger_run(GB_gameboy_t *gb)
bool should_delete_state = true;
if (jump_to_result == JUMP_TO_BREAK) {
GB_debugger_break(gb);
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, address, true));
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, address, true, false));
GB_cpu_disassemble(gb, gb->pc, 5);
gb->non_trivial_jump_breakpoint_occured = false;
}
Expand All @@ -2438,7 +2438,7 @@ static void noinline debugger_run(GB_gameboy_t *gb)
}
else {
gb->non_trivial_jump_breakpoint_occured = true;
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, gb->pc, true));
GB_log(gb, "Jumping to breakpoint %u: %s\n", breakpoint_id, value_to_string(gb, gb->pc, true, false));
GB_load_state_from_buffer(gb, gb->nontrivial_jump_state, -1);
GB_cpu_disassemble(gb, gb->pc, 5);
GB_debugger_break(gb);
Expand Down Expand Up @@ -2570,20 +2570,20 @@ void GB_debugger_clear_symbols(GB_gameboy_t *gb)
}
}

const GB_bank_symbol_t *GB_debugger_find_symbol(GB_gameboy_t *gb, uint16_t addr)
const GB_bank_symbol_t *GB_debugger_find_symbol(GB_gameboy_t *gb, uint16_t addr, bool prefer_local)
{
uint16_t bank = bank_for_addr(gb, addr);

const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, bank), addr);
const GB_bank_symbol_t *symbol = GB_map_find_symbol(get_symbol_map(gb, bank), addr, prefer_local);
if (symbol) return symbol;
if (bank != 0) return GB_map_find_symbol(get_symbol_map(gb, 0), addr); /* Maybe the symbol incorrectly uses bank 0? */
if (bank != 0) return GB_map_find_symbol(get_symbol_map(gb, 0), addr, false); /* Maybe the symbol incorrectly uses bank 0? */

return NULL;
}

const char *GB_debugger_name_for_address(GB_gameboy_t *gb, uint16_t addr)
{
const GB_bank_symbol_t *symbol = GB_debugger_find_symbol(gb, addr);
const GB_bank_symbol_t *symbol = GB_debugger_find_symbol(gb, addr, false);
if (symbol && symbol->addr == addr) return symbol->name;
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion Core/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal void GB_debugger_call_hook(GB_gameboy_t *gb, uint16_t call_addr);
internal void GB_debugger_ret_hook(GB_gameboy_t *gb);
internal void GB_debugger_test_write_watchpoint(GB_gameboy_t *gb, uint16_t addr, uint8_t value);
internal void GB_debugger_test_read_watchpoint(GB_gameboy_t *gb, uint16_t addr);
internal const GB_bank_symbol_t *GB_debugger_find_symbol(GB_gameboy_t *gb, uint16_t addr);
internal const GB_bank_symbol_t *GB_debugger_find_symbol(GB_gameboy_t *gb, uint16_t addr, bool prefer_local);
internal void GB_debugger_add_symbol(GB_gameboy_t *gb, uint16_t bank, uint16_t address, const char *symbol);
#endif

Expand Down
4 changes: 2 additions & 2 deletions Core/sm83_disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ static opcode_t *opcodes[256] = {

void GB_cpu_disassemble(GB_gameboy_t *gb, uint16_t pc, uint16_t count)
{
const GB_bank_symbol_t *function_symbol = GB_debugger_find_symbol(gb, pc);
const GB_bank_symbol_t *function_symbol = GB_debugger_find_symbol(gb, pc, false);

if (function_symbol && pc - function_symbol->addr > 0x1000) {
function_symbol = NULL;
Expand All @@ -771,7 +771,7 @@ void GB_cpu_disassemble(GB_gameboy_t *gb, uint16_t pc, uint16_t count)
uint16_t current_function = function_symbol? function_symbol->addr : 0;

while (count--) {
function_symbol = GB_debugger_find_symbol(gb, pc);
function_symbol = GB_debugger_find_symbol(gb, pc, false);
if (function_symbol && function_symbol->addr == pc) {
if (current_function != function_symbol->addr) {
GB_log(gb, "\n");
Expand Down
16 changes: 9 additions & 7 deletions Core/symbol_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <string.h>
#include <sys/types.h>

static size_t map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr)
static size_t map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr, bool is_local)
{
if (!map->symbols) {
return 0;
Expand All @@ -13,8 +13,8 @@ static size_t map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr)
ssize_t max = map->n_symbols;
while (min < max) {
size_t pivot = (min + max) / 2;
if (map->symbols[pivot].addr == addr) return pivot;
if (map->symbols[pivot].addr > addr) {
if (map->symbols[pivot].addr == addr && map->symbols[pivot].is_local == is_local) return pivot;
if ((map->symbols[pivot].addr * 2 + !map->symbols[pivot].is_local) > (addr * 2 + !is_local)) {
max = pivot;
}
else {
Expand All @@ -26,25 +26,27 @@ static size_t map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr)

GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name)
{
size_t index = map_find_symbol_index(map, addr);
bool is_local = strchr(name, '.');
size_t index = map_find_symbol_index(map, addr, is_local);

map->symbols = realloc(map->symbols, (map->n_symbols + 1) * sizeof(map->symbols[0]));
memmove(&map->symbols[index + 1], &map->symbols[index], (map->n_symbols - index) * sizeof(map->symbols[0]));
map->symbols[index].addr = addr;
map->symbols[index].name = strdup(name);
map->symbols[index].is_local = is_local;
map->n_symbols++;
return &map->symbols[index];
}

const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr)
const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr, bool prefer_local)
{
if (!map) return NULL;
size_t index = map_find_symbol_index(map, addr);
size_t index = map_find_symbol_index(map, addr, prefer_local);
if (index >= map->n_symbols || map->symbols[index].addr != addr) {
index--;
}
if (index < map->n_symbols) {
while (index && map->symbols[index].addr == map->symbols[index - 1].addr) {
while (index && map->symbols[index].addr == map->symbols[index - 1].addr && map->symbols[index].is_local == map->symbols[index - 1].is_local) {
index--;
}
return &map->symbols[index];
Expand Down
3 changes: 2 additions & 1 deletion Core/symbol_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
typedef struct {
char *name;
uint16_t addr;
bool is_local;
} GB_bank_symbol_t;

typedef struct GB_symbol_s {
Expand All @@ -30,7 +31,7 @@ typedef struct {
internal void GB_reversed_map_add_symbol(GB_reversed_symbol_map_t *map, uint16_t bank, GB_bank_symbol_t *symbol);
internal const GB_symbol_t *GB_reversed_map_find_symbol(GB_reversed_symbol_map_t *map, const char *name);
internal GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name);
internal const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr);
internal const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr, bool prefer_local);
internal GB_symbol_map_t *GB_map_alloc(void);
internal void GB_map_free(GB_symbol_map_t *map);
#endif
Expand Down

0 comments on commit 29becc2

Please sign in to comment.