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:
Fangrui Song 2017-08-22 01:46:48 -07:00 committed by radare
parent 2f201bded0
commit a9bf4aae2b
19 changed files with 163 additions and 194 deletions

View File

@ -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;
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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;
}

View File

@ -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

View File

@ -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 {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}