Fix 'oo' bug (sync rcorefile and riofile lists), Better 'ob'

This commit is contained in:
pancake 2014-10-17 00:04:52 +02:00
parent 907d17460f
commit da866539ee
13 changed files with 183 additions and 104 deletions

View file

@ -224,3 +224,4 @@ All your base are belong to r2
Ask not what r2 can do for you - ask what you can do for r2
Try with ASAN, and be amazed
bash: r3: command not found :D
R2 loves everyone, even Java coders, but less than others

View file

@ -1265,27 +1265,26 @@ R_API int r_bin_select_object(RBinFile *binfile, const char *arch, int bits, con
return obj && r_bin_file_set_cur_binfile_obj (binfile->rbin, binfile, obj);
}
static RBinObject * r_bin_file_object_find_by_id (RBinFile *binfile, ut32 binobj_id) {
RBinObject *obj = NULL;
RListIter *iter = NULL;
static RBinObject* r_bin_file_object_find_by_id (RBinFile *binfile, ut32 binobj_id) {
RBinObject *obj;
RListIter *iter;
if (!binfile) return obj;
if (binfile)
r_list_foreach (binfile->objs, iter, obj) {
if (obj->id == binobj_id) break;
obj = NULL;
if (obj->id == binobj_id)
return obj;
}
return obj;
return NULL;
}
static RBinFile * r_bin_file_find_by_object_id (RBin *bin, ut32 binobj_id) {
RListIter *iter = NULL;
RBinFile *binfile = NULL;
static RBinFile* r_bin_file_find_by_object_id (RBin *bin, ut32 binobj_id) {
RListIter *iter;
RBinFile *binfile;
r_list_foreach (bin->binfiles, iter, binfile) {
if (r_bin_file_object_find_by_id (binfile, binobj_id)) break;
binfile = NULL;
if (r_bin_file_object_find_by_id (binfile, binobj_id))
return binfile;
}
return binfile;
return NULL;
}
#if 0
@ -1314,16 +1313,14 @@ static RBinFile * r_bin_file_find_by_id (RBin *bin, ut32 binfile_id) {
}
R_API int r_bin_object_delete (RBin *bin, ut32 binfile_id, ut32 binobj_id) {
RBinFile *binfile = NULL;//, *cbinfile = r_bin_cur (bin);
RBinObject *obj = NULL;
int res = R_FALSE;
if (binfile_id == UT32_MAX && binobj_id == UT32_MAX) {
if (binfile_id == UT32_MAX && binobj_id == UT32_MAX)
return R_FALSE;
}
if (binfile_id == -1 ) {
if (binfile_id == -1) {
binfile = r_bin_file_find_by_object_id (bin, binobj_id);
obj = binfile ? r_bin_file_object_find_by_id (binfile, binobj_id) : NULL;
} else if (binobj_id == -1) {
@ -1598,16 +1595,29 @@ R_API ut64 r_bin_get_size (RBin *bin) {
return UT64_MAX;
}
R_API int r_bin_file_delete(RBin *bin, ut32 bin_fd) {
RListIter *iter;
RBinFile *bf;
if (bin)
r_list_foreach (bin->binfiles, iter, bf) {
if (bf && bf->fd == bin_fd) {
r_list_delete (bin->binfiles, iter);
return 1;
}
}
return 0;
}
R_API RBinFile * r_bin_file_find_by_fd (RBin *bin, ut32 bin_fd) {
RListIter *iter;
RBinFile *bf = NULL;
if (!bin) return bf;
RBinFile *bf;
if (bin)
r_list_foreach (bin->binfiles, iter, bf) {
if (bf && bf->fd == bin_fd) break;
bf = NULL;
if (bf && bf->fd == bin_fd)
return bf;
}
return bf;
return NULL;
}
R_API RBinFile * r_bin_file_find_by_name (RBin * bin, const char * name) {

View file

@ -1346,43 +1346,59 @@ R_API int r_core_bin_delete (RCore *core, ut32 binfile_idx, ut32 binobj_idx) {
RBin *bin = core->bin;
RBinFile *binfile = NULL;
if (binfile_idx == UT32_MAX && binobj_idx == UT32_MAX) {
if (binfile_idx == UT32_MAX && binobj_idx == UT32_MAX)
return R_FALSE;
if (!r_bin_object_delete (bin, binfile_idx, binobj_idx))
return R_FALSE;
}
if (!r_bin_object_delete (bin, binfile_idx, binobj_idx)) return R_FALSE;
binfile = r_core_bin_cur (core);
if (binfile) {
if (binfile)
r_io_raise (core->io, binfile->fd);
}
core->switch_file_view = 1;
return binfile && r_core_bin_set_env (core, binfile) && r_core_block_read (core, 0);
}
static int r_core_bin_file_print (RCore *core, RBinFile *binfile) {
static int r_core_bin_file_print (RCore *core, RBinFile *binfile, int mode) {
RListIter *iter;
RBinObject *obj;
const char *name = binfile ? binfile->file : NULL;
ut32 id = binfile ? binfile->id : 0;
ut32 fd = binfile ? binfile->fd : 0;
ut32 obj_cnt = binfile ? r_list_length (binfile->objs) : 0;
ut32 bin_sz = binfile ? binfile->size : 0;
int i = 0;
// TODO: TODO: handle mode to print in json and r2 commands
if (!binfile) return R_FALSE;
r_cons_printf("%s %d %d 0x%04x\n", name, id, obj_cnt, bin_sz );
r_list_foreach (binfile->objs, iter, obj) {
RBinInfo *info = obj->info;
ut8 bits = info ? info->bits : 0;
const char *arch = info ? info->arch : "unknown";
r_cons_printf("\t%d) %d %s %d 0x%04"PFMT64x" 0x%04"PFMT64x"\n",
i, obj->id, arch, bits, obj->boffset, obj->obj_size );
i++;
switch (mode) {
case 'j':
r_cons_printf("{\"name\":\"%s\",\"fd\":%d,\"id\":%d,\"objcnt\":%d,\"size\":%d,\"objs\":[",
name, fd, id, obj_cnt, bin_sz);
r_list_foreach (binfile->objs, iter, obj) {
RBinInfo *info = obj->info;
ut8 bits = info ? info->bits : 0;
const char *arch = info ? info->arch : "unknown";
r_cons_printf("{\"objid\":%d,\"arch\":\"%s\",\"bits\":%d,\"binoffset\":%"
PFMT64d",\"objsize\":%"PFMT64d"}",
obj->id, arch, bits, obj->boffset, obj->obj_size);
if (iter->n) r_cons_printf (",");
}
r_cons_printf("]}");
break;
default:
r_cons_printf("%d %s %d %d 0x%04x\n", fd, name, id, obj_cnt, bin_sz );
r_list_foreach (binfile->objs, iter, obj) {
RBinInfo *info = obj->info;
ut8 bits = info ? info->bits : 0;
const char *arch = info ? info->arch : "unknown";
r_cons_printf("- %d %s %d 0x%04"PFMT64x" 0x%04"PFMT64x"\n",
obj->id, arch, bits, obj->boffset, obj->obj_size );
}
break;
}
return R_TRUE;
}
R_API int r_core_bin_list(RCore *core) {
R_API int r_core_bin_list(RCore *core, int mode) {
// list all binfiles and there objects and there archs
int count = 0;
RListIter *iter;
@ -1392,9 +1408,12 @@ R_API int r_core_bin_list(RCore *core) {
if (!binfiles) return R_FALSE;
if (mode=='j') r_cons_printf("[");
r_list_foreach (binfiles, iter, binfile) {
r_core_bin_file_print (core, binfile);
r_core_bin_file_print (core, binfile, mode);
if (iter->n && mode=='j') r_cons_printf(",");
}
if (mode=='j') r_cons_printf("]\n");
//r_core_file_set_by_file (core, cur_cf);
//r_core_bin_bind (core, cur_bf);
return count;

View file

@ -31,14 +31,19 @@ static int cmd_open(void *data, const char *input) {
addr = 0LL;
}
if (num<=0) {
const char *fn = input+(isn?2:1);
file = r_core_file_open (core, fn, perms, addr);
if (file) {
// MUST CLEAN BEFORE LOADING
if (!isn)
r_core_bin_load (core, fn, baddr);
} else if (!nowarn) {
eprintf ("Cannot open file '%s'\n", fn);
const char *fn = input+1; //(isn?2:1);
if (fn && *fn) {
if (isn) fn++;
file = r_core_file_open (core, fn, perms, addr);
if (file) {
// MUST CLEAN BEFORE LOADING
if (!isn)
r_core_bin_load (core, fn, baddr);
} else if (!nowarn) {
eprintf ("Cannot open file '%s'\n", fn);
}
} else {
eprintf ("Usage: on [file]\n");
}
} else {
RListIter *iter = NULL;
@ -59,9 +64,12 @@ static int cmd_open(void *data, const char *input) {
const char *value = NULL;
ut32 binfile_num = -1, binobj_num = -1;
switch (*(input+1)) {
switch (input[1]) {
case 0:
case 'l':
r_core_bin_list (core);
case 'j':
case '*':
r_core_bin_list (core, input[1]);
break;
case 's':
value = *(input+2) ? input+3 : NULL;
@ -89,7 +97,6 @@ static int cmd_open(void *data, const char *input) {
}
r_core_bin_raise (core, binfile_num, binobj_num);
break;
case 'b':
value = *(input+2) ? input+3 : NULL;
if (!value) {
@ -103,7 +110,6 @@ static int cmd_open(void *data, const char *input) {
eprintf ("Invalid binfile number.");
break;
}
value = *(value+1) ? r_str_tok (value+1, ' ', -1) : NULL;
value = value && *(value+1) ? value+1 : NULL;
@ -122,18 +128,21 @@ static int cmd_open(void *data, const char *input) {
eprintf ("Invalid bin object number.");
break;
}
r_core_bin_raise (core, -1, binobj_num);
break;
case 'd':
value = *(input+2) ? input+3 : NULL;
case '-':
if (!r_bin_file_delete (core->bin, r_num_math (core->num, input+2))) {
eprintf ("Cant find an RBinFile associated with that fd.\n");
}
break;
case 'd': // backward compat, must be deleted
value = *(input+2) ? input+2 : NULL;
if (!value) {
eprintf ("Invalid binfile number.");
break;
}
binobj_num = *value && r_is_valid_input_num_value (core->num, value) ?
r_get_input_num_value (core->num, value) : UT32_MAX;
if (binobj_num == UT32_MAX) {
eprintf ("Invalid bin object number.");
break;
@ -143,8 +152,9 @@ static int cmd_open(void *data, const char *input) {
case '?':{
const char* help_msg[] = {
"Usage:", "ob", " # List open binary files backed by fd",
"obl", "", "List opened binfiles and bin objects",
"ob", "", "List opened binfiles and bin objects",
"obb", " [binfile #]", "Prioritize by binfile number with current selected object",
"ob-", " [binfile #]", "Delete binfile",
"obd", " [binobject #]", "Delete binfile object numbers, if more than 1 object is loaded",
"obo", " [binobject #]", "Prioritize by bin object number",
"obs", " [bf #] [bobj #]", "Prioritize by binfile and object numbers",

View file

@ -23,6 +23,7 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
char *ofilepath = odesc ? strdup (odesc->uri) : NULL;
char *obinfilepath = bf ? strdup (bf->file) : NULL;
int newpid, ret = R_FALSE;
ut64 origoff = core->offset;
if (r_sandbox_enable (0)) {
eprintf ("Cannot reopen in sandbox\n");
return R_FALSE;
@ -41,31 +42,41 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
}
newpid = odesc ? odesc->fd : -1;
if (!perm) perm = odesc ? odesc->flags : 0; //maybe (odesc->flags & 7)
path = strdup (ofilepath);
if (isdebug) {
r_debug_kill (core->dbg, core->dbg->pid,
core->dbg->tid, 9); // KILL
perm = 7;
} else {
if (!perm) {
perm = 4; //R_IO_READ;
}
}
if (ofilepath) {
path = strdup (ofilepath);
} else {
eprintf ("Unknown file path");
return R_FALSE;
}
// HACK: move last mapped address to higher place
// XXX - why does this hack work?
if (ofile->map) {
ofrom = ofile->map->from;
ofile->map->from = UT64_MAX;
ofile->map->from = UT32_MAX;
}
// closing the file to make sure there are no collisions
// when the new memory maps are created.
//r_core_file_close (core, ofile);
file = r_core_file_open (core, path, perm, baddr);
if (file) {
ofile->map->from = ofrom;
r_core_file_close (core, ofile);
r_core_file_set_by_file (core, file);
r_core_file_set_by_fd (core, file->desc->fd);
ofile = NULL;
odesc = NULL;
// core->file = file;
eprintf ("File %s reopened in %s mode\n", path,
perm&R_IO_WRITE?"read-write": "read-only");
(perm&R_IO_WRITE)? "read-write": "read-only");
ret = r_core_bin_load (core, obinfilepath, baddr);
if (!ret) {
@ -78,7 +89,6 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
ret = R_TRUE;
}*/
// close old file
core->file = file;
} else if (ofile) {
eprintf ("r_core_file_reopen: Cannot reopen file: %s with perms 0x%04x,"
" attempting to open read-only.\n", path, perm);
@ -86,6 +96,8 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
//ofile = r_core_file_open (core, path, R_IO_READ, addr);
r_core_file_set_by_file (core, ofile);
ofile->map->from = ofrom;
} else {
eprintf ("Cannot reopen\n");
}
if (isdebug) {
// XXX - select the right backend
@ -98,9 +110,11 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
if (core->file) {
RCoreFile * cf = core->file;
RIODesc *desc = cf ? cf->desc : NULL;
if (desc){
if (desc) {
#if 0
r_io_raise (core->io, desc->fd);
core->switch_file_view = 1;
#endif
r_core_block_read (core, 0);
} else {
const char *name = (cf && cf->desc) ? cf->desc->name : "ERROR";
@ -111,6 +125,7 @@ R_API int r_core_file_reopen(RCore *core, const char *args, int perm) {
r_core_cmd0 (core, ".dr*");
r_core_cmd0 (core, "sr pc");
}
r_core_seek (core, origoff, 1);
// This is done to ensure that the file is correctly
// loaded into the view
free (obinfilepath);
@ -499,10 +514,12 @@ R_API RIOMap *r_core_file_get_next_map (RCore *core, RCoreFile * fh, int mode, u
R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int flags, ut64 loadaddr) {
RList *list_fds = NULL;
RCoreFile *fh, *top_file = NULL;
RIODesc *fd;
RList *list_fds = NULL;
const char *cp = NULL;
char *loadmethod = NULL;
RListIter *fd_iter, *iter2;
RCoreFile *fh, *top_file = NULL;
ut64 current_loadaddr = loadaddr;
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
int openmany = r_config_get_i (r->config, "file.openmany"), opened_count = 0;
@ -510,9 +527,6 @@ R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int flags, ut
list_fds = r_io_open_many (r->io, file, flags, 0644);
const char *cp = NULL;
char *loadmethod = NULL;
if (!list_fds || r_list_length (list_fds) == 0 ) {
r_list_free (list_fds);
return NULL;
@ -676,13 +690,17 @@ R_API int r_core_file_close(RCore *r, RCoreFile *fh) {
// fh in the r->files list, we are hosed. (design flaw)
// TODO maybe using sdb to keep track of the allocated and
// deallocated files might be a good solutions
if (!r) return R_FALSE;
else if (r_list_length (r->files) == 0) return R_FALSE;
else if (!desc) return R_FALSE;
if (!r || !desc || r_list_empty (r->files))
return R_FALSE;
if (fh == r->file) r->file = NULL;
r_core_file_set_by_fd (r, desc->fd);
r_core_bin_set_by_fd (r, desc->fd);
r_core_file_set_by_fd (r, fh->desc->fd);
r_core_bin_set_by_fd (r, fh->desc->fd);
/* delete filedescriptor from io descs here */
r_io_desc_del (r->io, fh->desc->fd);
int ret = r_list_delete_data (r->files, fh);
if (ret) {
if (!prev_cf && r_list_length (r->files) > 0)
@ -693,9 +711,21 @@ R_API int r_core_file_close(RCore *r, RCoreFile *fh) {
if (!desc)
eprintf ("Error: RCoreFile's found with out a supporting RIODesc.\n");
ret = r_core_file_set_by_file (r, prev_cf);
r_core_block_read (r, 0);
}
}
#if 0
{
RListIter *iter;
RIODesc *iod;
RCoreFile *mcf;
r_list_foreach (r->files, iter, mcf) {
r_cons_printf ("[cf]--> %p %p %d\n", mcf, mcf->desc, mcf->desc->fd);
}
r_list_foreach (r->io->files, iter, iod) {
r_cons_printf ("[io]--> %p %d\n", iod, iod->fd);
}
}
#endif
return ret;
}
@ -859,12 +889,11 @@ R_API int r_core_file_set_by_name (RCore * core, const char * name) {
R_API int r_core_file_set_by_file (RCore * core, RCoreFile *cf) {
if (cf) {
RIODesc *desc = cf->desc;
core->offset = cf && cf->map ? cf->map->from : 0;
core->offset = cf && cf->map ? cf->map->from : 0LL;
core->file = cf;
if (desc) {
r_io_use_desc (core->io, desc);
r_core_bin_set_by_fd (core, desc->fd);
//r_core_bin_bind (core, NULL);
}
return R_TRUE;
}

View file

@ -371,7 +371,7 @@ R_API int r_core_block_read(RCore *core, int next) {
memset (core->block, 0xff, core->blocksize);
return -1;
}
if (core->switch_file_view) {
if (core->file && core->switch_file_view) {
r_io_use_desc (core->io, core->file->desc);
r_core_bin_set_by_fd (core, core->file->desc->fd); //needed?
core->switch_file_view = 0;

View file

@ -423,6 +423,7 @@ R_API void r_bin_set_user_ptr(RBin *bin, void *user);
R_API RBuffer *r_bin_create (RBin *bin, const ut8 *code, int codelen, const ut8 *data, int datalen);
R_API ut64 r_bin_get_offset (RBin *bin);
R_API ut64 r_bin_get_vaddr (RBin *bin, ut64 baddr, ut64 paddr, ut64 vaddr);
R_API int r_bin_file_delete(RBin *bin, ut32 bin_fd);
R_API int r_bin_file_set_cur_by_fd (RBin *bin, ut32 bin_fd);
R_API int r_bin_file_set_cur_by_name (RBin * bin, const char * name);
R_API RBinFile * r_bin_file_find_by_fd (RBin *bin, ut32 bin_fd);

View file

@ -327,7 +327,7 @@ R_API int r_core_bin_set_by_name (RCore *core, const char *name);
R_API int r_core_bin_reload(RCore *core, const char *file, ut64 baseaddr);
R_API int r_core_bin_load(RCore *core, const char *file, ut64 baseaddr);
R_API int r_core_hash_load(RCore *core, const char *file);
R_API int r_core_bin_list(RCore *core);
R_API int r_core_bin_list(RCore *core, int mode);
R_API int r_core_bin_raise (RCore *core, ut32 binfile_idx, ut32 obj_idx);
R_API int r_core_bin_delete (RCore *core, ut32 binfile_idx, ut32 binobj_idx);

View file

@ -334,6 +334,7 @@ R_API int r_io_cache_read(RIO *io, ut64 addr, ut8 *buf, int len);
/* io/map.c */
R_API void r_io_map_init(RIO *io);
R_API int r_io_map_overlaps (RIO *io, RIODesc *fd, RIOMap *map);
R_API ut64 r_io_map_next(RIO *io, ut64 addr);
R_API RIOMap *r_io_map_add(RIO *io, int fd, int flags, ut64 delta, ut64 offset, ut64 size);
R_API int r_io_map_del_at(RIO *io, ut64 addr);

View file

@ -4,7 +4,7 @@
// TODO: to be deprecated.. this is slow and boring
R_API void r_io_desc_init(RIO *io) {
io->files= r_list_new ();
io->files = r_list_new ();
io->files->free = (RListFree)r_io_desc_free;
}
@ -68,7 +68,7 @@ R_API void r_io_desc_free(RIODesc *desc) {
R_FREE (desc->uri);
}
memset (desc, 0, sizeof (RIODesc));
// free (desc); double free orw at
free (desc);
}
R_API int r_io_desc_add(RIO *io, RIODesc *desc) {
@ -86,6 +86,8 @@ R_API int r_io_desc_del(RIO *io, int fd) {
/* No _safe loop necessary because we return immediately after the delete. */
r_list_foreach (io->files, iter, d) {
if (d->fd == fd) {
r_io_desc_free (d);
iter->data = NULL; // enforce free
r_list_delete (io->files, iter);
return R_TRUE;
}

View file

@ -138,9 +138,10 @@ static inline RIODesc *__getioplugin(RIO *io, const char *_uri, int flags, int m
desc->uri = uri;
}
}
if (!desc)
if (!desc) {
free (uri);
io->plugin = NULL;
io->plugin = NULL;
}
return desc;
}
@ -338,13 +339,14 @@ R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
#if USE_NEW_IO
return r_io_read_cr (io, addr, buf, len);
#else
ut64 paddr, last, last2;
int ms, ret, l = 0, olen = len, w = 0;
if (io->raw) {
if (r_io_seek (io, addr, R_IO_SEEK_SET)==UT64_MAX)
memset (buf, 0xff, len);
return r_io_read_internal (io, buf, len);
}
ut64 paddr, last, last2;
int ms, ret, l = 0, olen = len, w = 0;
io->off = addr;
memset (buf, 0xff, len); // probably unnecessary
@ -446,10 +448,8 @@ R_API int r_io_read_at(RIO *io, ut64 addr, ut8 *buf, int len) {
// XXX is this necessary?
ms = r_io_map_select (io, addr+w);
ret = r_io_read_internal (io, buf+w, l);
//eprintf ("READ 0x%llx = %d\n", addr+w, ret);
if (ret<1) {
memset (buf+w, 0xff, l); // reading out of file
//memset(buf, 0xff, olen);
ret = l;
} else if (ret<l) {
l = ret;

View file

@ -56,12 +56,15 @@ static int __io_posix_open (const char *file, int flags, int mode) {
static int r_io_def_mmap_refresh_def_mmap_buf(RIOMMapFileObj *mmo) {
RIO* io = mmo->io_backref;
ut64 cur = mmo->buf ? mmo->buf->cur : 0;
ut64 cur;
if (mmo->buf) {
cur = mmo->buf->cur;
r_buf_free (mmo->buf);
mmo->buf = NULL;
} else {
cur = 0;
}
if (r_file_size (mmo->filename)> ST32_MAX) {
if (r_file_size (mmo->filename) > ST32_MAX) {
// Do not use mmap if the file is huge
mmo->rawio = 1;
}
@ -70,9 +73,15 @@ static int r_io_def_mmap_refresh_def_mmap_buf(RIOMMapFileObj *mmo) {
return (mmo->fd != -1);
}
mmo->buf = r_buf_mmap (mmo->filename, mmo->flags);
if (mmo->buf)
if (mmo->buf) {
r_io_def_mmap_seek (io, mmo, cur, SEEK_SET);
return (mmo->buf ? R_TRUE : R_FALSE);
return R_TRUE;
} else {
mmo->rawio = 1;
mmo->fd = __io_posix_open (mmo->filename, mmo->flags, mmo->mode);
return (mmo->fd != -1);
}
return R_FALSE;
}
RIOMMapFileObj *r_io_def_mmap_create_new_file(RIO *io, const char *filename, int mode, int flags) {
@ -132,8 +141,12 @@ static int r_io_def_mmap_check_default (const char *filename) {
static int r_io_def_mmap_read(RIO *io, RIODesc *fd, ut8 *buf, int count) {
RIOMMapFileObj *mmo = NULL;
if (!fd || !fd->data || !buf)
if (!fd || !fd->data || !buf) {
// in this case we fallback reopening in raw mode
eprintf ("MAJOR FAILURE fOR %p %p\n", fd, fd->data);
asm("int3");
return -1;
}
if (io->off==UT64_MAX) {
memset (buf, 0xff, count);
return count;

View file

@ -26,15 +26,7 @@ R_API RBuffer *r_buf_from_bytes( const ut8 *bytes, ut64 len) {
}
R_API RBuffer *r_buf_new() {
RBuffer *b = R_NEW0 (RBuffer);
if (b) {
b->buf = NULL;
b->length = 0;
b->cur = 0;
b->base = 0LL;
b->mmap = NULL;
}
return b;
return R_NEW0 (RBuffer);
}
R_API const ut8 *r_buf_buffer (RBuffer *b) {
@ -59,6 +51,7 @@ R_API RBuffer *r_buf_mmap (const char *file, int flags) {
if (b->length == 0) b->empty = 1;
return b;
}
eprintf ("MMAP FAIL\n");
r_buf_free (b);
return NULL; /* we just freed b, don't return it */
}