Skip to content

Commit 6dfb51c

Browse files
committed
core: Make destructors receive the 'struct cu' their object may have been allocated from
The default, most simple way of freeing memory associated with tags is to just call free(), but the DWARF loader is a bit more involved in which it needs extra info to keep its large data structures around for further processing after loading. This way we need to provide a way for the DWARF loader to find the real pointer to release. So far it was just freeing the tag, which ended up leaking the tag->priv part, i.e. the associated 'struct dwarf_tag', which wasn't that much of a problem as the bulk of freeing takes place at tool exit, but since we want to avoid two allocations and get the 'struct dwarf_tag' out of pointer arithmetic from the 'struct tag' pointer associated with it in a single allocation, we have to catch all free() calls with a 'struct cu' specific tag destructor so that we do that pointer arithmetic and find the right pointer to feed free(). That or just do nothing when we use obstacks, as in the BTF encoder case. So this is all for consistency and correctness, it _shouldn't_ affect the most critical use case which is BTF encoding, where no such use of destructors take place. In the process of getting the codebase more correct we are indeed catching cases where we, in error paths, were calling free() on obstack allocated memory, which, again, is a corner case, but lets plug all these to avoid surprises, that, we know, appear from time to time. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent ce3540e commit 6dfb51c

7 files changed

Lines changed: 110 additions & 110 deletions

File tree

btf_loader.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static int cu__load_ftype(struct cu *cu, struct ftype *proto, uint32_t tag, cons
7777

7878
return 0;
7979
out_free_parameters:
80-
ftype__delete(proto);
80+
ftype__delete(proto, cu);
8181
return -ENOMEM;
8282
}
8383

@@ -255,7 +255,7 @@ static int create_new_class(struct cu *cu, const struct btf_type *tp, uint32_t i
255255

256256
return 0;
257257
out_free:
258-
class__delete(class);
258+
class__delete(class, cu);
259259
return -ENOMEM;
260260
}
261261

@@ -271,7 +271,7 @@ static int create_new_union(struct cu *cu, const struct btf_type *tp, uint32_t i
271271

272272
return 0;
273273
out_free:
274-
type__delete(un);
274+
type__delete(un, cu);
275275
return -ENOMEM;
276276
}
277277

@@ -320,7 +320,7 @@ static int create_new_enumeration(struct cu *cu, const struct btf_type *tp, uint
320320

321321
return 0;
322322
out_free:
323-
enumeration__delete(enumeration);
323+
enumeration__delete(enumeration, cu);
324324
return -ENOMEM;
325325
}
326326

@@ -366,7 +366,7 @@ static int create_new_enumeration64(struct cu *cu, const struct btf_type *tp, ui
366366

367367
return 0;
368368
out_free:
369-
enumeration__delete(enumeration);
369+
enumeration__delete(enumeration, cu);
370370
return -ENOMEM;
371371
}
372372
#else

ctf_loader.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static void *tag__alloc(const size_t size)
3434
return tag;
3535
}
3636

