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 <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include "stab.h"
/* Callback for binary image data */ /* Callback for binary image data */
typedef int (*imgfunc_t)(void *user_data, typedef int (*imgfunc_t)(void *user_data,
u_int16_t addr, const u_int8_t *data, int len); 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 */ /* Intel HEX file support */
int ihex_check(FILE *in); int ihex_check(FILE *in);
int ihex_extract(FILE *in, imgfunc_t cb, void *user_data); 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 */ /* ELF32 file support */
int elf32_check(FILE *in); int elf32_check(FILE *in);
int elf32_extract(FILE *in, imgfunc_t cb, void *user_data); 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 */ /* *.map file support */
int symmap_check(FILE *in); int symmap_check(FILE *in);
int symmap_syms(FILE *in, symfunc_t cb); int symmap_syms(FILE *in, stab_t stab);
#endif #endif

17
cproc.c
View File

@ -43,6 +43,7 @@ struct cproc {
int in_reader_loop; int in_reader_loop;
device_t device; device_t device;
stab_t stab;
}; };
static struct cproc_option *find_option(cproc_t cp, const char *name) 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; 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) { switch (o->type) {
case CPROC_OPTION_BOOL: case CPROC_OPTION_BOOL:
@ -208,7 +210,7 @@ static int parse_option(struct cproc_option *o, const char *word)
break; break;
case CPROC_OPTION_NUMERIC: case CPROC_OPTION_NUMERIC:
return expr_eval(word, &o->data.numeric); return expr_eval(stab, word, &o->data.numeric);
case CPROC_OPTION_STRING: case CPROC_OPTION_STRING:
strncpy(o->data.text, word, sizeof(o->data.text)); 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 (**arg) {
if (parse_option(opt, *arg) < 0) { if (parse_option(cp->stab, opt, *arg) < 0) {
fprintf(stderr, "opt: can't parse option: %s\n", fprintf(stderr, "opt: can't parse option: %s\n",
*arg); *arg);
return -1; 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)); cproc_t cp = malloc(sizeof(*cp));
@ -332,6 +334,7 @@ cproc_t cproc_new(device_t dev)
memset(cp, 0, sizeof(*cp)); memset(cp, 0, sizeof(*cp));
cp->device = dev; cp->device = dev;
cp->stab = st;
vector_init(&cp->command_list, sizeof(struct cproc_command)); vector_init(&cp->command_list, sizeof(struct cproc_command));
vector_init(&cp->option_list, sizeof(struct cproc_option)); vector_init(&cp->option_list, sizeof(struct cproc_option));
@ -354,6 +357,7 @@ void cproc_destroy(cproc_t cp)
cp->device->destroy(cp->device); cp->device->destroy(cp->device);
vector_destroy(&cp->command_list); vector_destroy(&cp->command_list);
vector_destroy(&cp->option_list); vector_destroy(&cp->option_list);
stab_destroy(cp->stab);
free(cp); free(cp);
} }
@ -362,6 +366,11 @@ device_t cproc_device(cproc_t cp)
return cp->device; 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 cproc_register_commands(cproc_t cp, const struct cproc_command *cmd,
int count) int count)
{ {

View File

@ -20,6 +20,7 @@
#define CPROC_H_ #define CPROC_H_
#include "device.h" #include "device.h"
#include "stab.h"
/* Command processor. /* Command processor.
* *
@ -89,11 +90,12 @@ struct cproc_option {
* has been given. When you destroy a command processor, the device is * has been given. When you destroy a command processor, the device is
* also destroyed. * 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); 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); device_t cproc_device(cproc_t cp);
stab_t cproc_stab(cproc_t cp);
/* Register commands and options with the command processor. These functions /* Register commands and options with the command processor. These functions
* return 0 on success or -1 if an error occurs (failure to allocate memory). * return 0 on success or -1 if an error occurs (failure to allocate memory).

View File

@ -24,7 +24,7 @@
#include "stab.h" #include "stab.h"
#include "util.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) msp430_amode_t amode, u_int16_t addr)
{ {
char name[64]; char name[64];
@ -54,7 +54,7 @@ static int format_addr(char *buf, int max_len,
if ((!numeric || if ((!numeric ||
(addr >= 0x200 && addr < 0xfff0)) && (addr >= 0x200 && addr < 0xfff0)) &&
!stab_nearest(addr, name, sizeof(name), &offset) && !stab_nearest(stab, addr, name, sizeof(name), &offset) &&
!offset) !offset)
return snprintf(buf, max_len, return snprintf(buf, max_len,
"%s\x1b[1m%s\x1b[0m", prefix, name); "%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. * 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_amode_t amode, u_int16_t addr,
msp430_reg_t reg) msp430_reg_t reg)
{ {
int len = 0; 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); len += format_reg(buf + len, max_len - len, amode, reg);
return len; return len;
} }
/* Write assembly language for the instruction to this buffer */ /* 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) const struct msp430_instruction *insn)
{ {
int len; int len;
@ -144,7 +144,7 @@ static int dis_format(char *buf, int max_len,
/* Source operand */ /* Source operand */
if (insn->itype == MSP430_ITYPE_DOUBLE) { if (insn->itype == MSP430_ITYPE_DOUBLE) {
len = format_operand(buf + total, len = format_operand(stab, buf + total,
max_len - total, max_len - total,
insn->src_mode, insn->src_mode,
insn->src_addr, insn->src_addr,
@ -166,7 +166,7 @@ static int dis_format(char *buf, int max_len,
/* Destination operand */ /* Destination operand */
if (insn->itype != MSP430_ITYPE_NOARG) if (insn->itype != MSP430_ITYPE_NOARG)
total += format_operand(buf + total, total += format_operand(stab, buf + total,
max_len - total, max_len - total,
insn->dst_mode, insn->dst_mode,
insn->dst_addr, insn->dst_addr,
@ -185,6 +185,7 @@ static int dis_format(char *buf, int max_len,
void cproc_disassemble(cproc_t cp, void cproc_disassemble(cproc_t cp,
u_int16_t offset, const u_int8_t *data, int length) u_int16_t offset, const u_int8_t *data, int length)
{ {
stab_t stab = cproc_stab(cp);
int first_line = 1; int first_line = 1;
while (length) { while (length) {
@ -197,7 +198,8 @@ void cproc_disassemble(cproc_t cp,
char buf[256]; char buf[256];
int len = 0; int len = 0;
if (!stab_nearest(offset, obname, sizeof(obname), &oboff)) { if (!stab_nearest(stab, offset, obname, sizeof(obname),
&oboff)) {
if (!oboff) if (!oboff)
cproc_printf(cp, "\x1b[m%s:\x1b[0m", obname); cproc_printf(cp, "\x1b[m%s:\x1b[0m", obname);
else if (first_line) else if (first_line)
@ -226,7 +228,7 @@ void cproc_disassemble(cproc_t cp,
} }
if (retval >= 0) if (retval >= 0)
len += dis_format(buf + len, sizeof(buf) - len, len += dis_format(stab, buf + len, sizeof(buf) - len,
&insn); &insn);
cproc_printf(cp, "%s", buf); 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) static int cmd_md(cproc_t cp, char **arg)
{ {
stab_t stab = cproc_stab(cp);
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *len_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; 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); fprintf(stderr, "md: can't parse offset: %s\n", off_text);
return -1; return -1;
} }
if (len_text) { 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", fprintf(stderr, "md: can't parse length: %s\n",
len_text); len_text);
return -1; return -1;
@ -100,6 +101,7 @@ static int cmd_md(cproc_t cp, char **arg)
static int cmd_mw(cproc_t cp, char **arg) static int cmd_mw(cproc_t cp, char **arg)
{ {
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp);
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *byte_text; char *byte_text;
int offset = 0; int offset = 0;
@ -111,7 +113,7 @@ static int cmd_mw(cproc_t cp, char **arg)
return -1; 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); fprintf(stderr, "md: can't parse offset: %s\n", off_text);
return -1; return -1;
} }
@ -178,12 +180,13 @@ static int cmd_step(cproc_t cp, char **arg)
static int cmd_run(cproc_t cp, char **arg) static int cmd_run(cproc_t cp, char **arg)
{ {
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp);
char *bp_text = get_arg(arg); char *bp_text = get_arg(arg);
int bp_addr; int bp_addr;
device_status_t status; device_status_t status;
if (bp_text) { 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", fprintf(stderr, "run: can't parse breakpoint: %s\n",
bp_text); bp_text);
return -1; return -1;
@ -222,6 +225,7 @@ static int cmd_run(cproc_t cp, char **arg)
static int cmd_set(cproc_t cp, char **arg) static int cmd_set(cproc_t cp, char **arg)
{ {
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp);
char *reg_text = get_arg(arg); char *reg_text = get_arg(arg);
char *val_text = get_arg(arg); char *val_text = get_arg(arg);
int reg; int reg;
@ -237,7 +241,7 @@ static int cmd_set(cproc_t cp, char **arg)
reg_text++; reg_text++;
reg = atoi(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); fprintf(stderr, "set: can't parse value: %s\n", val_text);
return -1; return -1;
} }
@ -260,6 +264,7 @@ static int cmd_set(cproc_t cp, char **arg)
static int cmd_dis(cproc_t cp, char **arg) static int cmd_dis(cproc_t cp, char **arg)
{ {
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp);
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *len_text = get_arg(arg); char *len_text = get_arg(arg);
int offset = 0; int offset = 0;
@ -271,13 +276,13 @@ static int cmd_dis(cproc_t cp, char **arg)
return -1; 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); fprintf(stderr, "dis: can't parse offset: %s\n", off_text);
return -1; return -1;
} }
if (len_text) { 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", fprintf(stderr, "dis: can't parse length: %s\n",
len_text); len_text);
return -1; return -1;
@ -384,6 +389,7 @@ static int hexout_feed(struct hexout_data *hexout,
static int cmd_hexout(cproc_t cp, char **arg) static int cmd_hexout(cproc_t cp, char **arg)
{ {
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp);
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *len_text = get_arg(arg); char *len_text = get_arg(arg);
char *filename = *arg; char *filename = *arg;
@ -396,8 +402,8 @@ static int cmd_hexout(cproc_t cp, char **arg)
return -1; return -1;
} }
if (expr_eval(off_text, &off) < 0 || if (expr_eval(stab, off_text, &off) < 0 ||
expr_eval(len_text, &length) < 0) expr_eval(stab, len_text, &length) < 0)
return -1; return -1;
if (hexout_start(&hexout, filename) < 0) 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) static int cmd_prog(cproc_t cp, char **arg)
{ {
device_t dev = cproc_device(cp); device_t dev = cproc_device(cp);
stab_t stab = cproc_stab(cp);
FILE *in; FILE *in;
int result = 0; int result = 0;
struct prog_data prog; struct prog_data prog;
@ -544,8 +551,8 @@ static int cmd_prog(cproc_t cp, char **arg)
if (elf32_check(in)) { if (elf32_check(in)) {
result = elf32_extract(in, prog_feed, &prog); result = elf32_extract(in, prog_feed, &prog);
stab_clear(); stab_clear(stab);
elf32_syms(in, stab_set); elf32_syms(in, stab);
} else if (ihex_check(in)) { } else if (ihex_check(in)) {
result = ihex_extract(in, prog_feed, &prog); result = ihex_extract(in, prog_feed, &prog);
} else { } 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 #define N_SYMS 128
static int syms_load_syms(struct elf32_info *info, FILE *in, 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]; Elf32_Sym syms[N_SYMS];
int len = s->sh_size / sizeof(syms[0]); 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; 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; return -1;
} }
@ -307,7 +308,7 @@ static int syms_load_syms(struct elf32_info *info, FILE *in,
return 0; return 0;
} }
int elf32_syms(FILE *in, symfunc_t cb) int elf32_syms(FILE *in, stab_t stab)
{ {
struct elf32_info info; struct elf32_info info;
Elf32_Shdr *s; 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 || 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; ret = -1;
if (info.string_tab) if (info.string_tab)

9
expr.c
View File

@ -40,7 +40,8 @@ struct addr_exp_state {
int op_stack_size; 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; 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); value = strtoul(text + 2, NULL, 16);
else if (isdigit(*text)) else if (isdigit(*text))
value = atoi(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); fprintf(stderr, "can't parse token: %s\n", text);
return -1; return -1;
} }
@ -225,7 +226,7 @@ static int addr_exp_finish(struct addr_exp_state *s, int *ret)
return 0; 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; const char *text_save = text;
int last_cc = 1; int last_cc = 1;
@ -263,7 +264,7 @@ int expr_eval(const char *text, int *addr)
token_buf[token_len] = 0; token_buf[token_len] = 0;
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; goto fail;
} }

3
expr.h
View File

@ -20,10 +20,11 @@
#define EXPR_H_ #define EXPR_H_
#include <sys/types.h> #include <sys/types.h>
#include "stab.h"
/* Parse an address expression, storing the result in the integer /* Parse an address expression, storing the result in the integer
* pointed to. Returns 0 if parsed successfully, -1 if not. * 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 #endif

45
main.c
View File

@ -41,12 +41,13 @@
#include "uif.h" #include "uif.h"
#include "rf2500.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) u_int16_t addr, int is_byte)
{ {
char name[64]; char name[64];
if (!stab_nearest(pc, name, sizeof(name), &pc)) { if (!stab_nearest(stab, pc, name, sizeof(name), &pc)) {
printf("%s", name); printf("%s", name);
if (pc) if (pc)
printf("+0x%x", 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); 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); printf(" (%s", name);
if (addr) if (addr)
printf("+0x%x", 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, static int fetch_io(void *user_data, u_int16_t pc,
u_int16_t addr, int is_byte, u_int16_t *data_ret) 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 (;;) { for (;;) {
char text[128]; char text[128];
@ -88,7 +91,7 @@ static int fetch_io(void *user_data, u_int16_t pc,
if (!len) if (!len)
return 0; return 0;
if (!expr_eval(text, &data)) { if (!expr_eval(stab, text, &data)) {
if (data_ret) if (data_ret)
*data_ret = data; *data_ret = data;
return 0; 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, static void store_io(void *user_data, u_int16_t pc,
u_int16_t addr, int is_byte, u_int16_t data) 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) if (is_byte)
printf(" => 0x%02x\n", data & 0xff); printf(" => 0x%02x\n", data & 0xff);
@ -231,14 +236,15 @@ static int parse_cmdline_args(int argc, char **argv,
return 0; 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; device_t msp430_dev = NULL;
transport_t trans = NULL; transport_t trans = NULL;
/* Open a device */ /* Open a device */
if (args->mode == MODE_SIM) { 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) { } else if (args->mode == MODE_UIF_BSL) {
msp430_dev = bsl_open(args->bsl_device); msp430_dev = bsl_open(args->bsl_device);
} else if (args->mode == MODE_RF2500 || args->mode == MODE_UIF) { } 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) 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; cproc_t cp;
if (!msp430_dev) stab = stab_new();
if (!stab)
return NULL; 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) { if (!cp) {
msp430_dev->destroy(msp430_dev); msp430_dev->destroy(msp430_dev);
stab_destroy(stab);
return NULL; return NULL;
} }
@ -314,14 +329,9 @@ int main(int argc, char **argv)
ctrlc_init(); ctrlc_init();
if (stab_init() < 0)
return -1;
cp = setup_cproc(&args); cp = setup_cproc(&args);
if (!cp) { if (!cp)
stab_exit();
return -1; return -1;
}
if (!args.no_rc) if (!args.no_rc)
process_rc_file(cp); process_rc_file(cp);
@ -339,7 +349,6 @@ int main(int argc, char **argv)
} }
cproc_destroy(cp); cproc_destroy(cp);
stab_exit();
return ret; return ret;
} }

