Skip to content

Commit

Permalink
Remove read ahead globals.
Browse files Browse the repository at this point in the history
import from radare2 dd01b31f71ce7698a416f41556df488da5676dfe
  • Loading branch information
wargio committed Jan 5, 2024
1 parent 9be3f00 commit 2156361
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 42 deletions.
73 changes: 33 additions & 40 deletions librz/analysis/fcn.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <rz_util.h>
#include <rz_list.h>

#define READ_AHEAD 1
#define SDB_KEY_BB "bb.0x%" PFMT64x ".0x%" PFMT64x
// XXX must be configurable by the user
#define JMPTBL_LEA_SEARCH_SZ 64
Expand Down Expand Up @@ -45,46 +44,38 @@ RZ_API const char *rz_analysis_fcntype_tostring(int type) {
return "unk";
}

#if READ_AHEAD
static ut64 cache_addr = UT64_MAX;
typedef struct {
ut8 cache[1024];
ut64 cache_addr;
} ReadAhead;

// TODO: move into io :?
static int read_ahead(RzAnalysis *analysis, ut64 addr, ut8 *buf, int len) {
static ut8 cache[1024];
const int cache_len = sizeof(cache);

static int read_ahead(ReadAhead *ra, RzAnalysis *analysis, ut64 addr, ut8 *buf, ssize_t len) {
bool is_cached = false;
if (len < 1) {
return 0;
}
if (len > cache_len) {
int a = analysis->iob.read_at(analysis->iob.io, addr, buf, len); // double read
memcpy(cache, buf, cache_len);
cache_addr = addr;
return a;
return -1;
}

ut64 addr_end = UT64_ADD_OVFCHK(addr, len) ? UT64_MAX : addr + len;
ut64 cache_addr_end = UT64_ADD_OVFCHK(cache_addr, cache_len) ? UT64_MAX : cache_addr + cache_len;
bool isCached = ((addr != UT64_MAX) && (addr >= cache_addr) && (addr_end < cache_addr_end));
if (isCached) {
memcpy(buf, cache + (addr - cache_addr), len);
} else {
analysis->iob.read_at(analysis->iob.io, addr, cache, sizeof(cache));
memcpy(buf, cache, len);
cache_addr = addr;
if (ra->cache_addr != UT64_MAX && addr >= ra->cache_addr && addr < ra->cache_addr + sizeof(ra->cache)) {
ut64 addr_end = UT64_ADD_OVFCHK(addr, len) ? UT64_MAX : addr + len;
ut64 cache_addr_end = UT64_ADD_OVFCHK(ra->cache_addr, sizeof(ra->cache)) ? UT64_MAX : ra->cache_addr + sizeof(ra->cache);
is_cached = ((addr != UT64_MAX) && (addr >= ra->cache_addr) && (addr_end < cache_addr_end));
}
return len;
}
#else
static int read_ahead(RzAnalysis *analysis, ut64 addr, ut8 *buf, int len) {
return analysis->iob.read_at(analysis->iob.io, addr, buf, len);
}
#endif

RZ_API void rz_analysis_fcn_invalidate_read_ahead_cache(void) {
#if READ_AHEAD
cache_addr = UT64_MAX;
#endif
if (!is_cached) {
if (len > sizeof(ra->cache)) {
len = sizeof(ra->cache);
}
analysis->iob.read_at(analysis->iob.io, addr, ra->cache, sizeof(ra->cache));
ra->cache_addr = addr;
}
ssize_t delta = addr - ra->cache_addr;
if (delta >= 0) {
size_t length = sizeof(ra->cache) - delta;
memcpy(buf, ra->cache + delta, RZ_MIN(len, length));
return len;
}
return -1;
}

RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize) {
Expand Down Expand Up @@ -161,7 +152,7 @@ static bool isSymbolNextInstruction(RzAnalysis *analysis, RzAnalysisOp *op) {
return (fi && fi->name && (strstr(fi->name, "imp.") || strstr(fi->name, "sym.") || strstr(fi->name, "entry") || strstr(fi->name, "main")));
}

static bool is_delta_pointer_table(RzAnalysis *analysis, ut64 addr, ut64 lea_ptr, ut64 *jmptbl_addr, ut64 *casetbl_addr, RzAnalysisOp *jmp_aop) {
static bool is_delta_pointer_table(ReadAhead *ra, RzAnalysis *analysis, ut64 addr, ut64 lea_ptr, ut64 *jmptbl_addr, ut64 *casetbl_addr, RzAnalysisOp *jmp_aop) {
int i;
ut64 dst;
st32 jmptbl[64] = { 0 };
Expand All @@ -173,7 +164,7 @@ static bool is_delta_pointer_table(RzAnalysis *analysis, ut64 addr, ut64 lea_ptr
RzAnalysisOp add_aop = { 0 };
RzRegItem *reg_src = NULL, *o_reg_dst = NULL;
RzAnalysisValue cur_scr, cur_dst = { 0 };
read_ahead(analysis, addr, (ut8 *)buf, sizeof(buf));
read_ahead(ra, analysis, addr, buf, sizeof(buf));
bool isValid = false;
for (i = 0; i + 8 < JMPTBL_LEA_SEARCH_SZ; i++) {
ut64 at = addr + i;
Expand Down Expand Up @@ -237,7 +228,7 @@ static bool is_delta_pointer_table(RzAnalysis *analysis, ut64 addr, ut64 lea_ptr
}
#endif
/* check if jump table contains valid deltas */
read_ahead(analysis, *jmptbl_addr, (ut8 *)&jmptbl, 64);
read_ahead(ra, analysis, *jmptbl_addr, (ut8 *)&jmptbl, 64);
for (i = 0; i < 3; i++) {
dst = lea_ptr + (st32)rz_read_le32(jmptbl);
if (!analysis->iob.is_valid_offset(analysis->iob.io, dst, 0)) {
Expand Down Expand Up @@ -553,6 +544,7 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R
RzStackAddr sp = item->sp;
ut64 addr = item->start_address;
ut64 len = analysis->opt.bb_max_size;
ReadAhead read_ahead_cache = { 0 };
const int continue_after_jump = analysis->opt.afterjmp;
const int addrbytes = analysis->iob.io ? analysis->iob.io->addrbytes : 1;
char *last_reg_mov_lea_name = NULL;
Expand All @@ -575,6 +567,8 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R
} delay = {
0
};

read_ahead_cache.cache_addr = UT64_MAX; // invalidate the cache
char tmp_buf[MAX_FLG_NAME_SIZE + 5] = "skip";
bool arch_destroys_dst = does_arch_destroys_dst(analysis->cur->arch);
bool is_arm = false, is_x86 = false, is_amd64 = false, is_dalvik = false, is_hexagon = false;
Expand Down Expand Up @@ -707,7 +701,7 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R
break;
}
ut64 bytes_read = RZ_MIN(len - at_delta, sizeof(buf));
ret = read_ahead(analysis, at, buf, bytes_read);
ret = read_ahead(&read_ahead_cache, analysis, at, buf, bytes_read);

if (ret < 0) {
RZ_LOG_ERROR("Failed to read ahead\n");
Expand Down Expand Up @@ -972,7 +966,7 @@ static RzAnalysisBBEndCause run_basic_block_analysis(RzAnalysisTaskItem *item, R
RzAnalysisOp jmp_aop = { 0 };
ut64 jmptbl_addr = op.ptr;
ut64 casetbl_addr = op.ptr;
if (is_delta_pointer_table(analysis, op.addr, op.ptr, &jmptbl_addr, &casetbl_addr, &jmp_aop)) {
if (is_delta_pointer_table(&read_ahead_cache, analysis, op.addr, op.ptr, &jmptbl_addr, &casetbl_addr, &jmp_aop)) {
// we require both checks here since rz_analysis_get_jmptbl_info uses
// BB info of the final jmptbl jump, which is no present with
// is_delta_pointer_table just scanning ahead
Expand Down Expand Up @@ -2317,7 +2311,6 @@ static void update_analysis(RzAnalysis *analysis, RzList /*<RzAnalysisFunction *
RzAnalysisFunction *fcn;
bool old_jmpmid = analysis->opt.jmpmid;
analysis->opt.jmpmid = true;
rz_analysis_fcn_invalidate_read_ahead_cache();
rz_list_foreach (fcns, it, fcn) {
// Recurse through blocks of function, mark reachable,
// analyze edges that don't have a block
Expand Down
1 change: 0 additions & 1 deletion librz/core/canalysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,6 @@ static int __core_analysis_fcn(RzCore *core, ut64 at, ut64 from, int reftype, in
if (!fcn->name) {
fcn->name = rz_str_newf("%s.%08" PFMT64x, fcnpfx, at);
}
rz_analysis_fcn_invalidate_read_ahead_cache();
do {
RzFlagItem *f;
ut64 delta = rz_analysis_function_linear_size(fcn);
Expand Down
1 change: 0 additions & 1 deletion librz/include/rz_analysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -1727,7 +1727,6 @@ RZ_API int rz_analysis_fcn_del(RzAnalysis *analysis, ut64 addr);
RZ_API int rz_analysis_fcn_del_locs(RzAnalysis *analysis, ut64 addr);
RZ_API bool rz_analysis_fcn_add_bb(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail);
RZ_API bool rz_analysis_check_fcn(RzAnalysis *analysis, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high);
RZ_API void rz_analysis_fcn_invalidate_read_ahead_cache(void);

RZ_API void rz_analysis_function_check_bp_use(RzAnalysisFunction *fcn);
RZ_API void rz_analysis_update_analysis_range(RzAnalysis *analysis, ut64 addr, int size);
Expand Down

0 comments on commit 2156361

Please sign in to comment.