Skip to content

Commit

Permalink
Rewrite ar and dr with newshell (#2006)
Browse files Browse the repository at this point in the history
* Show group-level details of commands

Details can be defined at either a group command or its subcommand of
the same name. If define on group-level it will also be shown in the
group help without needing ??.

* Fix > $ redirection for errored command and leak

* Rewrite ar and dr commands with newshell

Breaking changes:
ar* => arf, ar- => arf-, ar. => ar*
ar, => art, ar? => arq
ar0 => ara0, arb => arab, ars => araS
arC => arpC
arn => arR
art => arT
arf => arF
Removed: drm, aer
  • Loading branch information
thestr4ng3r committed Dec 6, 2021
1 parent d2f649d commit 3c2e4bf
Show file tree
Hide file tree
Showing 76 changed files with 6,878 additions and 5,270 deletions.
12 changes: 12 additions & 0 deletions librz/cons/line.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,16 @@ RZ_API void rz_line_ns_completion_result_add(RzLineNSCompletionResult *res, cons
ht_pp_insert(res->options_ht, dup, dup);
}

/**
* \brief Add a new option to the list of possible autocomplete-able value if it matches the given string
* \param option the option to be added
* \param cur currently entered prefix
*/
RZ_API void rz_line_ns_completion_result_propose(RzLineNSCompletionResult *res, const char *option, const char *cur, size_t cur_len) {
if (strncmp(option, cur, cur_len)) {
return;
}
rz_line_ns_completion_result_add(res, option);
}

#include "dietline.c"
2 changes: 1 addition & 1 deletion librz/core/canalysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -7002,7 +7002,7 @@ RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core) {
const bool delete_regs = !rz_flag_space_count(core->flags, RZ_FLAGS_FS_REGISTERS);
seek = core->offset;
rz_reg_arena_push(core->analysis->reg);
rz_reg_arena_zero(core->analysis->reg);
rz_reg_arena_zero(core->analysis->reg, RZ_REG_TYPE_ANY);
rz_core_analysis_esil_init(core);
rz_core_analysis_esil_init_mem(core, NULL, UT64_MAX, UT32_MAX);
ut8 *saved_arena = rz_reg_arena_peek(core->analysis->reg);
Expand Down
57 changes: 57 additions & 0 deletions librz/core/cautocmpl.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,57 @@ static void autocmplt_cmd_arg_global_var(RzCore *core, RzLineNSCompletionResult
rz_list_free(list);
}

static void autocmplt_cmd_arg_reg_filter(RzCore *core, const RzCmdDesc *cd, RzLineNSCompletionResult *res, const char *s, size_t len) {
bool is_analysis = cd->name && cd->name[0] == 'a';
RzReg *reg = is_analysis ? core->analysis->reg : core->dbg->reg;
if (!reg) {
return;
}

rz_line_ns_completion_result_propose(res, "8", s, len);
rz_line_ns_completion_result_propose(res, "16", s, len);
rz_line_ns_completion_result_propose(res, "32", s, len);
rz_line_ns_completion_result_propose(res, "64", s, len);
rz_line_ns_completion_result_propose(res, "128", s, len);
rz_line_ns_completion_result_propose(res, "256", s, len);

for (int type = 0; type < RZ_REG_TYPE_LAST; type++) {
const char *name = rz_reg_get_type(type);
if (!name) {
continue;
}
rz_line_ns_completion_result_propose(res, name, s, len);
}
rz_line_ns_completion_result_propose(res, "all", s, len);

for (int role = 0; role < RZ_REG_NAME_LAST; role++) {
if (!reg->name[role]) {
// don't autocomplete if there isn't a register with this role anyway
continue;
}
const char *name = rz_reg_get_role(role);
if (!name) {
continue;
}
rz_line_ns_completion_result_propose(res, name, s, len);
}

RzListIter *iter;
RzRegItem *ri;
rz_list_foreach (reg->allregs, iter, ri) {
if (!ri->name) {
continue;
}
rz_line_ns_completion_result_propose(res, ri->name, s, len);
}
}

static void autocmplt_cmd_arg_reg_type(RzCore *core, const RzCmdDesc *cd, RzLineNSCompletionResult *res, const char *s, size_t len) {
for (int t = 0; t < RZ_REG_TYPE_LAST; t++) {
rz_line_ns_completion_result_propose(res, rz_reg_get_type(t), s, len);
}
}

static void autocmplt_cmd_arg_help_var(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len) {
const char **vars = rz_core_help_vars_get(core);
while (*vars) {
Expand Down Expand Up @@ -681,6 +732,12 @@ static void autocmplt_cmd_arg(RzCore *core, RzLineNSCompletionResult *res, const
case RZ_CMD_ARG_TYPE_GLOBAL_VAR:
autocmplt_cmd_arg_global_var(core, res, s, len);
break;
case RZ_CMD_ARG_TYPE_REG_FILTER:
autocmplt_cmd_arg_reg_filter(core, cd, res, s, len);
break;
case RZ_CMD_ARG_TYPE_REG_TYPE:
autocmplt_cmd_arg_reg_type(core, cd, res, s, len);
break;
default:
break;
}
Expand Down
177 changes: 34 additions & 143 deletions librz/core/cdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,37 +174,55 @@ RZ_API bool rz_core_debug_continue_until(RzCore *core, ut64 addr, ut64 to) {
}
return true;
}
static void regs_to_flags(RzCore *core, int size) {

/// Construct the list of registers that should be applied as flags by default
/// (e.g. because their size matches the pointer size)
RZ_IPI RzList /*<RzRegItem>*/ *rz_core_regs2flags_candidates(RzCore *core, RzReg *reg) {
const RzList *l = rz_reg_get_list(core->dbg->reg, RZ_REG_TYPE_GPR);
if (!l) {
return NULL;
}
int size = rz_analysis_get_address_bits(core->analysis);
RzList *ret = rz_list_new();
if (!ret) {
return NULL;
}
RzListIter *iter;
RzRegItem *reg;
rz_list_foreach (l, iter, reg) {
if (reg->type != RZ_REG_TYPE_GPR && reg->type != RZ_REG_TYPE_FLG) {
continue;
}
if (size != 0 && size != reg->size) {
RzRegItem *item;
rz_list_foreach (l, iter, item) {
if (size != 0 && size != item->size) {
continue;
}
rz_list_push(ret, item);
}
return ret;
}

static void regs_to_flags(RzCore *core) {
RzList *l = rz_core_regs2flags_candidates(core, core->dbg->reg);
if (!l) {
return;
}
rz_flag_space_push(core->flags, RZ_FLAGS_FS_REGISTERS);
RzListIter *iter;
RzRegItem *reg;
rz_list_foreach (l, iter, reg) {
ut64 regval = rz_reg_get_value(core->dbg->reg, reg);
rz_flag_set(core->flags, reg->name, regval, reg->size / 8);
}
rz_flag_space_pop(core->flags);
rz_list_free(l);
}

RZ_IPI void rz_core_regs2flags(RzCore *core) {
rz_flag_space_push(core->flags, RZ_FLAGS_FS_REGISTERS);
int size = rz_analysis_get_address_bits(core->analysis);
regs_to_flags(core, size);
rz_flag_space_pop(core->flags);
regs_to_flags(core);
}

/// update or create flags for all registers where it makes sense (regs that have the same size as an address)
RZ_IPI void rz_core_debug_regs2flags(RzCore *core) {
if (core->bin->is_debugger) {
if (rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_GPR, false)) {
rz_flag_space_push(core->flags, RZ_FLAGS_FS_REGISTERS);
int size = rz_analysis_get_address_bits(core->analysis);
regs_to_flags(core, size);
rz_flag_space_pop(core->flags);
regs_to_flags(core);
}
} else {
rz_core_regs2flags(core);
Expand Down Expand Up @@ -242,61 +260,6 @@ RZ_IPI bool rz_core_debug_reg_set(RzCore *core, const char *regname, ut64 val, c
return true;
}

static bool foreach_reg_cb(RzIntervalNode *node, void *user) {
RzRegItem *from_list = user;
RzRegItem *from_tree = node->data;
if (from_list == from_tree) {
return true;
}
// Check if from_list is covered entirely by from_tree, but is also smaller than it.
// We already know that
// from_tree->offset <= from_list->offset < from_tree->offset + from_tree->size
if (from_list->offset + from_list->size > from_tree->offset + from_tree->size) {
// from_list expands beyond from_tree, so it's not covered
return true;
}
if (from_list->offset + from_list->size == from_tree->offset + from_tree->size) {
// they end at the same position, so it is covered entirely, but is it also smaller?
if (from_list->offset == from_tree->offset) {
// nope
return true;
}
}
// from_list ends before from_tree, so it is covered and smaller
return false;
}

/// Filter out all registers that are smaller than but covered entirely by some other register
static RZ_OWN RzList *regs_filter_covered(RZ_BORROW const RzList /* <RzRegItem> */ *regs) {
RzList *ret = rz_list_new();
if (!ret) {
return NULL;
}
RzIntervalTree t;
rz_interval_tree_init(&t, NULL);
RzRegItem *item;
RzListIter *it;
rz_list_foreach (regs, it, item) {
if (item->offset < 0 || item->size <= 0) {
continue;
}
rz_interval_tree_insert(&t, item->offset, item->offset + item->size - 1, item);
}
rz_list_foreach (regs, it, item) {
if (item->offset < 0 || item->size <= 0) {
rz_list_push(ret, item);
continue;
}
if (!rz_interval_tree_all_in(&t, item->offset, true, foreach_reg_cb, item)) {
// foreach_reg_cb break-ed so it found a cover
continue;
}
rz_list_push(ret, item);
}
rz_interval_tree_fini(&t);
return ret;
}

RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, bool skip_covered, PJ *pj, int rad, const char *use_color) {
RzDebug *dbg = core->dbg;
int delta, cols, n = 0;
Expand Down Expand Up @@ -351,7 +314,7 @@ RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, bool skip_c
}
RzList *filtered_list = NULL;
if (skip_covered) {
filtered_list = regs_filter_covered(head);
filtered_list = rz_reg_filter_items_covered(head);
if (filtered_list) {
head = filtered_list;
}
Expand Down Expand Up @@ -513,78 +476,6 @@ RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, bool skip_c
return n != 0;
}

HEAPTYPE(ut64);

static int regcmp(const void *a, const void *b) {
const ut64 *A = (const ut64 *)a;
const ut64 *B = (const ut64 *)b;
if (*A > *B) {
return 1;
}
if (*A == *B) {
return 0;
}
return -1;
}

static bool regcb(void *u, const ut64 k, const void *v) {
RzList *sorted = (RzList *)u;
ut64 *n = ut64_new(k);
rz_list_add_sorted(sorted, n, regcmp);
return true;
}

RZ_API void rz_core_debug_ri(RzCore *core, RzReg *reg, int mode) {
const RzList *list = rz_reg_get_list(reg, RZ_REG_TYPE_GPR);
RzListIter *iter;
RzRegItem *r;
HtUP *db = ht_up_new0();

rz_list_foreach (list, iter, r) {
if (r->size != core->rasm->bits) {
continue;
}
ut64 value = rz_reg_get_value(reg, r);
RzList *list = ht_up_find(db, value, NULL);
if (!list) {
list = rz_list_newf(NULL);
ht_up_update(db, value, list);
}
rz_list_append(list, r->name);
}

RzList *sorted = rz_list_newf(free);
ht_up_foreach(db, regcb, sorted);
ut64 *addr;
rz_list_foreach (sorted, iter, addr) {
int rwx = 0;
RzDebugMap *map = rz_debug_map_get(core->dbg, *addr);
if (map) {
rwx = map->perm;
}
rz_cons_printf(" %s ", rz_str_rwx_i(rwx));

rz_cons_printf("0x%08" PFMT64x " ", *addr);
RzList *list = ht_up_find(db, *addr, NULL);
if (list) {
RzListIter *iter;
const char *r;
rz_cons_strcat(Color_YELLOW);
rz_list_foreach (list, iter, r) {
rz_cons_printf(" %s", r);
}
rz_cons_strcat(Color_RESET);
char *rrstr = rz_core_analysis_hasrefs(core, *addr, true);
if (rrstr && *rrstr && strchr(rrstr, 'R')) {
rz_cons_printf(" ;%s" Color_RESET, rrstr);
}
rz_cons_newline();
}
}
rz_list_free(sorted);
ht_up_free(db);
}

RZ_IPI void rz_core_debug_sync_bits(RzCore *core) {
if (rz_config_get_b(core->config, "cfg.debug")) {
ut64 asm_bits = rz_config_get_i(core->config, "asm.bits");
Expand Down
5 changes: 3 additions & 2 deletions librz/core/cmd/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ static RzCmdDescriptor *cmd_descriptor(const char *cmd, const char *help[]) {

static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpseek);

static void cmd_debug_reg(RzCore *core, const char *str);
static bool lastcmd_repeat(RzCore *core, int next);

#include "cmd_block.c"
Expand All @@ -89,6 +88,7 @@ static bool lastcmd_repeat(RzCore *core, int next);
#include "cmd_eval.c"
#include "cmd_interpret.c"
#include "cmd_analysis.c"
#include "cmd_regs.c"
#include "cmd_open.c"
#include "cmd_type.c"
#include "cmd_info.c"
Expand Down Expand Up @@ -4103,7 +4103,8 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(redirect_stmt) {
} else {
old_alias_value = "";
}
new_alias_value = rz_str_newf("%s%s%s", start_char, old_alias_value, output);
new_alias_value = rz_str_newf("%s%s%s", start_char, old_alias_value, output ? output : "");
free(output);
rz_cmd_alias_set(state->core->rcmd, arg_str, new_alias_value, 1);
free(new_alias_value);
free(command_str);
Expand Down
Loading

0 comments on commit 3c2e4bf

Please sign in to comment.