Symbol table is an object.
This commit is contained in:
parent
2794165dee
commit
ca3e5dd645
|
@ -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
17
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)
|
||||
{
|
||||
|
|
6
cproc.h
6
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).
|
||||
|
|
20
cproc_util.c
20
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);
|
||||
|
|
29
devcmd.c
29
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 {
|
||||
|
|
9
elf32.c
9
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)
|
||||
|
|
9
expr.c
9
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;
|
||||
}
|
||||
|
||||
|
|
3
expr.h
3
expr.h
|
@ -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
45
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;
|
||||
}
|
||||
|
|
25
rtools.c
25
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;
|
||||
}
|
||||
|
|
95
stab.c
95
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);
|
||||
}
|
||||
|
|
23
stab.h
23
stab.h
|
@ -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
44
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);
|
||||
|
|
4
symmap.c
4
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue