From 4df85046fdfcbe06d1f085b5a224ef844c3dca79 Mon Sep 17 00:00:00 2001 From: pancake Date: Thu, 15 Sep 2016 17:19:39 +0200 Subject: [PATCH] Add r_buf_resize and make ihex:// .resize() work --- libr/include/r_util/r_buf.h | 1 + libr/io/p/io_ihex.c | 23 ++++++++++------ libr/util/buf.c | 53 ++++++++++++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/libr/include/r_util/r_buf.h b/libr/include/r_util/r_buf.h index 476b82cd28..416f934b85 100644 --- a/libr/include/r_util/r_buf.h +++ b/libr/include/r_util/r_buf.h @@ -59,4 +59,5 @@ R_API void r_buf_free(RBuffer *b); R_API char *r_buf_free_to_string(RBuffer *b); R_API const ut8 *r_buf_buffer(RBuffer *b); R_API ut64 r_buf_size(RBuffer *b); +R_API bool r_buf_resize(RBuffer *b, ut64 newsize); #endif // R_BUF_H diff --git a/libr/io/p/io_ihex.c b/libr/io/p/io_ihex.c index 74531836e7..cabcdbc3f8 100644 --- a/libr/io/p/io_ihex.c +++ b/libr/io/p/io_ihex.c @@ -67,18 +67,19 @@ static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { /* disk write : process each sparse chunk */ //TODO : sort addresses + check overlap? - r_list_foreach(rih->rbuf->sparse, iter, rbs) { + r_list_foreach (rih->rbuf->sparse, iter, rbs) { ut16 addl0 = rbs->from & 0xffff; - ut16 addh0 = rbs->from >>16; - ut16 addh1 = rbs->to >>16; + ut16 addh0 = rbs->from >> 16; + ut16 addh1 = rbs->to >> 16; ut16 tsiz =0; - if (rbs->size == 0) + if (rbs->size == 0) { continue; + } if (addh0 != addh1) { //we cross a 64k boundary, so write in two steps //04 record (ext address) - if (fw04b(out, addh0) < 0) { + if (fw04b (out, addh0) < 0) { eprintf("ihex:write: file error\n"); fclose (out); return -1; @@ -86,7 +87,7 @@ static int __write(RIO *io, RIODesc *fd, const ut8 *buf, int count) { //00 records (data) tsiz = -addl0; addl0 = 0; - if (fwblock(out, rbs->data, rbs->from, tsiz)) { + if (fwblock (out, rbs->data, rbs->from, tsiz)) { eprintf("ihex:fwblock error\n"); fclose (out); return -1; @@ -196,7 +197,7 @@ static ut64 __lseek(struct r_io_t *io, RIODesc *fd, ut64 offset, int whence) { return -1; } rih = fd->data; - return r_buf_seek(rih->rbuf, offset, whence); + return r_buf_seek (rih->rbuf, offset, whence); } static bool __plugin_open(RIO *io, const char *pathname, bool many) { @@ -368,7 +369,7 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { if (__plugin_open (io, pathname, 0)) { str = r_file_slurp (pathname + 7, NULL); if (!str) return NULL; - mal= R_NEW (Rihex); + mal= R_NEW0 (Rihex); if (!mal) { free (str); return NULL; @@ -394,6 +395,11 @@ static RIODesc *__open(RIO *io, const char *pathname, int rw, int mode) { return NULL; } +static bool __resize(RIO *io, RIODesc *fd, ut64 size) { + Rihex *rih = fd->data; + return r_buf_resize (rih->rbuf, size); +} + RIOPlugin r_io_plugin_ihex = { .name = "ihex", .desc = "Intel HEX file (ihex://eeproms.hex)", @@ -404,6 +410,7 @@ RIOPlugin r_io_plugin_ihex = { .check = __plugin_open, .lseek = __lseek, .write = __write, + .resize = __resize }; #ifndef CORELIB diff --git a/libr/util/buf.c b/libr/util/buf.c index ca17b7214d..d7dcdea2e8 100644 --- a/libr/util/buf.c +++ b/libr/util/buf.c @@ -122,8 +122,7 @@ static bool sparse_limits(RList *l, ut64 *min, ut64 *max) { R_API RBuffer *r_buf_new_with_pointers (const ut8 *bytes, ut64 len) { RBuffer *b = r_buf_new (); - if (!b) return NULL; - if (bytes && (len > 0 && len != UT64_MAX)) { + if (b && bytes && len > 0 && len != UT64_MAX) { b->buf = (ut8*)bytes; b->length = len; b->empty = false; @@ -134,9 +133,9 @@ R_API RBuffer *r_buf_new_with_pointers (const ut8 *bytes, ut64 len) { R_API RBuffer *r_buf_new_with_bytes (const ut8 *bytes, ut64 len) { RBuffer *b = r_buf_new (); - if (!b) return NULL; - if (bytes && (len > 0 && len != UT64_MAX)) + if (b && bytes && (len > 0 && len != UT64_MAX)) { r_buf_set_bytes (b, bytes, len); + } return b; } @@ -146,7 +145,9 @@ R_API RBuffer *r_buf_new_with_buf(RBuffer *b) { R_API RBuffer *r_buf_new_sparse() { RBuffer *b = r_buf_new (); - if (!b) return NULL; + if (!b) { + return NULL; + } b->sparse = r_list_newf ((RListFree)free); return b; } @@ -170,7 +171,6 @@ R_API ut64 r_buf_size (RBuffer *b) { } if (b->sparse) { ut64 max = 0LL; -eprintf ("GETTING SIZE\n"); if (sparse_limits (b->sparse, NULL, &max)) { return max; // -min } @@ -324,7 +324,9 @@ R_API bool r_buf_append_bytes(RBuffer *b, const ut8 *buf, int length) { r_sandbox_write (b->fd, buf, length); return true; } - if (b->empty) b->length = b->empty = 0; + if (b->empty) { + b->length = b->empty = 0; + } if (!(b->buf = realloc (b->buf, 1 + b->length + length))) { return false; } @@ -668,3 +670,40 @@ R_API char *r_buf_free_to_string (RBuffer *b) { free (b); return p; } + +R_API bool r_buf_resize (RBuffer *b, ut64 newsize) { + if (b->mmap) { + return false; + } + if ((!b->sparse && !b->buf) || newsize < 1) { + return false; + } + if (b->sparse) { + ut64 last_addr = 0; + sparse_limits (b->sparse, 0, &last_addr); + int buf_len = newsize - last_addr; + if (buf_len > 0) { + ut8 *buf = malloc (buf_len); + if (buf) { + memset (buf, 0xff, buf_len); + sparse_write (b->sparse, last_addr, buf, buf_len); + free (buf); + return true; + } + } + eprintf ("Invalid resize for an sparse RBuffer\n"); + return false; + } + ut8 *buf = calloc (newsize, 1); + if (buf) { + ut32 len = R_MIN (newsize, b->length); + memcpy (buf, b->buf, len); + memset (buf + len, 0xff, newsize - len); + /* commit */ + free (b->buf); + b->buf = buf; + b->length = newsize; + return true; + } + return false; +}