Skip to content

Commit

Permalink
reimplement RIOAccessLog, better and much more elegant than the last …
Browse files Browse the repository at this point in the history
…time
  • Loading branch information
condret committed Aug 24, 2017
1 parent 7b40f7a commit 17ef439
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 15 deletions.
15 changes: 14 additions & 1 deletion libr/include/r_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,18 @@ typedef struct r_io_desc_cache_t {
typedef struct r_io_access_log_element_t {
ut64 vaddr;
ut64 paddr;
int buf_idx;
int expect_len;
int len;
int fd;
int mapid;
//something with flags here maybe
int flags;
} RIOAccessLogElement;

typedef struct r_io_access_log_t {
bool allocation_failed;
ut8 *buf;
RList *log;
} RIOAccessLog;

struct r_io_bind_t;
Expand Down Expand Up @@ -291,6 +298,8 @@ 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 RIOAccessLog *r_io_al_vread_at (RIO *io, ut64 vaddr, ut8 *buf, int len);
R_API RIOAccessLog *r_io_al_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 void r_io_alprint(RList *ls);
R_API bool r_io_write_at (RIO *io, ut64 addr, const ut8 *buf, int len);
Expand Down Expand Up @@ -441,6 +450,10 @@ R_API bool r_io_is_valid_offset (RIO *io, ut64 offset, int hasperm);
R_API bool r_io_addr_is_mapped(RIO *io, ut64 vaddr);
R_API bool r_io_read_i (RIO* io, ut64 addr, ut64 *val, int size, bool endian);
R_API bool r_io_write_i (RIO* io, ut64 addr, ut64 *val, int size, bool endian);
R_API RIOAccessLog *r_io_accesslog_new ();
R_API void r_io_accesslog_free (RIOAccessLog *log);
R_API void r_io_acccesslog_sort (RIOAccessLog *log);
R_API void r_io_accesslog_sqash_byflags (RIOAccessLog *log);

extern RIOPlugin r_io_plugin_procpid;
extern RIOPlugin r_io_plugin_malloc;
Expand Down
107 changes: 93 additions & 14 deletions libr/io/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,58 @@

R_LIB_VERSION (r_io);

typedef int (*cbOnIterMap) (RIO *io, int fd, ut64 addr, ut8*buf, int len);
static void fd_read_at_wrap (RIO *io, int fd, ut64 addr, ut8 *buf, int len, RIOMap *map, void *user) {
bool *ret = (bool *)user;
*ret &= (r_io_fd_read_at (io, fd, addr, buf, len) == len);
}

static void fd_write_at_wrap (RIO *io, int fd, ut64 addr, ut8 *buf, int len, RIOMap *map, void *user) {
bool *ret = (bool *)user;
*ret &= (r_io_fd_write_at (io, fd, addr, buf, len) == len);
}

static void al_fd_read_at_wrap (RIO *io, int fd, ut64 addr, ut8 *buf, int len, RIOMap *map, void *user) {
RIOAccessLog *log = (RIOAccessLog *)user;
RIOAccessLogElement *ale = R_NEW0(RIOAccessLogElement);
int rlen = r_io_fd_read_at (io, fd, addr, buf, len);
if (ale) {
ale->expect_len = len;
ale->len = rlen;
ale->buf_idx = (int)(size_t)(buf - log->buf);
ale->flags = map->flags;
ale->fd = fd;
ale->mapid = map->id;
ale->paddr = addr;
ale->vaddr = map->from + (addr - map->delta);
r_list_append (log->log, ale);
} else {
log->allocation_failed = true;
}
}

static void al_fd_write_at_wrap (RIO *io, int fd, ut64 addr, ut8 *buf, int len, RIOMap *map, void *user) {
RIOAccessLog *log = (RIOAccessLog *)user;
RIOAccessLogElement *ale = R_NEW0(RIOAccessLogElement);
int rlen = r_io_fd_write_at (io, fd, addr, buf, len);
if (ale) {
ale->expect_len = len;
ale->len = rlen;
ale->buf_idx = (int)(size_t)(buf - log->buf);
ale->flags = map->flags;
ale->fd = fd;
ale->mapid = map->id;
ale->paddr = addr;
ale->vaddr = map->from + (addr - map->delta);
r_list_append (log->log, ale);
} else {
log->allocation_failed = true;
}
}

typedef void (*cbOnIterMap) (RIO *io, int fd, ut64 addr, ut8 *buf, int len, RIOMap *map, void *user);

static void onIterMap(SdbListIter* iter, RIO* io, ut64 vaddr, ut8* buf,
int len, int match_flg, cbOnIterMap op, bool *ret) {
int len, int match_flg, cbOnIterMap op, void *user) {
ut64 vendaddr;
if (!io || !buf || len < 1) {
return;
Expand All @@ -25,7 +73,7 @@ static void onIterMap(SdbListIter* iter, RIO* io, ut64 vaddr, ut8* buf,
// 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, ret);
onIterMap (iter->p, io, 0LL, buf + nlen, len - nlen, match_flg, op, user);
} else {
vendaddr = vaddr + len - 1;
}
Expand All @@ -41,39 +89,39 @@ static void onIterMap(SdbListIter* iter, RIO* io, ut64 vaddr, ut8* buf,
map = (RIOMap*) iter->data;
}
if (map->from >= vaddr) {
onIterMap (iter->p, io, vaddr, buf, (int) (map->from - vaddr), match_flg, op, ret);
onIterMap (iter->p, io, vaddr, buf, (int) (map->from - vaddr), match_flg, op, user);
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) {
*ret = (op (io, map->fd, map->delta, buf, len) == len);
op (io, map->fd, map->delta, buf, len, map, user);
}
} else {
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
int nlen = len - (int) (vendaddr - map->to);
*ret &= (op (io, map->fd, map->delta, buf, nlen) == nlen);
op (io, map->fd, map->delta, buf, nlen, map, user);
}
vaddr = map->to + 1;
buf = buf + (len - (int) (vendaddr - map->to));
len = (int) (vendaddr - map->to);
onIterMap (iter->p, io, vaddr, buf, len, match_flg, op, ret);
onIterMap (iter->p, io, vaddr, buf, len, match_flg, op, user);
}
} else {
if (vendaddr <= map->to) {
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
//can it overflow
*ret &= (op (io, map->fd, map->delta + (vaddr - map->from), buf, len) == len);
op (io, map->fd, map->delta + (vaddr - map->from), buf, len, map, user);
}
} else {
if (((map->flags & match_flg) == match_flg) || io->p_cache) {
int nlen = len - (int) (vendaddr - map->to);
*ret &= (op (io, map->fd, map->delta + (vaddr - map->from), buf, nlen) == nlen);
op (io, map->fd, map->delta + (vaddr - map->from), buf, nlen, map, user);
}
vaddr = map->to + 1;
buf = buf + (len - (int) (vendaddr - map->to));
len = (int) (vendaddr - map->to);
onIterMap (iter->p, io, vaddr, buf, len, match_flg, op, ret);
onIterMap (iter->p, io, vaddr, buf, len, match_flg, op, user);
}
}
}
Expand Down Expand Up @@ -281,7 +329,7 @@ R_API bool r_io_vread_at(RIO* io, ut64 vaddr, ut8* buf, int len) {
if (!io->maps) {
return false;
}
onIterMap (io->maps->tail, io, vaddr, buf, len, R_IO_READ, r_io_fd_read_at, &ret);
onIterMap (io->maps->tail, io, vaddr, buf, len, R_IO_READ, fd_read_at_wrap, &ret);
return ret;
}

