git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

Core/symbol_hash.c

      1 #include "gb.h"
      2 #include <stdint.h>
      3 #include <stdlib.h>
      4 #include <string.h>
      5 #include <sys/types.h>
      6 
      7 static size_t map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr, bool is_local)
      8 {
      9     if (!map->symbols) {
     10         return 0;
     11     }
     12     ssize_t min = 0;
     13     ssize_t max = map->n_symbols;
     14     while (min < max) {
     15         size_t pivot = (min + max) / 2;
     16         if (map->symbols[pivot].addr == addr && map->symbols[pivot].is_local == is_local) return pivot;
     17         if ((map->symbols[pivot].addr * 2 + !map->symbols[pivot].is_local) > (addr * 2 + !is_local)) {
     18             max = pivot;
     19         }
     20         else {
     21             min = pivot + 1;
     22         }
     23     }
     24     return (size_t) min;
     25 }
     26 
     27 GB_bank_symbol_t *GB_map_add_symbol(GB_symbol_map_t *map, uint16_t addr, const char *name)
     28 {
     29     bool is_local = strchr(name, '.');
     30     size_t index = map_find_symbol_index(map, addr, is_local);
     31 
     32     map->symbols = realloc(map->symbols, (map->n_symbols + 1) * sizeof(map->symbols[0]));
     33     memmove(&map->symbols[index + 1], &map->symbols[index], (map->n_symbols - index) * sizeof(map->symbols[0]));
     34     map->symbols[index].addr = addr;
     35     map->symbols[index].name = strdup(name);
     36     map->symbols[index].is_local = is_local;
     37     map->n_symbols++;
     38     return &map->symbols[index];
     39 }
     40 
     41 const GB_bank_symbol_t *GB_map_find_symbol(GB_symbol_map_t *map, uint16_t addr, bool prefer_local)
     42 {
     43     if (!map) return NULL;
     44     size_t index = map_find_symbol_index(map, addr, prefer_local);
     45     if (index >= map->n_symbols || map->symbols[index].addr != addr) {
     46         index--;
     47     }
     48     if (index < map->n_symbols) {
     49         while (index && map->symbols[index].addr == map->symbols[index - 1].addr && map->symbols[index].is_local == map->symbols[index - 1].is_local) {
     50             index--;
     51         }
     52         return &map->symbols[index];
     53     }
     54     return NULL;
     55 }
     56 
     57 GB_symbol_map_t *GB_map_alloc(void)
     58 {
     59     GB_symbol_map_t *map = malloc(sizeof(*map));
     60     memset(map, 0, sizeof(*map));
     61     return map;
     62 }
     63 
     64 void GB_map_free(GB_symbol_map_t *map)
     65 {
     66     for (unsigned i = 0; i < map->n_symbols; i++) {
     67         free(map->symbols[i].name);
     68     }
     69 
     70     if (map->symbols) {
     71         free(map->symbols);
     72     }
     73 
     74     free(map);
     75 }
     76 
     77 static unsigned hash_name(const char *name)
     78 {
     79     unsigned r = 0;
     80     while (*name) {
     81         r <<= 1;
     82         if (r & 0x2000) {
     83             r ^= 0x2001;
     84         }
     85         r ^= (unsigned char)*(name++);
     86     }
     87 
     88     return r;
     89 }
     90 
     91 void GB_reversed_map_add_symbol(GB_reversed_symbol_map_t *map, uint16_t bank, GB_bank_symbol_t *bank_symbol)
     92 {
     93     unsigned hash = hash_name(bank_symbol->name);
     94     GB_symbol_t *symbol = malloc(sizeof(*symbol));
     95     symbol->name = bank_symbol->name;
     96     symbol->addr = bank_symbol->addr;
     97     symbol->bank = bank;
     98     symbol->next = map->buckets[hash];
     99     map->buckets[hash] = symbol;
    100 }
    101 
    102 const GB_symbol_t *GB_reversed_map_find_symbol(GB_reversed_symbol_map_t *map, const char *name)
    103 {
    104     unsigned hash = hash_name(name);
    105     GB_symbol_t *symbol = map->buckets[hash];
    106 
    107     while (symbol) {
    108         if (strcmp(symbol->name, name) == 0) return symbol;
    109         symbol = symbol->next;
    110     }
    111 
    112     return NULL;
    113 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.