Clean up io and add some comments

* Add prefix mode r_io_nread_at
* Add r_io_read_at_mapped
This commit is contained in:
Fangrui Song 2018-02-27 09:41:52 -08:00 committed by radare
parent 02b77432c1
commit 0ac144d06a
2 changed files with 68 additions and 16 deletions

View File

@ -60,7 +60,6 @@ typedef struct r_io_undo_w_t {
typedef struct r_io_t {
struct r_io_desc_t *desc;
int ret; // number of bytes read or written
ut64 off;
int bits;
int va; //all of this config stuff must be in 1 int
@ -335,11 +334,12 @@ 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_vread_at_mapped(RIO* io, ut64 vaddr, 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 bool r_io_read_at_mapped(RIO *io, ut64 addr, ut8 *buf, int len);
R_API int r_io_nread_at (RIO *io, ut64 addr, ut8 *buf, int len);
R_API RIOAccessLog *r_io_al_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);

View File

@ -385,7 +385,8 @@ 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) {
// Returns true iff all reads on mapped regions are successful and complete.
R_API bool r_io_vread_at_mapped(RIO* io, ut64 vaddr, ut8* buf, int len) {
if (!io || !buf || (len < 1)) {
return false;
}
@ -399,7 +400,7 @@ R_API bool r_io_vread_at(RIO* io, ut64 vaddr, ut8* buf, int len) {
return onIterMap_wrap (io->maps->tail, io, vaddr, buf, len, R_IO_READ, fd_read_at_wrap, NULL);
}
R_API bool r_io_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int len) {
static bool r_io_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int len) {
if (!io || !buf || (len < 1)) {
return false;
}
@ -441,23 +442,77 @@ R_API RIOAccessLog *r_io_al_vwrite_at(RIO* io, ut64 vaddr, const ut8* buf, int l
return log;
}
R_API bool r_io_read_at(RIO* io, ut64 addr, ut8* buf, int len) {
// Deprecated, use either r_io_read_at_mapped or r_io_nread_at instead.
// For virtual mode, returns true if all reads on mapped regions are successful
// and complete.
// For physical mode, the interface is broken because the actual read bytes are
// not available. This requires fixes in all call sites.
R_API bool r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
bool ret;
if (!io || !buf || len < 1) {
return false;
}
if (io->buffer_enabled) {
return !!r_io_buffer_read (io, addr, buf, len);
return !!r_io_buffer_read(io, addr, buf, len);
}
if (io->va) {
ret = r_io_vread_at (io, addr, buf, len);
io->ret = ret? len: -1;
ret = r_io_vread_at_mapped(io, addr, buf, len);
} else {
io->ret = r_io_pread_at (io, addr, buf, len);
ret = io->ret > 0;
ret = r_io_pread_at(io, addr, buf, len) > 0;
}
if (io->cached & R_IO_READ) {
(void)r_io_cache_read (io, addr, buf, len);
(void)r_io_cache_read(io, addr, buf, len);
}
return ret;
}
// Returns true iff all reads on mapped regions are successful and complete.
// Unmapped regions are filled with io->Oxff in both physical and virtual modes.
// Use this function if you want to ignore gaps or do not care about the number
// of read bytes.
R_API bool r_io_read_at_mapped(RIO *io, ut64 addr, ut8 *buf, int len) {
bool ret;
if (!io || !buf) {
return false;
}
if (io->buffer_enabled) {
return !!r_io_buffer_read(io, addr, buf, len);
}
if (io->ff) {
memset(buf, io->Oxff, len);
}
if (io->va) {
ret = on_map_skyline(io, addr, buf, len, R_IO_READ, fd_read_at_wrap, false);
} else {
ret = r_io_pread_at(io, addr, buf, len) > 0;
}
if (io->cached & R_IO_READ) {
(void)r_io_cache_read(io, addr, buf, len);
}
return ret;
}
// For both virtual and physical mode, returns the number of bytes of read
// prefix.
// Returns -1 on error.
R_API int r_io_nread_at(RIO *io, ut64 addr, ut8 *buf, int len) {
int ret;
if (!io || !buf) {
return -1;
}
if (io->buffer_enabled) {
return r_io_buffer_read(io, addr, buf, len);
}
if (io->va) {
if (io->ff) {
memset(buf, io->Oxff, len);
}
ret = on_map_skyline(io, addr, buf, len, R_IO_READ, fd_read_at_wrap, true);
} else {
ret = r_io_pread_at(io, addr, buf, len);
}
if (ret > 0 && io->cached & R_IO_READ) {
(void)r_io_cache_read(io, addr, buf, len);
}
return ret;
}
@ -512,13 +567,10 @@ R_API bool r_io_write_at(RIO* io, ut64 addr, const ut8* buf, int len) {
}
if (io->cached & R_IO_WRITE) {
ret = r_io_cache_write (io, addr, mybuf, len);
io->ret = ret? len: -1;
} else if (io->va) {
ret = r_io_vwrite_at (io, addr, mybuf, len);
io->ret = ret? len: -1;
} else {
io->ret = r_io_pwrite_at (io, addr, mybuf, len);
ret = io->ret > 0;
ret = r_io_pwrite_at (io, addr, mybuf, len) > 0;
}
if (buf != mybuf) {
free (mybuf);