mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 21:29:49 +00:00
Misc fixes to siol (#8262)
* Fix onIterMap (divide-and-conquer like USACO Shaping Regions), check return values of every `op` call * Change return types of r_io_read_at and friends back to `int` * Fix some analysis tests and others * Fix mem leaks
This commit is contained in:
parent
2f201bded0
commit
a9bf4aae2b
@ -418,7 +418,7 @@ static ut8 *slurp(RCore **c, const char *file, int *sz) {
|
||||
size = r_io_size (io);
|
||||
if (size > 0 && size < ST32_MAX) {
|
||||
data = calloc (1, size);
|
||||
if (r_io_read_at (io, 0, data, size)) {
|
||||
if (r_io_read_all_at (io, 0, data, size)) {
|
||||
if (sz) {
|
||||
*sz = size;
|
||||
}
|
||||
|
@ -872,16 +872,12 @@ repeat:
|
||||
{
|
||||
bool must_eob = anal->opt.eobjmp;
|
||||
if (!must_eob) {
|
||||
RIOSection *s = NULL;
|
||||
SdbList *secs = anal->iob.sections_vget (anal->iob.io, addr);
|
||||
SdbList *secs = anal->iob.sections_vget (anal->iob.io, addr);
|
||||
if (secs) {
|
||||
s = (RIOSection *) ls_pop (secs);
|
||||
RIOSection *s = (RIOSection *) ls_pop (secs);
|
||||
secs->free = NULL;
|
||||
ls_free (secs);
|
||||
}
|
||||
if (s) {
|
||||
must_eob = (s->vaddr <= op.jump);
|
||||
must_eob &= ((s->vaddr + s->vsize) > op.jump);
|
||||
must_eob = !(s->vaddr <= op.jump && op.jump < s->vaddr + s->vsize);
|
||||
}
|
||||
}
|
||||
if (must_eob) {
|
||||
|
@ -516,14 +516,17 @@ static int core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth
|
||||
RAnalRef *ref;
|
||||
int delta = r_anal_fcn_size (fcn);
|
||||
// XXX hack slow check io error
|
||||
if (!r_io_read_at (core->io, at + delta, buf, buflen)) {
|
||||
eprintf ("read errro\n");
|
||||
if (!r_io_read_all_at (core->io, at + delta, buf, 4)) {
|
||||
eprintf ("read error\n");
|
||||
goto error;
|
||||
}
|
||||
// real read.
|
||||
// this is unnecessary if its contiguous
|
||||
buflen = r_io_read_at (core->io, at+delta, buf, core->anal->opt.bb_max_size) ?
|
||||
core->anal->opt.bb_max_size : 0;
|
||||
buflen = r_io_read_at (core->io, at+delta, buf, core->anal->opt.bb_max_size);
|
||||
if (buflen < 0) {
|
||||
eprintf ("read error\n");
|
||||
goto error;
|
||||
}
|
||||
if (core->io->va) {
|
||||
if (!r_io_is_valid_section_offset (core->io, at+delta, !core->anal->opt.noncode)) {
|
||||
goto error;
|
||||
@ -3367,7 +3370,7 @@ static int esilbreak_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
ut8 buf[8];
|
||||
ut64 refptr;
|
||||
if (len == 8) {
|
||||
if (!r_io_read_at (mycore->io, addr, (ut8*)buf, sizeof (buf))) {
|
||||
if (!r_io_read_all_at (mycore->io, addr, (ut8*)buf, len)) {
|
||||
/* invalid read */
|
||||
refptr = UT64_MAX;
|
||||
} else {
|
||||
@ -3375,7 +3378,7 @@ static int esilbreak_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
|
||||
esilbreak_last_data = refptr;
|
||||
}
|
||||
} else {
|
||||
if (!r_io_read_at (mycore->io, addr, (ut8*)buf, sizeof (buf))) {
|
||||
if (!r_io_read_all_at (mycore->io, addr, (ut8*)buf, len)) {
|
||||
/* invalid read */
|
||||
refptr = UT64_MAX;
|
||||
} else {
|
||||
|
@ -280,7 +280,7 @@ R_API bool r_core_seek(RCore *core, ut64 addr, bool rb) {
|
||||
if (rb) {
|
||||
r_core_block_read (core);
|
||||
}
|
||||
return (core->offset != addr);
|
||||
return core->offset == addr;
|
||||
}
|
||||
|
||||
R_API int r_core_seek_delta(RCore *core, st64 addr) {
|
||||
@ -309,13 +309,12 @@ R_API int r_core_seek_delta(RCore *core, st64 addr) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API bool r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
|
||||
bool ret;
|
||||
R_API int r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size) {
|
||||
if (!core) {
|
||||
return false;
|
||||
}
|
||||
ret = r_io_write_at (core->io, addr, buf, size);
|
||||
if (addr >= core->offset && addr <= core->offset + core->blocksize) {
|
||||
int ret = r_io_write_at (core->io, addr, buf, size);
|
||||
if (core->offset <= addr && addr < core->offset + core->blocksize) {
|
||||
r_core_block_read (core);
|
||||
}
|
||||
return ret;
|
||||
@ -397,18 +396,9 @@ R_API int r_core_block_read(RCore *core) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
R_API bool r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
|
||||
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size) {
|
||||
if (core) {
|
||||
return r_io_read_at (core->io, addr, buf, size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API int r_core_is_valid_offset (RCore *core, ut64 offset) {
|
||||
if (!core) {
|
||||
eprintf ("r_core_is_valid_offset: core is NULL\n");
|
||||
r_sys_backtrace ();
|
||||
return R_FAIL;
|
||||
}
|
||||
return r_io_is_valid_real_offset (core->io, offset, 0);
|
||||
return -1;
|
||||
}
|
||||
|
@ -2899,8 +2899,7 @@ repeat:
|
||||
goto out_return_one;
|
||||
}
|
||||
}
|
||||
int rc = r_io_read_at (core->io, addr, code, sizeof (code));
|
||||
if (!rc) {
|
||||
if (!r_io_read_all_at (core->io, addr, code, sizeof (code))) {
|
||||
eprintf ("read error\n");
|
||||
}
|
||||
// TODO: sometimes this is dupe
|
||||
|
@ -479,7 +479,7 @@ static int cmd_cmp(void *data, const char *input) {
|
||||
case 'X':
|
||||
buf = malloc (core->blocksize);
|
||||
if (buf) {
|
||||
if (!r_io_read_at (core->io, r_num_math (core->num,
|
||||
if (!r_io_read_all_at (core->io, r_num_math (core->num,
|
||||
input + 1), buf, core->blocksize)) {
|
||||
eprintf ("Cannot read hexdump\n");
|
||||
} else {
|
||||
|
@ -1333,8 +1333,7 @@ static void get_hash_debug_file(const char *path, char *hash, int hash_len) {
|
||||
}
|
||||
r_list_foreach (sects, iter, s) {
|
||||
if (strstr (s->name, ".note.gnu.build-id")) {
|
||||
err = r_io_read_at (core->io, s->vaddr + 16, (ut8 *) buf, 20);
|
||||
if (!err) {
|
||||
if (!r_io_read_all_at (core->io, s->vaddr + 16, (ut8 *) buf, 20)) {
|
||||
eprintf ("Unable to read from memory\n");
|
||||
goto out_error;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ static void __section_list (RIO *io, ut64 offset, RPrint *print, int rad) {
|
||||
ls_foreach (io->sections, iter, s) {
|
||||
char *n = strdup (s->name);
|
||||
r_name_filter (n, strlen (n));
|
||||
print->cb_printf ("f section.%s %"PFMT64d" 0x%"PFMT64x"\n", n, s->vaddr, s->vsize);
|
||||
print->cb_printf ("f section.%s %"PFMT64d" 0x%"PFMT64x"\n", n, s->size, s->vaddr);
|
||||
print->cb_printf ("S 0x%08"PFMT64x" 0x%08"PFMT64x" 0x%08"
|
||||
PFMT64x" 0x%08"PFMT64x" %s %s\n", s->paddr,
|
||||
s->vaddr, s->size, s->vsize, n, r_str_rwx_i (s->flags));
|
||||
@ -124,7 +124,7 @@ static bool dumpSectionToDisk(RCore *core, char *file) {
|
||||
}
|
||||
ut64 o = core->offset;
|
||||
if (core->io->va || core->io->debug) {
|
||||
s = r_io_section_vget (core->io, o);
|
||||
s = r_io_section_vget (core->io, o);
|
||||
o = s ? o - s->vaddr + s->paddr : o;
|
||||
}
|
||||
ls_foreach (core->io->sections, iter, s) {
|
||||
|
@ -626,7 +626,7 @@ static bool searchRange(RCore *core, ut64 from, ut64 to, bool rad, struct ctxSea
|
||||
break;
|
||||
}
|
||||
rlen = R_MIN (core->blocksize, to - at);
|
||||
if (!r_io_read_at (core->io, at, buf, rlen)) {
|
||||
if (!r_io_read_all_at (core->io, at, buf, rlen)) {
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
|
@ -1539,7 +1539,7 @@ static char *r_core_anal_hasrefs_to_depth(RCore *core, ut64 value, int depth) {
|
||||
int len, r;
|
||||
r = r_io_read_at (core->io, value, buf, sizeof (buf));
|
||||
buf[sizeof (buf) - 1] = 0;
|
||||
if (r) {
|
||||
if (r > 0) {
|
||||
switch (is_string (buf, sizeof(buf), &len)) {
|
||||
case 1:
|
||||
r_strbuf_appendf (s, " (%s%s%s)", c, buf, cend);
|
||||
@ -2389,7 +2389,7 @@ R_API int r_core_search_cb(RCore *core, ut64 from, ut64 to, RCoreSearchCallback
|
||||
if (delta < len) {
|
||||
len = (int)delta;
|
||||
}
|
||||
if (!r_io_read_at (core->io, from, buf, len)) {
|
||||
if (r_io_read_at (core->io, from, buf, len) < 0) { // XXX
|
||||
eprintf ("Cannot read at 0x%"PFMT64x"\n", from);
|
||||
break;
|
||||
}
|
||||
|
@ -78,7 +78,8 @@ static int perform_mapped_file_yank(RCore *core, ut64 offset, ut64 len, const ch
|
||||
ut8 *buf = NULL;
|
||||
if (actual_len > 0 && res == addr) {
|
||||
buf = malloc (actual_len);
|
||||
if (!r_io_read_at (core->io, addr, buf, actual_len)) {
|
||||
actual_len = r_io_read_at (core->io, addr, buf, actual_len);
|
||||
if ((st64)actual_len < 0) {
|
||||
actual_len = 0;
|
||||
}
|
||||
r_core_yank_set (core, R_CORE_FOREIGN_ADDR, buf, len);
|
||||
|
@ -246,7 +246,7 @@ R_API int r_core_seek_align(RCore *core, ut64 align, int count);
|
||||
R_API void r_core_seek_archbits (RCore *core, ut64 addr);
|
||||
R_API int r_core_block_read(RCore *core);
|
||||
R_API int r_core_block_size(RCore *core, int bsize);
|
||||
R_API bool r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size);
|
||||
R_API int r_core_read_at(RCore *core, ut64 addr, ut8 *buf, int size);
|
||||
R_API int r_core_is_valid_offset (RCore *core, ut64 offset);
|
||||
R_API int r_core_shift_block(RCore *core, ut64 addr, ut64 b_size, st64 dist);
|
||||
R_API void r_core_visual_prompt_input (RCore *core);
|
||||
@ -305,7 +305,7 @@ R_API int r_core_file_binlist(RCore *core);
|
||||
R_API int r_core_file_bin_raise(RCore *core, ut32 num);
|
||||
R_API int r_core_seek_delta(RCore *core, st64 addr);
|
||||
R_API int r_core_extend_at(RCore *core, ut64 addr, int size);
|
||||
R_API bool r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size);
|
||||
R_API int r_core_write_at(RCore *core, ut64 addr, const ut8 *buf, int size);
|
||||
R_API int r_core_write_op(RCore *core, const char *arg, char op);
|
||||
R_API int r_core_set_file_by_fd (RCore * core, ut64 bin_fd);
|
||||
R_API int r_core_set_file_by_name (RBin * bin, const char * name);
|
||||
|
@ -201,8 +201,8 @@ typedef ut64 (*RIODescSize) (RIODesc *desc);
|
||||
typedef RIODesc *(*RIOOpen) (RIO *io, const char *uri, int flags, int mode);
|
||||
typedef RIODesc *(*RIOOpenAt) (RIO *io, const char *uri, int flags, int mode, ut64 at);
|
||||
typedef bool (*RIOClose) (RIO *io, int fd);
|
||||
typedef bool (*RIOReadAt) (RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
typedef bool (*RIOWriteAt) (RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
typedef int (*RIOReadAt) (RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
typedef int (*RIOWriteAt) (RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
typedef int (*RIOSystem) (RIO *io, const char* cmd);
|
||||
typedef bool (*RIOIsValidOff) (RIO *io, ut64 addr, int hasperm);
|
||||
typedef SdbList *(*RIOSectionVgetSecsAt) (RIO *io, ut64 vaddr);
|
||||
@ -256,12 +256,14 @@ R_API bool r_io_reopen (RIO *io, int fd, int flags, int mode);
|
||||
R_API int r_io_close_all (RIO *io);
|
||||
R_API int r_io_pread_at (RIO *io, ut64 paddr, ut8 *buf, int len);
|
||||
R_API int r_io_pwrite_at (RIO *io, ut64 paddr, const ut8 *buf, int len);
|
||||
R_API bool r_io_vread_at (RIO *io, ut64 vaddr, ut8 *buf, int len);
|
||||
R_API bool r_io_vwrite_at (RIO *io, ut64 vaddr, const ut8 *buf, int len);
|
||||
R_API bool r_io_read_at (RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
R_API bool r_io_write_at (RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API bool r_io_read (RIO *io, ut8 *buf, int len);
|
||||
R_API bool r_io_write (RIO *io, ut8 *buf, int len);
|
||||
R_API int r_io_vread_at (RIO *io, ut64 vaddr, ut8 *buf, int len);
|
||||
R_API int r_io_vwrite_at (RIO *io, ut64 vaddr, const ut8 *buf, int len);
|
||||
R_API int r_io_read_at (RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
R_API int r_io_write_at (RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API bool r_io_read_all_at (RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
R_API bool r_io_write_all_at (RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API int r_io_read (RIO *io, ut8 *buf, int len);
|
||||
R_API int r_io_write (RIO *io, ut8 *buf, int len);
|
||||
R_API ut64 r_io_size (RIO *io);
|
||||
R_API bool r_io_is_listener (RIO *io);
|
||||
R_API int r_io_system (RIO *io, const char* cmd);
|
||||
@ -336,8 +338,8 @@ R_API void r_io_cache_enable(RIO *io, int read, int write);
|
||||
R_API void r_io_cache_init(RIO *io);
|
||||
R_API int r_io_cache_list(RIO *io, int rad);
|
||||
R_API void r_io_cache_reset(RIO *io, int set);
|
||||
R_API bool r_io_cache_write(RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API bool r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
R_API int r_io_cache_write(RIO *io, ut64 addr, const ut8 *buf, int len);
|
||||
R_API int r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len);
|
||||
|
||||
/* io/section.c */
|
||||
R_API void r_io_section_init (RIO *io);
|
||||
|
@ -118,32 +118,32 @@ R_API int r_io_cache_list(RIO *io, int rad) {
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API bool r_io_cache_write(RIO *io, ut64 addr, const ut8 *buf, int len) {
|
||||
R_API int r_io_cache_write(RIO *io, ut64 addr, const ut8 *buf, int len) {
|
||||
RIOCache *ch;
|
||||
ch = R_NEW0 (RIOCache);
|
||||
if (!ch) {
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
ch->from = addr;
|
||||
ch->to = addr + len;
|
||||
ch->size = len;
|
||||
ch->odata = (ut8*)calloc (1, len + 1);
|
||||
if (!ch->odata) {
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
ch->data = (ut8*)calloc (1, len + 1);
|
||||
if (!ch->data) {
|
||||
free (ch->odata);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
ch->written = io->cached? false: true;
|
||||
r_io_read_at (io, addr, ch->odata, len);
|
||||
memcpy (ch->data, buf, len);
|
||||
r_list_append (io->cache, ch);
|
||||
return true;
|
||||
return len;
|
||||
}
|
||||
|
||||
R_API bool r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len) {
|
||||
R_API int r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len) {
|
||||
int l, covered = 0;
|
||||
RListIter *iter;
|
||||
RIOCache *c;
|
||||
@ -159,5 +159,5 @@ R_API bool r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len) {
|
||||
covered += l;
|
||||
}
|
||||
}
|
||||
return (covered == 0) ? false: true;
|
||||
return covered;
|
||||
}
|
||||
|
@ -283,6 +283,7 @@ static bool desc_fini_cb(void* user, void* data, ut32 id) {
|
||||
if (desc->plugin && desc->plugin->close) {
|
||||
desc->plugin->close (desc);
|
||||
}
|
||||
r_io_desc_free (desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
212
libr/io/io.c
212
libr/io/io.c
@ -6,83 +6,48 @@
|
||||
|
||||
R_LIB_VERSION (r_io);
|
||||
|
||||
typedef int (*cbOnIterMap) (RIO *io, int fd, ut64 addr, ut8*buf, int len);
|
||||
static void onIterMap(SdbListIter* iter, RIO* io, ut64 vaddr, ut8* buf,
|
||||
int len, int match_flg, cbOnIterMap op) {
|
||||
RIOMap* map;
|
||||
// TODO closed interval [vaddr, vendaddr] is used, this is cumbersome and should be refactored later
|
||||
ut64 vendaddr;
|
||||
if (!io || !buf || len < 1) {
|
||||
return;
|
||||
}
|
||||
if (!iter) {
|
||||
// end of list
|
||||
if (io->desc) {
|
||||
op (io, io->desc->fd ,vaddr, buf, len);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// this block is not that much elegant
|
||||
if (UT64_ADD_OVFCHK (len - 1, vaddr)) {
|
||||
// needed for edge-cases
|
||||
int nlen;
|
||||
// add a test for this block
|
||||
vendaddr = UT64_MAX;
|
||||
nlen = (int) (UT64_MAX - vaddr + 1);
|
||||
onIterMap (iter->p, io, 0LL, buf + nlen, len - nlen, match_flg, op);
|
||||
} else {
|
||||
vendaddr = vaddr + len - 1;
|
||||
}
|
||||
map = (RIOMap*) iter->data;
|
||||
// search for next map or end of list
|
||||
while (!(map->from <= vendaddr && vaddr < map->to)) {
|
||||
iter = iter->p;
|
||||
// end of list
|
||||
if (!iter) {
|
||||
if (io->desc) {
|
||||
op (io, io->desc->fd, vaddr, buf, len);
|
||||
typedef int (*cbOnIterMap) (RIO *io, int fd, ut64 vaddr, ut8 *buf, int len);
|
||||
static int onIterMap(SdbListIter *iter, RIO *io, ut64 vaddr, ut8 *buf,
|
||||
int len, int match_flg, cbOnIterMap op) {
|
||||
ut64 vendaddr = vaddr + len;
|
||||
int t, ret = 0;
|
||||
for (; iter; iter = iter->p) {
|
||||
RIOMap *map = (RIOMap *)iter->data;
|
||||
if (vaddr < map->to && map->from < vendaddr) {
|
||||
if ((map->flags & match_flg) == match_flg || io->p_cache) {
|
||||
RIODesc *desc = io->desc;
|
||||
r_io_use_fd (io, map->fd);
|
||||
t = vaddr < map->from
|
||||
? op (io, map->fd, map->delta, buf + map->from - vaddr,
|
||||
R_MIN (vendaddr - map->from, map->to - map->from))
|
||||
: op (io, map->fd, map->delta + vaddr - map->from, buf,
|
||||
R_MIN (map->to - vaddr, len));
|
||||
io->desc = desc;
|
||||
if (t < 0) {
|
||||
return t;
|
||||
}
|
||||
ret += t;
|
||||
}
|
||||
return;
|
||||
}
|
||||
map = (RIOMap*) iter->data;
|
||||
}
|
||||
if (map->from >= vaddr) {
|
||||
onIterMap (iter->p, io, vaddr, buf, (int) (map->from - vaddr), match_flg, op);
|
||||
buf = buf + (map->from - vaddr);
|
||||
vaddr = map->from;
|
||||
len = (int) (vendaddr - vaddr + 1);
|
||||
if (vendaddr < map->to) {
|
||||
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
|
||||
op (io, map->fd ,map->delta, buf, len);
|
||||
if (vaddr < map->from) {
|
||||
t = onIterMap (iter->p, io, vaddr, buf, map->from - vaddr, match_flg, op);
|
||||
if (t < 0) {
|
||||
return t;
|
||||
}
|
||||
ret += t;
|
||||
}
|
||||
} else {
|
||||
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
|
||||
op (io, map->fd, map->delta, buf, len - (int) (vendaddr - map->to + 1));
|
||||
if (map->to < vendaddr) {
|
||||
t = onIterMap (iter->p, io, map->to, buf + map->to - vaddr, vendaddr - map->to, match_flg, op);
|
||||
if (t < 0) {
|
||||
return t;
|
||||
}
|
||||
ret += t;
|
||||
}
|
||||
vaddr = map->to;
|
||||
buf = buf + (len - (int) (vendaddr - map->to + 1));
|
||||
len = (int) (vendaddr - map->to + 1);
|
||||
onIterMap (iter->p, io, vaddr, buf, len, match_flg, op);
|
||||
}
|
||||
} else {
|
||||
if (vendaddr < map->to) {
|
||||
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
|
||||
//warning: may overflow in rare usecases
|
||||
op (io, map->fd, map->delta + (vaddr - map->from), buf, len);
|
||||
}
|
||||
} else {
|
||||
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
|
||||
op (io, map->fd, map->delta + (vaddr - map->from), buf, len - (int) (vendaddr - map->to + 1));
|
||||
}
|
||||
vaddr = map->to;
|
||||
buf = buf + (len - (int) (vendaddr - map->to + 1));
|
||||
len = (int) (vendaddr - map->to + 1);
|
||||
onIterMap (iter->p, io, vaddr, buf, len, match_flg, op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
R_API RIO* r_io_new() {
|
||||
return r_io_init (R_NEW0 (RIO));
|
||||
}
|
||||
@ -274,72 +239,73 @@ R_API int r_io_pwrite_at(RIO* io, ut64 paddr, const ut8* buf, int len) {
|
||||
return r_io_desc_write_at (io->desc, paddr, buf, len);
|
||||
}
|
||||
|
||||
R_API bool r_io_vread_at(RIO* io, ut64 vaddr, ut8* buf, int len) {
|
||||
if (!io || !buf || (len < 1)) {
|
||||
return false;
|
||||
R_API int r_io_vread_at(RIO* io, ut64 vaddr, ut8* buf, int len) {
|
||||
if (!io || !buf || len < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (io->ff) {
|
||||
memset (buf, 0xff, len);
|
||||
}
|
||||
r_io_map_cleanup (io);
|
||||
if (!io->maps) {
|
||||
return !!r_io_pread_at (io, vaddr, buf, len);
|
||||
return r_io_pread_at (io, vaddr, buf, len);
|
||||
}
|
||||
onIterMap (io->maps->tail, io, vaddr, buf, len, R_IO_READ, r_io_fd_read_at);
|
||||
return true; //rethink the return value, we should keep track of succes on onIterMap
|
||||
if (io->ff) {
|
||||
memset (buf, 0xff, len);
|
||||
}
|
||||
return onIterMap (io->maps->tail, io, vaddr, buf, len, R_IO_READ, r_io_fd_read_at);
|
||||
}
|
||||
|
||||
R_API bool r_io_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int len) {
|
||||
if (!io || !buf || (len < 1)) {
|
||||
return false;
|
||||
R_API int r_io_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int len) {
|
||||
if (!io || !buf || len < 0) {
|
||||
return -1;
|
||||
}
|
||||
r_io_map_cleanup (io);
|
||||
if (!io->maps) {
|
||||
return !!r_io_pwrite_at (io, vaddr, buf, len);
|
||||
return r_io_pwrite_at (io, vaddr, buf, len);
|
||||
}
|
||||
onIterMap (io->maps->tail, io, vaddr, (ut8*)buf, len, R_IO_WRITE, (cbOnIterMap)r_io_fd_write_at);
|
||||
return true; //rethink the return value, we should keep track of succes on onIterMap
|
||||
return onIterMap (io->maps->tail, io, vaddr, (ut8*)buf, len, R_IO_WRITE, (cbOnIterMap)r_io_fd_write_at);
|
||||
}
|
||||
|
||||
R_API bool r_io_read_at(RIO* io, ut64 addr, ut8* buf, int len) {
|
||||
bool ret;
|
||||
if (!io || !buf || len < 1) {
|
||||
return false;
|
||||
R_API int r_io_read_at(RIO* io, ut64 addr, ut8* buf, int len) {
|
||||
if (!io || !buf || len < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (io->buffer_enabled) {
|
||||
return !!r_io_buffer_read (io, addr, buf, len);
|
||||
}
|
||||
if (io->va) {
|
||||
ret = r_io_vread_at (io, addr, buf, len);
|
||||
} else {
|
||||
ret = !!r_io_pread_at (io, addr, buf, len) > 0;
|
||||
return r_io_buffer_read (io, addr, buf, len);
|
||||
}
|
||||
int ret = io->va
|
||||
? r_io_vread_at (io, addr, buf, len)
|
||||
: r_io_pread_at (io, addr, buf, len);
|
||||
if (io->cached_read) {
|
||||
ret &= !!r_io_cache_read (io, addr, buf, len);
|
||||
(void)r_io_cache_read (io, addr, buf, len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API bool r_io_write_at(RIO* io, ut64 addr, const ut8* buf, int len) {
|
||||
int i;
|
||||
bool ret;
|
||||
R_API bool r_io_read_all_at(RIO* io, ut64 addr, ut8* buf, int len) {
|
||||
return r_io_read_at (io, addr, buf, len) == len;
|
||||
}
|
||||
|
||||
R_API int r_io_write_at(RIO* io, ut64 addr, const ut8* buf, int len) {
|
||||
int i, ret = 0;
|
||||
ut8 *mybuf = (ut8*)buf;
|
||||
if (!io || !buf || len < 1) {
|
||||
return false;
|
||||
if (!io || !buf || len < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (io->write_mask) {
|
||||
mybuf = r_mem_dup ((void*)buf, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
//this sucks
|
||||
mybuf[i] &= io->write_mask[i % io->write_mask_len];
|
||||
mybuf[i] &= io->write_mask[i % io->write_mask_len];
|
||||
}
|
||||
}
|
||||
if (io->cached) {
|
||||
ret = !!r_io_cache_write (io, addr, mybuf, len);
|
||||
ret = r_io_cache_write (io, addr, mybuf, len);
|
||||
} else if (io->va) {
|
||||
ret = r_io_vwrite_at (io, addr, mybuf, len);
|
||||
} else {
|
||||
ret = !!r_io_pwrite_at (io, addr, mybuf, len);
|
||||
ret = r_io_pwrite_at (io, addr, mybuf, len);
|
||||
}
|
||||
if (buf != mybuf) {
|
||||
free (mybuf);
|
||||
@ -347,26 +313,30 @@ R_API bool r_io_write_at(RIO* io, ut64 addr, const ut8* buf, int len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API bool r_io_read(RIO* io, ut8* buf, int len) {
|
||||
if (!io) {
|
||||
return false;
|
||||
}
|
||||
if (r_io_read_at (io, io->off, buf, len)) {
|
||||
io->off += len;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
R_API bool r_io_write_all_at(RIO* io, ut64 addr, const ut8* buf, int len) {
|
||||
return r_io_write_at (io, addr, buf, len) == len;
|
||||
}
|
||||
|
||||
R_API bool r_io_write(RIO* io, ut8* buf, int len) {
|
||||
if (!io || !buf || len < 1) {
|
||||
return false;
|
||||
R_API int r_io_read(RIO* io, ut8* buf, int len) {
|
||||
if (!io) {
|
||||
return -1;
|
||||
}
|
||||
if (r_io_write_at (io, io->off, buf, len)) {
|
||||
io->off += len;
|
||||
return true;
|
||||
int ret = r_io_read_at (io, io->off, buf, len);
|
||||
if (ret > 0) {
|
||||
io->off += ret;
|
||||
}
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API int r_io_write(RIO* io, ut8* buf, int len) {
|
||||
if (!io) {
|
||||
return -1;
|
||||
}
|
||||
int ret = r_io_write_at (io, io->off, buf, len);
|
||||
if (ret > 0) {
|
||||
io->off += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
R_API ut64 r_io_size(RIO* io) {
|
||||
@ -527,8 +497,9 @@ R_API int r_io_create(RIO* io, const char* file, int mode, int type) {
|
||||
|
||||
R_API ut64 r_io_seek(RIO* io, ut64 offset, int whence) {
|
||||
if (!io) {
|
||||
return 0LL;
|
||||
return -1;
|
||||
}
|
||||
ut64 t;
|
||||
switch (whence) {
|
||||
case R_IO_SEEK_SET:
|
||||
io->off = offset;
|
||||
@ -538,7 +509,10 @@ R_API ut64 r_io_seek(RIO* io, ut64 offset, int whence) {
|
||||
break;
|
||||
case R_IO_SEEK_END:
|
||||
default:
|
||||
io->off = UT64_MAX;
|
||||
if (!io->desc || (t = r_io_desc_size (io->desc)) == -1) {
|
||||
return -1;
|
||||
}
|
||||
io->off = t + offset;
|
||||
break;
|
||||
}
|
||||
return io->off;
|
||||
|
@ -47,7 +47,7 @@ R_API bool r_io_read_i(RIO* io, ut64 addr, ut64 *val, int size, bool endian) {
|
||||
return false;
|
||||
}
|
||||
size = R_DIM (size, 1, 8);
|
||||
if (!r_io_read_at (io, addr, buf, size)) {
|
||||
if (r_io_read_at (io, addr, buf, size) != size) {
|
||||
return false;
|
||||
}
|
||||
*val = r_read_ble (buf, endian, size);
|
||||
@ -62,7 +62,7 @@ R_API bool r_io_write_i(RIO* io, ut64 addr, ut64 *val, int size, bool endian) {
|
||||
}
|
||||
size = R_DIM (size, 1, 8);
|
||||
r_write_ble (buf, *val, endian, size);
|
||||
if (!r_io_write_at (io, addr, buf, size)) {
|
||||
if (r_io_write_at (io, addr, buf, size) != size) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
R_API RIOMap* r_io_map_new(RIO* io, int fd, int flags, ut64 delta, ut64 addr, ut64 size) {
|
||||
RIOMap* map = NULL;
|
||||
if (!size || !io || !io->maps || ((UT64_MAX - size + 1) < addr) || !io->map_ids) {
|
||||
if (!io || !io->maps || UT64_ADD_OVFCHK (size, addr) || !io->map_ids) {
|
||||
return NULL;
|
||||
}
|
||||
map = R_NEW0 (RIOMap);
|
||||
@ -20,7 +20,7 @@ R_API RIOMap* r_io_map_new(RIO* io, int fd, int flags, ut64 delta, ut64 addr, ut
|
||||
map->fd = fd;
|
||||
map->from = addr;
|
||||
// RIOMap describes an interval of addresses (map->from; map->to)
|
||||
map->to = addr + size - 1;
|
||||
map->to = addr + size;
|
||||
map->flags = flags;
|
||||
map->delta = delta;
|
||||
// new map lives on the top, being top the list's tail
|
||||
@ -99,7 +99,7 @@ R_API RIOMap* r_io_map_get(RIO* io, ut64 addr) {
|
||||
return NULL;
|
||||
}
|
||||
ls_foreach_prev (io->maps, iter, map) {
|
||||
if ((map->from <= addr) && (map->to >= addr)) {
|
||||
if (map->from <= addr && addr < map->to) {
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -182,9 +182,7 @@ R_API bool r_io_map_priorize_for_fd(RIO* io, int fd) {
|
||||
ls_delete (io->maps, iter);
|
||||
}
|
||||
}
|
||||
while (ls_length (list)) {
|
||||
ls_append (io->maps, ls_pop (list));
|
||||
}
|
||||
ls_join (io->maps, list);
|
||||
ls_free (list);
|
||||
io->maps->free = _map_free;
|
||||
return true;
|
||||
@ -247,7 +245,7 @@ R_API RIOMap* r_io_map_add_next_available(RIO* io, int fd, int flags, ut64 delta
|
||||
ut64 next_addr = addr,
|
||||
end_addr = next_addr + size;
|
||||
ls_foreach (io->maps, iter, map) {
|
||||
next_addr = R_MAX (next_addr, map->to + (load_align - (map->to % load_align)));
|
||||
next_addr = R_MAX (next_addr, map->to + (load_align - (map->to % load_align)) % load_align);
|
||||
// XXX - This does not handle when file overflow 0xFFFFFFFF000 -> 0x00000FFF
|
||||
// adding the check for the map's fd to see if this removes contention for
|
||||
// memory mapping with multiple files.
|
||||
@ -255,7 +253,7 @@ R_API RIOMap* r_io_map_add_next_available(RIO* io, int fd, int flags, ut64 delta
|
||||
if (map->fd == fd && ((map->from <= next_addr && next_addr < map->to) ||
|
||||
(map->from <= end_addr && end_addr < map->to))) {
|
||||
//return r_io_map_add(io, fd, flags, delta, map->to, size);
|
||||
next_addr = map->to + (load_align - (map->to % load_align));
|
||||
next_addr = map->to + (load_align - (map->to % load_align)) % load_align;
|
||||
return r_io_map_add_next_available (io, fd, flags, delta, next_addr, size, load_align);
|
||||
} else {
|
||||
break;
|
||||
|
@ -54,7 +54,7 @@ RIOSection *_section_chk_dup(RIO *io, ut64 paddr, ut64 vaddr, ut64 size, ut64 vs
|
||||
SdbListIter *iter;
|
||||
char sname[32];
|
||||
if (!name) {
|
||||
snprintf (sname, sizeof (sname) - 1, "section.0x016%"PFMT64x "", vaddr);
|
||||
snprintf (sname, sizeof (sname), "section.0x016%"PFMT64x "", vaddr);
|
||||
}
|
||||
ls_foreach (io->sections, iter, sec) {
|
||||
if ((sec->paddr == paddr) && (sec->vaddr == vaddr) && (sec->size == size) &&
|
||||
@ -79,10 +79,6 @@ R_API RIOSection *r_io_section_add(RIO *io, ut64 paddr, ut64 vaddr, ut64 size,
|
||||
if (!sec) {
|
||||
return NULL;
|
||||
}
|
||||
if (!r_id_pool_grab_id (io->sec_ids, &sec->id)) {
|
||||
free (sec);
|
||||
return NULL;
|
||||
}
|
||||
sec->paddr = paddr;
|
||||
sec->vaddr = vaddr;
|
||||
sec->size = size;
|
||||
@ -95,6 +91,15 @@ R_API RIOSection *r_io_section_add(RIO *io, ut64 paddr, ut64 vaddr, ut64 size,
|
||||
} else {
|
||||
sec->name = strdup (name);
|
||||
}
|
||||
if (!sec->name) {
|
||||
free (sec);
|
||||
return NULL;
|
||||
}
|
||||
if (!r_id_pool_grab_id (io->sec_ids, &sec->id)) {
|
||||
free (sec->name);
|
||||
free (sec);
|
||||
return NULL;
|
||||
}
|
||||
ls_append (io->sections, sec);
|
||||
}
|
||||
return sec;
|
||||
@ -416,6 +421,7 @@ static bool _create_null_map(RIO *io, RIOSection *sec, ut64 at) {
|
||||
}
|
||||
uri = r_str_newf ("null://%"PFMT64u "", sec->vsize - sec->size);
|
||||
desc = r_io_open_at (io, uri, sec->flags, 664, at);
|
||||
free (uri);
|
||||
if (!desc) {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user