Symbol table is an object.

This commit is contained in:
Daniel Beer 2010-05-01 18:34:43 +12:00
parent 2794165dee
commit ca3e5dd645
14 changed files with 204 additions and 134 deletions

View File

@ -22,13 +22,12 @@
#include <stdio.h>
#include <sys/types.h>
#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

17
cproc.c
View File

@ -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)
{

View File

@ -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).

View File

@ -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);

View File

@ -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 {

View File

@ -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)

9
expr.c
View File

@ -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;
}

3
expr.h
View File

@ -20,10 +20,11 @@
#define EXPR_H_
#include <sys/types.h>
#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

45
main.c
View File

@ -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;
}

View File

@ -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;
}

95
stab.c
View File

@ -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);
}

23
stab.h
View File

@ -21,40 +21,43 @@
#include <sys/types.h>
/* 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

44
sym.c
View File

@ -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);

View File

@ -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;
}
}