Separated command database.

This commit is contained in:
Daniel Beer 2010-08-13 16:06:23 +12:00
parent e834241e90
commit 6dd1ab25c3
14 changed files with 364 additions and 355 deletions

View File

@ -56,7 +56,8 @@ install: mspdebug mspdebug.man
mspdebug: main.o fet.o rf2500.o dis.o uif.o olimex.o ihex.o elf32.o stab.o \ mspdebug: main.o fet.o rf2500.o dis.o uif.o olimex.o ihex.o elf32.o stab.o \
util.o bsl.o sim.o symmap.o gdb.o btree.o rtools.o sym.o devcmd.o \ util.o bsl.o sim.o symmap.o gdb.o btree.o rtools.o sym.o devcmd.o \
cproc.o vector.o output_util.o expr.o fet_error.o binfile.o \ cproc.o vector.o output_util.o expr.o fet_error.o binfile.o \
fet_db.o usbutil.o titext.o srec.o device.o coff.o opdb.o output.o fet_db.o usbutil.o titext.o srec.o device.o coff.o opdb.o output.o \
cmddb.o
$(CC) $(LDFLAGS) $(MACPORTS_LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS) $(CC) $(LDFLAGS) $(MACPORTS_LDFLAGS) -o $@ $^ -lusb $(READLINE_LIBS)
.c.o: .c.o:

247
cmddb.c Normal file
View File

