Fix memory leaks in arch and core (#6590)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
parent
6249c2e5f2
commit
84b2f31035
8 changed files with 52 additions and 14 deletions
|
|
@ -559,7 +559,7 @@ RZ_IPI RzILOpEffect *rz_8051_il_op(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL c
|
|||
}
|
||||
|
||||
RzILOpEffect *eff = i_op_dispatch(op);
|
||||
free(op);
|
||||
rz_8051_op_free(op);
|
||||
return eff;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ typedef struct i8051_op_t {
|
|||
} I8051Op;
|
||||
|
||||
RZ_IPI I8051Op *rz_8051_op_parse(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL const ut8 *buf, int len, ut64 pc);
|
||||
RZ_IPI void rz_8051_op_free(I8051Op *op);
|
||||
RZ_IPI RzILOpEffect *rz_8051_il_op(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL const ut8 *buf, int len, ut64 pc);
|
||||
RZ_IPI RzAnalysisILConfig *rz_8051_il_config(RZ_NONNULL RzAnalysis *analysis);
|
||||
|
||||
|
|
|
|||
|
|
@ -191,6 +191,30 @@ static bool addressing_pattern2(I8051Op *op, const ut8 *buf) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void addressing_free(I8051OpAddressing *a) {
|
||||
if (!a) {
|
||||
return;
|
||||
}
|
||||
// Indirect addressing owns the nested addressing it points at.
|
||||
if (a->mode == I8051_ADDRESSING_INDIRECT) {
|
||||
addressing_free(a->d.indirect);
|
||||
}
|
||||
free(a);
|
||||
}
|
||||
|
||||
RZ_IPI void rz_8051_op_free(I8051Op *op) {
|
||||
if (!op) {
|
||||
return;
|
||||
}
|
||||
if (op->argv) {
|
||||
for (size_t i = 0; i < op->argc; i++) {
|
||||
addressing_free(op->argv[i]);
|
||||
}
|
||||
free(op->argv);
|
||||
}
|
||||
free(op);
|
||||
}
|
||||
|
||||
RZ_IPI I8051Op *rz_8051_op_parse(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL const ut8 *buf, int len, ut64 pc) {
|
||||
rz_return_val_if_fail(analysis && buf && len > 0, NULL);
|
||||
I8051Op *op = RZ_NEW0(I8051Op);
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ static RzILOpEffect *sh_il_set_param_pc_ctx(SHParam param, RZ_OWN RzILOpPure *va
|
|||
|
||||
if (!ret) {
|
||||
SHParamHelper ret_h = sh_il_get_param(param, scaling);
|
||||
RZ_FREE(ret_h.pure);
|
||||
rz_il_op_pure_free(ret_h.pure);
|
||||
RzILOpPure *eff_addr = sh_il_get_effective_addr(param, scaling);
|
||||
ret = STOREW(eff_addr, val);
|
||||
pre = ret_h.pre;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ static void arglist_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbT
|
|||
static RzType *mfunction_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name);
|
||||
static RzType *onemethod_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info);
|
||||
static RzType *member_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name, ut64 *bitfield_width);
|
||||
static RzType *nest_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *t, char *name);
|
||||
static RzType *nest_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *t);
|
||||
static RzType *union_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type);
|
||||
static RzTypeUnionMember *union_member_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info);
|
||||
static RzType *class_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type);
|
||||
|
|
@ -328,7 +328,7 @@ static RzTypeIdentifierKind iKind_from_bKind(RzBaseTypeKind k) {
|
|||
return RZ_TYPE_IDENTIFIER_KIND_UNSPECIFIED;
|
||||
}
|
||||
|
||||
static RzType *nest_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info, char *name) {
|
||||
static RzType *nest_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbTpiType *type_info) {
|
||||
rz_return_val_if_fail(type_info && stream && typedb, NULL);
|
||||
Tpi_LF_NestType *lf_nest = type_info->data;
|
||||
RzPdbTpiType *utpi = rz_bin_pdb_get_type_by_index(stream, lf_nest->index);
|
||||
|
|
@ -342,12 +342,9 @@ static RzType *nest_parse(const RzTypeDB *typedb, RzPdbTpiStream *stream, RzPdbT
|
|||
return type_new_identify(bt->name, iKind_from_bKind(bt->kind));
|
||||
}
|
||||
}
|
||||
|
||||
RzType *utype = pdb_type_parse(typedb, stream, utpi, NULL);
|
||||
if (!utype) {
|
||||
return NULL;
|
||||
}
|
||||
return rz_type_clone(utype);
|
||||
// pdb_type_parse() already returns an owned type, so return it directly
|
||||
// instead of cloning and leaking the original.
|
||||
return pdb_type_parse(typedb, stream, utpi, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -384,7 +381,7 @@ static RzTypeStructMember *class_member_parse(
|
|||
}
|
||||
case TpiKind_NESTTYPE: {
|
||||
name = rz_bin_pdb_get_type_name(t);
|
||||
type = nest_parse(typedb, stream, t, rz_str_dup(name));
|
||||
type = nest_parse(typedb, stream, t);
|
||||
break;
|
||||
}
|
||||
case TpiKind_VBCLASS:
|
||||
|
|
@ -572,7 +569,7 @@ static RzTypeUnionMember *union_member_parse(const RzTypeDB *typedb, RzPdbTpiStr
|
|||
}
|
||||
case TpiKind_NESTTYPE: {
|
||||
name = rz_bin_pdb_get_type_name(type_info);
|
||||
type = nest_parse(typedb, stream, type_info, rz_str_dup(name));
|
||||
type = nest_parse(typedb, stream, type_info);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -861,7 +858,11 @@ RZ_API void rz_type_db_pdb_load(const RzTypeDB *typedb, const RzPdb *pdb) {
|
|||
RzPdbTpiType *type;
|
||||
rz_rbtree_foreach (stream->types, it, type, RzPdbTpiType, rb) {
|
||||
if (type && is_parsable_type(type)) {
|
||||
rz_type_db_pdb_parse(typedb, stream, type);
|
||||
// rz_type_db_pdb_parse() returns an owned clone of the parsed type.
|
||||
// The base type itself is saved into the typedb during parsing, so
|
||||
// this returned clone is not needed here and must be freed, otherwise
|
||||
// one type tree leaks for every parsable type in the PDB.
|
||||
rz_type_free(rz_type_db_pdb_parse(typedb, stream, type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ RZ_IPI bool gdata_stream_parse(RzPdb *pdb, RzPdbMsfStream *stream) {
|
|||
|
||||
PDBSymbolIter iter = { 0 };
|
||||
PDBSymbolTable_iter(syms, &iter);
|
||||
if (!PDBSymbolIter_collect(&iter, &s->global_symbols)) {
|
||||
bool collected = PDBSymbolIter_collect(&iter, &s->global_symbols);
|
||||
rz_buf_free(iter.b);
|
||||
if (!collected) {
|
||||
goto err;
|
||||
}
|
||||
free(syms);
|
||||
|
|
|
|||
|
|
@ -128,8 +128,10 @@ RZ_IPI PDBSymbol *PDBSymbolTable_symbol_by_index(PDBSymbolTable *symbol_table, P
|
|||
map_err(symbol);
|
||||
map_err(PDBSymbolIter_next(&iter, symbol));
|
||||
|
||||
rz_buf_free(iter.b);
|
||||
return symbol;
|
||||
err:
|
||||
rz_buf_free(iter.b);
|
||||
free(symbol);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -864,6 +864,14 @@ static bool get_bin_info(RzCore *core, const char *file, ut64 baseaddr,
|
|||
return false;
|
||||
}
|
||||
rz_core_bin_print(core, bf, action, filter, state, NULL);
|
||||
// rz_bin_object_new() registers bf->sdb under core->bin->sdb ("cur" and
|
||||
// "fd.<fd>") and takes an extra reference. Restoring the previous binfile
|
||||
// below only updates bin->cur, so drop every reference to this temporary sdb
|
||||
// here, otherwise it dangles in core->bin->sdb and is double-freed on teardown.
|
||||
while (sdb_ns_unset(core->bin->sdb, NULL, bf->sdb)) {
|
||||
;
|
||||
}
|
||||
sdb_free(bf->sdb);
|
||||
rz_bin_file_delete(core->bin, bf);
|
||||
rz_bin_file_set_obj(obf, obf->o);
|
||||
rz_bin_set_cur_binfile(core->bin, obf);
|
||||
|
|
|
|||
Loading…
Reference in a new issue