Add r_buf_resize and make ihex:// .resize() work

This commit is contained in:
pancake 2016-09-15 17:19:39 +02:00
parent 0209a1679e
commit 4df85046fd
3 changed files with 62 additions and 15 deletions

View File

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

View File

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

View File

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