@ -0,0 +1,247 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 Daniel Beer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <string.h>
#include "cmddb.h"
#include "util.h"
#include "devcmd.h"
#include "gdb.h"
#include "rtools.h"
#include "cproc.h"
#include "sym.h"
const struct cmddb_record commands[] = {
{
.name = "help",
.func = cmd_help,
.help =
"help [command]\n"
" Without arguments, displays a list of commands. With a command\n"
" name as an argument, displays help for that command.\n"
},
{
.name = "opt",
.func = cmd_opt,
.help =
"opt [name] [value]\n"
" Query or set option variables. With no arguments, displays all\n"
" available options.\n"
},
{
.name = "read",
.func = cmd_read,
.help =
"read <filename>\n"
" Read commands from a file and evaluate them.\n"
},
{
.name = "setbreak",
.func = cmd_setbreak,
.help =
"setbreak <addr> [index]\n"
" Set a breakpoint. If no index is specified, the first available\n"
" slot will be used.\n"
},
{
.name = "delbreak",
.func = cmd_delbreak,
.help =
"delbreak [index]\n"
" Delete a breakpoint. If no index is specified, then all active\n"
" breakpoints are cleared.\n"
},
{
.name = "break",
.func = cmd_break,
.help =
"break\n"
" List active breakpoints.\n"
},
{
.name = "regs",
.func = cmd_regs,
.help =
"regs\n"
" Read and display the current register contents.\n"
},
{
.name = "prog",
.func = cmd_prog,
.help =
"prog <filename>\n"
" Erase the device and flash the data contained in a binary file.\n"
" This command also loads symbols from the file, if available.\n"
},
{
.name = "md",
.func = cmd_md,
.help =
"md <address> [length]\n"
" Read the specified number of bytes from memory at the given\n"
" address, and display a hexdump.\n"
},
{
.name = "mw",
.func = cmd_mw,
.help =
"mw <address> bytes ...\n"
" Write a sequence of bytes to a memory address. Byte values are\n"
" two-digit hexadecimal numbers.\n"
},
{
.name = "reset",
.func = cmd_reset,
.help =
"reset\n"
" Reset (and halt) the CPU.\n"
},
{
.name = "erase",
.func = cmd_erase,
.help =
"erase\n"
" Erase the device under test.\n"
},
{
.name = "step",
.func = cmd_step,
.help =
"step [count]\n"
" Single-step the CPU, and display the register state.\n"
},
{
.name = "run",
.func = cmd_run,
.help =
"run\n"
" Run the CPU to until a breakpoint is reached or the command is\n"
" interrupted.\n"
},
{
.name = "set",
.func = cmd_set,
.help =
"set <register> <value>\n"
" Change the value of a CPU register.\n"
},
{
.name = "dis",
.func = cmd_dis,
.help =
"dis <address> [length]\n"
" Disassemble a section of memory.\n"
},
{
.name = "hexout",
.func = cmd_hexout,
.help =
"hexout <address> <length> <filename.hex>\n"
" Save a region of memory into a HEX file.\n"
},
{
.name = "gdb",
.func = cmd_gdb,
.help =
"gdb [port]\n"
" Run a GDB remote stub on the given TCP/IP port.\n"
},
{
.name = "=",
.func = cmd_eval,
.help =
"= <expression>\n"
" Evaluate an expression using the symbol table.\n"
},
{
.name = "sym",
.func = cmd_sym,
.help =
"sym clear\n"
" Clear the symbol table.\n"
"sym set <name> <value>\n"
" Set or overwrite the value of a symbol.\n"
"sym del <name>\n"
" Delete a symbol from the symbol table.\n"
"sym import <filename>\n"
" Load symbols from the given file.\n"
"sym import+ <filename>\n"
" Load additional symbols from the given file.\n"
"sym export <filename>\n"
" Save the current symbols to a BSD-style symbol file.\n"
"sym find <regex>\n"
" Search for symbols by regular expression.\n"
"sym rename <regex> <string>\n"
" Replace every occurance of a pattern in symbol names.\n"
},
{
.name = "isearch",
.func = cmd_isearch,
.help =
"isearch <address> <length> [options ...]\n"
" Search for an instruction matching certain search terms. These\n"
" terms may be any of the following:\n"
" opcode <opcode>\n"
" byte|word|aword\n"
" jump|single|double|noarg\n"
" src <value>\n"
" dst <value>\n"
" srcreg <register>\n"
" dstreg <register>\n"
" srcmode R|I|S|&|@|+|#\n"
" dstmode R|I|S|&|@|+|#\n"
" For single-operand instructions, the operand is considered the\n"
" destination operand.\n"
},
{
.name = "cgraph",
.func = cmd_cgraph,
.help =
"cgraph <address> <length> [function]\n"
" Analyse the range given and produce a call graph. Displays a summary\n"
" of all functions if no function address is given.\n"
}
};
int cmddb_get(const char *name, struct cmddb_record *ret)
{
int i;
for (i = 0; i < ARRAY_LEN(commands); i++) {
const struct cmddb_record *r = &commands[i];
if (!strcasecmp(r->name, name)) {
memcpy(ret, r, sizeof(*ret));
return 0;
}
}
return -1;
}
int cmddb_enum(cmddb_enum_func_t func, void *user_data)
{
int i;
for (i = 0; i < ARRAY_LEN(commands); i++)
if (func(user_data, &commands[i]) < 0)
return -1;
return 0;
}

44
cmddb.h Normal file
View File

@ -0,0 +1,44 @@
/* MSPDebug - debugging tool for MSP430 MCUs
* Copyright (C) 2009, 2010 Daniel Beer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CMDDB_H_
#define CMDDB_H_
#include "cproc.h"
typedef int (*cproc_command_func_t)(cproc_t cp, char **arg);
struct cmddb_record {
const char *name;
cproc_command_func_t func;
const char *help;
};
/* Fetch a command record */
int cmddb_get(const char *name, struct cmddb_record *r);
/* Enumerate all command records.
*
* Returns 0, or -1 if an error occurs during enumeration.
*/
typedef int (*cmddb_enum_func_t)(void *user_data,
const struct cmddb_record *r);
int cmddb_enum(cmddb_enum_func_t func, void *user_data);
#endif

125
cproc.c
View File

