Initial WIP implementation of pl ##shell

* early merged to avoid future abi breaking blockers
This commit is contained in:
pancake 2024-02-16 12:53:10 +01:00 committed by GitHub
parent dec3698578
commit 71f1b5f30b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 161 additions and 10 deletions

View File

@ -2578,8 +2578,8 @@ R_API RList *r_bin_dwarf_parse_line(RBin *bin, int mode) {
int len, ret;
const bool be = r_bin_is_big_endian (bin);
RBinSection *section = getsection (bin, DWARF_SN_LINE);
RBinFile *binfile = bin->cur;
if (binfile && section) {
RBinFile *bf = bin->cur;
if (bf && section) {
len = section->size;
if (len < 1) {
return NULL;
@ -2588,7 +2588,7 @@ R_API RList *r_bin_dwarf_parse_line(RBin *bin, int mode) {
if (!buf) {
return NULL;
}
ret = r_buf_read_at (binfile->buf, section->paddr, buf, len);
ret = r_buf_read_at (bf->buf, section->paddr, buf, len);
if (ret != len) {
free (buf);
return NULL;
@ -2604,7 +2604,7 @@ R_API RList *r_bin_dwarf_parse_line(RBin *bin, int mode) {
// k bin/cur/addrinfo/*
SdbListIter *iter;
SdbKv *kv;
SdbList *ls = sdb_foreach_list (binfile->sdb_addrinfo, false);
SdbList *ls = sdb_foreach_list (bf->sdb_addrinfo, false);
// Use the parsed information from _raw and transform it to more useful format
ls_foreach (ls, iter, kv) {
const char *key = sdbkv_key (kv);
@ -2642,8 +2642,8 @@ R_API RList *r_bin_dwarf_parse_line(RBin *bin, int mode) {
R_API void r_bin_dwarf_parse_aranges(RBin *bin, int mode) {
RBinSection *section = getsection (bin, DWARF_SN_ARANGES);
RBinFile *binfile = bin ? bin->cur: NULL;
if (binfile && section) {
RBinFile *bf = bin ? bin->cur: NULL;
if (bf && section) {
size_t len = section->size;
if (len < 1 || len > ST32_MAX) {
return;
@ -2652,8 +2652,7 @@ R_API void r_bin_dwarf_parse_aranges(RBin *bin, int mode) {
if (!buf) {
return;
}
int ret = r_buf_read_at (binfile->buf, section->paddr, buf, len);
if (!ret) {
if (!r_buf_read_at (bf ->buf, section->paddr, buf, len)) {
free (buf);
return;
}

View File

@ -8,7 +8,7 @@ R2DEPS+=r_reg r_search r_syscall r_socket r_fs r_magic r_crypto
OBJS=core.o cmd.o cfile.o cconfig.o visual.o cio.o yank.o libs.o agraph.o
OBJS+=fortune.o hack.o vasm.o patch.o cbin.o corelog.o rtr.o cmd_api.o
OBJS+=carg.o canal.o project.o gdiff.o casm.o disasm.o cplugin.o
OBJS+=carg.o canal.o project.o gdiff.o casm.o disasm.o cplugin.o cmd_print_list.o
OBJS+=vmenus.o vmenus_graph.o vmenus_zigns.o zdiff.o citem.o vslides.o
OBJS+=task.o panels.o pseudo.o vmarks.o anal_tp.o anal_objc.o blaze.o cundo.o
OBJS+=cproject.o

View File

@ -197,6 +197,7 @@ static RCoreHelpMessage help_msg_p = {
"pj", "[?] [len]", "print as indented JSON",
"pk", " [len]", "print key in randomart mosaic",
"pK", " [len]", "print key in randomart mosaic",
"pl", "[?][format] [arg]", "print list of data (pl Ffvc)",
"pm", "[?] [magic]", "print libmagic data (see pm? and /m?)",
"po", "[?] hex", "print operation applied to block (see po?)",
"pp", "[?][sz] [len]", "print patterns, see pp? for more help",
@ -8177,6 +8178,9 @@ static int cmd_print(void *data, const char *input) {
case 'n': // easter
R_LOG_ERROR ("easter egg license has expired");
break;
case 'l': // "pl"
r_print_list (core, r_str_trim_head_ro (input + 1));
break;
case 't': // "pt"
switch (input[1]) {
case '.': // "pt." same as "date"

146
libr/core/cmd_print_list.c Normal file
View File

@ -0,0 +1,146 @@
/* radare - LGPL - Copyright 2023-2024 - pancake */
#include <r_core.h>
struct treestate;
typedef void (*treefcn)(struct treestate *ts, int indent);
typedef struct treestate {
RCore *core;
int level;
int layers;
treefcn layer[4];
RList list[4];
} TreeState;
static ut64 itemcmp(const void* _a) {
const char* a = _a;
return r_str_hash64 (a);
}
static RList *functions_for_file(TreeState *ts, const char *file) {
RList *list = r_list_newf (free);
RListIter *iter;
RAnalFunction *fcn;
r_list_foreach (ts->core->anal->fcns, iter, fcn) {
if (strstr (fcn->name, ".str.") || strstr (fcn->name, "JTI")) {
continue;
}
char *s = r_core_cmd_strf (ts->core, "CLf @ 0x%08"PFMT64x, fcn->addr);
r_str_trim (s);
if (s && *s && strstr (file, s)) {
char *fstr = r_str_newf ("0x%08"PFMT64x" %s", fcn->addr, fcn->name);
r_list_append (list, fstr);
if (r_list_length (list) > 5) {
break;
}
}
free (s);
}
return list;
}
static void tree_files(struct treestate *ts, int indent) {
RListIter *iter, *iter2;
RList *files = r_list_newf (free);
char *file;
RBinFile *bf = r_bin_cur (ts->core->bin);
if (!bf) {
R_LOG_WARN ("Unable to find current bin file");
return;
}
SdbList *ls = sdb_foreach_list (bf->sdb_addrinfo, false);
// Use the parsed information from _raw and transform it to more useful format
SdbListIter *sdbiter;
SdbKv *kv;
ls_foreach (ls, sdbiter, kv) {
const char *key = kv->base.key;
if (strchr (key, '/') || r_str_endswith (key, ".c")) {
char *s = strdup (key);
r_str_after (s, '|');
const char *lastslash = r_str_rchr (s, "/", -1);
if (lastslash) {
r_list_append (files, strdup (lastslash + 1));
free (s);
} else {
r_list_append (files, s);
}
}
}
r_list_sort (files, (RListComparator)strcmp);
r_list_uniq_inplace (files, (RListComparatorItem)itemcmp);
r_list_foreach (files, iter, file) {
const char *pad = r_str_pad (' ', indent);
r_cons_printf ("%s%c %s\n", pad, '+', file);
RList *children = functions_for_file (ts, file);
char *fcnstr;
r_list_foreach (children, iter2, fcnstr) {
const char *pad = r_str_pad (' ', indent + 2);
r_cons_printf ("%s%c %s\n", pad, '-', fcnstr);
}
r_list_free (children);
}
r_list_free (files);
}
static void tree_functions(struct treestate *ts, int indent) {
RListIter *iter;
RAnalFunction *fcn;
r_list_foreach (ts->core->anal->fcns, iter, fcn) {
const char *pad = r_str_pad (' ', indent);
r_cons_printf ("%s%c 0x%08"PFMT64x" %s\n", pad, '-', fcn->addr, fcn->name);
}
}
R_API void r_print_list(RCore *core, const char *input) {
TreeState ts = {0};
ts.core = core;
// int level = 0;
char *oargstr = strdup (input);
char *argstr = oargstr;
// char *arg = r_str_after (argstr, ' ');
//bool dash = false;
while (*argstr) {
if (ts.layers > 3) {
R_LOG_ERROR ("too many layers");
break;
}
switch (*argstr) {
case '-':
// dash = true;
// ignored on purpose
break;
case ' ':
goto done;
case 'l':
ts.layer[ts.layers++] = (treefcn)&tree_files;
break;
case 'f':
ts.layer[ts.layers++] = (treefcn)&tree_functions;
break;
default:
break;
}
argstr++;
}
done:
free (oargstr);
// RListIter *iter;
// RPrintTreeCallback ptcb;
treefcn ptcb = ts.layer[0];
// ts.layer[0](&ts, 0);
if (ptcb != NULL) {
ptcb (&ts, 0);
}
#if 0
void *entry;
RList *root = NULL;
r_list_foreach (ts.levels, iter, ptcb) {
ptcb (core, indent, NULL, NULL);
r_list_foreach (root, iter, entry) {
r_cons_printf ("L0 ..\n");
}
indent ++;
}
#endif
}

View File

@ -8,6 +8,7 @@ r_core_sources = [
'canal.c',
'carg.c',
'cbin.c',
'cmd_print_list.c',
'cconfig.c',
'cio.c',
'cmd.c',

View File

@ -567,7 +567,7 @@ typedef struct r_bin_plugin_t {
RList/*<RBinClass>*/* (*classes)(RBinFile *bf);
RList/*<RBinMem>*/* (*mem)(RBinFile *bf);
RList/*<RBinReloc>*/* (*patch_relocs)(RBinFile *bf);
RList/*<RBinMap>*/* (*maps)(RBinFile *bf);
RList/*<RBinMap>*/* (*maps)(RBinFile *bf); // this should be segments!
RList/*<RBinFileHash>*/* (*hashes)(RBinFile *bf);
void (*header)(RBinFile *bf);
char* (*signature)(RBinFile *bf, bool json);

View File

@ -984,6 +984,7 @@ typedef struct r_core_task_t {
typedef void (*RCoreTaskOneShot)(void *);
R_API void r_print_list(RCore *core, const char *input);
R_API void r_core_echo(RCore *core, const char *msg);
R_API RTable *r_core_table(RCore *core, const char *name);