Skip to content

Commit

Permalink
Refactor dm commands ##refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
MalhotraPulak authored Jun 17, 2021
1 parent e54990b commit 6fabb6d
Show file tree
Hide file tree
Showing 19 changed files with 2,595 additions and 1,644 deletions.
237 changes: 235 additions & 2 deletions librz/core/cdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, PJ *pj, int
return false;
}
if (rad == 1 || rad == '*') {
dbg->cb_printf("fs+%s\n", RZ_FLAGS_FS_REGISTERS);
rz_cons_printf("fs+%s\n", RZ_FLAGS_FS_REGISTERS);
}
rz_list_foreach (head, iter, item) {
ut64 value;
Expand Down Expand Up @@ -442,7 +442,7 @@ RZ_IPI bool rz_core_debug_reg_list(RzCore *core, int type, int size, PJ *pj, int
n++;
}
if (rad == 1 || rad == '*') {
dbg->cb_printf("fs-\n");
rz_cons_printf("fs-\n");
}
beach:
if (isJson) {
Expand Down Expand Up @@ -639,3 +639,236 @@ RZ_API RzCmdStatus rz_core_debug_plugins_print(RzCore *core, RzCmdStateOutput *s
rz_cmd_state_output_array_end(state);
return RZ_CMD_STATUS_OK;
}

/* Print out the JSON body for memory maps in the passed map region */
static void print_debug_map_json(RzDebugMap *map, PJ *pj) {
pj_o(pj);
if (map->name && *map->name) {
pj_ks(pj, "name", map->name);
}
if (map->file && *map->file) {
pj_ks(pj, "file", map->file);
}
pj_kn(pj, "addr", map->addr);
pj_kn(pj, "addr_end", map->addr_end);
pj_ks(pj, "type", map->user ? "u" : "s");
pj_ks(pj, "perm", rz_str_rwx_i(map->perm));
pj_end(pj);
}

/* Write a single memory map line to the console */
static void print_debug_map_line(RzDebug *dbg, RzDebugMap *map, ut64 addr, RzOutputMode mode) {
char humansz[8];
if (mode == RZ_OUTPUT_MODE_QUIET) { // "dmq"
char *name = (map->name && *map->name)
? rz_str_newf("%s.%s", map->name, rz_str_rwx_i(map->perm))
: rz_str_newf("%08" PFMT64x ".%s", map->addr, rz_str_rwx_i(map->perm));
rz_name_filter(name, 0, true);
rz_num_units(humansz, sizeof(humansz), map->addr_end - map->addr);
rz_cons_printf("0x%016" PFMT64x " - 0x%016" PFMT64x " %6s %5s %s\n",
map->addr,
map->addr_end,
humansz,
rz_str_rwx_i(map->perm),
name);
free(name);
} else {
const char *fmtstr = dbg->bits & RZ_SYS_BITS_64
? "0x%016" PFMT64x " - 0x%016" PFMT64x " %c %s %6s %c %s %s %s%s%s\n"
: "0x%08" PFMT64x " - 0x%08" PFMT64x " %c %s %6s %c %s %s %s%s%s\n";
const char *type = map->shared ? "sys" : "usr";
const char *flagname = dbg->corebind.getName
? dbg->corebind.getName(dbg->corebind.core, map->addr)
: NULL;
if (!flagname) {
flagname = "";
} else if (map->name) {
char *filtered_name = strdup(map->name);
rz_name_filter(filtered_name, 0, true);
if (!strncmp(flagname, "map.", 4) &&
!strcmp(flagname + 4, filtered_name)) {
flagname = "";
}
free(filtered_name);
}
rz_num_units(humansz, sizeof(humansz), map->size);
rz_cons_printf(fmtstr,
map->addr,
map->addr_end,
(addr >= map->addr && addr < map->addr_end) ? '*' : '-',
type,
humansz,
map->user ? 'u' : 's',
rz_str_rwx_i(map->perm),
map->name ? map->name : "?",
map->file ? map->file : "?",
*flagname ? " ; " : "",
flagname);
}
}

RZ_API void rz_debug_map_print(RzDebug *dbg, ut64 addr, RzCmdStateOutput *state) {
int i;
RzListIter *iter;
RzDebugMap *map;
PJ *pj = state->d.pj;
if (!dbg) {
return;
}
RzOutputMode mode = state->mode;
rz_cmd_state_output_array_start(state);
for (i = 0; i < 2; i++) { // Iterate over dbg::maps and dbg::maps_user
RzList *maps = rz_debug_map_list(dbg, (bool)i);
rz_list_foreach (maps, iter, map) {
switch (mode) {
case RZ_OUTPUT_MODE_JSON: // "dmj"
print_debug_map_json(map, pj);
break;
case RZ_OUTPUT_MODE_RIZIN: // "dm*"
{
char *name = (map->name && *map->name)
? rz_str_newf("%s.%s", map->name, rz_str_rwx_i(map->perm))
: rz_str_newf("%08" PFMT64x ".%s", map->addr, rz_str_rwx_i(map->perm));
rz_name_filter(name, 0, true);
rz_cons_printf("f map.%s 0x%08" PFMT64x " 0x%08" PFMT64x "\n",
name, map->addr_end - map->addr + 1, map->addr);
free(name);
} break;
case RZ_OUTPUT_MODE_QUIET: // "dmq"
print_debug_map_line(dbg, map, addr, mode);
break;
case RZ_OUTPUT_MODE_LONG: // workaround for '.'
if (addr >= map->addr && addr < map->addr_end) {
print_debug_map_line(dbg, map, addr, mode);
}
break;
default:
print_debug_map_line(dbg, map, addr, mode);
break;
}
}
}
rz_cmd_state_output_array_end(state);
}

static int cmp(const void *a, const void *b) {
RzDebugMap *ma = (RzDebugMap *)a;
RzDebugMap *mb = (RzDebugMap *)b;
return ma->addr - mb->addr;
}

/**
* \brief Find the min and max addresses in an RzList of maps.
* \param maps RzList of maps that will be searched through
* \param min Pointer to a ut64 that the min will be stored in
* \param max Pointer to a ut64 that the max will be stored in
* \param skip How many maps to skip at the start of iteration
* \param width Divisor for the return value
* \return (max-min)/width
*
* Used to determine the min & max addresses of maps and
* scale the ascii bar to the width of the terminal
*/
static int findMinMax(RzList *maps, ut64 *min, ut64 *max, int skip, int width) {
RzDebugMap *map;
RzListIter *iter;
*min = UT64_MAX;
*max = 0;
rz_list_foreach (maps, iter, map) {
if (skip > 0) {
skip--;
continue;
}
if (map->addr < *min) {
*min = map->addr;
}
if (map->addr_end > *max) {
*max = map->addr_end;
}
}
return (int)(*max - *min) / width;
}

static void print_debug_maps_ascii_art(RzDebug *dbg, RzList *maps, ut64 addr, int colors) {
ut64 mul; // The amount of address space a single console column will represent in bar graph
ut64 min = -1, max = 0;
int width = rz_cons_get_size(NULL) - 90;
RzListIter *iter;
RzDebugMap *map;
RzConsPrintablePalette *pal = &rz_cons_singleton()->context->pal;
if (width < 1) {
width = 30;
}
rz_list_sort(maps, cmp);
mul = findMinMax(maps, &min, &max, 0, width);
ut64 last = min;
if (min != -1 && mul != 0) {
const char *color_prefix = ""; // Color escape code prefixed to string (address coloring)
const char *color_suffix = ""; // Color escape code appended to end of string
const char *fmtstr;
char humansz[8]; // Holds the human formatted size string [124K]
int skip = 0; // Number of maps to skip when re-calculating the minmax
rz_list_foreach (maps, iter, map) {
rz_num_units(humansz, sizeof(humansz), map->size); // Convert map size to human readable string
if (colors) {
color_suffix = Color_RESET;
if ((map->perm & 2) && (map->perm & 1)) { // Writable & Executable
color_prefix = pal->widget_sel;
} else if (map->perm & 2) { // Writable
color_prefix = pal->graph_false;
} else if (map->perm & 1) { // Executable
color_prefix = pal->graph_true;
} else {
color_prefix = "";
color_suffix = "";
}
} else {
color_prefix = "";
color_suffix = "";
}
if ((map->addr - last) > UT32_MAX) { // TODO: Comment what this is for
mul = findMinMax(maps, &min, &max, skip, width); // Recalculate minmax
}
skip++;
fmtstr = dbg->bits & RZ_SYS_BITS_64 // Prefix formatting string (before bar)
? "map %4.8s %c %s0x%016" PFMT64x "%s |"
: "map %4.8s %c %s0x%08" PFMT64x "%s |";
rz_cons_printf(fmtstr, humansz,
(addr >= map->addr &&
addr < map->addr_end)
? '*'
: '-',
color_prefix, map->addr, color_suffix); // * indicates map is within our current sought offset
int col;
for (col = 0; col < width; col++) { // Iterate over the available width/columns for bar graph
ut64 pos = min + (col * mul); // Current address space to check
ut64 npos = min + ((col + 1) * mul); // Next address space to check
if (map->addr < npos && map->addr_end > pos) {
rz_cons_printf("#"); // TODO: Comment what a # represents
} else {
rz_cons_printf("-");
}
}
fmtstr = dbg->bits & RZ_SYS_BITS_64 ? // Suffix formatting string (after bar)
"| %s0x%016" PFMT64x "%s %s %s\n"
: "| %s0x%08" PFMT64x "%s %s %s\n";
rz_cons_printf(fmtstr, color_prefix, map->addr_end, color_suffix,
rz_str_rwx_i(map->perm), map->name);
last = map->addr;
}
}
}

RZ_API void rz_debug_map_list_visual(RzDebug *dbg, ut64 addr, const char *input, int colors) {
if (!dbg) {
return;
}
int i;
for (i = 0; i < 2; i++) { // Iterate over dbg::maps and dbg::maps_user
RzList *maps = rz_debug_map_list(dbg, (bool)i);
if (!maps) {
continue;
}
print_debug_maps_ascii_art(dbg, maps, addr, colors);
}
}
1 change: 1 addition & 0 deletions librz/core/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static bool lastcmd_repeat(RzCore *core, int next);
#include "cmd_help.c"
#include "cmd_remote.c"
#include "cmd_tasks.c"
#include "cmd_linux_heap_glibc.c"

static const char *help_msg_dollar[] = {
"Usage:", "$alias[=cmd] [args...]", "Alias commands and strings (See ?$? for help on $variables)",
Expand Down
Loading

0 comments on commit 6fabb6d

Please sign in to comment.