@ -35,56 +35,26 @@
#include "stab.h" #include "stab.h"
#include "util.h" #include "util.h"
#include "output.h" #include "output.h"
#include "cmddb.h"
struct cproc { struct cproc {
struct vector command_list;
int lists_modified;
int modify_flags; int modify_flags;
int in_reader_loop; int in_reader_loop;
}; };
static struct cproc_command *find_command(cproc_t cp, const char *name)
{
int i;
for (i = 0; i < cp->command_list.size; i++) {
struct cproc_command *cmd =
VECTOR_PTR(cp->command_list, i, struct cproc_command);
if (!strcasecmp(cmd->name, name))
return cmd;
}
return NULL;
}
static int namelist_cmp(const void *a, const void *b) static int namelist_cmp(const void *a, const void *b)
{ {
return strcasecmp(*(const char **)a, *(const char **)b); return strcasecmp(*(const char **)a, *(const char **)b);
} }
/* NOTE: Both sort_lists and namelist_print assume that the first item in each
* vector element is a const char *
*/
static void sort_lists(cproc_t cp)
{
if (!cp->lists_modified)
return;
if (cp->command_list.ptr)
qsort(cp->command_list.ptr, cp->command_list.size,
cp->command_list.elemsize, namelist_cmp);
cp->lists_modified = 0;
}
static void namelist_print(struct vector *v) static void namelist_print(struct vector *v)
{ {
int i; int i;
int max_len = 0; int max_len = 0;
int rows, cols; int rows, cols;
qsort(v->ptr, v->size, v->elemsize, namelist_cmp);
for (i = 0; i < v->size; i++) { for (i = 0; i < v->size; i++) {
const char *text = VECTOR_AT(*v, i, const char *); const char *text = VECTOR_AT(*v, i, const char *);
int len = strlen(text); int len = strlen(text);
@ -137,22 +107,25 @@ static const char *type_text(opdb_type_t type)
static int push_option_name(void *user_data, const struct opdb_key *key, static int push_option_name(void *user_data, const struct opdb_key *key,
const union opdb_value *value) const union opdb_value *value)
{ {
struct vector *v = (struct vector *)user_data; return vector_push((struct vector *)user_data, &key->name, 1);
return vector_push(v, &key->name, 1);
} }
static int cmd_help(cproc_t cp, char **arg) static int push_command_name(void *user_data, const struct cmddb_record *rec)
{
return vector_push((struct vector *)user_data, &rec->name, 1);
}
int cmd_help(cproc_t cp, char **arg)
{ {
const char *topic = get_arg(arg); const char *topic = get_arg(arg);
if (topic) { if (topic) {
const struct cproc_command *cmd = find_command(cp, topic); struct cmddb_record cmd;
struct opdb_key key; struct opdb_key key;
if (cmd) { if (!cmddb_get(topic, &cmd)) {
printc("\x1b[1mCOMMAND: %s\x1b[0m\n\n%s\n", printc("\x1b[1mCOMMAND: %s\x1b[0m\n\n%s\n",
cmd->name, cmd->help); cmd.name, cmd.help);
return 0; return 0;
} }
@ -168,18 +141,23 @@ static int cmd_help(cproc_t cp, char **arg)
struct vector v; struct vector v;
vector_init(&v, sizeof(const char *)); vector_init(&v, sizeof(const char *));
sort_lists(cp);
printf("Available commands:\n"); if (!cmddb_enum(push_command_name, &v)) {
namelist_print(&cp->command_list); printf("Available commands:\n");
printf("\n"); namelist_print(&v);
printf("\n");
} else {
perror("help: can't allocate memory for command list");
}
vector_realloc(&v, 0);
if (!opdb_enum(push_option_name, &v)) { if (!opdb_enum(push_option_name, &v)) {
printf("Available options:\n"); printf("Available options:\n");
namelist_print(&v); namelist_print(&v);
printf("\n"); printf("\n");
} else { } else {
perror("failed to allocate memory"); perror("help: can't allocate memory for option list");
} }
vector_destroy(&v); vector_destroy(&v);
@ -236,7 +214,7 @@ static int display_option(void *user_data, const struct opdb_key *key,
return 0; return 0;
} }
static int cmd_opt(cproc_t cp, char **arg) int cmd_opt(cproc_t cp, char **arg)
{ {
const char *opt_text = get_arg(arg); const char *opt_text = get_arg(arg);
struct opdb_key key; struct opdb_key key;
@ -267,7 +245,7 @@ static int cmd_opt(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_read(cproc_t cp, char **arg) int cmd_read(cproc_t cp, char **arg)
{ {
char *filename = get_arg(arg); char *filename = get_arg(arg);
@ -279,32 +257,6 @@ static int cmd_read(cproc_t cp, char **arg)
return cproc_process_file(cp, filename); return cproc_process_file(cp, filename);
} }
static const struct cproc_command built_in_commands[] = {
{
.name = "help",
.func = cmd_help,
.help =
"help [command]\n"
" Without arguments, displays a list of commands. With a command\n"
" name as an argument, displays help for that command.\n"
},
{
.name = "opt",
.func = cmd_opt,
.help =
"opt [name] [value]\n"
" Query or set option variables. With no arguments, displays all\n"
" available options.\n"
},
{
.name = "read",
.func = cmd_read,
.help =
"read <filename>\n"
" Read commands from a file and evaluate them.\n"
}
};
cproc_t cproc_new(void) cproc_t cproc_new(void)
{ {
cproc_t cp = malloc(sizeof(*cp)); cproc_t cp = malloc(sizeof(*cp));
@ -313,35 +265,14 @@ cproc_t cproc_new(void)
return NULL; return NULL;
memset(cp, 0, sizeof(*cp)); memset(cp, 0, sizeof(*cp));
vector_init(&cp->command_list, sizeof(struct cproc_command));
if (vector_push(&cp->command_list, &built_in_commands,
ARRAY_LEN(built_in_commands)) < 0) {
vector_destroy(&cp->command_list);
free(cp);
return NULL;
}
return cp; return cp;
} }
void cproc_destroy(cproc_t cp) void cproc_destroy(cproc_t cp)
{ {
vector_destroy(&cp->command_list);
free(cp); free(cp);
} }
int cproc_register_commands(cproc_t cp, const struct cproc_command *cmd,
int count)
{
if (vector_push(&cp->command_list, cmd, count) < 0)
return -1;
cp->lists_modified = 1;
return 0;
}
void cproc_modify(cproc_t cp, int flags) void cproc_modify(cproc_t cp, int flags)
{ {
cp->modify_flags |= flags; cp->modify_flags |= flags;
@ -423,14 +354,14 @@ static int process_command(cproc_t cp, char *arg, int interactive)
cmd_text = get_arg(&arg); cmd_text = get_arg(&arg);
if (cmd_text) { if (cmd_text) {
const struct cproc_command *cmd = find_command(cp, cmd_text); struct cmddb_record cmd;
if (cmd) { if (!cmddb_get(cmd_text, &cmd)) {
int old = cp->in_reader_loop; int old = cp->in_reader_loop;
int ret; int ret;
cp->in_reader_loop = interactive; cp->in_reader_loop = interactive;
ret = cmd->func(cp, &arg); ret = cmd.func(cp, &arg);
cp->in_reader_loop = old; cp->in_reader_loop = old;
return ret; return ret;

26
cproc.h
View File

@ -27,21 +27,6 @@
struct cproc; struct cproc;
typedef struct cproc *cproc_t; typedef struct cproc *cproc_t;
/* Command definitions.
*
* Each command is specified as a tuple of name, command function and help
* text. When the command is invoked, the command function is called with
* a mutable pointer to the command line text, and a pointer to the command
* processor.
*/
typedef int (*cproc_command_func_t)(cproc_t cp, char **arg);
struct cproc_command {
const char *name;
cproc_command_func_t func;
const char *help;
};
/* Commmand processor modification flags. /* Commmand processor modification flags.
* *
* Within the context of a command processor, various data items may be * Within the context of a command processor, various data items may be
@ -65,12 +50,6 @@ struct cproc_command {
cproc_t cproc_new(void); cproc_t cproc_new(void);
void cproc_destroy(cproc_t cp); void cproc_destroy(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).
*/
int cproc_register_commands(cproc_t cp, const struct cproc_command *cmd,
int count);
/* This should be called before a destructive operation to give the user /* This should be called before a destructive operation to give the user
* a chance to abort. If it returns 1, then the operation should be aborted. * a chance to abort. If it returns 1, then the operation should be aborted.
* *
@ -90,4 +69,9 @@ void cproc_reader_loop(cproc_t cp);
int cproc_process_command(cproc_t cp, char *cmd); int cproc_process_command(cproc_t cp, char *cmd);
int cproc_process_file(cproc_t cp, const char *filename); int cproc_process_file(cproc_t cp, const char *filename);
/* Built-in commands */
int cmd_help(cproc_t cp, char **arg);
int cmd_read(cproc_t cp, char **arg);
int cmd_opt(cproc_t cp, char **arg);
#endif #endif

140
devcmd.c
View File

@ -31,7 +31,7 @@
#include "util.h" #include "util.h"
#include "dis.h" #include "dis.h"
static int cmd_regs(cproc_t cp, char **arg) int cmd_regs(cproc_t cp, char **arg)
{ {
address_t regs[DEVICE_NUM_REGS]; address_t regs[DEVICE_NUM_REGS];
uint8_t code[16]; uint8_t code[16];
@ -51,7 +51,7 @@ static int cmd_regs(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_md(cproc_t cp, char **arg) int cmd_md(cproc_t cp, char **arg)
{ {
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *len_text = get_arg(arg); char *len_text = get_arg(arg);
@ -94,7 +94,7 @@ static int cmd_md(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_mw(cproc_t cp, char **arg) int cmd_mw(cproc_t cp, char **arg)
{ {
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *byte_text; char *byte_text;
@ -130,12 +130,12 @@ static int cmd_mw(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_reset(cproc_t cp, char **arg) int cmd_reset(cproc_t cp, char **arg)
{ {
return device_default->ctl(device_default, DEVICE_CTL_RESET); return device_default->ctl(device_default, DEVICE_CTL_RESET);
} }
static int cmd_erase(cproc_t cp, char **arg) int cmd_erase(cproc_t cp, char **arg)
{ {
if (device_default->ctl(device_default, DEVICE_CTL_HALT) < 0) if (device_default->ctl(device_default, DEVICE_CTL_HALT) < 0)
return -1; return -1;
@ -144,7 +144,7 @@ static int cmd_erase(cproc_t cp, char **arg)
return device_default->ctl(device_default, DEVICE_CTL_ERASE); return device_default->ctl(device_default, DEVICE_CTL_ERASE);
} }
static int cmd_step(cproc_t cp, char **arg) int cmd_step(cproc_t cp, char **arg)
{ {
char *count_text = get_arg(arg); char *count_text = get_arg(arg);
int count = 1; int count = 1;
@ -161,7 +161,7 @@ static int cmd_step(cproc_t cp, char **arg)
return cmd_regs(cp, NULL); return cmd_regs(cp, NULL);
} }
static int cmd_run(cproc_t cp, char **arg) int cmd_run(cproc_t cp, char **arg)
{ {
device_status_t status; device_status_t status;
address_t regs[DEVICE_NUM_REGS]; address_t regs[DEVICE_NUM_REGS];
@ -210,7 +210,7 @@ static int cmd_run(cproc_t cp, char **arg)
return cmd_regs(cp, NULL); return cmd_regs(cp, NULL);
} }
static int cmd_set(cproc_t cp, char **arg) int cmd_set(cproc_t cp, char **arg)
{ {
char *reg_text = get_arg(arg); char *reg_text = get_arg(arg);
char *val_text = get_arg(arg); char *val_text = get_arg(arg);
@ -244,7 +244,7 @@ static int cmd_set(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_dis(cproc_t cp, char **arg) int cmd_dis(cproc_t cp, char **arg)
{ {
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *len_text = get_arg(arg); char *len_text = get_arg(arg);
@ -393,7 +393,7 @@ static int hexout_feed(struct hexout_data *hexout,
return 0; return 0;
} }
static int cmd_hexout(cproc_t cp, char **arg) int cmd_hexout(cproc_t cp, char **arg)
{ {
char *off_text = get_arg(arg); char *off_text = get_arg(arg);
char *len_text = get_arg(arg); char *len_text = get_arg(arg);
@ -523,7 +523,7 @@ static int prog_feed(void *user_data,
return 0; return 0;
} }
static int cmd_prog(cproc_t cp, char **arg) int cmd_prog(cproc_t cp, char **arg)
{ {
FILE *in; FILE *in;
struct prog_data prog; struct prog_data prog;
@ -568,7 +568,7 @@ static int cmd_prog(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_setbreak(cproc_t cp, char **arg) int cmd_setbreak(cproc_t cp, char **arg)
{ {
char *addr_text = get_arg(arg); char *addr_text = get_arg(arg);
char *index_text = get_arg(arg); char *index_text = get_arg(arg);
@ -606,7 +606,7 @@ static int cmd_setbreak(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_delbreak(cproc_t cp, char **arg) int cmd_delbreak(cproc_t cp, char **arg)
{ {
char *index_text = get_arg(arg); char *index_text = get_arg(arg);
int ret = 0; int ret = 0;
@ -633,7 +633,7 @@ static int cmd_delbreak(cproc_t cp, char **arg)
return ret; return ret;
} }
static int cmd_break(cproc_t cp, char **arg) int cmd_break(cproc_t cp, char **arg)
{ {
int i; int i;
@ -660,115 +660,3 @@ static int cmd_break(cproc_t cp, char **arg)
return 0; return 0;
} }
static const struct cproc_command commands[] = {
{
.name = "setbreak",
.func = cmd_setbreak,
.help =
"setbreak <addr> [index]\n"
" Set a breakpoint. If no index is specified, the first available\n"
" slot will be used.\n"
},
{
.name = "delbreak",
.func = cmd_delbreak,
.help =
"delbreak [index]\n"
" Delete a breakpoint. If no index is specified, then all active\n"
" breakpoints are cleared.\n"
},
{
.name = "break",
.func = cmd_break,
.help =
"break\n"
" List active breakpoints.\n"
},
{
.name = "regs",
.func = cmd_regs,
.help =
"regs\n"
" Read and display the current register contents.\n"
},
{
.name = "prog",
.func = cmd_prog,
.help =
"prog <filename>\n"
" Erase the device and flash the data contained in a binary file.\n"
" This command also loads symbols from the file, if available.\n"
},
{
.name = "md",
.func = cmd_md,
.help =
"md <address> [length]\n"
" Read the specified number of bytes from memory at the given\n"
" address, and display a hexdump.\n"
},
{
.name = "mw",
.func = cmd_mw,
.help =
"mw <address> bytes ...\n"
" Write a sequence of bytes to a memory address. Byte values are\n"
" two-digit hexadecimal numbers.\n"
},
{
.name = "reset",
.func = cmd_reset,
.help =
"reset\n"
" Reset (and halt) the CPU.\n"
},
{
.name = "erase",
.func = cmd_erase,
.help =
"erase\n"
" Erase the device under test.\n"
},
{
.name = "step",
.func = cmd_step,
.help =
"step [count]\n"
" Single-step the CPU, and display the register state.\n"
},
{
.name = "run",
.func = cmd_run,
.help =
"run\n"
" Run the CPU to until a breakpoint is reached or the command is\n"
" interrupted.\n"
},
{
.name = "set",
.func = cmd_set,
.help =
"set <register> <value>\n"
" Change the value of a CPU register.\n"
},
{
.name = "dis",
.func = cmd_dis,
.help =
"dis <address> [length]\n"
" Disassemble a section of memory.\n"
},
{
.name = "hexout",
.func = cmd_hexout,
.help =
"hexout <address> <length> <filename.hex>\n"
" Save a region of memory into a HEX file.\n"
}
};
int devcmd_register(cproc_t cp)
{
return cproc_register_commands(cp, commands, ARRAY_LEN(commands));
}

View File

@ -21,7 +21,19 @@
#include "cproc.h" #include "cproc.h"
/* Register device commands */ int cmd_regs(cproc_t cp, char **arg);
int devcmd_register(cproc_t cp); int cmd_md(cproc_t cp, char **arg);
int cmd_mw(cproc_t cp, char **arg);
int cmd_reset(cproc_t cp, char **arg);
int cmd_erase(cproc_t cp, char **arg);
int cmd_step(cproc_t cp, char **arg);
int cmd_run(cproc_t cp, char **arg);
int cmd_set(cproc_t cp, char **arg);
int cmd_dis(cproc_t cp, char **arg);
int cmd_hexout(cproc_t cp, char **arg);
int cmd_prog(cproc_t cp, char **arg);
int cmd_setbreak(cproc_t cp, char **arg);
int cmd_delbreak(cproc_t cp, char **arg);
int cmd_break(cproc_t cp, char **arg);
#endif #endif

15
gdb.c
View File

@ -662,7 +662,7 @@ static int gdb_server(int port)
return data.error ? -1 : 0; return data.error ? -1 : 0;
} }
static int cmd_gdb(cproc_t cp, char **arg) int cmd_gdb(cproc_t cp, char **arg)
{ {
char *port_text = get_arg(arg); char *port_text = get_arg(arg);
int port = 2000; int port = 2000;
@ -682,16 +682,3 @@ static int cmd_gdb(cproc_t cp, char **arg)
return 0; return 0;
} }
static const struct cproc_command command_gdb = {
.name = "gdb",
.func = cmd_gdb,
.help =
"gdb [port]\n"
" Run a GDB remote stub on the given TCP/IP port.\n"
};
int gdb_register(cproc_t cp)
{
return cproc_register_commands(cp, &command_gdb, 1);
}

3
gdb.h
View File

@ -21,7 +21,6 @@
#include "cproc.h" #include "cproc.h"
/* Register the "gdb" command */ int cmd_gdb(cproc_t cp, char **arg);
int gdb_register(cproc_t cp);
#endif #endif

8
main.c
View File

@ -437,14 +437,6 @@ cproc_t setup_cproc(struct cmdline_args *args)
return NULL; return NULL;
} }
if (sym_register(cp) < 0 ||
devcmd_register(cp) < 0 ||
gdb_register(cp) < 0 ||
rtools_register(cp) < 0) {
cproc_destroy(cp);
return NULL;
}
return cp; return cp;
} }

View File

@ -373,7 +373,7 @@ static int do_isearch(cproc_t cp, address_t addr, address_t len,
return 0; return 0;
} }
static int cmd_isearch(cproc_t cp, char **arg) int cmd_isearch(cproc_t cp, char **arg)
{ {
const static struct { const static struct {
const char *name; const char *name;
@ -900,7 +900,7 @@ static void cgraph_func_info(struct call_graph *graph, cproc_t cp,
} }
} }
static int cmd_cgraph(cproc_t cp, char **arg) int cmd_cgraph(cproc_t cp, char **arg)
{ {
char *offset_text, *len_text, *addr_text;; char *offset_text, *len_text, *addr_text;;
address_t offset, len, addr; address_t offset, len, addr;
@ -965,43 +965,3 @@ static int cmd_cgraph(cproc_t cp, char **arg)
cgraph_destroy(&graph); cgraph_destroy(&graph);
return 0; return 0;
} }
/************************************************************************
* Setup and registration
*/
static const struct cproc_command rtools_commands[] = {
{
.name = "isearch",
.func = cmd_isearch,
.help =
"isearch <address> <length> [options ...]\n"
" Search for an instruction matching certain search terms. These\n"
" terms may be any of the following:\n"
" opcode <opcode>\n"
" byte|word|aword\n"
" jump|single|double|noarg\n"
" src <value>\n"
" dst <value>\n"
" srcreg <register>\n"
" dstreg <register>\n"
" srcmode R|I|S|&|@|+|#\n"
" dstmode R|I|S|&|@|+|#\n"
" For single-operand instructions, the operand is considered the\n"
" destination operand.\n"
},
{
.name = "cgraph",
.func = cmd_cgraph,
.help =
"cgraph <address> <length> [function]\n"
" Analyse the range given and produce a call graph. Displays a summary\n"
" of all functions if no function address is given.\n"
}
};
int rtools_register(cproc_t cp)
{
return cproc_register_commands(cp, rtools_commands,
ARRAY_LEN(rtools_commands));
}

View File

@ -21,7 +21,7 @@
#include "cproc.h" #include "cproc.h"
/* Register reverse-engineering tool commands. */ int cmd_isearch(cproc_t cp, char **arg);
int rtools_register(cproc_t cp); int cmd_cgraph(cproc_t cp, char **arg);
#endif #endif

40
sym.c
View File

@ -30,7 +30,7 @@
#include "vector.h" #include "vector.h"
#include "sym.h" #include "sym.h"
static int cmd_eval(cproc_t cp, char **arg) int cmd_eval(cproc_t cp, char **arg)
{ {
address_t addr; address_t addr;
address_t offset; address_t offset;
@ -288,7 +288,7 @@ static int cmd_sym_del(cproc_t cp, char **arg)
return 0; return 0;
} }
static int cmd_sym(cproc_t cp, char **arg) int cmd_sym(cproc_t cp, char **arg)
{ {
char *subcmd = get_arg(arg); char *subcmd = get_arg(arg);
@ -346,39 +346,3 @@ static int cmd_sym(cproc_t cp, char **arg)
fprintf(stderr, "sym: unknown subcommand: %s\n", subcmd); fprintf(stderr, "sym: unknown subcommand: %s\n", subcmd);
return -1; return -1;
} }
static const struct cproc_command commands[] = {
{
.name = "=",
.func = cmd_eval,
.help =
"= <expression>\n"
" Evaluate an expression using the symbol table.\n"
},
{
.name = "sym",
.func = cmd_sym,
.help =
"sym clear\n"
" Clear the symbol table.\n"
"sym set <name> <value>\n"
" Set or overwrite the value of a symbol.\n"
"sym del <name>\n"
" Delete a symbol from the symbol table.\n"
"sym import <filename>\n"
" Load symbols from the given file.\n"
"sym import+ <filename>\n"
" Load additional symbols from the given file.\n"
"sym export <filename>\n"
" Save the current symbols to a BSD-style symbol file.\n"
"sym find <regex>\n"
" Search for symbols by regular expression.\n"
"sym rename <regex> <string>\n"
" Replace every occurance of a pattern in symbol names.\n"
}
};
int sym_register(cproc_t cp)
{
return cproc_register_commands(cp, commands, ARRAY_LEN(commands));
}

4
sym.h
View File

@ -21,7 +21,7 @@
#include "cproc.h" #include "cproc.h"
/* Register symbol-table manipulation commands */ int cmd_eval(cproc_t cp, char **arg);
int sym_register(cproc_t cp); int cmd_sym(cproc_t cp, char **arg);
#endif #endif