mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 22:00:18 +00:00
* Apply patch from @w_levin fixing lot of memory leaks - Thanks!
This commit is contained in:
parent
16cf2367b9
commit
997a6dbd14
@ -1,5 +1,5 @@
|
||||
NAME=r_anal
|
||||
DEPS=r_util r_lib r_reg r_syscall r_diff
|
||||
DEPS=r_util r_lib r_reg r_syscall r_diff # r_core (commented as it would be recursive)
|
||||
CFLAGS+=-DCORELIB -Iarch
|
||||
|
||||
include ../config.mk
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <r_anal.h>
|
||||
#include <r_util.h>
|
||||
#include <r_list.h>
|
||||
#include <r_io.h>
|
||||
#include "../config.h"
|
||||
|
||||
static RAnalPlugin *anal_static_plugins[] =
|
||||
@ -57,9 +58,16 @@ R_API RAnal *r_anal_new() {
|
||||
R_API void r_anal_free(RAnal *anal) {
|
||||
if (!anal) return;
|
||||
/* TODO: Free anals here */
|
||||
r_listrange_free (anal->fcnstore);
|
||||
anal->fcns->free = r_anal_fcn_free;
|
||||
r_list_free (anal->fcns);
|
||||
// r_listrange_free (anal->fcnstore); // might provoke double frees since this is used in r_anal_fcn_insert()
|
||||
r_list_free (anal->refs);
|
||||
r_list_free (anal->vartypes);
|
||||
r_list_free (anal->meta->data);
|
||||
r_reg_free(anal->reg);
|
||||
r_syscall_free(anal->syscall);
|
||||
r_anal_op_free(anal->queued);
|
||||
// r_io_free(anal->iob.io); // need r_core (but recursive problem to fix)
|
||||
free (anal);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,6 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
|
||||
bb->addr = addr;
|
||||
len -= 16; // XXX: hack to avoid segfault by x86im
|
||||
while (idx < len) {
|
||||
r_anal_op_free (op);
|
||||
if (!(op = r_anal_op_new ())) {
|
||||
eprintf ("Error: new (op)\n");
|
||||
return R_ANAL_RET_ERROR;
|
||||
@ -77,6 +76,7 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
|
||||
bb->type = R_ANAL_BB_TYPE_HEAD;
|
||||
switch (op->type) {
|
||||
case R_ANAL_OP_TYPE_CMP:
|
||||
r_anal_cond_free(bb->cond);
|
||||
bb->cond = r_anal_cond_new_from_op (op);
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
@ -100,6 +100,7 @@ R_API int r_anal_bb(RAnal *anal, RAnalBlock *bb, ut64 addr, ut8 *buf, ut64 len,
|
||||
bb->type |= R_ANAL_BB_TYPE_LAST;
|
||||
goto beach;
|
||||
}
|
||||
r_anal_op_free (op);
|
||||
}
|
||||
return bb->size;
|
||||
beach:
|
||||
|
@ -143,6 +143,7 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len,
|
||||
return fcn->size;
|
||||
}
|
||||
|
||||
// TODO: need to implement r_anal_fcn_remove(RAnal *anal, RAnalFcn *fcn);
|
||||
R_API int r_anal_fcn_insert(RAnal *anal, RAnalFcn *fcn) {
|
||||
#if USE_NEW_FCN_STORE
|
||||
r_listrange_add (anal->fcnstore, fcn);
|
||||
|
@ -5,6 +5,7 @@
|
||||
// TODO: We need a standard struct named Surface1D {.addr, .size}, so we can
|
||||
// simplify all this by just passing the offset of the field of the given ptr
|
||||
// TODO: RListComparator does not supports *user
|
||||
// TODO: RRef - reference counting
|
||||
|
||||
#define RANGEBITS 10
|
||||
// 1024
|
||||
@ -39,8 +40,9 @@ static inline ut64 r_listrange_next(ut64 addr) {
|
||||
}
|
||||
|
||||
R_API void r_listrange_free(RListRange *s) {
|
||||
if (!s) return;
|
||||
r_hashtable64_free (s->h);
|
||||
r_list_destroy (s->l);
|
||||
r_list_free (s->l);
|
||||
free (s);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ R_API RAnalValue *r_anal_value_copy (RAnalValue *ov) {
|
||||
|
||||
// TODO: move into .h as #define free
|
||||
R_API void r_anal_value_free(RAnalValue *value) {
|
||||
/* TODO: free RRegItem objects? */
|
||||
free (value);
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,7 @@ R_API RAsm *r_asm_new() {
|
||||
a->ofilter = NULL;
|
||||
a->syntax = R_ASM_SYNTAX_INTEL;
|
||||
a->plugins = r_list_new ();
|
||||
a->plugins->free = free;
|
||||
for (i=0; asm_static_plugins[i]; i++) {
|
||||
static_plugin = R_NEW (RAsmPlugin);
|
||||
memcpy (static_plugin, asm_static_plugins[i], sizeof (RAsmPlugin));
|
||||
@ -175,6 +176,7 @@ R_API int r_asm_filter_output(RAsm *a, const char *f) {
|
||||
}
|
||||
|
||||
R_API void r_asm_free(RAsm *a) {
|
||||
if (!a) return;
|
||||
// TODO: any memory leak here?
|
||||
r_pair_free (a->pair);
|
||||
r_list_free (a->plugins);
|
||||
|
@ -148,6 +148,7 @@ static void r_bin_free_items(RBin *bin) {
|
||||
if (a->sections) r_list_free (a->sections);
|
||||
if (a->strings) r_list_free (a->strings);
|
||||
if (a->symbols) r_list_free (a->symbols);
|
||||
if (a->classes) r_list_free (a->classes);
|
||||
if (a->binsym)
|
||||
for (i=0; i<R_BIN_SYM_LAST; i++)
|
||||
free (a->binsym[i]);
|
||||
@ -226,6 +227,9 @@ R_API void* r_bin_free(RBin *bin) {
|
||||
r_bin_free_items (bin);
|
||||
if (bin->curxtr && bin->curxtr->destroy)
|
||||
bin->curxtr->destroy (bin);
|
||||
r_list_free(bin->binxtrs);
|
||||
r_list_free(bin->plugins);
|
||||
free(bin->file);
|
||||
free (bin);
|
||||
return NULL;
|
||||
}
|
||||
@ -353,12 +357,14 @@ R_API RBin* r_bin_new() {
|
||||
if (bin) {
|
||||
memset (bin, 0, sizeof (RBin));
|
||||
bin->plugins = r_list_new();
|
||||
bin->plugins->free = free;
|
||||
for (i=0; bin_static_plugins[i]; i++) {
|
||||
static_plugin = R_NEW (RBinPlugin);
|
||||
memcpy (static_plugin, bin_static_plugins[i], sizeof (RBinPlugin));
|
||||
r_bin_add (bin, static_plugin);
|
||||
}
|
||||
bin->binxtrs = r_list_new();
|
||||
bin->binxtrs->free = free;
|
||||
for (i=0; bin_xtr_static_plugins[i]; i++) {
|
||||
static_xtr_plugin = R_NEW (RBinXtrPlugin);
|
||||
memcpy (static_xtr_plugin, bin_xtr_static_plugins[i], sizeof (RBinXtrPlugin));
|
||||
@ -384,7 +390,6 @@ R_API int r_bin_use_arch(RBin *bin, const char *arch, int bits, const char *name
|
||||
r_list_foreach(bin->plugins, it, plugin) {
|
||||
if (!strcmp (name, plugin->name)) {
|
||||
bin->curarch.curplugin = plugin;
|
||||
// TODO: set bits and name
|
||||
return R_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ R_API RCmd *r_cmd_new () {
|
||||
}
|
||||
|
||||
R_API RCmd *r_cmd_free(RCmd *cmd) {
|
||||
if (!cmd) return NULL;
|
||||
r_list_free(cmd->plist);
|
||||
free (cmd);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ R_API RConfig *r_config_new(void *user) {
|
||||
}
|
||||
|
||||
R_API int r_config_free(RConfig *cfg) {
|
||||
// XXX: memory leak ! r_list_destroy (cfg->nodes);
|
||||
if (!cfg) return 0;
|
||||
r_list_free (cfg->nodes);
|
||||
r_hashtable_free (cfg->ht);
|
||||
free (cfg);
|
||||
|
@ -111,7 +111,7 @@ R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int head) {
|
||||
struct r_anal_bb_t *bb = NULL, *bbi;
|
||||
RListIter *iter;
|
||||
ut64 jump, fail;
|
||||
ut8 *buf;
|
||||
ut8 *buf = NULL;
|
||||
int ret = R_ANAL_RET_NEW, buflen, bblen = 0;
|
||||
int split = core->anal->split;
|
||||
|
||||
@ -123,21 +123,17 @@ R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int head) {
|
||||
ret = R_ANAL_RET_DUP;
|
||||
}
|
||||
if (ret == R_ANAL_RET_DUP) { /* Dupped bb */
|
||||
r_anal_bb_free (bb);
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
} else if (ret == R_ANAL_RET_NEW) { /* New bb */
|
||||
if (!(buf = malloc (core->blocksize)))
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
do {
|
||||
if ((buflen = r_io_read_at (core->io, at+bblen, buf, core->blocksize)) != core->blocksize) {
|
||||
r_anal_bb_free (bb);
|
||||
return R_FALSE;
|
||||
}
|
||||
if ((buflen = r_io_read_at (core->io, at+bblen, buf, core->blocksize)) != core->blocksize)
|
||||
goto error;
|
||||
bblen = r_anal_bb (core->anal, bb, at+bblen, buf, buflen, head);
|
||||
if (bblen == R_ANAL_RET_ERROR ||
|
||||
(bblen == R_ANAL_RET_END && bb->size < 1)) { /* Error analyzing bb */
|
||||
r_anal_bb_free (bb);
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
} else if (bblen == R_ANAL_RET_END) { /* bb analysis complete */
|
||||
if (split)
|
||||
ret = r_anal_fcn_overlap_bb (fcn, bb);
|
||||
@ -152,9 +148,16 @@ R_API int r_core_anal_bb(RCore *core, RAnalFcn *fcn, ut64 at, int head) {
|
||||
}
|
||||
}
|
||||
} while (bblen != R_ANAL_RET_END);
|
||||
free (buf);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return R_TRUE;
|
||||
|
||||
error:
|
||||
r_list_unlink(fcn->bbs, bb);
|
||||
r_anal_bb_free(bb);
|
||||
free(buf);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_core_anal_bb_seek(RCore *core, ut64 addr) {
|
||||
@ -176,8 +179,8 @@ static int cmpaddr (void *_a, void *_b) {
|
||||
R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int depth) {
|
||||
RListIter *iter, *iter2;
|
||||
int buflen, fcnlen = 0;
|
||||
RAnalFcn *fcn, *fcni;
|
||||
RAnalRef *ref, *refi;
|
||||
RAnalFcn *fcn = NULL, *fcni;
|
||||
RAnalRef *ref = NULL, *refi;
|
||||
ut8 *buf;
|
||||
|
||||
if (depth < 0)
|
||||
@ -206,17 +209,16 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
|
||||
}
|
||||
if (!(buf = malloc (core->blocksize))) {
|
||||
eprintf ("Error: malloc (buf)\n");
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
do {
|
||||
if ((buflen = r_io_read_at (core->io, at+fcnlen, buf, core->blocksize)) != core->blocksize)
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
fcnlen = r_anal_fcn (core->anal, fcn, at+fcnlen, buf, buflen, reftype);
|
||||
if (fcnlen == R_ANAL_RET_ERROR ||
|
||||
(fcnlen == R_ANAL_RET_END && fcn->size < 1)) { /* Error analyzing function */
|
||||
r_anal_fcn_free (fcn);
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
} else if (fcnlen == R_ANAL_RET_END) { /* Function analysis complete */
|
||||
RFlagItem *f = r_flag_get_i (core->flags, at);
|
||||
if (f) { /* Check if it's already flagged */
|
||||
@ -237,7 +239,7 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
|
||||
if (from != -1) {
|
||||
if (!(ref = r_anal_ref_new ())) {
|
||||
eprintf ("Error: new (xref)\n");
|
||||
return R_FALSE;
|
||||
goto error;
|
||||
}
|
||||
ref->addr = from;
|
||||
ref->at = at;
|
||||
@ -249,11 +251,24 @@ R_API int r_core_anal_fcn(RCore *core, ut64 at, ut64 from, int reftype, int dept
|
||||
//r_list_append (core->anal->fcns, fcn);
|
||||
r_list_foreach (fcn->refs, iter, refi)
|
||||
if (refi->addr != -1)
|
||||
// TODO: fix memleak here, fcn not freed even though it is
|
||||
// added in core->anal->fcns which is freed in r_anal_free()
|
||||
r_core_anal_fcn (core, refi->addr, refi->at, refi->type, depth-1);
|
||||
}
|
||||
} while (fcnlen != R_ANAL_RET_END);
|
||||
free (buf);
|
||||
return R_TRUE;
|
||||
|
||||
error:
|
||||
free(buf);
|
||||
// ugly hack to free fcn
|
||||
if (fcn) {
|
||||
// unlink from list to avoid double free later when we call r_anal_free()
|
||||
r_list_unlink(core->anal->fcns, fcn);
|
||||
if (core->anal->fcns->free == NULL)
|
||||
r_anal_fcn_free (fcn);
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_core_anal_fcn_clean(RCore *core, ut64 addr) {
|
||||
|
@ -396,7 +396,25 @@ R_API int r_core_init(RCore *core) {
|
||||
}
|
||||
|
||||
R_API RCore *r_core_free(RCore *c) {
|
||||
if (!c) return NULL;
|
||||
/* TODO: it leaks as shit */
|
||||
r_io_free(c->io);
|
||||
r_core_file_free(c->file);
|
||||
r_list_free(c->files);
|
||||
free(c->num);
|
||||
r_lib_free(c->lib);
|
||||
r_cmd_free(c->cmd);
|
||||
r_anal_free(c->anal);
|
||||
r_asm_free(c->assembler);
|
||||
r_print_free(c->print);
|
||||
r_bin_free(c->bin);
|
||||
r_lang_free(c->lang);
|
||||
r_debug_free(c->dbg);
|
||||
r_flag_free(c->flags);
|
||||
r_config_free(c->config);
|
||||
r_search_free(c->search);
|
||||
r_sign_free(c->sign);
|
||||
r_fs_free(c->fs);
|
||||
r_egg_free (c->egg);
|
||||
free (c);
|
||||
return NULL;
|
||||
|
@ -189,10 +189,14 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode, ut64 loa
|
||||
}
|
||||
|
||||
R_API void r_core_file_free(RCoreFile *cf) {
|
||||
if (!cf) return;
|
||||
|
||||
free (cf->uri);
|
||||
cf->uri = NULL;
|
||||
free (cf->filename);
|
||||
cf->filename = NULL;
|
||||
free(cf->map);
|
||||
r_io_desc_free(cf->fd);
|
||||
cf->fd = NULL;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ R_API RDebug *r_debug_new(int hard) {
|
||||
}
|
||||
|
||||
R_API struct r_debug_t *r_debug_free(struct r_debug_t *dbg) {
|
||||
if (!dbg) return NULL;
|
||||
// TODO: free it correctly.. we must ensure this is an instance and not a reference..
|
||||
//r_bp_free(&dbg->bp);
|
||||
//r_reg_free(&dbg->reg);
|
||||
|
@ -54,11 +54,15 @@ R_API char *r_egg_to_string (REgg *egg) {
|
||||
}
|
||||
|
||||
R_API void r_egg_free (REgg *egg) {
|
||||
if (!egg) return;
|
||||
r_buf_free (egg->src);
|
||||
r_buf_free (egg->buf);
|
||||
r_buf_free (egg->bin);
|
||||
r_list_free(egg->list);
|
||||
r_asm_free (egg->rasm);
|
||||
r_syscall_free (egg->syscall);
|
||||
r_pair_free(egg->pair);
|
||||
r_list_free (egg->plugins);
|
||||
r_list_free (egg->patches);
|
||||
free (egg);
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ R_API int r_flag_sort(RFlag *f, int namesort) {
|
||||
}
|
||||
|
||||
R_API RFlag * r_flag_free(RFlag *f) {
|
||||
if (!f) return NULL;
|
||||
r_list_free (f->flags);
|
||||
free (f);
|
||||
return NULL;
|
||||
|
@ -17,6 +17,7 @@ R_API RFS *r_fs_new () {
|
||||
fs->roots = r_list_new ();
|
||||
fs->roots->free = (RListFree)r_fs_root_free;
|
||||
fs->plugins = r_list_new ();
|
||||
fs->plugins->free = free;
|
||||
// XXX fs->roots->free = r_fs_plugin_free;
|
||||
for (i=0; fs_static_plugins[i]; i++) {
|
||||
static_plugin = R_NEW (RFSPlugin);
|
||||
@ -38,6 +39,8 @@ R_API RFSPlugin *r_fs_plugin_get (RFS *fs, const char *name) {
|
||||
}
|
||||
|
||||
R_API void r_fs_free (RFS* fs) {
|
||||
if (!fs) return;
|
||||
r_io_free(fs->iob.io);
|
||||
r_list_free (fs->plugins);
|
||||
r_list_free (fs->roots);
|
||||
free (fs);
|
||||
|
@ -48,7 +48,13 @@ R_API int r_io_write_buf(struct r_io_t *io, struct r_buf_t *b) {
|
||||
}
|
||||
|
||||
R_API struct r_io_t *r_io_free(struct r_io_t *io) {
|
||||
if (!io) return NULL;
|
||||
/* TODO: properly free inner nfo */
|
||||
/* TODO: memory leaks */
|
||||
r_io_desc_free(io->desc);
|
||||
r_list_free(io->sections);
|
||||
r_list_free(io->maps);
|
||||
r_list_free(io->desc);
|
||||
free (io);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ R_API RLang *r_lang_new() {
|
||||
}
|
||||
|
||||
R_API void *r_lang_free(RLang *lang) {
|
||||
if (!lang) return NULL;
|
||||
r_lang_undef (lang, NULL);
|
||||
r_list_free (lang->langs);
|
||||
r_list_free (lang->defs);
|
||||
|
@ -105,6 +105,7 @@ R_API RLib *r_lib_new(const char *symname) {
|
||||
}
|
||||
|
||||
R_API RLib *r_lib_free(RLib *lib) {
|
||||
if (!lib) return;
|
||||
/* TODO: iterate over libraries and free them all */
|
||||
/* TODO: iterate over handlers and free them all */
|
||||
r_lib_close (lib, NULL);
|
||||
|
@ -27,6 +27,7 @@ R_API RPrint *r_print_new() {
|
||||
}
|
||||
|
||||
R_API RPrint *r_print_free(RPrint *p) {
|
||||
if (!p) return NULL;
|
||||
if (p->zoom) {
|
||||
free (p->zoom->buf);
|
||||
free (p->zoom);
|
||||
|
@ -29,10 +29,12 @@ R_API RSearch *r_search_new(int mode) {
|
||||
}
|
||||
|
||||
R_API RSearch *r_search_free(RSearch *s) {
|
||||
if (!s) return NULL;
|
||||
// TODO: it leaks
|
||||
r_mem_pool_free (s->pool);
|
||||
r_list_destroy (s->hits);
|
||||
r_list_destroy (s->kws);
|
||||
r_list_free (s->hits);
|
||||
r_list_free (s->kws);
|
||||
r_io_free(s->iob.io);
|
||||
free (s);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -114,6 +114,7 @@ R_API void r_sign_reset(RSign *sig) {
|
||||
}
|
||||
|
||||
R_API RSign *r_sign_free(RSign *sig) {
|
||||
if (!sig) return NULL;
|
||||
r_list_free (sig->items);
|
||||
free (sig);
|
||||
return NULL;
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* radare - LGPL - Copyright 2007-2011 pancake<nopcode.org> */
|
||||
// TODO: RRef - reference counting
|
||||
|
||||
#include "r_util.h"
|
||||
|
||||
@ -122,7 +123,6 @@ R_API void r_list_destroy (RList *list) {
|
||||
|
||||
R_API void r_list_free (RList *list) {
|
||||
if (list) {
|
||||
list->free = NULL;
|
||||
r_list_destroy (list);
|
||||
free (list);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user