sig.cpp 3.64 KB
#include <stdio.h>
#include "romhack.h"

void add_bb_symbols(symmap_t &syms)
{
    static struct {
        char *symbol;
        u32 hi;
        u32 lo;
        u8 found;
        u32 size;
    } bbsym[] = {
        {"__osBbEepromAddress", 0x8000, 0x035c, 1, 4},
        {"__osBbEepromSize", 0x8000, 0x0360, 1, 4},
        {"__osBbFlashAddress", 0x8000, 0x0364, 1, 4},
        {"__osBbFlashSize", 0x8000, 0x0368, 1, 4},
        {"__osBbFlashBuffer", 0x8070, 0x4000, 1, 128},
        {"__osBbSramAddress", 0x8000, 0x036c, 1, 4},
        {"__osBbSramSize", 0x8000, 0x0370, 1, 4},
        {"__osBbPakAddress", 0x8000, 0x0374, 1, 16},
        {"__osBbPakSize", 0x8000, 0x0384, 1, 4},
        {"__osBbIsBb", 0x8000, 0x0388, 1, 4},
        {"__osBbHackFlags", 0x8000, 0x038c, 1, 4},
        {"osMemSize", 0x8000, 0x0318, 1, 4},
        {"__osBbLastRCount", 0x807b, 0xff00, 1, 4},
        {"__osBbLastVCount", 0x807b, 0xfff4, 1, 4},
        {"__osBbRCountWraps", 0x807b, 0xfff8, 1, 4},
        {"__osBbVCountWraps", 0x807b, 0xfffc, 1, 4},
    };

    for (int i = 0; i < sizeof(bbsym)/sizeof(bbsym[0]); ++i) {
        sym_t *s = new sym_t;
        s->symbol = strdup(bbsym[i].symbol);
        s->hi = bbsym[i].hi;
        s->lo = bbsym[i].lo;
        s->found = bbsym[i].found;
        s->size = bbsym[i].size;
        syms[s->symbol] = s;
    }
}

void read_symbols(FILE *fp, symmap_t &syms)
{
    char line[256];

    while (fgets(line, sizeof(line), fp)) {
        char symbol[256];
        u32 size;
        if (line[0] == '\n') break;
        if (sscanf(line, "%s %d", symbol, &size) == 2) {
            sym_t *s = new sym_t;
            s->symbol = strdup(symbol);
            s->hi = s->lo = s->found = 0;
            s->size = size;
            syms[s->symbol] = s;
        }
    }
    add_bb_symbols(syms);
}

void read_signatures(FILE *fp, sigmap_t &sigs, symmap_t &syms)
{
    char line[256];

    while (fgets(line, sizeof(line), fp)) {
        char symbol[256];
        u32 num_ops, first_op, first_mask, crc, partial_crc;
        u8 ambiguous;

        if (sscanf(line, "%s %d %x %x %x %x %d", symbol, &num_ops, &first_op, &first_mask, &crc, &partial_crc, &ambiguous) == 7) {
            sig_t *s = new sig_t;
            s->symbol = strdup(symbol);
            s->num_ops = num_ops;
            s->first_op = first_op;
            s->first_mask = first_mask;
            s->crc = crc;
            s->partial_crc = partial_crc;
            s->ambiguous = ambiguous;
            sigs[s->symbol] = s;
            while (fgets(line, sizeof(line), fp)) {
                u32 index, hi_offset, lo_offset, type, text;
                char symbol[256];
                if (line[0] == '\n') break;
                if (sscanf(line, "%d %d %d %d %s %d", &index, &hi_offset, &lo_offset, &type, symbol, &text) == 6) {
                    rel_t *r = new rel_t;
                    r->index = index;
                    r->hi_offset = hi_offset;
                    r->lo_offset = lo_offset;
                    r->text = text;
                    r->type = (reltype_t)type;
                    if (strcmp(symbol, "NULL")) {
                        r->sym = syms[symbol];
                    } else {
                        r->sym = NULL;
                    }
                    s->relocs.push_back(r);
                }
            }
        }
    }
}

void read_library(char *filename, symmap_t &syms, sigmap_t &sigs) 
{
    fprintf(stderr, "Reading library signatures: %s\n", filename);
    FILE *fp = fopen(filename, "r");
    if (fp == NULL) {
        perror(filename);
        goto done;
    }

    read_symbols(fp, syms);
    read_signatures(fp, sigs, syms);

done:
    if (fp) fclose(fp);
    fprintf(stderr, "done.\n\n");
}