37-
static int ctf__load_ftype(struct ctf *ctf, struct ftype *proto, uint16_t tag,
37+
static int ctf__load_ftype(struct ctf *ctf, struct ftype *proto, struct cu *cu, uint16_t tag,
3838
uint16_t type, uint16_t vlen, uint16_t *args, long id)
3939
{
4040
proto->tag.tag = tag;
@@ -80,12 +80,12 @@ static int ctf__load_ftype(struct ctf *ctf, struct ftype *proto, uint16_t tag,
8080

8181
return vlen;
8282
out_free_parameters:
83-
ftype__delete(proto);
83+
ftype__delete(proto, cu);
8484
return -ENOMEM;
8585
}
8686

8787
static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
88-
struct ctf *ctf)
88+
struct ctf *ctf, struct cu *cu)
8989
{
9090
struct function *func = tag__alloc(sizeof(*func));
9191

@@ -116,7 +116,7 @@ static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
116116

117117
++*ptr;
118118

119-
if (ctf__load_ftype(ctf, &func->proto, DW_TAG_subprogram,
119+
if (ctf__load_ftype(ctf, &func->proto, cu, DW_TAG_subprogram,
120120
type, vlen, *ptr, id) < 0)
121121
return NULL;
122122
/*
@@ -133,7 +133,7 @@ static struct function *function__new(uint16_t **ptr, GElf_Sym *sym,
133133
return NULL;
134134
}
135135

136-
static int ctf__load_funcs(struct ctf *ctf)
136+
static int ctf__load_funcs(struct ctf *ctf, struct cu *cu)
137137
{
138138
struct ctf_header *hp = ctf__get_buffer(ctf);
139139
uint16_t *func_ptr = (ctf__get_buffer(ctf) + sizeof(*hp) +
@@ -142,7 +142,7 @@ static int ctf__load_funcs(struct ctf *ctf)
142142
GElf_Sym sym;
143143
uint32_t idx;
144144
ctf__for_each_symtab_function(ctf, idx, sym)
145-
if (function__new(&func_ptr, &sym, ctf) == NULL)
145+
if (function__new(&func_ptr, &sym, ctf, cu) == NULL)
146146
return -ENOMEM;
147147

148148
return 0;
@@ -262,7 +262,7 @@ static int create_new_array(struct ctf *ctf, void *ptr, uint32_t id)
262262

263263
static int create_new_subroutine_type(struct ctf *ctf, void *ptr,
264264
int vlen, struct ctf_full_type *tp,
265-
uint32_t id)
265+
uint32_t id, struct cu *cu)
266266
{
267267
uint16_t *args = ptr;
268268
unsigned int type = ctf__get16(ctf, &tp->base.ctf_type);
@@ -271,7 +271,7 @@ static int create_new_subroutine_type(struct ctf *ctf, void *ptr,
271271
if (proto == NULL)
272272
return -ENOMEM;
273273

274-
vlen = ctf__load_ftype(ctf, proto, DW_TAG_subroutine_type,
274+
vlen = ctf__load_ftype(ctf, proto, cu, DW_TAG_subroutine_type,
275275
type, vlen, args, id);
276276
return vlen < 0 ? -ENOMEM : vlen;
277277
}
@@ -326,7 +326,7 @@ static int create_short_members(struct ctf *ctf, void *ptr,
326326

327327
static int create_new_class(struct ctf *ctf, void *ptr,
328328
int vlen, struct ctf_full_type *tp,
329-
uint64_t size, uint32_t id)
329+
uint64_t size, uint32_t id, struct cu *cu)
330330
{
331331
int member_size;
332332
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
@@ -345,13 +345,13 @@ static int create_new_class(struct ctf *ctf, void *ptr,
345345

346346
return (vlen * member_size);
347347
out_free:
348-
class__delete(class);
348+
class__delete(class, cu);
349349
return -ENOMEM;
350350
}
351351

352352
static int create_new_union(struct ctf *ctf, void *ptr,
353353
int vlen, struct ctf_full_type *tp,
354-
uint64_t size, uint32_t id)
354+
uint64_t size, uint32_t id, struct cu *cu)
355355
{
356356
int member_size;
357357
const char *name = ctf__string(ctf, ctf__get32(ctf, &tp->base.ctf_name));
@@ -370,7 +370,7 @@ static int create_new_union(struct ctf *ctf, void *ptr,
370370

371371
return (vlen * member_size);
372372
out_free:
373-
type__delete(un);
373+
type__delete(un, cu);
374374
return -ENOMEM;
375375
}
376376

@@ -389,7 +389,7 @@ static struct enumerator *enumerator__new(const char *name, uint32_t value)
389389

390390
static int create_new_enumeration(struct ctf *ctf, void *ptr,
391391
int vlen, struct ctf_full_type *tp,
392-
uint16_t size, uint32_t id)
392+
uint16_t size, uint32_t id, struct cu *cu)
393393
{
394394
struct ctf_enum *ep = ptr;
395395
uint16_t i;
@@ -414,7 +414,7 @@ static int create_new_enumeration(struct ctf *ctf, void *ptr,
414414

415415
return (vlen * sizeof(*ep));
416416
out_free:
417-
enumeration__delete(enumeration);
417+
enumeration__delete(enumeration, cu);
418418
return -ENOMEM;
419419
}
420420

@@ -473,7 +473,7 @@ static int create_new_tag(struct ctf *ctf, int type,
473473
return 0;
474474
}
475475

476-
static int ctf__load_types(struct ctf *ctf)
476+
static int ctf__load_types(struct ctf *ctf, struct cu *cu)
477477
{
478478
void *ctf_buffer = ctf__get_buffer(ctf);
479479
struct ctf_header *hp = ctf_buffer;
@@ -510,16 +510,16 @@ static int ctf__load_types(struct ctf *ctf)
510510
} else if (type == CTF_TYPE_KIND_ARR) {
511511
vlen = create_new_array(ctf, ptr, type_index);
512512
} else if (type == CTF_TYPE_KIND_FUNC) {
513-
vlen = create_new_subroutine_type(ctf, ptr, vlen, type_ptr, type_index);
513+
vlen = create_new_subroutine_type(ctf, ptr, vlen, type_ptr, type_index, cu);
514514
} else if (type == CTF_TYPE_KIND_STR) {
515515
vlen = create_new_class(ctf, ptr,
516-
vlen, type_ptr, size, type_index);
516+
vlen, type_ptr, size, type_index, cu);
517517
} else if (type == CTF_TYPE_KIND_UNION) {
518518
vlen = create_new_union(ctf, ptr,
519-
vlen, type_ptr, size, type_index);
519+
vlen, type_ptr, size, type_index, cu);
520520
} else if (type == CTF_TYPE_KIND_ENUM) {
521521
vlen = create_new_enumeration(ctf, ptr, vlen, type_ptr,
522-
size, type_index);
522+
size, type_index, cu);
523523
} else if (type == CTF_TYPE_KIND_FWD) {
524524
vlen = create_new_forward_decl(ctf, type_ptr, size, type_index);
525525
} else if (type == CTF_TYPE_KIND_TYPDEF) {
@@ -589,15 +589,15 @@ static int ctf__load_objects(struct ctf *ctf)
589589
return 0;
590590
}
591591

592-
static int ctf__load_sections(struct ctf *ctf)
592+
static int ctf__load_sections(struct ctf *ctf, struct cu *cu)
593593
{
594594
int err = ctf__load_symtab(ctf);
595595

596596
if (err != 0)
597597
goto out;
598-
err = ctf__load_funcs(ctf);
598+
err = ctf__load_funcs(ctf, cu);
599599
if (err == 0)
600-
err = ctf__load_types(ctf);
600+
err = ctf__load_types(ctf, cu);
601601
if (err == 0)
602602
err = ctf__load_objects(ctf);
603603
out:
@@ -716,7 +716,7 @@ int ctf__load_file(struct cus *cus, struct conf_load *conf,
716716
if (ctf__load(state) != 0)
717717
return -1;
718718

719-
err = ctf__load_sections(state);
719+
err = ctf__load_sections(state, cu);
720720

721721
if (err != 0) {
722722
cu__delete(cu);

ctracer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ static struct class *class__clone_base_types(const struct tag *tag,
349349
{
350350
struct class *class = tag__class(tag);
351351
struct class_member *pos, *next;
352-
struct class *clone = class__clone(class, new_class_name);
352+
struct class *clone = class__clone(class, new_class_name, cu);
353353

354354
if (clone == NULL)
355355
return NULL;
@@ -360,7 +360,7 @@ static struct class *class__clone_base_types(const struct tag *tag,
360360
tag__assert_search_result(member_type, pos->tag.tag, class_member__name(pos));
361361
if (!tag__is_base_type(member_type, cu)) {
362362
next = class__remove_member(clone, cu, pos);
363-
class_member__delete(pos);
363+
class_member__delete(pos, cu);
364364
}
365365
}
366366
class__fixup_alignment(clone, cu);

dwarf_loader.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ static struct template_parameter_pack *template_parameter_pack__new(Dwarf_Die *d
11581158
INIT_LIST_HEAD(&pack->params);
11591159

11601160
if (template_parameter_pack__load_params(pack, die, cu, conf)) {
1161-
template_parameter_pack__delete(pack);
1161+
template_parameter_pack__delete(pack, cu);
11621162
pack = NULL;
11631163
}
11641164
}
@@ -1289,7 +1289,7 @@ static struct formal_parameter_pack *formal_parameter_pack__new(Dwarf_Die *die,
12891289
INIT_LIST_HEAD(&pack->params);
12901290

12911291
if (formal_parameter_pack__load_params(pack, die, cu, conf)) {
1292-
formal_parameter_pack__delete(pack);
1292+
formal_parameter_pack__delete(pack, cu);
12931293
pack = NULL;
12941294
}
12951295
}
@@ -1606,7 +1606,7 @@ static struct tag *die__create_new_class(Dwarf_Die *die, struct cu *cu, struct c
16061606
dwarf_haschildren(die) != 0 &&
16071607
dwarf_child(die, &child) == 0) {
16081608
if (die__process_class(&child, &class->type, cu, conf) != 0) {
1609-
class__delete(class);
1609+
class__delete(class, cu);
16101610
class = NULL;
16111611
}
16121612
}
@@ -1626,7 +1626,7 @@ static struct tag *die__create_new_namespace(Dwarf_Die *die, struct cu *cu, stru
16261626
dwarf_haschildren(die) != 0 &&
16271627
dwarf_child(die, &child) == 0) {
16281628
if (die__process_namespace(&child, namespace, cu, conf) != 0) {
1629-
namespace__delete(namespace);
1629+
namespace__delete(namespace, cu);
16301630
namespace = NULL;
16311631
}
16321632
}
@@ -1643,7 +1643,7 @@ static struct tag *die__create_new_union(Dwarf_Die *die, struct cu *cu, struct c
16431643
dwarf_haschildren(die) != 0 &&
16441644
dwarf_child(die, &child) == 0) {
16451645
if (die__process_class(&child, utype, cu, conf) != 0) {
1646-
type__delete(utype);
1646+
type__delete(utype, cu);
16471647
utype = NULL;
16481648
}
16491649
}
@@ -1854,9 +1854,9 @@ static struct tag *die__create_new_subroutine_type(Dwarf_Die *die,
18541854
out:
18551855
return &ftype->tag;
18561856
out_delete_tag:
1857-
tag__delete(tag);
1857+
tag__delete(tag, cu);
18581858
out_delete:
1859-
ftype__delete(ftype);
1859+
ftype__delete(ftype, cu);
18601860
return NULL;
18611861
}
18621862

@@ -1897,7 +1897,7 @@ static struct tag *die__create_new_enumeration(Dwarf_Die *die, struct cu *cu, st
18971897
out:
18981898
return &enumeration->namespace.tag;
18991899
out_delete:
1900-
enumeration__delete(enumeration);
1900+
enumeration__delete(enumeration, cu);
19011901
return NULL;
19021902
}
19031903

@@ -1960,7 +1960,7 @@ static int die__process_class(Dwarf_Die *die, struct type *class,
19601960
uint32_t id;
19611961

19621962
if (cu__table_add_tag(cu, &member->tag, &id) < 0) {
1963-
class_member__delete(member);
1963+
class_member__delete(member, cu);
19641964
return -ENOMEM;
19651965
}
19661966

@@ -1993,7 +1993,7 @@ static int die__process_class(Dwarf_Die *die, struct type *class,
19931993
uint32_t id;
19941994

19951995
if (cu__table_add_tag(cu, tag, &id) < 0) {
1996-
tag__delete(tag);
1996+
tag__delete(tag, cu);
19971997
return -ENOMEM;
19981998
}
19991999

@@ -2043,7 +2043,7 @@ static int die__process_namespace(Dwarf_Die *die, struct namespace *namespace,
20432043

20442044
return 0;
20452045
out_delete_tag:
2046-
tag__delete(tag);
2046+
tag__delete(tag, cu);
20472047
out_enomem:
20482048
return -ENOMEM;
20492049
}
@@ -2064,7 +2064,7 @@ static int die__create_new_lexblock(Dwarf_Die *die,
20642064
lexblock__add_lexblock(father, lexblock);
20652065
return 0;
20662066
out_delete:
2067-
lexblock__delete(lexblock);
2067+
lexblock__delete(lexblock, cu);
20682068
return -ENOMEM;
20692069
}
20702070

@@ -2152,7 +2152,7 @@ static int die__process_inline_expansion(Dwarf_Die *die, struct lexblock *lexblo
21522152

21532153
return 0;
21542154
out_delete_tag:
2155-
tag__delete(tag);
2155+
tag__delete(tag, cu);
21562156
out_enomem:
21572157
return -ENOMEM;
21582158
}
@@ -2314,7 +2314,7 @@ static int die__process_function(Dwarf_Die *die, struct ftype *ftype,
23142314

23152315
return 0;
23162316
out_delete_tag:
2317-
tag__delete(tag);
2317+
tag__delete(tag, cu);
23182318
out_enomem:
23192319
return -ENOMEM;
23202320
}
@@ -2325,7 +2325,7 @@ static struct tag *die__create_new_function(Dwarf_Die *die, struct cu *cu, struc
23252325

23262326
if (function != NULL &&
23272327
die__process_function(die, &function->proto, &function->lexblock, cu, conf) != 0) {
2328-
function__delete(function);
2328+
function__delete(function, cu);
23292329
function = NULL;
23302330
}
23312331

0 commit comments

Comments
 (0)