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