Symbol support in the expression evaluator

This commit is contained in:
Lior Halphon 2016-07-15 14:31:27 +03:00
parent c3a831db7d
commit e20e81befd
5 changed files with 79 additions and 7 deletions

View File

@ -498,7 +498,16 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
return VALUE_16(GB_read_memory(gb, *watchpoint_address)); return VALUE_16(GB_read_memory(gb, *watchpoint_address));
} }
} }
GB_log(gb, "Unknown register: %.*s\n", length, string);
char symbol_name[length + 1];
memcpy(symbol_name, string, length);
symbol_name[length] = 0;
const GB_symbol_t *symbol = GB_reversed_map_find_symbol(&gb->reversed_symbol_map, symbol_name);
if (symbol) {
return (value_t){true, symbol->bank, symbol->addr};
}
GB_log(gb, "Unknown register or symbol: %.*s\n", length, string);
*error = true; *error = true;
return ERROR; return ERROR;
} }
@ -1361,7 +1370,10 @@ void GB_debugger_load_symbol_file(GB_gameboy_t *gb, const char *path)
if (!gb->bank_symbols[bank]) { if (!gb->bank_symbols[bank]) {
gb->bank_symbols[bank] = GB_map_alloc(); gb->bank_symbols[bank] = GB_map_alloc();
} }
GB_map_add_symbol(gb->bank_symbols[bank], address, symbol); GB_bank_symbol_t *allocated_symbol = GB_map_add_symbol(gb->bank_symbols[bank], address, symbol);
if (allocated_symbol) {
GB_reversed_map_add_symbol(&gb->reversed_symbol_map, bank, allocated_symbol);
}
} }
} }
free(line); free(line);

View File

@ -142,6 +142,13 @@ void GB_free(GB_gameboy_t *gb)
GB_map_free(gb->bank_symbols[i]); GB_map_free(gb->bank_symbols[i]);
} }
} }
for (int i = 0x400; i--;) {
if (gb->reversed_symbol_map.buckets[i]) {
GB_symbol_t *next = gb->reversed_symbol_map.buckets[i]->next;
free(gb->reversed_symbol_map.buckets[i]);
gb->reversed_symbol_map.buckets[i] = next;
}
}
} }
int GB_load_boot_rom(GB_gameboy_t *gb, const char *path) int GB_load_boot_rom(GB_gameboy_t *gb, const char *path)

View File

@ -360,8 +360,9 @@ typedef struct GB_gameboy_s {
uint16_t n_watchpoints; uint16_t n_watchpoints;
struct GB_watchpoint_s *watchpoints; struct GB_watchpoint_s *watchpoints;
/* Symbol table */ /* Symbol tables */
GB_symbol_map_t *bank_symbols[0x200]; GB_symbol_map_t *bank_symbols[0x200];
GB_reversed_symbol_map_t reversed_symbol_map;
/* Misc */ /* Misc */
bool turbo; bool turbo;

View File

@ -20,17 +20,18 @@ static size_t GB_map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr)
return (size_t) min; return (size_t) min;
} }
void GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name) GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name)
{ {
size_t index = GB_map_find_symbol_index(map, addr); size_t index = GB_map_find_symbol_index(map, addr);
if (index < map->n_symbols && map->symbols[index].addr == addr) return; if (index < map->n_symbols && map->symbols[index].addr == addr) return NULL;
map->symbols = realloc(map->symbols, (map->n_symbols + 1) * sizeof(map->symbols[0])); 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])); memmove(&map->symbols[index + 1], &map->symbols[index], (map->n_symbols - index) * sizeof(map->symbols[0]));
map->symbols[index].addr = addr; map->symbols[index].addr = addr;
map->symbols[index].name = strdup(name); map->symbols[index].name = strdup(name);
map->n_symbols++; 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)
@ -65,3 +66,41 @@ void GB_map_free(GB_symbol_map_t *map)
free(map); free(map);
} }
static int hash_name(const char *name)
{
int r = 0;
while (*name) {
r <<= 1;
if (r & 0x400) {
r ^= 0x401;
}
r += (unsigned char)*(name++);
}
return r & 0x3FF;
}
void GB_reversed_map_add_symbol(GB_reversed_symbol_map_t *map, uint16_t bank, GB_bank_symbol_t *bank_symbol)
{
int hash = hash_name(bank_symbol->name);
GB_symbol_t *symbol = malloc(sizeof(*symbol));
symbol->name = bank_symbol->name;
symbol->addr = bank_symbol->addr;
symbol->bank = bank;
symbol->next = map->buckets[hash];
map->buckets[hash] = symbol;
}
const GB_symbol_t *GB_reversed_map_find_symbol(GB_reversed_symbol_map_t *map, const char *name)
{
int hash = hash_name(name);
GB_symbol_t *symbol = map->buckets[hash];
while (symbol) {
if (strcmp(symbol->name, name) == 0) return symbol;
symbol = symbol->next;
}
return NULL;
}

View File

@ -5,19 +5,32 @@
#include <string.h> #include <string.h>
typedef struct { typedef struct {
uint16_t addr;
char *name; char *name;
uint16_t addr;
} GB_bank_symbol_t; } GB_bank_symbol_t;
typedef struct GB_symbol_s {
struct GB_symbol_s *next;
const char *name;
uint16_t bank;
uint16_t addr;
} GB_symbol_t;
typedef struct { typedef struct {
GB_bank_symbol_t *symbols; GB_bank_symbol_t *symbols;
size_t n_symbols; size_t n_symbols;
} GB_symbol_map_t; } GB_symbol_map_t;
void GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name); GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name);
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);
GB_symbol_map_t *GB_map_alloc(void); GB_symbol_map_t *GB_map_alloc(void);
void GB_map_free(GB_symbol_map_t *map); void GB_map_free(GB_symbol_map_t *map);
typedef struct {
GB_symbol_t *buckets[0x400];
} GB_reversed_symbol_map_t;
void GB_reversed_map_add_symbol(GB_reversed_symbol_map_t *map, uint16_t bank, GB_bank_symbol_t *symbol);
const GB_symbol_t *GB_reversed_map_find_symbol(GB_reversed_symbol_map_t *map, const char *name);
#endif /* symbol_hash_h */ #endif /* symbol_hash_h */