Improve RBuffer api, start to refactor rbin to use more rbuf ##bin (#12495)

- Added a new rule in the DEVELOPERS.md file
This commit is contained in:
radare 2018-12-17 11:54:46 +01:00 committed by GitHub
parent 63fae31b1e
commit 7060103292
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 325 additions and 332 deletions

View File

@ -160,6 +160,21 @@ a = (b << 3) * 5;
}
```
* Structure in the C files
The structure of the C files in r2 must be like this:
```c
/* Copyright ... */ ## copyright
#include <r_core.h> ## includes
static int globals ## const, define, global variables
static void helper() {} ## static functions
R_IPI void internal() {} ## internal apis (used only inside the library
R_API void public() {} ## public apis starting with constructor/destructor
```
* Why return int vs enum
The reason why many places in r2land functions return int instead of an enum type is because enums cant be OR'ed; otherwise, it breaks the usage within a switch statement and swig can't handle that stuff.

View File

@ -147,13 +147,13 @@ static bool isBinopHelp(const char *op) {
}
static bool extract_binobj(const RBinFile *bf, RBinXtrData *data, int idx) {
ut64 bin_size = data ? data->size : 0;
ut64 bin_size = data? data->size: 0;
ut8 *bytes;
const char *xtr_type = "";
char *arch = "unknown";
int bits = 0;
int bits = 0, nb;
char *libname = NULL;
const char *filename = bf ? bf->file : NULL;
const char *filename = bf? bf->file: NULL;
char *path = NULL, *ptr = NULL;
bool res = false;
@ -170,11 +170,16 @@ static bool extract_binobj(const RBinFile *bf, RBinXtrData *data, int idx) {
eprintf ("This is not a fat bin\n");
return false;
}
bytes = data->buffer;
bytes = malloc (bin_size);
if (!bytes) {
eprintf ("error: BinFile buffer is empty\n");
return false;
}
nb = r_buf_read_at (data->buf, 0, bytes, bin_size);
if (nb <= 0) {
eprintf ("Couldn't read xtrdata\n");
return false;
}
if (!arch) {
arch = "unknown";
}
@ -212,7 +217,7 @@ static bool extract_binobj(const RBinFile *bf, RBinXtrData *data, int idx) {
free (outfile);
free (outpath);
free (path);
R_FREE (data->buffer);
free (bytes);
return res;
}

View File

@ -259,6 +259,65 @@ static int string_scan_range(RList *list, RBinFile *bf, int min,
return count;
}
static int is_data_section(RBinFile *a, RBinSection *s) {
if (s->has_strings || s->is_data) {
return true;
}
// Rust
return strstr (s->name, "_const") != NULL;
}
static void get_strings_range(RBinFile *bf, RList *list, int min, int raw, ut64 from, ut64 to) {
r_return_if_fail (bf && bf->buf);
RBinPlugin *plugin = r_bin_file_cur_plugin (bf);
RBinString *ptr;
RListIter *it;
if (!raw && (!plugin || !plugin->info)) {
return;
}
if (!min) {
min = plugin? plugin->minstrlen: 4;
}
/* Some plugins return zero, fix it up */
if (!min) {
min = 4;
}
if (min < 0) {
return;
}
if (!to || to > bf->buf->length) {
to = r_buf_size (bf->buf);
}
if (!to) {
return;
}
if (raw != 2) {
ut64 size = to - from;
// in case of dump ignore here
if (bf->rbin->maxstrbuf && size && size > bf->rbin->maxstrbuf) {
if (bf->rbin->verbose) {
eprintf ("WARNING: bin_strings buffer is too big (0x%08" PFMT64x "). Use -zzz or set bin.maxstrbuf (RABIN2_MAXSTRBUF) in r2 (rabin2)\n",
size);
}
return;
}
}
if (string_scan_range (list, bf, min, from, to, -1) < 0) {
return;
}
if (bf->o) {
r_list_foreach (list, it, ptr) {
RBinSection *s = r_bin_get_section_at (bf->o, ptr->paddr, false);
if (s) {
ptr->vaddr = s->vaddr + (ptr->paddr - s->paddr);
}
}
}
}
R_IPI RBinFile *r_bin_file_new(RBin *bin, const char *file, const ut8 *bytes, ut64 sz, ut64 file_sz, int rawstr, int fd, const char *xtrname, Sdb *sdb, bool steal_ptr) {
RBinFile *binfile = R_NEW0 (RBinFile);
if (!binfile) {
@ -285,7 +344,7 @@ R_IPI RBinFile *r_bin_file_new(RBin *bin, const char *file, const ut8 *bytes, ut
binfile->size = file_sz;
binfile->xtr_data = r_list_newf ((RListFree)r_bin_xtrdata_free);
binfile->objs = r_list_newf ((RListFree)r_bin_object_free);
binfile->xtr_obj = NULL;
binfile->xtr_obj = NULL;
if (!binfile->buf) {
//r_bin_file_free (binfile);
@ -328,32 +387,28 @@ static RBinPlugin *get_plugin(RBin *bin, const char *pluginname, const ut8 *byte
return r_bin_get_binplugin_any (bin);
}
static RBinPlugin * get_plugin_with_buffer (RBin *bin, RBuffer *buf) {
ut8 bytes[4096];
// XXX this must be removed to make get_plugin work with RBuffer instead of char*+sz
r_buf_read_at (buf, 0, bytes, sizeof (bytes));
return get_plugin (bin, NULL, (const ut8 *)bytes, sizeof (bytes));
}
R_API bool r_bin_file_object_new_from_xtr_data(RBin *bin, RBinFile *bf, ut64 baseaddr, ut64 loadaddr, RBinXtrData *data) {
r_return_val_if_fail (bin && bf && data, false);
RBinObject *o = NULL;
RBinPlugin *plugin = NULL;
ut8* bytes;
ut64 offset = data->offset;
ut64 sz = data->size;
// for right now the bytes used will just be the offest into the binfile
// buffer if the extraction requires some sort of transformation then
// this will need to be fixed here.
bytes = data->buffer;
r_return_val_if_fail (bytes, false);
RBinPlugin *plugin = get_plugin_with_buffer (bin, data->buf);
bf->buf = r_buf_new_with_bufref (data->buf);
plugin = get_plugin (bin, NULL, (const ut8 *)bytes, sz);
r_buf_free (bf->buf);
bf->buf = r_buf_new_with_bytes ((const ut8 *)bytes, data->size);
// r_bin_object_new append the new object into binfile
o = r_bin_object_new (bf, plugin, baseaddr, loadaddr, offset, sz);
// size is set here because the reported size of the object depends on
// if loaded from xtr plugin or partially read
RBinObject *o = r_bin_object_new (bf, plugin, baseaddr, loadaddr, offset, sz);
if (!o) {
return false;
}
// size is set here because the reported size of the object depends on
// if loaded from xtr plugin or partially read
if (!o->size) {
o->size = sz;
}
@ -376,14 +431,23 @@ R_API bool r_bin_file_object_new_from_xtr_data(RBin *bin, RBinFile *bf, ut64 bas
}
static RBinFile *file_create_append(RBin *bin, const char *file, const ut8 *bytes, ut64 sz, ut64 file_sz, int rawstr, int fd, const char *xtrname, bool steal_ptr) {
RBinFile *bf = r_bin_file_new (bin, file, bytes, sz, file_sz, rawstr,
fd, xtrname, bin->sdb, steal_ptr);
RBinFile *bf = r_bin_file_new (bin, file, bytes, sz, file_sz, rawstr, fd, xtrname, bin->sdb, steal_ptr);
if (bf) {
r_list_append (bin->binfiles, bf);
}
return bf;
}
static bool xtr_metadata_match(RBinXtrData *xtr_data, const char *arch, int bits) {
if (!xtr_data->metadata || !xtr_data->metadata->arch) {
return false;
}
char *iter_arch = xtr_data->metadata->arch;
int iter_bits = xtr_data->metadata->bits;
return bits == iter_bits && !strcmp (iter_arch, arch) && !xtr_data->loaded;
}
R_IPI RBinFile *r_bin_file_new_from_bytes(RBin *bin, const char *file, const ut8 *bytes, ut64 sz, ut64 file_sz, int rawstr, ut64 baseaddr, ut64 loadaddr, int fd, const char *pluginname, ut64 offset) {
r_return_val_if_fail (sz != UT64_MAX, NULL);
@ -403,20 +467,9 @@ R_IPI RBinFile *r_bin_file_new_from_bytes(RBin *bin, const char *file, const ut8
if (!o->size) {
o->size = file_sz;
}
return bf;
}
static bool xtr_metadata_match(RBinXtrData *xtr_data, const char *arch, int bits) {
if (!xtr_data->metadata || !xtr_data->metadata->arch) {
return false;
}
char *iter_arch = xtr_data->metadata->arch;
int iter_bits = xtr_data->metadata->bits;
return bits == iter_bits && !strcmp (iter_arch, arch) && !xtr_data->loaded;
}
R_API RBinFile *r_bin_file_find_by_arch_bits(RBin *bin, const char *arch, int bits) {
RListIter *iter;
RBinFile *binfile = NULL;
@ -698,66 +751,6 @@ R_API RBinPlugin *r_bin_file_cur_plugin(RBinFile *binfile) {
return (binfile && binfile->o)? binfile->o->plugin: NULL;
}
static int is_data_section(RBinFile *a, RBinSection *s) {
if (s->has_strings || s->is_data) {
return true;
}
// Rust
return strstr (s->name, "_const") != NULL;
}
static void get_strings_range(RBinFile *bf, RList *list, int min, int raw, ut64 from, ut64 to) {
r_return_if_fail (bf && bf->buf);
RBinPlugin *plugin = r_bin_file_cur_plugin (bf);
RBinString *ptr;
RListIter *it;
if (!raw) {
if (!plugin || !plugin->info) {
return;
}
}
if (!min) {
min = plugin? plugin->minstrlen: 4;
}
/* Some plugins return zero, fix it up */
if (!min) {
min = 4;
}
if (min < 0) {
return;
}
if (!to || to > bf->buf->length) {
to = r_buf_size (bf->buf);
}
if (!to) {
return;
}
if (raw != 2) {
ut64 size = to - from;
// in case of dump ignore here
if (bf->rbin->maxstrbuf && size && size > bf->rbin->maxstrbuf) {
if (bf->rbin->verbose) {
eprintf ("WARNING: bin_strings buffer is too big (0x%08" PFMT64x "). Use -zzz or set bin.maxstrbuf (RABIN2_MAXSTRBUF) in r2 (rabin2)\n",
size);
}
return;
}
}
if (string_scan_range (list, bf, min, from, to, -1) < 0) {
return;
}
if (bf->o) {
r_list_foreach (list, it, ptr) {
RBinSection *s = r_bin_get_section_at (bf->o, ptr->paddr, false);
if (s) {
ptr->vaddr = s->vaddr + (ptr->paddr - s->paddr);
}
}
}
}
R_IPI RList *r_bin_file_get_strings(RBinFile *a, int min, int dump, int raw) {
r_return_val_if_fail (a, NULL);
RListIter *iter;

View File

@ -56,9 +56,7 @@ static ut64 binobj_a2b(RBinObject *o, ut64 addr) {
}
// TODO: move these two function do a different file
R_API RBinXtrData *r_bin_xtrdata_new(RBuffer *buf, ut64 offset, ut64 size,
ut32 file_count,
RBinXtrMetadata *metadata) {
R_API RBinXtrData *r_bin_xtrdata_new(RBuffer *buf, ut64 offset, ut64 size, ut32 file_count, RBinXtrMetadata *metadata) {
RBinXtrData *data = R_NEW0 (RBinXtrData);
if (!data) {
return NULL;
@ -69,15 +67,8 @@ R_API RBinXtrData *r_bin_xtrdata_new(RBuffer *buf, ut64 offset, ut64 size,
data->metadata = metadata;
data->loaded = 0;
// TODO: USE RBuffer *buf inside RBinXtrData*
data->buffer = malloc (size + 1);
// data->laddr = 0; /// XXX
if (!data->buffer) {
free (data);
return NULL;
}
// XXX unnecessary memcpy, this is slow
memcpy (data->buffer, r_buf_buffer (buf), size);
data->buffer[size] = 0;
data->buf = r_buf_ref (buf);
// TODO. subbuffer?
return data;
}
@ -102,7 +93,7 @@ R_API void r_bin_xtrdata_free(void /*RBinXtrData*/ *data_) {
free (data->metadata);
}
free (data->file);
free (data->buffer);
r_buf_free (data->buf);
free (data);
}

View File

@ -330,7 +330,7 @@ typedef struct r_bin_xtr_metadata_t {
typedef int (*FREE_XTR)(void *xtr_obj);
typedef struct r_bin_xtr_extract_t {
char *file;
ut8 *buffer;
RBuffer *buf;
ut64 size;
ut64 offset;
ut64 baddr;

View File

@ -44,6 +44,7 @@ R_API RBuffer *r_buf_new_with_bytes(const ut8* bytes, ut64 len);
R_API RBuffer *r_buf_new_with_string (const char *msg);
R_API RBuffer *r_buf_new_with_pointers(const ut8 *bytes, ut64 len);
R_API RBuffer *r_buf_new_with_buf(RBuffer *b);
R_API RBuffer *r_buf_new_with_bufref(RBuffer *b);
R_API RBuffer *r_buf_new_file(const char *file, bool newFile);
R_API RBuffer *r_buf_new_slurp(const char *file);
R_API RBuffer *r_buf_new_empty (ut64 len);

View File

@ -106,6 +106,200 @@ static bool sparse_limits(RList *l, ut64 *min, ut64 *max) {
return set;
}
static ut64 remainingBytes(ut64 limit, ut64 length, ut64 offset) {
if (offset >= length ) {
return 0;
}
return R_MIN (limit, length - offset);
}
// ret copied length if successful, -1 if failed
static int r_buf_cpy(RBuffer *b, ut64 addr, ut8 *dst, const ut8 *src, int len, int write) {
r_return_val_if_fail (b && !b->empty, 0);
ut64 start = addr - b->base + b->offset;
ut64 effective_size = r_buf_size (b);
int real_len = len;
if (start - b->offset + len > effective_size) {
real_len = effective_size - start + b->offset;
}
if (real_len < 1) {
return 0;
}
if (b->iob) {
RIOBind *iob = b->iob;
if (b->fd != -1) {
return write
? iob->fd_write_at (iob->io, b->fd, start, src, real_len)
: iob->fd_read_at (iob->io, b->fd, start, dst, real_len);
}
return write
? iob->write_at (iob->io, start, src, real_len)
: iob->read_at (iob->io, start, dst, real_len);
}
if (b->fd != -1) {
if (r_sandbox_lseek (b->fd, start, SEEK_SET) == -1) {
// seek failed - print error here?
// return 0;
}
if (write) {
return r_sandbox_write (b->fd, src, real_len);
}
memset (dst, 0, real_len);
return r_sandbox_read (b->fd, dst, real_len);
}
if (b->sparse) {
if (write) {
// create new with src + len
if (sparse_write (b->sparse, start, src, real_len) < 0) {
return -1;
}
} else {
// read from sparse and write into dst
memset (dst, b->Oxff, len);
(void)sparse_read (b->sparse, start, dst, real_len);
len = R_MIN (real_len , r_buf_size (b) - addr);
}
return real_len;
}
addr = (addr == R_BUF_CUR) ? b->cur : start;
if (len < 1 || !dst || addr - b->offset > effective_size) {
return -1;
}
if (write) {
dst += addr;
} else {
src += addr;
}
memmove (dst, src, real_len);
b->cur = addr + real_len;
return real_len;
}
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) {
ut64 len, check_len;
int i, j, k, tsize, m = 1;
bool bigendian = true;
r_return_val_if_fail (b && !b->empty, 0);
if ((b->iob || b->fd != -1) && write) {
eprintf ("r_buf_fcpy_at write not supported yet for r_buf_new_file\n");
return 0;
}
ut64 vaddr;
if (addr == R_BUF_CUR) {
vaddr = addr = b->cur;
} else {
vaddr = addr;
addr = addr - b->base + b->offset;
}
ut64 effective_size = r_buf_size (b);
if (addr == UT64_MAX || addr > effective_size) {
return -1;
}
tsize = 2;
for (i = len = 0; i < n; i++) {
for (j = 0; fmt[j]; j++) {
switch (fmt[j]) {
#ifdef _MSC_VER
case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':
#else
case '0'...'9':
#endif
if (m == 1) {
m = r_num_get (NULL, &fmt[j]);
}
continue;
case 's': tsize = 2; bigendian = false; break;
case 'S': tsize = 2; bigendian = true; break;
case 'i': tsize = 4; bigendian = false; break;
case 'I': tsize = 4; bigendian = true; break;
case 'l': tsize = 8; bigendian = false; break;
case 'L': tsize = 8; bigendian = true; break;
case 'c': tsize = 1; bigendian = false; break;
default: return -1;
}
/* Avoid read/write out of bound.
tsize and m are not user controled, then don't
need to check possible overflow.
*/
if (!UT64_ADD (&check_len, len, tsize*m)) {
return -1;
}
if (!UT64_ADD (&check_len, check_len, addr)) {
return -1;
}
if (check_len > effective_size) {
return check_len;
}
for (k = 0; k < m; k++) {
ut8 _dest1[sizeof (ut64)] = {0};
ut8 _dest2[sizeof (ut64)] = {0};
int left1, left2;
ut64 addr1 = len + (k * tsize);
ut64 addr2 = vaddr + addr1;
ut8 *src1=NULL, *src2=NULL;
if (b->fd == -1) {
src1 = r_buf_get_at (b, addr1, &left1);
src2 = r_buf_get_at (b, addr2, &left2);
}
if (!src1 || !src2) {
left1 = r_buf_read_at (b, addr1, _dest1, sizeof (_dest1));
left2 = r_buf_read_at (b, addr2, _dest2, sizeof (_dest2));
src1 = _dest1;
src2 = _dest2;
}
void* dest1 = buf + addr + addr1; // shouldn't this be an address in b ?
void* dest2 = buf + addr1;
ut8* dest1_8 = (ut8*)dest1;
ut16* dest1_16 = (ut16*)dest1;
ut32* dest1_32 = (ut32*)dest1;
ut64* dest1_64 = (ut64*)dest1;
ut8* dest2_8 = (ut8*)dest2;
ut16* dest2_16 = (ut16*)dest2;
ut32* dest2_32 = (ut32*)dest2;
ut64* dest2_64 = (ut64*)dest2;
if (write) {
switch (tsize) {
case 1:
*dest1_8 = r_read_ble8 (src1);
break;
case 2:
*dest1_16 = r_read_ble16 (src1, bigendian);
break;
case 4:
*dest1_32 = r_read_ble32 (src1, bigendian);
break;
case 8:
*dest1_64 = r_read_ble64 (src1, bigendian);
break;
}
} else {
switch (tsize) {
case 1:
*dest2_8 = r_read_ble8 (src2);
break;
case 2:
*dest2_16 = r_read_ble16 (src2, bigendian);
break;
case 4:
*dest2_32 = r_read_ble32 (src2, bigendian);
break;
case 8:
*dest2_64 = r_read_ble64 (src2, bigendian);
break;
}
}
}
len += tsize * m;
m = 1;
}
}
b->cur = vaddr + len;
return len;
}
R_API RBuffer *r_buf_new_with_io(void *iob, int fd) {
RBuffer *b = r_buf_new ();
b->iob = iob;
@ -171,9 +365,7 @@ R_API RBuffer *r_buf_new_sparse(ut8 Oxff) {
}
R_API RBuffer *r_buf_new_slice(RBuffer *b, ut64 offset, ut64 size) {
if (!b) {
return NULL;
}
r_return_val_if_fail (b, NULL);
if (b->sparse) {
eprintf ("r_buf_new_slice not supported yet for sparse buffers\n");
return NULL;
@ -208,13 +400,6 @@ R_API const ut8 *r_buf_buffer (RBuffer *b) {
return (b && !b->sparse)? b->buf: NULL;
}
static ut64 remainingBytes(ut64 limit, ut64 length, ut64 offset) {
if (offset >= length ) {
return 0;
}
return R_MIN (limit, length - offset);
}
R_API ut64 r_buf_size (RBuffer *b) {
if (!b) {
return 0LL;
@ -515,196 +700,6 @@ R_API bool r_buf_append_buf(RBuffer *b, RBuffer *a) {
return false;
}
// ret copied length if successful, -1 if failed
static int r_buf_cpy(RBuffer *b, ut64 addr, ut8 *dst, const ut8 *src, int len, int write) {
if (!b || b->empty) {
return 0;
}
ut64 start = addr - b->base + b->offset;
ut64 effective_size = r_buf_size (b);
int real_len = len;
if (start - b->offset + len > effective_size) {
real_len = effective_size - start + b->offset;
}
if (real_len < 1) {
return 0;
}
if (b->iob) {
RIOBind *iob = b->iob;
if (b->fd != -1) {
return write
? iob->fd_write_at (iob->io, b->fd, start, src, real_len)
: iob->fd_read_at (iob->io, b->fd, start, dst, real_len);
}
return write
? iob->write_at (iob->io, start, src, real_len)
: iob->read_at (iob->io, start, dst, real_len);
}
if (b->fd != -1) {
if (r_sandbox_lseek (b->fd, start, SEEK_SET) == -1) {
// seek failed - print error here?
// return 0;
}
if (write) {
return r_sandbox_write (b->fd, src, real_len);
}
memset (dst, 0, real_len);
return r_sandbox_read (b->fd, dst, real_len);
}
if (b->sparse) {
if (write) {
// create new with src + len
if (sparse_write (b->sparse, start, src, real_len) < 0) {
return -1;
}
} else {
// read from sparse and write into dst
memset (dst, b->Oxff, len);
(void)sparse_read (b->sparse, start, dst, real_len);
len = R_MIN (real_len , r_buf_size (b) - addr);
}
return real_len;
}
addr = (addr == R_BUF_CUR) ? b->cur : start;
if (len < 1 || !dst || addr - b->offset > effective_size) {
return -1;
}
if (write) {
dst += addr;
} else {
src += addr;
}
memmove (dst, src, real_len);
b->cur = addr + real_len;
return real_len;
}
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) {
ut64 len, check_len;
int i, j, k, tsize, m = 1;
bool bigendian = true;
if (!b || b->empty) {
return 0;
}
if ((b->iob || b->fd != -1) && write) {
eprintf ("r_buf_fcpy_at write not supported yet for r_buf_new_file\n");
return 0;
}
ut64 vaddr;
if (addr == R_BUF_CUR) {
vaddr = addr = b->cur;
} else {
vaddr = addr;
addr = addr - b->base + b->offset;
}
ut64 effective_size = r_buf_size (b);
if (addr == UT64_MAX || addr > effective_size) {
return -1;
}
tsize = 2;
for (i = len = 0; i < n; i++) {
for (j = 0; fmt[j]; j++) {
switch (fmt[j]) {
#ifdef _MSC_VER
case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':
#else
case '0'...'9':
#endif
if (m == 1) {
m = r_num_get (NULL, &fmt[j]);
}
continue;
case 's': tsize = 2; bigendian = false; break;
case 'S': tsize = 2; bigendian = true; break;
case 'i': tsize = 4; bigendian = false; break;
case 'I': tsize = 4; bigendian = true; break;
case 'l': tsize = 8; bigendian = false; break;
case 'L': tsize = 8; bigendian = true; break;
case 'c': tsize = 1; bigendian = false; break;
default: return -1;
}
/* Avoid read/write out of bound.
tsize and m are not user controled, then don't
need to check possible overflow.
*/
if (!UT64_ADD (&check_len, len, tsize*m)) {
return -1;
}
if (!UT64_ADD (&check_len, check_len, addr)) {
return -1;
}
if (check_len > effective_size) {
return check_len;
}
for (k = 0; k < m; k++) {
ut8 _dest1[sizeof (ut64)] = {0};
ut8 _dest2[sizeof (ut64)] = {0};
int left1, left2;
ut64 addr1 = len + (k * tsize);
ut64 addr2 = vaddr + addr1;
ut8 *src1=NULL, *src2=NULL;
if (b->fd == -1) {
src1 = r_buf_get_at (b, addr1, &left1);
src2 = r_buf_get_at (b, addr2, &left2);
}
if (!src1 || !src2) {
left1 = r_buf_read_at (b, addr1, _dest1, sizeof (_dest1));
left2 = r_buf_read_at (b, addr2, _dest2, sizeof (_dest2));
src1 = _dest1;
src2 = _dest2;
}
void* dest1 = buf + addr + addr1; // shouldn't this be an address in b ?
void* dest2 = buf + addr1;
ut8* dest1_8 = (ut8*)dest1;
ut16* dest1_16 = (ut16*)dest1;
ut32* dest1_32 = (ut32*)dest1;
ut64* dest1_64 = (ut64*)dest1;
ut8* dest2_8 = (ut8*)dest2;
ut16* dest2_16 = (ut16*)dest2;
ut32* dest2_32 = (ut32*)dest2;
ut64* dest2_64 = (ut64*)dest2;
if (write) {
switch (tsize) {
case 1:
*dest1_8 = r_read_ble8 (src1);
break;
case 2:
*dest1_16 = r_read_ble16 (src1, bigendian);
break;
case 4:
*dest1_32 = r_read_ble32 (src1, bigendian);
break;
case 8:
*dest1_64 = r_read_ble64 (src1, bigendian);
break;
}
} else {
switch (tsize) {
case 1:
*dest2_8 = r_read_ble8 (src2);
break;
case 2:
*dest2_16 = r_read_ble16 (src2, bigendian);
break;
case 4:
*dest2_32 = r_read_ble32 (src2, bigendian);
break;
case 8:
*dest2_64 = r_read_ble64 (src2, bigendian);
break;
}
}
}
len += tsize * m;
m = 1;
}
}
b->cur = vaddr + len;
return len;
}
R_API ut8 *r_buf_get_at(RBuffer *b, ut64 addr, int *left) {
if (b->empty) {
return NULL;
@ -843,25 +838,6 @@ R_API int r_buf_fwrite_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int
return r_buf_fcpy_at (b, addr, buf, fmt, n, true);
}
R_API void r_buf_deinit(RBuffer *b) {
if (!b) {
return;
}
if (b->fd != -1) {
r_sandbox_close (b->fd);
b->fd = -1;
return;
}
if (b->sparse) {
r_list_free (b->sparse);
b->sparse = NULL;
}
if (b->mmap) {
r_file_mmap_free (b->mmap);
b->mmap = NULL;
} else R_FREE (b->buf);
}
R_API bool r_buf_fini(RBuffer *b) {
if (!b) {
return false;
@ -878,7 +854,21 @@ R_API bool r_buf_fini(RBuffer *b) {
return false;
}
if (!b->ro) {
r_buf_deinit (b);
if (b->fd != -1) {
r_sandbox_close (b->fd);
b->fd = -1;
return false;
}
if (b->sparse) {
r_list_free (b->sparse);
b->sparse = NULL;
}
if (b->mmap) {
r_file_mmap_free (b->mmap);
b->mmap = NULL;
} else {
R_FREE (b->buf);
}
}
// true -> can bee free()d
return true;
@ -895,10 +885,8 @@ R_API int r_buf_append_string (RBuffer *b, const char *str) {
}
R_API char *r_buf_free_to_string(RBuffer *b) {
r_return_val_if_fail (b, NULL);
char *p;
if (!b) {
return NULL;
}
if (b->mmap) {
p = r_buf_to_string (b);
} else {