Expand All @@ -294,10 +342,41 @@ R_API bool r_io_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int len) {
if (!io->maps) {
return false;
}
onIterMap (io->maps->tail, io, vaddr, (ut8*)buf, len, R_IO_WRITE, (cbOnIterMap)r_io_fd_write_at, &ret);
onIterMap (io->maps->tail, io, vaddr, (ut8*)buf, len, R_IO_WRITE, fd_write_at_wrap, &ret);
return ret;
}

R_API RIOAccessLog *r_io_al_vread_at(RIO* io, ut64 vaddr, ut8* buf, int len) {
RIOAccessLog *log;
if (!io || !buf || (len < 1)) {
return NULL;
}
r_io_map_cleanup (io);
if (!io->maps || !(log = r_io_accesslog_new ())) {
return NULL;
}
if (io->ff) {
memset (buf, 0xff, len);
}
log->buf = buf;
onIterMap (io->maps->tail, io, vaddr, buf, len, R_IO_READ, al_fd_read_at_wrap, log);
return log;
}

R_API RIOAccessLog *r_io_al_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int len) {
RIOAccessLog *log;
if (!io || !buf || (len < 1)) {
return NULL;
}
r_io_map_cleanup (io);
if (!io->maps || !(log = r_io_accesslog_new ())) {
return NULL;
}
log->buf = buf;
onIterMap (io->maps->tail, io, vaddr, buf, len, R_IO_WRITE, al_fd_write_at_wrap, log);
return log;
}

R_API bool r_io_read_at(RIO* io, ut64 addr, ut8* buf, int len) {
bool ret;
if (!io || !buf || len < 1) {
Expand All @@ -309,7 +388,7 @@ R_API bool r_io_read_at(RIO* io, ut64 addr, ut8* buf, int len) {
if (io->va) {
ret = r_io_vread_at (io, addr, buf, len);
} else {
ret = !!r_io_pread_at (io, addr, buf, len) > 0;
ret = (r_io_pread_at (io, addr, buf, len) > 0);
}
if (io->cached_read) {
(void)r_io_cache_read (io, addr, buf, len);
Expand All @@ -336,7 +415,7 @@ R_API bool r_io_write_at(RIO* io, ut64 addr, const ut8* buf, int 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) > 0);
}
if (buf != mybuf) {
free (mybuf);
Expand Down
41 changes: 41 additions & 0 deletions libr/io/ioutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include <r_util.h>
#include <r_types.h>

static int __access_log_e_cmp (const void *a, const void *b) {
RIOAccessLogElement *A = (RIOAccessLogElement *)a;
RIOAccessLogElement *B = (RIOAccessLogElement *)b;
return (A->buf_idx > B->buf_idx);
}

//This helper function only check if the given vaddr is mapped, it does not account
//for map perms
Expand Down Expand Up @@ -69,3 +74,39 @@ R_API bool r_io_write_i(RIO* io, ut64 addr, ut64 *val, int size, bool endian) {
}
return true;
}

R_API RIOAccessLog *r_io_accesslog_new() {
RIOAccessLog *log = R_NEW0 (RIOAccessLog);
if (!log) {
return NULL;
}
if (!(log->log = r_list_newf (free))) {
free (log);
return NULL;
}
return log;
}

R_API void r_io_accesslog_free(RIOAccessLog *log) {
if (log) {
r_list_free (log->log);
}
free (log);
}

R_API void r_io_acccesslog_sort(RIOAccessLog *log) {
if (!log || !log->log) {
return;
}
r_list_sort (log->log, __access_log_e_cmp);
}

#if 0
//TODO
R_API void r_io_accesslog_sqash_byflags(RIOAccessLog *log) {
if (!log || !log->log) {
return;
}
return;
}
#endif

0 comments on commit 17ef439

Please sign in to comment.