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:
parent
67f0794b82
commit
8846cb79cf
9 changed files with 109 additions and 61 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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':
|
||||
|
|
|
|||
|
|
@ -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}'
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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?"[":"]"))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue