mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 15:41:38 +00:00
New command 'ss' (Silent Seek)
These commands seek to an address or a register without logging the entry in the seek history.
This commit is contained in:
parent
42f9d62a61
commit
26fd259d04
2
Makefile
2
Makefile
@ -5,7 +5,7 @@ PREVIOUS_RELEASE=1.2.0
|
|||||||
|
|
||||||
R2R=radare2-regressions
|
R2R=radare2-regressions
|
||||||
R2R_URL=$(shell doc/repo REGRESSIONS)
|
R2R_URL=$(shell doc/repo REGRESSIONS)
|
||||||
R2BINS=$(shell cd binr ; echo r*2 r2agent r2pm)
|
R2BINS=$(shell cd binr ; echo r*2 r2agent r2pm r2-indent)
|
||||||
BUILDSEC=$(shell date "+__%H:%M:%S")
|
BUILDSEC=$(shell date "+__%H:%M:%S")
|
||||||
DATADIRS=libr/cons/d libr/bin/d libr/asm/d libr/syscall/d libr/magic/d libr/anal/d
|
DATADIRS=libr/cons/d libr/bin/d libr/asm/d libr/syscall/d libr/magic/d libr/anal/d
|
||||||
USE_ZIP=YES
|
USE_ZIP=YES
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "r_debug.h"
|
#include "r_debug.h"
|
||||||
#include "r_io.h"
|
#include "r_io.h"
|
||||||
|
|
||||||
static void __init_seek_line (RCore *core) {
|
static void __init_seek_line(RCore *core) {
|
||||||
ut64 from, to;
|
ut64 from, to;
|
||||||
|
|
||||||
r_config_bump (core->config, "lines.to");
|
r_config_bump (core->config, "lines.to");
|
||||||
@ -29,38 +29,38 @@ static void printPadded(RCore *core, int pad) {
|
|||||||
free (fmt);
|
free (fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __get_current_line (RCore *core) {
|
static void __get_current_line(RCore *core) {
|
||||||
if (core->print->lines_cache_sz > 0) {
|
if (core->print->lines_cache_sz > 0) {
|
||||||
int curr = r_util_lines_getline (core->print->lines_cache, core->print->lines_cache_sz, core->offset);
|
int curr = r_util_lines_getline (core->print->lines_cache, core->print->lines_cache_sz, core->offset);
|
||||||
r_cons_printf ("%d\n", curr);
|
r_cons_printf ("%d\n", curr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __seek_line_absolute (RCore *core, int numline) {
|
static void __seek_line_absolute(RCore *core, int numline) {
|
||||||
if (numline < 1 || numline > core->print->lines_cache_sz - 1) {
|
if (numline < 1 || numline > core->print->lines_cache_sz - 1) {
|
||||||
eprintf ("ERROR: Line must be between 1 and %d\n", core->print->lines_cache_sz-1);
|
eprintf ("ERROR: Line must be between 1 and %d\n", core->print->lines_cache_sz - 1);
|
||||||
} else {
|
} else {
|
||||||
r_core_seek (core, core->print->lines_cache[numline-1], 1);
|
r_core_seek (core, core->print->lines_cache[numline - 1], 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __seek_line_relative (RCore *core, int numlines) {
|
static void __seek_line_relative(RCore *core, int numlines) {
|
||||||
int curr = r_util_lines_getline (core->print->lines_cache, core->print->lines_cache_sz, core->offset);
|
int curr = r_util_lines_getline (core->print->lines_cache, core->print->lines_cache_sz, core->offset);
|
||||||
if (numlines > 0 && curr+numlines >= core->print->lines_cache_sz-1) {
|
if (numlines > 0 && curr + numlines >= core->print->lines_cache_sz - 1) {
|
||||||
eprintf ("ERROR: Line must be < %d\n", core->print->lines_cache_sz-1);
|
eprintf ("ERROR: Line must be < %d\n", core->print->lines_cache_sz - 1);
|
||||||
} else if (numlines < 0 && curr+numlines < 1) {
|
} else if (numlines < 0 && curr + numlines < 1) {
|
||||||
eprintf ("ERROR: Line must be > 1\n");
|
eprintf ("ERROR: Line must be > 1\n");
|
||||||
} else {
|
} else {
|
||||||
r_core_seek (core, core->print->lines_cache[curr+numlines-1], 1);
|
r_core_seek (core, core->print->lines_cache[curr + numlines - 1], 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __clean_lines_cache (RCore *core) {
|
static void __clean_lines_cache(RCore *core) {
|
||||||
core->print->lines_cache_sz = -1;
|
core->print->lines_cache_sz = -1;
|
||||||
R_FREE (core->print->lines_cache);
|
R_FREE (core->print->lines_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_core_lines_currline (RCore *core) { // make priv8 again
|
R_API int r_core_lines_currline(RCore *core) { // make priv8 again
|
||||||
int imin = 0;
|
int imin = 0;
|
||||||
int imax = core->print->lines_cache_sz;
|
int imax = core->print->lines_cache_sz;
|
||||||
int imid = 0;
|
int imid = 0;
|
||||||
@ -69,21 +69,21 @@ R_API int r_core_lines_currline (RCore *core) { // make priv8 again
|
|||||||
imid = imin + ((imax - imin) / 2);
|
imid = imin + ((imax - imin) / 2);
|
||||||
if (core->print->lines_cache[imid] == core->offset) {
|
if (core->print->lines_cache[imid] == core->offset) {
|
||||||
return imid;
|
return imid;
|
||||||
}
|
} else if (core->print->lines_cache[imid] < core->offset) {
|
||||||
else if (core->print->lines_cache[imid] < core->offset)
|
|
||||||
imin = imid + 1;
|
imin = imid + 1;
|
||||||
else
|
} else {
|
||||||
imax = imid - 1;
|
imax = imid - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return imin;
|
return imin;
|
||||||
}
|
}
|
||||||
|
|
||||||
R_API int r_core_lines_initcache (RCore *core, ut64 start_addr, ut64 end_addr) {
|
R_API int r_core_lines_initcache(RCore *core, ut64 start_addr, ut64 end_addr) {
|
||||||
int i, line_count;
|
int i, line_count;
|
||||||
int bsz = core->blocksize;
|
int bsz = core->blocksize;
|
||||||
char *buf;
|
char *buf;
|
||||||
ut64 off = start_addr;
|
ut64 off = start_addr;
|
||||||
ut64 baddr;
|
ut64 baddr;
|
||||||
if (start_addr == UT64_MAX || end_addr == UT64_MAX) {
|
if (start_addr == UT64_MAX || end_addr == UT64_MAX) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -96,11 +96,11 @@ R_API int r_core_lines_initcache (RCore *core, ut64 start_addr, ut64 end_addr) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
RIOSection *s = r_io_section_mget_in (core->io, core->offset);
|
RIOSection *s = r_io_section_mget_in (core->io, core->offset);
|
||||||
baddr = s ? s->paddr : r_config_get_i (core->config, "bin.baddr");
|
baddr = s? s->paddr: r_config_get_i (core->config, "bin.baddr");
|
||||||
}
|
}
|
||||||
|
|
||||||
line_count = start_addr ? 0 : 1;
|
line_count = start_addr? 0: 1;
|
||||||
core->print->lines_cache[0] = start_addr ? 0 : baddr;
|
core->print->lines_cache[0] = start_addr? 0: baddr;
|
||||||
buf = malloc (bsz);
|
buf = malloc (bsz);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -110,14 +110,14 @@ R_API int r_core_lines_initcache (RCore *core, ut64 start_addr, ut64 end_addr) {
|
|||||||
if (r_cons_is_breaked ()) {
|
if (r_cons_is_breaked ()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
r_io_read_at (core->io, off, (ut8*)buf, bsz);
|
r_io_read_at (core->io, off, (ut8 *) buf, bsz);
|
||||||
for (i = 0; i < bsz; i++) {
|
for (i = 0; i < bsz; i++) {
|
||||||
if (buf[i] == '\n') {
|
if (buf[i] == '\n') {
|
||||||
core->print->lines_cache[line_count] = start_addr ? off+i+1 : off+i+1+baddr;
|
core->print->lines_cache[line_count] = start_addr? off + i + 1: off + i + 1 + baddr;
|
||||||
line_count++;
|
line_count++;
|
||||||
if (line_count % bsz == 0) {
|
if (line_count % bsz == 0) {
|
||||||
ut64 *tmp = realloc (core->print->lines_cache,
|
ut64 *tmp = realloc (core->print->lines_cache,
|
||||||
(line_count+bsz)*sizeof(ut64));
|
(line_count + bsz) * sizeof(ut64));
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
core->print->lines_cache = tmp;
|
core->print->lines_cache = tmp;
|
||||||
} else {
|
} else {
|
||||||
@ -138,341 +138,401 @@ beach:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void seek_to_register(RCore *core, const char *input, bool is_silent) {
|
||||||
|
ut64 off;
|
||||||
|
if (core->io->debug) {
|
||||||
|
off = r_debug_reg_get (core->dbg, input);
|
||||||
|
if (!is_silent) {
|
||||||
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
|
}
|
||||||
|
r_core_seek (core, off, 1);
|
||||||
|
} else {
|
||||||
|
RReg *orig = core->dbg->reg;
|
||||||
|
core->dbg->reg = core->anal->reg;
|
||||||
|
off = r_debug_reg_get (core->dbg, input);
|
||||||
|
core->dbg->reg = orig;
|
||||||
|
if (!is_silent) {
|
||||||
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
|
}
|
||||||
|
r_core_seek (core, off, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_seek(void *data, const char *input) {
|
static int cmd_seek(void *data, const char *input) {
|
||||||
RCore *core = (RCore *)data;
|
RCore *core = (RCore *) data;
|
||||||
char *cmd, *p;
|
char *cmd, *p;
|
||||||
ut64 off;
|
ut64 off;
|
||||||
|
|
||||||
if (*input == 'r') {
|
if (*input == 'r') {
|
||||||
if (input[1] && input[2]) {
|
if (input[1] && input[2]) {
|
||||||
if (core->io->debug) {
|
seek_to_register (core, input + 2, false);
|
||||||
off = r_debug_reg_get (core->dbg, input + 2);
|
} else {
|
||||||
|
eprintf ("|Usage| 'sr PC' seek to program counter register\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!*input) {
|
||||||
|
r_cons_printf ("0x%"PFMT64x "\n", core->offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
char *ptr;
|
||||||
|
if ((ptr = strstr (input, "+.")) != NULL) {
|
||||||
|
char *dup = strdup (input);
|
||||||
|
dup[ptr - input] = '\x00';
|
||||||
|
off = r_num_math (core->num, dup + 1);
|
||||||
|
core->offset = off;
|
||||||
|
free (dup);
|
||||||
|
}
|
||||||
|
const char *inputnum = strchr (input, ' ');
|
||||||
|
int sign = 1;
|
||||||
|
{
|
||||||
|
const char *u_num = inputnum? inputnum + 1: input + 1;
|
||||||
|
off = r_num_math (core->num, u_num);
|
||||||
|
if (*u_num == '-') {
|
||||||
|
off = -off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (input[0] == ' ') {
|
||||||
|
switch (input[1]) {
|
||||||
|
case '-': sign = -1;
|
||||||
|
case '+': input++; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*input) {
|
||||||
|
case 'C':
|
||||||
|
if (input[1] == '*') {
|
||||||
|
r_core_cmd0 (core, "C*~^\"CC");
|
||||||
|
} else if (input[1] == ' ') {
|
||||||
|
typedef struct {
|
||||||
|
ut64 addr;
|
||||||
|
char *str;
|
||||||
|
} MetaCallback;
|
||||||
|
int count = 0;
|
||||||
|
MetaCallback cb = {
|
||||||
|
0, NULL
|
||||||
|
};
|
||||||
|
ut64 addr;
|
||||||
|
char key[128];
|
||||||
|
const char *val, *comma;
|
||||||
|
char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
|
||||||
|
char *str, *next, *cur = list;
|
||||||
|
if (list) {
|
||||||
|
for (;;) {
|
||||||
|
cur = sdb_anext (cur, &next);
|
||||||
|
addr = sdb_atoi (cur);
|
||||||
|
snprintf (key, sizeof (key) - 1, "meta.C.0x%"PFMT64x, addr);
|
||||||
|
val = sdb_const_get (core->anal->sdb_meta, key, 0);
|
||||||
|
if (val) {
|
||||||
|
comma = strchr (val, ',');
|
||||||
|
if (comma) {
|
||||||
|
str = (char *) sdb_decode (comma + 1, 0);
|
||||||
|
if (strstr (str, input + 2)) {
|
||||||
|
r_cons_printf ("0x%08"PFMT64x " %s\n", addr, str);
|
||||||
|
count++;
|
||||||
|
cb.addr = addr;
|
||||||
|
free (cb.str);
|
||||||
|
cb.str = str;
|
||||||
|
} else {
|
||||||
|
free (str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintf ("sdb_const_get key not found '%s'\n", key);
|
||||||
|
}
|
||||||
|
if (!next) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (count) {
|
||||||
|
case 0:
|
||||||
|
eprintf ("No matching comments\n");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
off = cb.addr;
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
r_core_seek (core, off, 1);
|
r_core_seek (core, off, 1);
|
||||||
} else {
|
r_core_block_read (core);
|
||||||
RReg *orig = core->dbg->reg;
|
break;
|
||||||
core->dbg->reg = core->anal->reg;
|
default:
|
||||||
off = r_debug_reg_get (core->dbg, input + 2);
|
eprintf ("Too many results\n");
|
||||||
core->dbg->reg = orig;
|
break;
|
||||||
r_core_seek (core, off, 1);
|
|
||||||
}
|
}
|
||||||
} else eprintf ("|Usage| 'sr PC' seek to program counter register\n");
|
free (cb.str);
|
||||||
|
} else {
|
||||||
|
const char *help_msg[] = {
|
||||||
|
"Usage:", "sC", "Comment grep",
|
||||||
|
"sC", "*", "List all comments",
|
||||||
|
"sC", " str", "Seek to the first comment matching 'str'",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
r_core_cmd_help (core, help_msg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
|
r_core_seek (core, off * sign, 1);
|
||||||
|
r_core_block_read (core);
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
{
|
||||||
|
const char *pfx = r_config_get (core->config, "search.prefix");
|
||||||
|
ut64 from = r_config_get_i (core->config, "search.from");
|
||||||
|
// kwidx cfg var is ignored
|
||||||
|
int kwidx = core->search->n_kws; // (int)r_config_get_i (core->config, "search.kwidx")-1;
|
||||||
|
if (kwidx < 0) {
|
||||||
|
kwidx = 0;
|
||||||
|
}
|
||||||
|
switch (input[1]) {
|
||||||
|
case ' ':
|
||||||
|
case 'v':
|
||||||
|
case 'V':
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
case 'z':
|
||||||
|
case 'm':
|
||||||
|
case 'c':
|
||||||
|
case 'A':
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'i':
|
||||||
|
case 'R':
|
||||||
|
case 'r':
|
||||||
|
case '/':
|
||||||
|
case 'x':
|
||||||
|
r_config_set_i (core->config, "search.from", core->offset + 1);
|
||||||
|
r_config_set_i (core->config, "search.count", 1);
|
||||||
|
r_core_cmdf (core, "s+1; %s; s-1; s %s%d_0; f-%s%d_0",
|
||||||
|
input, pfx, kwidx, pfx, kwidx, pfx, kwidx);
|
||||||
|
r_config_set_i (core->config, "search.from", from);
|
||||||
|
r_config_set_i (core->config, "search.count", 0);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
eprintf ("Usage: s/.. arg.\n");
|
||||||
|
r_cons_printf ("/?\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf ("unknown search method\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (*input) {
|
break;
|
||||||
char* ptr;
|
case '.':
|
||||||
if ((ptr = strstr(input, "+.")) != NULL) {
|
for (input++; *input == '.'; input++) {
|
||||||
char* dup = strdup(input);
|
;
|
||||||
dup[ptr - input] = '\x00';
|
|
||||||
off = r_num_math (core->num, dup + 1);
|
|
||||||
core->offset = off;
|
|
||||||
free (dup);
|
|
||||||
}
|
}
|
||||||
const char *inputnum = strchr (input, ' ');
|
r_core_seek_base (core, input);
|
||||||
int sign = 1;
|
break;
|
||||||
{
|
case '*':
|
||||||
const char *u_num = inputnum? inputnum + 1: input + 1;
|
case '=':
|
||||||
off = r_num_math (core->num, u_num);
|
case 'j':
|
||||||
if (*u_num == '-') off = -off;
|
r_io_sundo_list (core->io, input[0]);
|
||||||
}
|
break;
|
||||||
#if 0
|
case '+':
|
||||||
if (input[0]!='/' && inputnum && isalpha (inputnum[0]) && off == 0) {
|
if (input[1] != '\0') {
|
||||||
if (!r_flag_get (core->flags, inputnum)) {
|
int delta = (input[1] == '+')? core->blocksize: off;
|
||||||
eprintf ("Cannot find address for '%s'\n", inputnum);
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
return false;
|
r_core_seek_delta (core, delta);
|
||||||
|
} else {
|
||||||
|
RIOUndos *undo = r_io_sundo_redo (core->io);
|
||||||
|
if (undo) {
|
||||||
|
r_core_seek (core, undo->off, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
break;
|
||||||
if (input[0]==' ') {
|
case '-':
|
||||||
switch (input[1]) {
|
if (input[1] != '\0') {
|
||||||
case '-': sign=-1;
|
int delta = (input[1] == '-')? -core->blocksize: -off;
|
||||||
case '+': input++; break;
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
|
r_core_seek_delta (core, delta);
|
||||||
|
} else {
|
||||||
|
RIOUndos *undo = r_io_sundo (core->io, core->offset);
|
||||||
|
if (undo) {
|
||||||
|
r_core_seek (core, undo->off, 0);
|
||||||
|
r_core_block_read (core);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
switch (*input) {
|
case 'n':
|
||||||
case 'C':
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
if (input[1]=='*') {
|
r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
|
||||||
r_core_cmd0 (core, "C*~^\"CC");
|
break;
|
||||||
} else
|
case 'p':
|
||||||
if (input[1]==' ') {
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
typedef struct {
|
r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
|
||||||
ut64 addr;
|
break;
|
||||||
char *str;
|
case 'a':
|
||||||
} MetaCallback;
|
off = core->blocksize;
|
||||||
int count = 0;
|
if (input[1] && input[2]) {
|
||||||
MetaCallback cb = { 0, NULL };
|
cmd = strdup (input);
|
||||||
ut64 addr;
|
p = strchr (cmd + 2, ' ');
|
||||||
char key[128];
|
if (p) {
|
||||||
const char *val, *comma;
|
off = r_num_math (core->num, p + 1);;
|
||||||
char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
|
*p = '\0';
|
||||||
char *str, *next, *cur = list;
|
}
|
||||||
if (list) {
|
cmd[0] = 's';
|
||||||
for (;;) {
|
// perform real seek if provided
|
||||||
cur = sdb_anext (cur, &next);
|
r_cmd_call (core->rcmd, cmd);
|
||||||
addr = sdb_atoi (cur);
|
free (cmd);
|
||||||
snprintf (key, sizeof (key)-1, "meta.C.0x%"PFMT64x, addr);
|
}
|
||||||
val = sdb_const_get (core->anal->sdb_meta, key, 0);
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
if (val) {
|
r_core_seek_align (core, off, 0);
|
||||||
comma = strchr (val, ',');
|
break;
|
||||||
if (comma) {
|
case 'b':
|
||||||
str = (char *)sdb_decode (comma+1, 0);
|
if (off == 0) {
|
||||||
if (strstr (str, input+2)) {
|
off = core->offset;
|
||||||
r_cons_printf ("0x%08"PFMT64x" %s\n", addr, str);
|
}
|
||||||
count++;
|
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
||||||
cb.addr = addr;
|
r_core_anal_bb_seek (core, off);
|
||||||
free (cb.str);
|
break;
|
||||||
cb.str = str;
|
case 'f': // "sf"
|
||||||
} else free (str);
|
if (strlen (input) > 2 && input[1] == ' ') {
|
||||||
}
|
RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, input + 2);
|
||||||
} else eprintf ("sdb_const_get key not found '%s'\n", key);
|
if (fcn) {
|
||||||
if (!next)
|
r_core_seek (core, fcn->addr, 1);
|
||||||
break;
|
|
||||||
cur = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (count) {
|
|
||||||
case 0:
|
|
||||||
eprintf ("No matching comments\n");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
off = cb.addr;
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_seek (core, off, 1);
|
|
||||||
r_core_block_read (core);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
eprintf ("Too many results\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free (cb.str);
|
|
||||||
} else {
|
|
||||||
const char *help_msg[] = {
|
|
||||||
"Usage:", "sC", "Comment grep",
|
|
||||||
"sC", "*", "List all comments",
|
|
||||||
"sC", " str", "Seek to the first comment matching 'str'",
|
|
||||||
NULL };
|
|
||||||
r_core_cmd_help (core, help_msg);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
|
||||||
|
if (fcn) {
|
||||||
|
r_core_seek (core, fcn->addr + r_anal_fcn_size (fcn), 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'o': // "so"
|
||||||
|
{
|
||||||
|
RAnalOp op;
|
||||||
|
int val = 0, ret, i, n = r_num_math (core->num, input + 1);
|
||||||
|
if (n == 0) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
if (n < 0) {
|
||||||
|
int instr_len;
|
||||||
|
ut64 addr = core->offset;
|
||||||
|
int numinstr = n * -1;
|
||||||
|
if (r_core_prevop_addr (core, core->offset, numinstr, &addr)) {
|
||||||
|
ret = core->offset - addr;
|
||||||
|
} else {
|
||||||
|
ret = r_core_asm_bwdis_len (core, &instr_len, &addr, numinstr);
|
||||||
|
}
|
||||||
|
r_core_seek (core, addr, true);
|
||||||
|
val += ret;
|
||||||
|
} else {
|
||||||
|
for (val = i = 0; i < n; i++) {
|
||||||
|
ret = r_anal_op (core->anal, &op,
|
||||||
|
core->offset, core->block, core->blocksize);
|
||||||
|
if (ret < 1) {
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
r_core_seek_delta (core, ret);
|
||||||
|
val += ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
core->num->value = val;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'g': // "sg"
|
||||||
|
{
|
||||||
|
RIOSection *s = r_io_section_vget (core->io, core->offset);
|
||||||
|
if (s) {
|
||||||
|
r_core_seek (core, s->vaddr, 1);
|
||||||
|
} else {
|
||||||
|
r_core_seek (core, 0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'G': // "sG"
|
||||||
|
{
|
||||||
|
if (!core->file) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RIOSection *s = r_io_section_vget (core->io, core->offset);
|
||||||
|
// XXX: this +2 is a hack. must fix gap between sections
|
||||||
|
if (s) {
|
||||||
|
r_core_seek (core, s->vaddr + s->size + 2, 1);
|
||||||
|
} else {
|
||||||
|
r_core_seek (core, r_io_desc_size (core->io, core->file->desc), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'l': // "sl"
|
||||||
|
{
|
||||||
|
int sl_arg = r_num_math (core->num, input + 1);
|
||||||
|
const char *help_msg[] = {
|
||||||
|
"Usage:", "sl+ or sl- or slc", "",
|
||||||
|
"sl", " [line]", "Seek to absolute line",
|
||||||
|
"sl", "[+-][line]", "Seek to relative line",
|
||||||
|
"slc", "", "Clear line cache",
|
||||||
|
"sll", "", "Show total number of lines",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
switch (input[1]) {
|
||||||
|
case 0:
|
||||||
|
if (!core->print->lines_cache) {
|
||||||
|
__init_seek_line (core);
|
||||||
|
}
|
||||||
|
__get_current_line (core);
|
||||||
|
break;
|
||||||
case ' ':
|
case ' ':
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
if (!core->print->lines_cache) {
|
||||||
|
__init_seek_line (core);
|
||||||
|
}
|
||||||
|
__seek_line_absolute (core, sl_arg);
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
if (!core->print->lines_cache) {
|
||||||
|
__init_seek_line (core);
|
||||||
|
}
|
||||||
|
__seek_line_relative (core, sl_arg);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
__clean_lines_cache (core);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (!core->print->lines_cache) {
|
||||||
|
__init_seek_line (core);
|
||||||
|
}
|
||||||
|
eprintf ("%d lines\n", core->print->lines_cache_sz - 1);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
r_core_cmd_help (core, help_msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
printPadded (core, atoi (input + 1));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
switch (input[1]) {
|
||||||
|
case 'r':
|
||||||
|
if (!input[2] || !input[3]) {
|
||||||
|
eprintf ("|Usage| 'ssr PC' seek to program counter register\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
seek_to_register (core, input + 3, true);
|
||||||
|
break;
|
||||||
|
case '?': {
|
||||||
|
const char *help_message[] = {
|
||||||
|
"Usage: ss", "", " # Seek silently commands (without adding the address to the seek history)",
|
||||||
|
"ss", " addr", "Seek silently to address",
|
||||||
|
"ssr", " pc", "Seek silently to register",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
r_core_cmd_help (core, help_message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
r_core_seek (core, off * sign, 1);
|
r_core_seek (core, off * sign, 1);
|
||||||
r_core_block_read (core);
|
r_core_block_read (core);
|
||||||
break;
|
break;
|
||||||
case '/':
|
}
|
||||||
{
|
|
||||||
const char *pfx = r_config_get (core->config, "search.prefix");
|
break;
|
||||||
ut64 from = r_config_get_i (core->config, "search.from");
|
case '?': {
|
||||||
//kwidx cfg var is ignored
|
const char *help_message[] = {
|
||||||
int kwidx = core->search->n_kws; //(int)r_config_get_i (core->config, "search.kwidx")-1;
|
|
||||||
if (kwidx<0) kwidx = 0;
|
|
||||||
switch (input[1]) {
|
|
||||||
case ' ':
|
|
||||||
case 'v':
|
|
||||||
case 'V':
|
|
||||||
case 'w':
|
|
||||||
case 'W':
|
|
||||||
case 'z':
|
|
||||||
case 'm':
|
|
||||||
case 'c':
|
|
||||||
case 'A':
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
case 'i':
|
|
||||||
case 'R':
|
|
||||||
case 'r':
|
|
||||||
case '/':
|
|
||||||
case 'x':
|
|
||||||
r_config_set_i (core->config, "search.from", core->offset+1);
|
|
||||||
r_config_set_i (core->config, "search.count", 1);
|
|
||||||
r_core_cmdf (core, "s+1; %s; s-1; s %s%d_0; f-%s%d_0",
|
|
||||||
input, pfx, kwidx, pfx, kwidx, pfx, kwidx);
|
|
||||||
r_config_set_i (core->config, "search.from", from);
|
|
||||||
r_config_set_i (core->config, "search.count", 0);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
eprintf ("Usage: s/.. arg.\n");
|
|
||||||
r_cons_printf ("/?\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
eprintf ("unknown search method\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '.':
|
|
||||||
for (input++;*input=='.';input++);
|
|
||||||
r_core_seek_base (core, input);
|
|
||||||
break;
|
|
||||||
case '*':
|
|
||||||
case '=':
|
|
||||||
case 'j':
|
|
||||||
r_io_sundo_list (core->io, input[0]);
|
|
||||||
break;
|
|
||||||
case '+':
|
|
||||||
if (input[1]!='\0') {
|
|
||||||
int delta = (input[1]=='+')? core->blocksize: off;
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_seek_delta (core, delta);
|
|
||||||
} else {
|
|
||||||
RIOUndos *undo = r_io_sundo_redo (core->io);
|
|
||||||
if (undo != NULL)
|
|
||||||
r_core_seek (core, undo->off, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
if (input[1]!='\0') {
|
|
||||||
int delta = (input[1]=='-') ? -core->blocksize: -off;
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_seek_delta (core, delta);
|
|
||||||
} else {
|
|
||||||
RIOUndos *undo = r_io_sundo (core->io, core->offset);
|
|
||||||
if (undo) {
|
|
||||||
r_core_seek (core, undo->off, 0);
|
|
||||||
r_core_block_read (core);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
off = core->blocksize;
|
|
||||||
if (input[1]&&input[2]) {
|
|
||||||
cmd = strdup (input);
|
|
||||||
p = strchr (cmd+2, ' ');
|
|
||||||
if (p) {
|
|
||||||
off = r_num_math (core->num, p+1);;
|
|
||||||
*p = '\0';
|
|
||||||
}
|
|
||||||
cmd[0] = 's';
|
|
||||||
// perform real seek if provided
|
|
||||||
r_cmd_call (core->rcmd, cmd);
|
|
||||||
free (cmd);
|
|
||||||
}
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_seek_align (core, off, 0);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
if (off == 0)
|
|
||||||
off = core->offset;
|
|
||||||
r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
|
|
||||||
r_core_anal_bb_seek (core, off);
|
|
||||||
break;
|
|
||||||
case 'f': // "sf"
|
|
||||||
if (strlen(input) > 2 && input[1]==' ') {
|
|
||||||
RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, input+2);
|
|
||||||
if (fcn) {
|
|
||||||
r_core_seek (core, fcn->addr, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
|
|
||||||
if (fcn) {
|
|
||||||
r_core_seek (core, fcn->addr + r_anal_fcn_size (fcn), 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'o': // "so"
|
|
||||||
{
|
|
||||||
RAnalOp op;
|
|
||||||
int val=0, ret, i, n = r_num_math (core->num, input+1);
|
|
||||||
if (n==0) n = 1;
|
|
||||||
if (n<0) {
|
|
||||||
int instr_len;
|
|
||||||
ut64 addr = core->offset;
|
|
||||||
int numinstr = n * -1;
|
|
||||||
if (r_core_prevop_addr (core, core->offset, numinstr, &addr)) {
|
|
||||||
ret = core->offset - addr;
|
|
||||||
} else {
|
|
||||||
ret = r_core_asm_bwdis_len (core, &instr_len, &addr, numinstr);
|
|
||||||
}
|
|
||||||
r_core_seek (core, addr, true);
|
|
||||||
val += ret;
|
|
||||||
} else {
|
|
||||||
for (val=i=0; i<n; i++) {
|
|
||||||
ret = r_anal_op (core->anal, &op,
|
|
||||||
core->offset, core->block, core->blocksize);
|
|
||||||
if (ret<1)
|
|
||||||
ret = 1;
|
|
||||||
r_core_seek_delta (core, ret);
|
|
||||||
val += ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
core->num->value = val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'g': // "sg"
|
|
||||||
{
|
|
||||||
RIOSection *s = r_io_section_vget (core->io, core->offset);
|
|
||||||
if (s) r_core_seek (core, s->vaddr, 1);
|
|
||||||
else r_core_seek (core, 0, 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'G': // "sG"
|
|
||||||
{
|
|
||||||
if (!core->file) break;
|
|
||||||
RIOSection *s = r_io_section_vget (core->io, core->offset);
|
|
||||||
// XXX: this +2 is a hack. must fix gap between sections
|
|
||||||
if (s) r_core_seek (core, s->vaddr+s->size+2, 1);
|
|
||||||
else r_core_seek (core, r_io_desc_size (core->io, core->file->desc), 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'l': // "sl"
|
|
||||||
{
|
|
||||||
int sl_arg = r_num_math (core->num, input+1);
|
|
||||||
const char *help_msg[] = {
|
|
||||||
"Usage:", "sl+ or sl- or slc", "",
|
|
||||||
"sl", " [line]", "Seek to absolute line",
|
|
||||||
"sl", "[+-][line]", "Seek to relative line",
|
|
||||||
"slc", "", "Clear line cache",
|
|
||||||
"sll", "", "Show total number of lines",
|
|
||||||
NULL };
|
|
||||||
switch (input[1]) {
|
|
||||||
case 0:
|
|
||||||
if (!core->print->lines_cache) {
|
|
||||||
__init_seek_line (core);
|
|
||||||
}
|
|
||||||
__get_current_line (core);
|
|
||||||
break;
|
|
||||||
case ' ':
|
|
||||||
if (!core->print->lines_cache) {
|
|
||||||
__init_seek_line (core);
|
|
||||||
}
|
|
||||||
__seek_line_absolute (core, sl_arg);
|
|
||||||
break;
|
|
||||||
case '+':
|
|
||||||
case '-':
|
|
||||||
if (!core->print->lines_cache) {
|
|
||||||
__init_seek_line (core);
|
|
||||||
}
|
|
||||||
__seek_line_relative (core, sl_arg);
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
__clean_lines_cache (core);
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
if (!core->print->lines_cache) {
|
|
||||||
__init_seek_line (core);
|
|
||||||
}
|
|
||||||
eprintf ("%d lines\n", core->print->lines_cache_sz-1);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
r_core_cmd_help (core, help_msg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ':':
|
|
||||||
printPadded (core, atoi (input + 1));
|
|
||||||
break;
|
|
||||||
case '?': {
|
|
||||||
const char * help_message[] = {
|
|
||||||
"Usage: s", "", " # Seek commands",
|
"Usage: s", "", " # Seek commands",
|
||||||
"s", "", "Print current address",
|
"s", "", "Print current address",
|
||||||
"s:", "pad", "Print current address with N padded zeros (defaults to 8)",
|
"s:", "pad", "Print current address with N padded zeros (defaults to 8)",
|
||||||
@ -497,13 +557,13 @@ static int cmd_seek(void *data, const char *input) {
|
|||||||
"sn/sp", "", "Seek next/prev scr.nkey",
|
"sn/sp", "", "Seek next/prev scr.nkey",
|
||||||
"so", " [N]", "Seek to N next opcode(s)",
|
"so", " [N]", "Seek to N next opcode(s)",
|
||||||
"sr", " pc", "Seek to register",
|
"sr", " pc", "Seek to register",
|
||||||
//"sp [page] seek page N (page = block)",
|
"ss", "", "Seek silently (without adding an entry to the seek history)",
|
||||||
|
// "sp [page] seek page N (page = block)",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
r_core_cmd_help(core, help_message);
|
r_core_cmd_help (core, help_message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else r_cons_printf ("0x%"PFMT64x"\n", core->offset);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2702,8 +2702,8 @@ dodo:
|
|||||||
|
|
||||||
if (cmdvhex && *cmdvhex) {
|
if (cmdvhex && *cmdvhex) {
|
||||||
snprintf (debugstr, sizeof (debugstr),
|
snprintf (debugstr, sizeof (debugstr),
|
||||||
"?0;f tmp;sr SP;%s;?1;%s;?1;s-;"
|
"?0;f tmp;ssr SP;%s;?1;%s;?1;"
|
||||||
"s tmp;f-tmp;pd $r", cmdvhex,
|
"ss tmp;f-tmp;pd $r", cmdvhex,
|
||||||
ref? "drr": "dr=");
|
ref? "drr": "dr=");
|
||||||
debugstr[sizeof (debugstr) - 1] = 0;
|
debugstr[sizeof (debugstr) - 1] = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -2722,9 +2722,9 @@ dodo:
|
|||||||
const char sign = (delta < 0)? '+': '-';
|
const char sign = (delta < 0)? '+': '-';
|
||||||
const int absdelta = R_ABS (delta);
|
const int absdelta = R_ABS (delta);
|
||||||
snprintf (debugstr, sizeof (debugstr),
|
snprintf (debugstr, sizeof (debugstr),
|
||||||
"?0;f tmp;sr SP;%s %d@$$%c%d;"
|
"?0;f tmp;ssr SP;%s %d@$$%c%d;"
|
||||||
"?1;%s;s-;"
|
"?1;%s;"
|
||||||
"?1;s tmp;f-tmp;pd $r",
|
"?1;ss tmp;f-tmp;pd $r",
|
||||||
pxa? "pxa": pxw, size, sign, absdelta,
|
pxa? "pxa": pxw, size, sign, absdelta,
|
||||||
ref? "drr": "dr=");
|
ref? "drr": "dr=");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user