Pass t/test.arm, new cmd !123 to run historic command

Fix all opcode constructions listed in t/test.arm
Add 'hlt' opcode for arm.
Minor changes in arm disassembly output
Typing !#number you re-run the command in !history
!history is now listed (! is an alias)
Added API to access history from dietline
This commit is contained in:
pancake 2013-03-14 02:32:53 +01:00
parent 67f0794b82
commit 8846cb79cf
9 changed files with 109 additions and 61 deletions

View file

@ -26,12 +26,13 @@ enum {
TYPE_MOV = 1,
TYPE_TST = 2,
TYPE_SWI = 3,
TYPE_BRA = 4,
TYPE_BRR = 5,
TYPE_ARI = 6,
TYPE_IMM = 7,
TYPE_MEM = 8,
TYPE_BKP = 9,
TYPE_HLT = 4,
TYPE_BRA = 5,
TYPE_BRR = 6,
TYPE_ARI = 7,
TYPE_IMM = 8,
TYPE_MEM = 9,
TYPE_BKP = 10,
};
// static const char *const arm_shift[] = {"lsl", "lsr", "asr", "ror"};
@ -77,6 +78,7 @@ static ArmOp ops[] = {
{ "mov", 0xa001, TYPE_MOV },
{ "mvn", 0xe000, TYPE_MOV },
{ "svc", 0xf, TYPE_SWI }, // ???
{ "hlt", 0x70000001, TYPE_HLT }, // ???
{ "and", 0x0000, TYPE_ARI },
{ "ands", 0x1000, TYPE_ARI },
@ -122,6 +124,15 @@ static char *getrange(char *s) {
return p;
}
static int getshift_unused (const char *s) {
int i;
const char *shifts[] = { "lsl", "lsr", "asr", "ror", NULL };
for (i=0; shifts[i]; i++)
if (!strcmp (s, shifts[i]))
return i * 0x20;
return 0;
}
static int getreg(const char *str) {
int i;
const char *aliases[] = { "sl", "fp", "ip", "sp", "lr", "pc", NULL };
@ -164,13 +175,11 @@ static ut32 getshift(const char *str) {
strncpy (type, str, sizeof (type)-1);
// handle RRX alias case
// XXX strcaecmp is probably unportable
if (!strcasecmp (type, shifts[5])) {
// handle RRX alias case
shift = 6;
}
// all other shift types
else {
// split the string into type and arg
} else { // all other shift types
space = strchr (type, ' ');
if (!space)
return 0;
@ -188,21 +197,22 @@ static ut32 getshift(const char *str) {
shift = (i*2);
if ((i = getreg (arg)) != -1) {
shift |= 1;
i = i<<4;
}
else {
i<<=8; // set reg
// i|=1; // use reg
i |= (1<<4); // bitshift
i|=shift<<4; // set shift mode
if (shift == 6) i|=(1<<20);
} else {
i = getnum (arg);
// ensure only the bottom 5 bits are used
i &= 0x1f;
if (!i)
i = 32;
if (!i) i = 32;
i = (i*8);
i |= shift; // lsl, ror, ...
i = i << 4;
}
}
i += shift;
i = i << 4;
r_mem_copyendian ((ut8*)&shift, (const ut8*)&i, sizeof (ut32), 0);
return shift;
@ -541,6 +551,16 @@ static int arm_assemble(ArmOpcode *ao, const char *str) {
return 0;
} else ao->o |= (getreg (ao->a[0])<<24);
break;
case TYPE_HLT:
{
ut32 o = 0, n = getnum (ao->a[0]);
o |= ((n>>12)&0xf)<<8;
o |= ((n>>8)&0xf)<<20;
o |= ((n>>4)&0xf)<<16;
o |= ((n)&0xf)<<24;
ao->o |=o;
}
break;
case TYPE_SWI:
ao->o |= (getnum (ao->a[0])&0xff)<<24;
ao->o |= ((getnum (ao->a[0])>>8)&0xff)<<16;
@ -575,23 +595,22 @@ static int arm_assemble(ArmOpcode *ao, const char *str) {
}
ao->o = 0x50e3;
// TODO: if (b>255) -> automatic multiplier
if (ao->a[2]) {
int n = getnum (ao->a[2]);
if (n&1) {
eprintf ("Invalid multiplier\n");
return 0;
}
ao->o |= (n>>1)<<16;
}
ao->o |= (a<<8);
ao->o |= ((b&0xff)<<24);
} else {
//ao->o |= getreg(ao->a[0])<<20; // ???
ao->o |= (a<<8);
ao->o |= (b<<24);
if (ao->a[2])
ao->o |= getshift (ao->a[2]);
}
if (ao->a[2]) {
int n = getnum (ao->a[2]);
if (n&1) {
eprintf ("Invalid multiplier\n");
return 0;
}
ao->o |= (n>>1)<<16;
}
break;
}
return 1;

View file

@ -3537,7 +3537,10 @@ print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
value_in_comment = value + 1;
break;
case 'x':
func (stream, "0x%08lx", value);
if (value)
func (stream, "0x%lx", value);
else
func (stream, "0");
/* Some SWI instructions have special
meanings. */
@ -3864,7 +3867,10 @@ print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
break;
case 'x':
func (stream, "0x%04lx", (long) reg);
if (reg) {
func (stream, "0x%lx", (long) reg);
}else
func (stream, "0");
break;
case 'B':

View file

@ -20,18 +20,23 @@ fi
BITS=32
# arm32
foo 'bkpt'
foo 'bkpt 0x0000'
foo 'svc 0x1024'
foo 'cmp r7, 1338'
foo 'cmp r7, 666'
foo 'tst r4, r5, 10' # e1140505
foo 'hlt 0x1024'
foo 'hlt 0x1234'
#foo 'cmp r7, 1338'
#foo 'cmp r7, 666'
foo 'cmp r7, 0xfe'
foo 'cmp r7, 0x20'
foo 'tst r4, r5' # e1140505
foo 'tst r4, r5, lsl 10' # e1140505
foo 'cmp r1, r2'
foo 'cmp r1, r2, lsl r3'
foo 'cmp sl, fp, lsl r3'
foo 'cmp sl, fp, ror r1'
foo 'mvn r4, 32' # e3e04020
foo 'mvn r4, 0x21' # e3e04020
foo 'add r2, r2, r1'
foo 'mov r2, #33'
foo 'mov r2, 0x21'
foo 'mov r2, 0x21'
foo 'sub r1, r3, r3'
foo 'push {r1, r2}'

View file

@ -140,13 +140,23 @@ static int r_line_hist_down() {
return R_FALSE;
}
R_API const char *r_line_hist_get(int n) {
int i = 0;
if (!I.history.data)
inithist ();
if (I.history.data != NULL)
for (i=0; i<I.history.size && I.history.data[i]; i++)
if (n==i) return I.history.data[i];
return NULL;
}
R_API int r_line_hist_list() {
int i = 0;
if (!I.history.data)
inithist ();
if (I.history.data != NULL)
for (i=0; i<I.history.size && I.history.data[i]; i++)
printf ("%.3d %s\n", i, I.history.data[i]);
printf (" !%d # %s\n", i, I.history.data[i]);
return i;
}
@ -625,6 +635,7 @@ _end:
fflush (stdout);
}
// should be here or not?
if (!memcmp (I.buffer.data, "!history", 8)) {
//if (I.buffer.data[0]=='!' && I.buffer.data[1]=='\0') {
r_line_hist_list ();

View file

@ -517,32 +517,42 @@ static int cmd_visual(void *data, const char *input) {
}
static int cmd_system(void *data, const char *input) {
RCore *core = (RCore*)data;
ut64 n;
int ret = 0;
switch (*input) {
case '!': {
int olen;
char *out = NULL;
char *cmd = r_core_sysenv_begin ((RCore*)data, input);
char *cmd = r_core_sysenv_begin (core, input);
if (cmd) {
ret = r_sys_cmd_str_full (cmd+1, NULL, &out, &olen, NULL);
r_core_sysenv_end ((RCore*)data, input);
r_core_sysenv_end (core, input);
r_cons_memcat (out, olen);
free (out);
free (cmd);
} else eprintf ("Error setting up system environment\n");
}
break;
case '\0':
r_line_hist_list ();
break;
case '?':
r_core_sysenv_help ();
break;
default:
{
char *cmd = r_core_sysenv_begin ((RCore*)data, input);
if (cmd) {
ret = r_sys_cmd (cmd);
r_core_sysenv_end ((RCore*)data, input);
free (cmd);
} else eprintf ("Error setting up system environment\n");
n = r_num_math (core->num, input);
if (*input=='0' || n>0) {
char *cmd = r_line_hist_get (n);
if (cmd) r_core_cmd0 (core, cmd);
else eprintf ("Error setting up system environment\n");
} else {
char *cmd = r_core_sysenv_begin (core, input);
if (cmd) {
ret = r_sys_cmd (cmd);
r_core_sysenv_end (core, input);
free (cmd);
} else eprintf ("Error setting up system environment\n");
}
break;
}

View file

@ -1,20 +1,14 @@
/* radare - LGPL - Copyright 2009-2012 - pancake */
/* radare - LGPL - Copyright 2009-2013 - pancake */
static int cmd_macro(void *data, const char *input) {
char *buf = NULL;
RCore *core = (RCore*)data;
switch (*input) {
case ')':
r_cmd_macro_break (&core->rcmd->macro, input+1);
break;
case '-':
r_cmd_macro_rm (&core->rcmd->macro, input+1);
break;
case ')': r_cmd_macro_break (&core->rcmd->macro, input+1); break;
case '-': r_cmd_macro_rm (&core->rcmd->macro, input+1); break;
case '*':
case '\0':
r_cmd_macro_list (&core->rcmd->macro);
break;
case '\0': r_cmd_macro_list (&core->rcmd->macro); break;
case '?':
eprintf (
"Usage: (foo args,cmd1,cmd2,..)\n"

View file

@ -38,7 +38,7 @@ static int r_core_magic_at(RCore *core, const char *file, ut64 addr, int depth,
str = r_magic_buffer (ck, core->block, core->blocksize);
if (str) {
if (!v && !strcmp (str, "data"))
return;
return -1;
p = strdup (str);
fmt = p;
// processing newlinez

View file

@ -58,10 +58,11 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
R_API void r_core_sysenv_help() {
r_cons_printf (
"Usage: !<cmd>\n"
" !ls ; execute 'ls' in shell\n"
" !!ls~txt ; printo utput of 'ls' and grep for 'txt'\n"
" .!rabin2 -rvi ${FILE} ; run each output line as a r2 cmd\n"
" !echo $SIZE ; display file size\n"
" ! list all historic commands\n"
" !ls execute 'ls' in shell\n"
" !!ls~txt printo utput of 'ls' and grep for 'txt'\n"
" .!rabin2 -rvi ${FILE} run each output line as a r2 cmd\n"
" !echo $SIZE display file size\n"
"Environment:\n"
" FILE file name\n"
" SIZE file size\n"

View file

@ -303,6 +303,8 @@ R_API int r_line_hist_add(const char *line);
R_API int r_line_hist_save(const char *file);
R_API int r_line_hist_label(const char *label, void (*cb)(const char*));
R_API void r_line_label_show();
R_API int r_line_hist_list();
R_API const char *r_line_hist_get(int n);
#define R_CONS_INVERT(x,y) (y? (x?Color_INVERT: Color_INVERT_RESET): (x?"[":"]"))