View File

@ -45,7 +45,7 @@ struct isearch_query {
struct msp430_instruction insn; 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) struct isearch_query *q)
{ {
const char *opname = get_arg(arg); const char *opname = get_arg(arg);
@ -70,7 +70,7 @@ static int isearch_opcode(const char *term, char **arg,
return 0; 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) struct isearch_query *q)
{ {
if (q->flags & ISEARCH_BW) { if (q->flags & ISEARCH_BW) {
@ -83,7 +83,7 @@ static int isearch_bw(const char *term, char **arg,
return 0; 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) struct isearch_query *q)
{ {
if (q->flags & ISEARCH_TYPE) { if (q->flags & ISEARCH_TYPE) {
@ -115,7 +115,7 @@ static int isearch_type(const char *term, char **arg,
return 0; 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) struct isearch_query *q)
{ {
int which = toupper(*term) == 'S' ? int which = toupper(*term) == 'S' ?
@ -134,7 +134,7 @@ static int isearch_addr(const char *term, char **arg,
return -1; return -1;
} }
if (expr_eval(addr_text, &addr) < 0) if (expr_eval(cproc_stab(cp), addr_text, &addr) < 0)
return -1; return -1;
q->flags |= which; q->flags |= which;
@ -146,7 +146,7 @@ static int isearch_addr(const char *term, char **arg,
return 0; 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) struct isearch_query *q)
{ {
int which = toupper(*term) == 'S' ? int which = toupper(*term) == 'S' ?
@ -178,7 +178,7 @@ static int isearch_reg(const char *term, char **arg,
return 0; 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) struct isearch_query *q)
{ {
int which = toupper(*term) == 'S' ? int which = toupper(*term) == 'S' ?
@ -360,7 +360,8 @@ static int cmd_isearch(cproc_t cp, char **arg)
{ {
const static struct { const static struct {
const char *name; const char *name;
int (*func)(const char *term, char **arg, int (*func)(cproc_t cp,
const char *term, char **arg,
struct isearch_query *q); struct isearch_query *q);
} term_handlers[] = { } term_handlers[] = {
{"opcode", isearch_opcode}, {"opcode", isearch_opcode},
@ -377,6 +378,7 @@ static int cmd_isearch(cproc_t cp, char **arg)
{"dstmode", isearch_mode} {"dstmode", isearch_mode}
}; };
stab_t stab = cproc_stab(cp);
struct isearch_query q; struct isearch_query q;
const char *addr_text; const char *addr_text;
const char *len_text; const char *len_text;
@ -391,8 +393,8 @@ static int cmd_isearch(cproc_t cp, char **arg)
return -1; return -1;
} }
if (expr_eval(addr_text, &addr) < 0 || if (expr_eval(stab, addr_text, &addr) < 0 ||
expr_eval(len_text, &len) < 0) expr_eval(stab, len_text, &len) < 0)
return -1; return -1;
q.flags = 0; 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++) for (i = 0; i < ARRAY_LEN(term_handlers); i++)
if (!strcasecmp(term_handlers[i].name, term)) { 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; return -1;
break; break;
} }

95
stab.c
View File

@ -28,11 +28,17 @@
#include "stab.h" #include "stab.h"
#include "util.h" #include "util.h"
/************************************************************************
* B+Tree definitions
*/
struct sym_key { struct sym_key {
char name[64]; 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) static int sym_key_compare(const void *left, const void *right)
{ {
@ -56,7 +62,10 @@ struct addr_key {
char name[64]; 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) 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 .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(st->sym);
btree_clear(addr_table); 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 sym_key skey;
struct addr_key akey; 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 /* Look for an old address first, and delete the reverse mapping
* if it's there. * 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); 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 */ /* Put the new mapping into both tables */
addr_key_init(&akey, addr, name); addr_key_init(&akey, addr, name);
if (btree_put(addr_table, &akey, NULL) < 0 || if (btree_put(st->addr, &akey, NULL) < 0 ||
btree_put(sym_table, &skey, &addr) < 0) { btree_put(st->sym, &skey, &addr) < 0) {
fprintf(stderr, "stab: can't set %s = 0x%04x\n", name, addr); fprintf(stderr, "stab: can't set %s = 0x%04x\n", name, addr);
return -1; return -1;
} }
@ -137,7 +152,7 @@ int stab_set(const char *name, int value)
return 0; 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) u_int16_t *ret_offset)
{ {
struct addr_key akey; 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[i] = 0xff;
akey.name[sizeof(akey.name) - 1] = 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); strncpy(ret_name, akey.name, max_len);
ret_name[max_len - 1] = 0; ret_name[max_len - 1] = 0;
*ret_offset = addr - akey.addr; *ret_offset = addr - akey.addr;
@ -158,73 +173,83 @@ int stab_nearest(u_int16_t addr, char *ret_name, int max_len,
return -1; 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; struct sym_key skey;
u_int16_t addr; u_int16_t addr;
sym_key_init(&skey, name); sym_key_init(&skey, name);
if (btree_get(sym_table, &skey, &addr)) if (btree_get(st->sym, &skey, &addr))
return -1; return -1;
*value = addr; *value = addr;
return 0; return 0;
} }
int stab_del(const char *name) int stab_del(stab_t st, const char *name)
{ {
struct sym_key skey; struct sym_key skey;
u_int16_t value; u_int16_t value;
struct addr_key akey; struct addr_key akey;
sym_key_init(&skey, name); sym_key_init(&skey, name);
if (btree_get(sym_table, &skey, &value)) if (btree_get(st->sym, &skey, &value))
return -1; return -1;
addr_key_init(&akey, value, name); addr_key_init(&akey, value, name);
btree_delete(sym_table, &skey); btree_delete(st->sym, &skey);
btree_delete(addr_table, &akey); btree_delete(st->addr, &akey);
return 0; 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; int ret;
struct addr_key akey; struct addr_key akey;
ret = btree_select(addr_table, NULL, BTREE_FIRST, ret = btree_select(st->addr, NULL, BTREE_FIRST,
&akey, NULL); &akey, NULL);
while (!ret) { while (!ret) {
if (cb(user_data, akey.name, akey.addr) < 0) if (cb(user_data, akey.name, akey.addr) < 0)
return -1; return -1;
ret = btree_select(addr_table, NULL, BTREE_NEXT, ret = btree_select(st->addr, NULL, BTREE_NEXT,
&akey, NULL); &akey, NULL);
} }
return 0; return 0;
} }
int stab_init(void) stab_t stab_new(void)
{ {
sym_table = btree_alloc(&sym_table_def); stab_t st = malloc(sizeof(*st));
if (!sym_table) {
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"); fprintf(stderr, "stab: failed to allocate symbol table\n");
return -1; free(st);
return NULL;
} }
addr_table = btree_alloc(&addr_table_def); st->addr = btree_alloc(&addr_table_def);
if (!addr_table) { if (!st->addr) {
fprintf(stderr, "stab: failed to allocate address table\n"); fprintf(stderr, "stab: failed to allocate address table\n");
btree_free(sym_table); btree_free(st->sym);
return -1; free(st);
return NULL;
} }
return 0; return st;
} }
void stab_exit(void) void stab_destroy(stab_t st)
{ {
btree_free(sym_table); btree_free(st->sym);
btree_free(addr_table); btree_free(st->addr);
free(st);
} }

23
stab.h
View File

@ -21,40 +21,43 @@
#include <sys/types.h> #include <sys/types.h>
/* Initialise/destroy the symbol table manager. If successful, init returns struct stab;
* 0, or -1 on error. 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); stab_t stab_new(void);
void stab_exit(void); void stab_destroy(stab_t st);
/* Reset the symbol table (delete all symbols) */ /* 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. */ /* 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 /* Take an address and find the nearest symbol and offset (always
* non-negative). * non-negative).
* *
* Returns 0 if found, 1 otherwise. * 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); u_int16_t *ret_offset);
/* Retrieve the value of a symbol. Returns 0 on success or -1 if the symbol /* Retrieve the value of a symbol. Returns 0 on success or -1 if the symbol
* doesn't exist. * 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 /* Delete a symbol table entry. Returns 0 on success or -1 if the symbol
* doesn't exist. * doesn't exist.
*/ */
int stab_del(const char *name); int stab_del(stab_t st, const char *name);
/* Enumerate all symbols in the table */ /* Enumerate all symbols in the table */
typedef int (*stab_callback_t)(void *user_data, typedef int (*stab_callback_t)(void *user_data,
const char *name, u_int16_t value); 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 #endif

44
sym.c
View File

@ -32,17 +32,18 @@
static int cmd_eval(cproc_t cp, char **arg) static int cmd_eval(cproc_t cp, char **arg)
{ {
stab_t stab = cproc_stab(cp);
int addr; int addr;
u_int16_t offset; u_int16_t offset;
char name[64]; char name[64];
if (expr_eval(*arg, &addr) < 0) { if (expr_eval(stab, *arg, &addr) < 0) {
fprintf(stderr, "=: can't parse: %s\n", *arg); fprintf(stderr, "=: can't parse: %s\n", *arg);
return -1; return -1;
} }
printf("0x%04x", addr); printf("0x%04x", addr);
if (!stab_nearest(addr, name, sizeof(name), &offset)) { if (!stab_nearest(stab, addr, name, sizeof(name), &offset)) {
printf(" = %s", name); printf(" = %s", name);
if (offset) if (offset)
printf("+0x%x", 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) static int cmd_sym_load_add(cproc_t cp, int clear, char **arg)
{ {
stab_t stab = cproc_stab(cp);
FILE *in; FILE *in;
int result = 0; int result = 0;
@ -67,12 +69,12 @@ static int cmd_sym_load_add(cproc_t cp, int clear, char **arg)
} }
if (clear) if (clear)
stab_clear(); stab_clear(stab);
if (elf32_check(in)) if (elf32_check(in))
result = elf32_syms(in, stab_set); result = elf32_syms(in, stab);
else if (symmap_check(in)) else if (symmap_check(in))
result = symmap_syms(in, stab_set); result = symmap_syms(in, stab);
else else
fprintf(stderr, "sym: %s: unknown file type\n", *arg); 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) static int cmd_sym_savemap(cproc_t cp, char **arg)
{ {
stab_t stab = cproc_stab(cp);
FILE *savemap_out; FILE *savemap_out;
char *fname = get_arg(arg); char *fname = get_arg(arg);
@ -115,7 +118,7 @@ static int cmd_sym_savemap(cproc_t cp, char **arg)
return -1; return -1;
} }
if (stab_enum(savemap_cb, savemap_out) < 0) { if (stab_enum(stab, savemap_cb, savemap_out) < 0) {
fclose(savemap_out); fclose(savemap_out);
return -1; 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) static int cmd_sym_find(cproc_t cp, char **arg)
{ {
stab_t stab = cproc_stab(cp);
regex_t find_preg; regex_t find_preg;
char *expr = get_arg(arg); char *expr = get_arg(arg);
if (!expr) { if (!expr) {
stab_enum(print_sym, NULL); stab_enum(stab, print_sym, NULL);
return 0; return 0;
} }
@ -160,7 +164,7 @@ static int cmd_sym_find(cproc_t cp, char **arg)
return -1; return -1;
} }
stab_enum(find_sym, &find_preg); stab_enum(stab, find_sym, &find_preg);
regfree(&find_preg); regfree(&find_preg);
return 0; return 0;
} }
@ -175,7 +179,8 @@ struct rename_data {
regex_t preg; 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 i;
int count = 0; 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); 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: " fprintf(stderr, "sym: warning: "
"symbol missing: %s\n", "symbol missing: %s\n",
r->old_name); r->old_name);
} else { } else {
stab_del(r->old_name); stab_del(stab, r->old_name);
if (stab_set(new_name, value) < 0) { if (stab_set(stab, new_name, value) < 0) {
fprintf(stderr, "sym: warning: " fprintf(stderr, "sym: warning: "
"failed to set new name: %s\n", "failed to set new name: %s\n",
new_name); new_name);
@ -243,6 +248,7 @@ static int cmd_sym_rename(cproc_t cp, char **arg)
const char *replace = get_arg(arg); const char *replace = get_arg(arg);
int ret; int ret;
struct rename_data rename; struct rename_data rename;
stab_t stab = cproc_stab(cp);
if (!(expr && replace)) { if (!(expr && replace)) {
fprintf(stderr, "sym: expected pattern and replacement\n"); 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)); 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"); fprintf(stderr, "sym: rename failed\n");
regfree(&rename.preg); regfree(&rename.preg);
vector_destroy(&rename.list); vector_destroy(&rename.list);
@ -264,7 +270,7 @@ static int cmd_sym_rename(cproc_t cp, char **arg)
} }
regfree(&rename.preg); regfree(&rename.preg);
ret = renames_do(&rename, replace); ret = renames_do(stab, &rename, replace);
vector_destroy(&rename.list); vector_destroy(&rename.list);
if (ret > 0) 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) static int cmd_sym_del(cproc_t cp, char **arg)
{ {
stab_t stab = cproc_stab(cp);
char *name = get_arg(arg); char *name = get_arg(arg);
if (!name) { if (!name) {
@ -283,7 +290,7 @@ static int cmd_sym_del(cproc_t cp, char **arg)
return -1; return -1;
} }
if (stab_del(name) < 0) { if (stab_del(stab, name) < 0) {
fprintf(stderr, "sym: can't delete nonexistent symbol: %s\n", fprintf(stderr, "sym: can't delete nonexistent symbol: %s\n",
name); name);
return -1; 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) static int cmd_sym(cproc_t cp, char **arg)
{ {
stab_t stab = cproc_stab(cp);
char *subcmd = get_arg(arg); char *subcmd = get_arg(arg);
if (!subcmd) { if (!subcmd) {
@ -306,7 +314,7 @@ static int cmd_sym(cproc_t cp, char **arg)
if (!strcasecmp(subcmd, "clear")) { if (!strcasecmp(subcmd, "clear")) {
if (cproc_prompt_abort(cp, CPROC_MODIFY_SYMS)) if (cproc_prompt_abort(cp, CPROC_MODIFY_SYMS))
return 0; return 0;
stab_clear(); stab_clear(stab);
cproc_unmodify(cp, CPROC_MODIFY_SYMS); cproc_unmodify(cp, CPROC_MODIFY_SYMS);
return 0; return 0;
} }
@ -322,13 +330,13 @@ static int cmd_sym(cproc_t cp, char **arg)
return -1; 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", fprintf(stderr, "sym: can't parse value: %s\n",
val_text); val_text);
return -1; return -1;
} }
if (stab_set(name, value) < 0) if (stab_set(stab, name, value) < 0)
return -1; return -1;
cproc_modify(cp, CPROC_MODIFY_SYMS); cproc_modify(cp, CPROC_MODIFY_SYMS);

View File

@ -45,7 +45,7 @@ int symmap_check(FILE *in)
return spc_count >= 2; return spc_count >= 2;
} }
int symmap_syms(FILE *in, symfunc_t cb) int symmap_syms(FILE *in, stab_t stab)
{ {
rewind(in); rewind(in);
char buf[128]; char buf[128];
@ -60,7 +60,7 @@ int symmap_syms(FILE *in, symfunc_t cb)
if (addr && name) { if (addr && name) {
int addr_val = strtoul(addr, NULL, 16); int addr_val = strtoul(addr, NULL, 16);
if (cb(name, addr_val) < 0) if (stab_set(stab, name, addr_val) < 0)
return -1; return -1;
} }
} }