From ca3e5dd645ac2758de8fab7fc3bbb12354ff4bb5 Mon Sep 17 00:00:00 2001 From: Daniel Beer Date: Sat, 1 May 2010 18:34:43 +1200 Subject: [PATCH] Symbol table is an object. --- binfile.h | 9 +++-- cproc.c | 17 +++++++--- cproc.h | 6 ++-- cproc_util.c | 20 ++++++----- devcmd.c | 29 ++++++++++------ elf32.c | 9 ++--- expr.c | 9 ++--- expr.h | 3 +- main.c | 45 +++++++++++++++---------- rtools.c | 25 ++++++++------ stab.c | 95 +++++++++++++++++++++++++++++++++------------------- stab.h | 23 +++++++------ sym.c | 44 ++++++++++++++---------- symmap.c | 4 +-- 14 files changed, 204 insertions(+), 134 deletions(-) diff --git a/binfile.h b/binfile.h index 966120f..c40a32d 100644 --- a/binfile.h +++ b/binfile.h @@ -22,13 +22,12 @@ #include #include +#include "stab.h" + /* Callback for binary image data */ typedef int (*imgfunc_t)(void *user_data, u_int16_t addr, const u_int8_t *data, int len); -/* Callback for symbol data */ -typedef int (*symfunc_t)(const char *name, int value); - /* Intel HEX file support */ int ihex_check(FILE *in); int ihex_extract(FILE *in, imgfunc_t cb, void *user_data); @@ -36,10 +35,10 @@ int ihex_extract(FILE *in, imgfunc_t cb, void *user_data); /* ELF32 file support */ int elf32_check(FILE *in); int elf32_extract(FILE *in, imgfunc_t cb, void *user_data); -int elf32_syms(FILE *in, symfunc_t cb); +int elf32_syms(FILE *in, stab_t stab); /* *.map file support */ int symmap_check(FILE *in); -int symmap_syms(FILE *in, symfunc_t cb); +int symmap_syms(FILE *in, stab_t stab); #endif diff --git a/cproc.c b/cproc.c index 98dee0c..b18b781 100644 --- a/cproc.c +++ b/cproc.c @@ -43,6 +43,7 @@ struct cproc { int in_reader_loop; device_t device; + stab_t stab; }; static struct cproc_option *find_option(cproc_t cp, const char *name) @@ -198,7 +199,8 @@ static int cmd_help(cproc_t cp, char **arg) return 0; } -static int parse_option(struct cproc_option *o, const char *word) +static int parse_option(stab_t stab, + struct cproc_option *o, const char *word) { switch (o->type) { case CPROC_OPTION_BOOL: @@ -208,7 +210,7 @@ static int parse_option(struct cproc_option *o, const char *word) break; case CPROC_OPTION_NUMERIC: - return expr_eval(word, &o->data.numeric); + return expr_eval(stab, word, &o->data.numeric); case CPROC_OPTION_STRING: strncpy(o->data.text, word, sizeof(o->data.text)); @@ -258,7 +260,7 @@ static int cmd_opt(cproc_t cp, char **arg) } if (**arg) { - if (parse_option(opt, *arg) < 0) { + if (parse_option(cp->stab, opt, *arg) < 0) { fprintf(stderr, "opt: can't parse option: %s\n", *arg); return -1; @@ -322,7 +324,7 @@ static const struct cproc_option built_in_options[] = { } }; -cproc_t cproc_new(device_t dev) +cproc_t cproc_new(device_t dev, stab_t st) { cproc_t cp = malloc(sizeof(*cp)); @@ -332,6 +334,7 @@ cproc_t cproc_new(device_t dev) memset(cp, 0, sizeof(*cp)); cp->device = dev; + cp->stab = st; vector_init(&cp->command_list, sizeof(struct cproc_command)); vector_init(&cp->option_list, sizeof(struct cproc_option)); @@ -354,6 +357,7 @@ void cproc_destroy(cproc_t cp) cp->device->destroy(cp->device); vector_destroy(&cp->command_list); vector_destroy(&cp->option_list); + stab_destroy(cp->stab); free(cp); } @@ -362,6 +366,11 @@ device_t cproc_device(cproc_t cp) return cp->device; } +stab_t cproc_stab(cproc_t cp) +{ + return cp->stab; +} + int cproc_register_commands(cproc_t cp, const struct cproc_command *cmd, int count) { diff --git a/cproc.h b/cproc.h index 20b765f..26861b6 100644 --- a/cproc.h +++ b/cproc.h @@ -20,6 +20,7 @@ #define CPROC_H_ #include "device.h" +#include "stab.h" /* Command processor. * @@ -89,11 +90,12 @@ struct cproc_option { * has been given. When you destroy a command processor, the device is * also destroyed. */ -cproc_t cproc_new(device_t dev); +cproc_t cproc_new(device_t dev, stab_t st); void cproc_destroy(cproc_t cp); -/* Fetch the command processor's device */ +/* Fetch the command processor's device and symbol table */ device_t cproc_device(cproc_t cp); +stab_t cproc_stab(cproc_t cp); /* Register commands and options with the command processor. These functions * return 0 on success or -1 if an error occurs (failure to allocate memory). diff --git a/cproc_util.c b/cproc_util.c index 3fb251e..87253f4 100644 --- a/cproc_util.c +++ b/cproc_util.c @@ -24,7 +24,7 @@ #include "stab.h" #include "util.h" -static int format_addr(char *buf, int max_len, +static int format_addr(stab_t stab, char *buf, int max_len, msp430_amode_t amode, u_int16_t addr) { char name[64]; @@ -54,7 +54,7 @@ static int format_addr(char *buf, int max_len, if ((!numeric || (addr >= 0x200 && addr < 0xfff0)) && - !stab_nearest(addr, name, sizeof(name), &offset) && + !stab_nearest(stab, addr, name, sizeof(name), &offset) && !offset) return snprintf(buf, max_len, "%s\x1b[1m%s\x1b[0m", prefix, name); @@ -108,19 +108,19 @@ static int format_reg(char *buf, int max_len, * * Returns the number of characters printed. */ -static int format_operand(char *buf, int max_len, +static int format_operand(stab_t stab, char *buf, int max_len, msp430_amode_t amode, u_int16_t addr, msp430_reg_t reg) { int len = 0; - len += format_addr(buf, max_len, amode, addr); + len += format_addr(stab, buf, max_len, amode, addr); len += format_reg(buf + len, max_len - len, amode, reg); return len; } /* Write assembly language for the instruction to this buffer */ -static int dis_format(char *buf, int max_len, +static int dis_format(stab_t stab, char *buf, int max_len, const struct msp430_instruction *insn) { int len; @@ -144,7 +144,7 @@ static int dis_format(char *buf, int max_len, /* Source operand */ if (insn->itype == MSP430_ITYPE_DOUBLE) { - len = format_operand(buf + total, + len = format_operand(stab, buf + total, max_len - total, insn->src_mode, insn->src_addr, @@ -166,7 +166,7 @@ static int dis_format(char *buf, int max_len, /* Destination operand */ if (insn->itype != MSP430_ITYPE_NOARG) - total += format_operand(buf + total, + total += format_operand(stab, buf + total, max_len - total, insn->dst_mode, insn->dst_addr, @@ -185,6 +185,7 @@ static int dis_format(char *buf, int max_len, void cproc_disassemble(cproc_t cp, u_int16_t offset, const u_int8_t *data, int length) { + stab_t stab = cproc_stab(cp); int first_line = 1; while (length) { @@ -197,7 +198,8 @@ void cproc_disassemble(cproc_t cp, char buf[256]; int len = 0; - if (!stab_nearest(offset, obname, sizeof(obname), &oboff)) { + if (!stab_nearest(stab, offset, obname, sizeof(obname), + &oboff)) { if (!oboff) cproc_printf(cp, "\x1b[m%s:\x1b[0m", obname); else if (first_line) @@ -226,7 +228,7 @@ void cproc_disassemble(cproc_t cp, } if (retval >= 0) - len += dis_format(buf + len, sizeof(buf) - len, + len += dis_format(stab, buf + len, sizeof(buf) - len, &insn); cproc_printf(cp, "%s", buf); diff --git a/devcmd.c b/devcmd.c index 5faa280..cae975e 100644 --- a/devcmd.c +++ b/devcmd.c @@ -51,6 +51,7 @@ static int cmd_regs(cproc_t cp, char **arg) static int cmd_md(cproc_t cp, char **arg) { + stab_t stab = cproc_stab(cp); device_t dev = cproc_device(cp); char *off_text = get_arg(arg); char *len_text = get_arg(arg); @@ -62,13 +63,13 @@ static int cmd_md(cproc_t cp, char **arg) return -1; } - if (expr_eval(off_text, &offset) < 0) { + if (expr_eval(stab, off_text, &offset) < 0) { fprintf(stderr, "md: can't parse offset: %s\n", off_text); return -1; } if (len_text) { - if (expr_eval(len_text, &length) < 0) { + if (expr_eval(stab, len_text, &length) < 0) { fprintf(stderr, "md: can't parse length: %s\n", len_text); return -1; @@ -100,6 +101,7 @@ static int cmd_md(cproc_t cp, char **arg) static int cmd_mw(cproc_t cp, char **arg) { device_t dev = cproc_device(cp); + stab_t stab = cproc_stab(cp); char *off_text = get_arg(arg); char *byte_text; int offset = 0; @@ -111,7 +113,7 @@ static int cmd_mw(cproc_t cp, char **arg) return -1; } - if (expr_eval(off_text, &offset) < 0) { + if (expr_eval(stab, off_text, &offset) < 0) { fprintf(stderr, "md: can't parse offset: %s\n", off_text); return -1; } @@ -178,12 +180,13 @@ static int cmd_step(cproc_t cp, char **arg) static int cmd_run(cproc_t cp, char **arg) { device_t dev = cproc_device(cp); + stab_t stab = cproc_stab(cp); char *bp_text = get_arg(arg); int bp_addr; device_status_t status; if (bp_text) { - if (expr_eval(bp_text, &bp_addr) < 0) { + if (expr_eval(stab, bp_text, &bp_addr) < 0) { fprintf(stderr, "run: can't parse breakpoint: %s\n", bp_text); return -1; @@ -222,6 +225,7 @@ static int cmd_run(cproc_t cp, char **arg) static int cmd_set(cproc_t cp, char **arg) { device_t dev = cproc_device(cp); + stab_t stab = cproc_stab(cp); char *reg_text = get_arg(arg); char *val_text = get_arg(arg); int reg; @@ -237,7 +241,7 @@ static int cmd_set(cproc_t cp, char **arg) reg_text++; reg = atoi(reg_text); - if (expr_eval(val_text, &value) < 0) { + if (expr_eval(stab, val_text, &value) < 0) { fprintf(stderr, "set: can't parse value: %s\n", val_text); return -1; } @@ -260,6 +264,7 @@ static int cmd_set(cproc_t cp, char **arg) static int cmd_dis(cproc_t cp, char **arg) { device_t dev = cproc_device(cp); + stab_t stab = cproc_stab(cp); char *off_text = get_arg(arg); char *len_text = get_arg(arg); int offset = 0; @@ -271,13 +276,13 @@ static int cmd_dis(cproc_t cp, char **arg) return -1; } - if (expr_eval(off_text, &offset) < 0) { + if (expr_eval(stab, off_text, &offset) < 0) { fprintf(stderr, "dis: can't parse offset: %s\n", off_text); return -1; } if (len_text) { - if (expr_eval(len_text, &length) < 0) { + if (expr_eval(stab, len_text, &length) < 0) { fprintf(stderr, "dis: can't parse length: %s\n", len_text); return -1; @@ -384,6 +389,7 @@ static int hexout_feed(struct hexout_data *hexout, static int cmd_hexout(cproc_t cp, char **arg) { device_t dev = cproc_device(cp); + stab_t stab = cproc_stab(cp); char *off_text = get_arg(arg); char *len_text = get_arg(arg); char *filename = *arg; @@ -396,8 +402,8 @@ static int cmd_hexout(cproc_t cp, char **arg) return -1; } - if (expr_eval(off_text, &off) < 0 || - expr_eval(len_text, &length) < 0) + if (expr_eval(stab, off_text, &off) < 0 || + expr_eval(stab, len_text, &length) < 0) return -1; if (hexout_start(&hexout, filename) < 0) @@ -522,6 +528,7 @@ static int prog_feed(void *user_data, static int cmd_prog(cproc_t cp, char **arg) { device_t dev = cproc_device(cp); + stab_t stab = cproc_stab(cp); FILE *in; int result = 0; struct prog_data prog; @@ -544,8 +551,8 @@ static int cmd_prog(cproc_t cp, char **arg) if (elf32_check(in)) { result = elf32_extract(in, prog_feed, &prog); - stab_clear(); - elf32_syms(in, stab_set); + stab_clear(stab); + elf32_syms(in, stab); } else if (ihex_check(in)) { result = ihex_extract(in, prog_feed, &prog); } else { diff --git a/elf32.c b/elf32.c index a68c90a..7a867eb 100644 --- a/elf32.c +++ b/elf32.c @@ -263,7 +263,7 @@ static int syms_load_strings(struct elf32_info *info, FILE *in, Elf32_Shdr *s) #define N_SYMS 128 static int syms_load_syms(struct elf32_info *info, FILE *in, - Elf32_Shdr *s, symfunc_t cb) + Elf32_Shdr *s, stab_t stab) { Elf32_Sym syms[N_SYMS]; int len = s->sh_size / sizeof(syms[0]); @@ -297,7 +297,8 @@ static int syms_load_syms(struct elf32_info *info, FILE *in, return -1; } - if (cb(info->string_tab + y->st_name, y->st_value) < 0) + if (stab_set(stab, info->string_tab + y->st_name, + y->st_value) < 0) return -1; } @@ -307,7 +308,7 @@ static int syms_load_syms(struct elf32_info *info, FILE *in, return 0; } -int elf32_syms(FILE *in, symfunc_t cb) +int elf32_syms(FILE *in, stab_t stab) { struct elf32_info info; Elf32_Shdr *s; @@ -328,7 +329,7 @@ int elf32_syms(FILE *in, symfunc_t cb) } if (syms_load_strings(&info, in, &info.file_shdrs[s->sh_link]) < 0 || - syms_load_syms(&info, in, s, cb) < 0) + syms_load_syms(&info, in, s, stab) < 0) ret = -1; if (info.string_tab) diff --git a/expr.c b/expr.c index 766c785..a193b60 100644 --- a/expr.c +++ b/expr.c @@ -40,7 +40,8 @@ struct addr_exp_state { int op_stack_size; }; -static int addr_exp_data(struct addr_exp_state *s, const char *text) +static int addr_exp_data(stab_t stab, + struct addr_exp_state *s, const char *text) { int value; @@ -54,7 +55,7 @@ static int addr_exp_data(struct addr_exp_state *s, const char *text) value = strtoul(text + 2, NULL, 16); else if (isdigit(*text)) value = atoi(text); - else if (stab_get(text, &value) < 0) { + else if (stab_get(stab, text, &value) < 0) { fprintf(stderr, "can't parse token: %s\n", text); return -1; } @@ -225,7 +226,7 @@ static int addr_exp_finish(struct addr_exp_state *s, int *ret) return 0; } -int expr_eval(const char *text, int *addr) +int expr_eval(stab_t stab, const char *text, int *addr) { const char *text_save = text; int last_cc = 1; @@ -263,7 +264,7 @@ int expr_eval(const char *text, int *addr) token_buf[token_len] = 0; token_len = 0; - if (addr_exp_data(&s, token_buf) < 0) + if (addr_exp_data(stab, &s, token_buf) < 0) goto fail; } diff --git a/expr.h b/expr.h index d157f75..e9b56fb 100644 --- a/expr.h +++ b/expr.h @@ -20,10 +20,11 @@ #define EXPR_H_ #include +#include "stab.h" /* Parse an address expression, storing the result in the integer * pointed to. Returns 0 if parsed successfully, -1 if not. */ -int expr_eval(const char *text, int *value); +int expr_eval(stab_t stab, const char *text, int *value); #endif diff --git a/main.c b/main.c index fabcffa..43cc1c5 100644 --- a/main.c +++ b/main.c @@ -41,12 +41,13 @@ #include "uif.h" #include "rf2500.h" -static void io_prefix(const char *prefix, u_int16_t pc, +static void io_prefix(stab_t stab, + const char *prefix, u_int16_t pc, u_int16_t addr, int is_byte) { char name[64]; - if (!stab_nearest(pc, name, sizeof(name), &pc)) { + if (!stab_nearest(stab, pc, name, sizeof(name), &pc)) { printf("%s", name); if (pc) printf("+0x%x", pc); @@ -55,7 +56,7 @@ static void io_prefix(const char *prefix, u_int16_t pc, } printf(": IO %s.%c: 0x%04x", prefix, is_byte ? 'B' : 'W', addr); - if (!stab_nearest(addr, name, sizeof(name), &addr)) { + if (!stab_nearest(stab, addr, name, sizeof(name), &addr)) { printf(" (%s", name); if (addr) printf("+0x%x", addr); @@ -66,7 +67,9 @@ static void io_prefix(const char *prefix, u_int16_t pc, static int fetch_io(void *user_data, u_int16_t pc, u_int16_t addr, int is_byte, u_int16_t *data_ret) { - io_prefix("READ", pc, addr, is_byte); + stab_t stab = (stab_t)user_data; + + io_prefix(stab, "READ", pc, addr, is_byte); for (;;) { char text[128]; @@ -88,7 +91,7 @@ static int fetch_io(void *user_data, u_int16_t pc, if (!len) return 0; - if (!expr_eval(text, &data)) { + if (!expr_eval(stab, text, &data)) { if (data_ret) *data_ret = data; return 0; @@ -101,7 +104,9 @@ static int fetch_io(void *user_data, u_int16_t pc, static void store_io(void *user_data, u_int16_t pc, u_int16_t addr, int is_byte, u_int16_t data) { - io_prefix("WRITE", pc, addr, is_byte); + stab_t stab = (stab_t)user_data; + + io_prefix(stab, "WRITE", pc, addr, is_byte); if (is_byte) printf(" => 0x%02x\n", data & 0xff); @@ -231,14 +236,15 @@ static int parse_cmdline_args(int argc, char **argv, return 0; } -device_t setup_device(const struct cmdline_args *args) +device_t setup_device(const struct cmdline_args *args, + stab_t stab) { device_t msp430_dev = NULL; transport_t trans = NULL; /* Open a device */ if (args->mode == MODE_SIM) { - msp430_dev = sim_open(fetch_io, store_io, NULL); + msp430_dev = sim_open(fetch_io, store_io, stab); } else if (args->mode == MODE_UIF_BSL) { msp430_dev = bsl_open(args->bsl_device); } else if (args->mode == MODE_RF2500 || args->mode == MODE_UIF) { @@ -273,15 +279,24 @@ device_t setup_device(const struct cmdline_args *args) cproc_t setup_cproc(const struct cmdline_args *args) { - device_t msp430_dev = setup_device(args); + device_t msp430_dev; + stab_t stab; cproc_t cp; - if (!msp430_dev) + stab = stab_new(); + if (!stab) return NULL; - cp = cproc_new(msp430_dev); + msp430_dev = setup_device(args, stab); + if (!msp430_dev) { + stab_destroy(stab); + return NULL; + } + + cp = cproc_new(msp430_dev, stab); if (!cp) { msp430_dev->destroy(msp430_dev); + stab_destroy(stab); return NULL; } @@ -314,14 +329,9 @@ int main(int argc, char **argv) ctrlc_init(); - if (stab_init() < 0) - return -1; - cp = setup_cproc(&args); - if (!cp) { - stab_exit(); + if (!cp) return -1; - } if (!args.no_rc) process_rc_file(cp); @@ -339,7 +349,6 @@ int main(int argc, char **argv) } cproc_destroy(cp); - stab_exit(); return ret; } diff --git a/rtools.c b/rtools.c index c5b7097..033ac13 100644 --- a/rtools.c +++ b/rtools.c @@ -45,7 +45,7 @@ struct isearch_query { struct msp430_instruction insn; }; -static int isearch_opcode(const char *term, char **arg, +static int isearch_opcode(cproc_t cp, const char *term, char **arg, struct isearch_query *q) { const char *opname = get_arg(arg); @@ -70,7 +70,7 @@ static int isearch_opcode(const char *term, char **arg, return 0; } -static int isearch_bw(const char *term, char **arg, +static int isearch_bw(cproc_t cp, const char *term, char **arg, struct isearch_query *q) { if (q->flags & ISEARCH_BW) { @@ -83,7 +83,7 @@ static int isearch_bw(const char *term, char **arg, return 0; } -static int isearch_type(const char *term, char **arg, +static int isearch_type(cproc_t cp, const char *term, char **arg, struct isearch_query *q) { if (q->flags & ISEARCH_TYPE) { @@ -115,7 +115,7 @@ static int isearch_type(const char *term, char **arg, return 0; } -static int isearch_addr(const char *term, char **arg, +static int isearch_addr(cproc_t cp, const char *term, char **arg, struct isearch_query *q) { int which = toupper(*term) == 'S' ? @@ -134,7 +134,7 @@ static int isearch_addr(const char *term, char **arg, return -1; } - if (expr_eval(addr_text, &addr) < 0) + if (expr_eval(cproc_stab(cp), addr_text, &addr) < 0) return -1; q->flags |= which; @@ -146,7 +146,7 @@ static int isearch_addr(const char *term, char **arg, return 0; } -static int isearch_reg(const char *term, char **arg, +static int isearch_reg(cproc_t cp, const char *term, char **arg, struct isearch_query *q) { int which = toupper(*term) == 'S' ? @@ -178,7 +178,7 @@ static int isearch_reg(const char *term, char **arg, return 0; } -static int isearch_mode(const char *term, char **arg, +static int isearch_mode(cproc_t cp, const char *term, char **arg, struct isearch_query *q) { int which = toupper(*term) == 'S' ? @@ -360,7 +360,8 @@ static int cmd_isearch(cproc_t cp, char **arg) { const static struct { const char *name; - int (*func)(const char *term, char **arg, + int (*func)(cproc_t cp, + const char *term, char **arg, struct isearch_query *q); } term_handlers[] = { {"opcode", isearch_opcode}, @@ -377,6 +378,7 @@ static int cmd_isearch(cproc_t cp, char **arg) {"dstmode", isearch_mode} }; + stab_t stab = cproc_stab(cp); struct isearch_query q; const char *addr_text; const char *len_text; @@ -391,8 +393,8 @@ static int cmd_isearch(cproc_t cp, char **arg) return -1; } - if (expr_eval(addr_text, &addr) < 0 || - expr_eval(len_text, &len) < 0) + if (expr_eval(stab, addr_text, &addr) < 0 || + expr_eval(stab, len_text, &len) < 0) return -1; q.flags = 0; @@ -405,7 +407,8 @@ static int cmd_isearch(cproc_t cp, char **arg) for (i = 0; i < ARRAY_LEN(term_handlers); i++) if (!strcasecmp(term_handlers[i].name, term)) { - if (term_handlers[i].func(term, arg, &q) < 0) + if (term_handlers[i].func(cp, term, arg, + &q) < 0) return -1; break; } diff --git a/stab.c b/stab.c index ebf2c41..b1ef57c 100644 --- a/stab.c +++ b/stab.c @@ -28,11 +28,17 @@ #include "stab.h" #include "util.h" +/************************************************************************ + * B+Tree definitions + */ + struct sym_key { char name[64]; }; -static const struct sym_key sym_key_zero; +static const struct sym_key sym_key_zero = { + .name = {0} +}; static int sym_key_compare(const void *left, const void *right) { @@ -56,7 +62,10 @@ struct addr_key { char name[64]; }; -static const struct addr_key addr_key_zero; +static const struct addr_key addr_key_zero = { + .addr = 0, + .name = {0} +}; static int addr_key_compare(const void *left, const void *right) { @@ -100,16 +109,22 @@ static const struct btree_def addr_table_def = { .data_size = 0 }; -static btree_t sym_table; -static btree_t addr_table; +/************************************************************************ + * Symbol table methods + */ -void stab_clear(void) +struct stab { + btree_t sym; + btree_t addr; +}; + +void stab_clear(stab_t st) { - btree_clear(sym_table); - btree_clear(addr_table); + btree_clear(st->sym); + btree_clear(st->addr); } -int stab_set(const char *name, int value) +int stab_set(stab_t st, const char *name, int value) { struct sym_key skey; struct addr_key akey; @@ -121,15 +136,15 @@ int stab_set(const char *name, int value) /* Look for an old address first, and delete the reverse mapping * if it's there. */ - if (!btree_get(sym_table, &skey, &old_addr)) { + if (!btree_get(st->sym, &skey, &old_addr)) { addr_key_init(&akey, old_addr, skey.name); - btree_delete(addr_table, &akey); + btree_delete(st->addr, &akey); } /* Put the new mapping into both tables */ addr_key_init(&akey, addr, name); - if (btree_put(addr_table, &akey, NULL) < 0 || - btree_put(sym_table, &skey, &addr) < 0) { + if (btree_put(st->addr, &akey, NULL) < 0 || + btree_put(st->sym, &skey, &addr) < 0) { fprintf(stderr, "stab: can't set %s = 0x%04x\n", name, addr); return -1; } @@ -137,7 +152,7 @@ int stab_set(const char *name, int value) return 0; } -int stab_nearest(u_int16_t addr, char *ret_name, int max_len, +int stab_nearest(stab_t st, u_int16_t addr, char *ret_name, int max_len, u_int16_t *ret_offset) { struct addr_key akey; @@ -148,7 +163,7 @@ int stab_nearest(u_int16_t addr, char *ret_name, int max_len, akey.name[i] = 0xff; akey.name[sizeof(akey.name) - 1] = 0xff; - if (!btree_select(addr_table, &akey, BTREE_LE, &akey, NULL)) { + if (!btree_select(st->addr, &akey, BTREE_LE, &akey, NULL)) { strncpy(ret_name, akey.name, max_len); ret_name[max_len - 1] = 0; *ret_offset = addr - akey.addr; @@ -158,73 +173,83 @@ int stab_nearest(u_int16_t addr, char *ret_name, int max_len, return -1; } -int stab_get(const char *name, int *value) +int stab_get(stab_t st, const char *name, int *value) { struct sym_key skey; u_int16_t addr; sym_key_init(&skey, name); - if (btree_get(sym_table, &skey, &addr)) + if (btree_get(st->sym, &skey, &addr)) return -1; *value = addr; return 0; } -int stab_del(const char *name) +int stab_del(stab_t st, const char *name) { struct sym_key skey; u_int16_t value; struct addr_key akey; sym_key_init(&skey, name); - if (btree_get(sym_table, &skey, &value)) + if (btree_get(st->sym, &skey, &value)) return -1; addr_key_init(&akey, value, name); - btree_delete(sym_table, &skey); - btree_delete(addr_table, &akey); + btree_delete(st->sym, &skey); + btree_delete(st->addr, &akey); return 0; } -int stab_enum(stab_callback_t cb, void *user_data) +int stab_enum(stab_t st, stab_callback_t cb, void *user_data) { int ret; struct addr_key akey; - ret = btree_select(addr_table, NULL, BTREE_FIRST, + ret = btree_select(st->addr, NULL, BTREE_FIRST, &akey, NULL); while (!ret) { if (cb(user_data, akey.name, akey.addr) < 0) return -1; - ret = btree_select(addr_table, NULL, BTREE_NEXT, + ret = btree_select(st->addr, NULL, BTREE_NEXT, &akey, NULL); } return 0; } -int stab_init(void) +stab_t stab_new(void) { - sym_table = btree_alloc(&sym_table_def); - if (!sym_table) { + stab_t st = malloc(sizeof(*st)); + + if (!st) { + perror("stab: failed to allocate memory\n"); + return NULL; + } + + st->sym = btree_alloc(&sym_table_def); + if (!st->sym) { fprintf(stderr, "stab: failed to allocate symbol table\n"); - return -1; + free(st); + return NULL; } - addr_table = btree_alloc(&addr_table_def); - if (!addr_table) { + st->addr = btree_alloc(&addr_table_def); + if (!st->addr) { fprintf(stderr, "stab: failed to allocate address table\n"); - btree_free(sym_table); - return -1; + btree_free(st->sym); + free(st); + return NULL; } - return 0; + return st; } -void stab_exit(void) +void stab_destroy(stab_t st) { - btree_free(sym_table); - btree_free(addr_table); + btree_free(st->sym); + btree_free(st->addr); + free(st); } diff --git a/stab.h b/stab.h index c363b95..5cda4e8 100644 --- a/stab.h +++ b/stab.h @@ -21,40 +21,43 @@ #include -/* Initialise/destroy the symbol table manager. If successful, init returns - * 0, or -1 on error. +struct stab; +typedef struct stab *stab_t; + +/* Create/destroy a symbol table. The constructor returns NULL if it + * was unable to allocate memory for the table. */ -int stab_init(void); -void stab_exit(void); +stab_t stab_new(void); +void stab_destroy(stab_t st); /* Reset the symbol table (delete all symbols) */ -void stab_clear(void); +void stab_clear(stab_t st); /* Set a symbol in the table. Returns 0 on success, or -1 on error. */ -int stab_set(const char *name, int value); +int stab_set(stab_t st, const char *name, int value); /* Take an address and find the nearest symbol and offset (always * non-negative). * * Returns 0 if found, 1 otherwise. */ -int stab_nearest(u_int16_t addr, char *ret_name, int max_len, +int stab_nearest(stab_t st, u_int16_t addr, char *ret_name, int max_len, u_int16_t *ret_offset); /* Retrieve the value of a symbol. Returns 0 on success or -1 if the symbol * doesn't exist. */ -int stab_get(const char *name, int *value); +int stab_get(stab_t st, const char *name, int *value); /* Delete a symbol table entry. Returns 0 on success or -1 if the symbol * doesn't exist. */ -int stab_del(const char *name); +int stab_del(stab_t st, const char *name); /* Enumerate all symbols in the table */ typedef int (*stab_callback_t)(void *user_data, const char *name, u_int16_t value); -int stab_enum(stab_callback_t cb, void *user_data); +int stab_enum(stab_t st, stab_callback_t cb, void *user_data); #endif diff --git a/sym.c b/sym.c index 2fbe607..c0b38a6 100644 --- a/sym.c +++ b/sym.c @@ -32,17 +32,18 @@ static int cmd_eval(cproc_t cp, char **arg) { + stab_t stab = cproc_stab(cp); int addr; u_int16_t offset; char name[64]; - if (expr_eval(*arg, &addr) < 0) { + if (expr_eval(stab, *arg, &addr) < 0) { fprintf(stderr, "=: can't parse: %s\n", *arg); return -1; } printf("0x%04x", addr); - if (!stab_nearest(addr, name, sizeof(name), &offset)) { + if (!stab_nearest(stab, addr, name, sizeof(name), &offset)) { printf(" = %s", name); if (offset) printf("+0x%x", offset); @@ -54,6 +55,7 @@ static int cmd_eval(cproc_t cp, char **arg) static int cmd_sym_load_add(cproc_t cp, int clear, char **arg) { + stab_t stab = cproc_stab(cp); FILE *in; int result = 0; @@ -67,12 +69,12 @@ static int cmd_sym_load_add(cproc_t cp, int clear, char **arg) } if (clear) - stab_clear(); + stab_clear(stab); if (elf32_check(in)) - result = elf32_syms(in, stab_set); + result = elf32_syms(in, stab); else if (symmap_check(in)) - result = symmap_syms(in, stab_set); + result = symmap_syms(in, stab); else fprintf(stderr, "sym: %s: unknown file type\n", *arg); @@ -100,6 +102,7 @@ static int savemap_cb(void *user_data, const char *name, u_int16_t value) static int cmd_sym_savemap(cproc_t cp, char **arg) { + stab_t stab = cproc_stab(cp); FILE *savemap_out; char *fname = get_arg(arg); @@ -115,7 +118,7 @@ static int cmd_sym_savemap(cproc_t cp, char **arg) return -1; } - if (stab_enum(savemap_cb, savemap_out) < 0) { + if (stab_enum(stab, savemap_cb, savemap_out) < 0) { fclose(savemap_out); return -1; } @@ -147,11 +150,12 @@ static int find_sym(void *user_data, const char *name, u_int16_t value) static int cmd_sym_find(cproc_t cp, char **arg) { + stab_t stab = cproc_stab(cp); regex_t find_preg; char *expr = get_arg(arg); if (!expr) { - stab_enum(print_sym, NULL); + stab_enum(stab, print_sym, NULL); return 0; } @@ -160,7 +164,7 @@ static int cmd_sym_find(cproc_t cp, char **arg) return -1; } - stab_enum(find_sym, &find_preg); + stab_enum(stab, find_sym, &find_preg); regfree(&find_preg); return 0; } @@ -175,7 +179,8 @@ struct rename_data { regex_t preg; }; -static int renames_do(struct rename_data *rename, const char *replace) +static int renames_do(stab_t stab, + struct rename_data *rename, const char *replace) { int i; int count = 0; @@ -197,13 +202,13 @@ static int renames_do(struct rename_data *rename, const char *replace) printf("%s -> %s\n", r->old_name, new_name); - if (stab_get(r->old_name, &value) < 0) { + if (stab_get(stab, r->old_name, &value) < 0) { fprintf(stderr, "sym: warning: " "symbol missing: %s\n", r->old_name); } else { - stab_del(r->old_name); - if (stab_set(new_name, value) < 0) { + stab_del(stab, r->old_name); + if (stab_set(stab, new_name, value) < 0) { fprintf(stderr, "sym: warning: " "failed to set new name: %s\n", new_name); @@ -243,6 +248,7 @@ static int cmd_sym_rename(cproc_t cp, char **arg) const char *replace = get_arg(arg); int ret; struct rename_data rename; + stab_t stab = cproc_stab(cp); if (!(expr && replace)) { fprintf(stderr, "sym: expected pattern and replacement\n"); @@ -256,7 +262,7 @@ static int cmd_sym_rename(cproc_t cp, char **arg) vector_init(&rename.list, sizeof(struct rename_record)); - if (stab_enum(find_renames, &rename) < 0) { + if (stab_enum(stab, find_renames, &rename) < 0) { fprintf(stderr, "sym: rename failed\n"); regfree(&rename.preg); vector_destroy(&rename.list); @@ -264,7 +270,7 @@ static int cmd_sym_rename(cproc_t cp, char **arg) } regfree(&rename.preg); - ret = renames_do(&rename, replace); + ret = renames_do(stab, &rename, replace); vector_destroy(&rename.list); if (ret > 0) @@ -275,6 +281,7 @@ static int cmd_sym_rename(cproc_t cp, char **arg) static int cmd_sym_del(cproc_t cp, char **arg) { + stab_t stab = cproc_stab(cp); char *name = get_arg(arg); if (!name) { @@ -283,7 +290,7 @@ static int cmd_sym_del(cproc_t cp, char **arg) return -1; } - if (stab_del(name) < 0) { + if (stab_del(stab, name) < 0) { fprintf(stderr, "sym: can't delete nonexistent symbol: %s\n", name); return -1; @@ -295,6 +302,7 @@ static int cmd_sym_del(cproc_t cp, char **arg) static int cmd_sym(cproc_t cp, char **arg) { + stab_t stab = cproc_stab(cp); char *subcmd = get_arg(arg); if (!subcmd) { @@ -306,7 +314,7 @@ static int cmd_sym(cproc_t cp, char **arg) if (!strcasecmp(subcmd, "clear")) { if (cproc_prompt_abort(cp, CPROC_MODIFY_SYMS)) return 0; - stab_clear(); + stab_clear(stab); cproc_unmodify(cp, CPROC_MODIFY_SYMS); return 0; } @@ -322,13 +330,13 @@ static int cmd_sym(cproc_t cp, char **arg) return -1; } - if (expr_eval(val_text, &value) < 0) { + if (expr_eval(stab, val_text, &value) < 0) { fprintf(stderr, "sym: can't parse value: %s\n", val_text); return -1; } - if (stab_set(name, value) < 0) + if (stab_set(stab, name, value) < 0) return -1; cproc_modify(cp, CPROC_MODIFY_SYMS); diff --git a/symmap.c b/symmap.c index 15eca68..ff77273 100644 --- a/symmap.c +++ b/symmap.c @@ -45,7 +45,7 @@ int symmap_check(FILE *in) return spc_count >= 2; } -int symmap_syms(FILE *in, symfunc_t cb) +int symmap_syms(FILE *in, stab_t stab) { rewind(in); char buf[128]; @@ -60,7 +60,7 @@ int symmap_syms(FILE *in, symfunc_t cb) if (addr && name) { int addr_val = strtoul(addr, NULL, 16); - if (cb(name, addr_val) < 0) + if (stab_set(stab, name, addr_val) < 0) return -1; } }