aboutsummaryrefslogtreecommitdiff
path: root/binutils/debug.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2023-04-03 22:21:59 +0930
committerAlan Modra <amodra@gmail.com>2023-04-04 12:47:56 +0930
commit19cacf672930cee20feaf1f3468e3d5ac3099ffd (patch)
treea85da4040a0d01240981754533db366f2ce172d5 /binutils/debug.c
parent59bb724b3591f270be752fb252bc6e01f1aae559 (diff)
downloadgdb-19cacf672930cee20feaf1f3468e3d5ac3099ffd.zip
gdb-19cacf672930cee20feaf1f3468e3d5ac3099ffd.tar.gz
gdb-19cacf672930cee20feaf1f3468e3d5ac3099ffd.tar.bz2
Use bfd_alloc memory for read_debugging_info storage
Trying to free malloc'd memory used by the stabs and coff debug info parsers is complicated, and traversing the trees generated requires a lot of code. It's better to bfd_alloc the memory which allows it all to be freed without fuss when the bfd is closed. In the process of doing this I reverted most of commit a6336913332. Some of the stabs handling code grows arrays of pointers with realloc, to deal with arbitrary numbers of fields, function args, etc. The code still does that but copies over to bfd_alloc memory when finished. The alternative is to parse twice, once to size, then again to populate the arrays. I think that complication is unwarranted. Note that there is a greater than zero chance this patch breaks something, eg. that I missed an attempt to free obj_alloc memory. Also it seems there are no tests in the binutils testsuite aimed at exercising objdump --debugging. * budbg.h (finish_stab, parse_stab): Update prototypes * debug.c: Include bucomm.h. (struct debug_handle): Add "abfd" field. (debug_init): Add "abfd" param. bfd_alloc handle. (debug_xalloc, debug_xzalloc): New functions. Use throughout in place of xmalloc and memset. (debug_start_source): Remove "name_used" param. * debug.h (debug_init, debug_start_source): Update prototypes. (debug_xalloc, debug_xzalloc): Declare. * objcopy.c (copy_object): Don't free dhandle. * objdump.c (dump_bfd): Likewise. * rdcoff.c (coff_get_slot): Add dhandle arg. debug_xzalloc memory in place of xcalloc. Update callers. (parse_coff_struct_type): Don't leak on error return. Copy fields over to debug_xalloc memory. (parse_coff_enum_type): Copy names and vals over the debug_xalloc memory. * rddbg.c (read_debugging_info): Adjust debug_init call. Don't free dhandle. (read_section_stabs_debugging_info): Don't free shandle. Adjust parse_stab call. Call finish_stab on error return. (read_symbol_stabs_debugging_info): Similarly. * stabs.c (savestring): Delete unnecessary forward declaration. Add dhandle param. debug_xalloc memory. Update callers. (start_stab): Delete unnecessary casts. (finish_stab): Add "emit" param. Free file_types, so_string, and stabs handle. (parse_stab): Delete string_used param. Revert code dealing with string_used. Copy so_string passed to debug_set_filename and stored as main_filename to debug_xalloc memory. Similarly for string passed to debug_start_source and push_bincl. Copy args to debug_xalloc memory. Don't leak args. (parse_stab_enum_type): Copy names and values to debug_xalloc memory. Don't free name. (parse_stab_struct_type): Don't free fields. (parse_stab_baseclasses): Delete unnecessary cast. (parse_stab_struct_fields): Return debug_xalloc fields. (parse_stab_cpp_abbrev): Use debug_xalloc for _vb$ type name. (parse_stab_one_struct_field): Don't free name. (parse_stab_members): Copy variants and methods to debug_xalloc memory. Don't free name or argtypes. (parse_stab_argtypes): Use debug_xalloc memory for physname and args. (push_bincl): Add dhandle param. Use debug_xalloc memory. (stab_record_variable): Use debug_xalloc memory. (stab_emit_pending_vars): Don't free var list. (stab_find_slot): Add dhandle param. Use debug_xzalloc memory. Update all callers. (stab_find_tagged_type): Don't free name. Use debug_xzalloc. (stab_demangle_qualified): Don't free name. (stab_demangle_template): Don't free s1. (stab_demangle_args): Tidy pvarargs refs. Copy *pargs on success to debug_xalloc memory, free on failure. (stab_demangle_fund_type): Don't free name. (stab_demangle_v3_arglist): Copy args to debug_xalloc memory. Don't free dt.
Diffstat (limited to 'binutils/debug.c')
-rw-r--r--binutils/debug.c150
1 files changed, 71 insertions, 79 deletions
diff --git a/binutils/debug.c b/binutils/debug.c
index fd9a98a..53b4587 100644
--- a/binutils/debug.c
+++ b/binutils/debug.c
@@ -31,6 +31,7 @@
#include "bfd.h"
#include "libiberty.h"
#include "filenames.h"
+#include "bucomm.h"
#include "debug.h"
/* Global information we keep for debugging. A pointer to this
@@ -38,6 +39,8 @@
struct debug_handle
{
+ /* The bfd where we objalloc memory. */
+ bfd *abfd;
/* A linked list of compilation units. */
struct debug_unit *units;
/* The current compilation unit. */
@@ -600,7 +603,7 @@ debug_error (const char *message)
/* Add an object to a namespace. */
static struct debug_name *
-debug_add_to_namespace (struct debug_handle *info ATTRIBUTE_UNUSED,
+debug_add_to_namespace (struct debug_handle *info,
struct debug_namespace **nsp, const char *name,
enum debug_object_kind kind,
enum debug_object_linkage linkage)
@@ -608,8 +611,7 @@ debug_add_to_namespace (struct debug_handle *info ATTRIBUTE_UNUSED,
struct debug_name *n;
struct debug_namespace *ns;
- n = (struct debug_name *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
+ n = debug_xzalloc (info, sizeof (*n));
n->name = name;
n->kind = kind;
@@ -618,8 +620,7 @@ debug_add_to_namespace (struct debug_handle *info ATTRIBUTE_UNUSED,
ns = *nsp;
if (ns == NULL)
{
- ns = (struct debug_namespace *) xmalloc (sizeof *ns);
- memset (ns, 0, sizeof *ns);
+ ns = debug_xzalloc (info, sizeof (*ns));
ns->tail = &ns->list;
@@ -659,13 +660,30 @@ debug_add_to_current_namespace (struct debug_handle *info, const char *name,
/* Return a handle for debugging information. */
void *
-debug_init (void)
+debug_init (bfd *abfd)
{
struct debug_handle *ret;
- ret = (struct debug_handle *) xmalloc (sizeof *ret);
- memset (ret, 0, sizeof *ret);
- return (void *) ret;
+ ret = bfd_xalloc (abfd, sizeof (*ret));
+ memset (ret, 0, sizeof (*ret));
+ ret->abfd = abfd;
+ return ret;
+}
+
+void *
+debug_xalloc (void *handle, size_t size)
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ return bfd_xalloc (info->abfd, size);
+}
+
+void *
+debug_xzalloc (void *handle, size_t size)
+{
+ struct debug_handle *info = (struct debug_handle *) handle;
+ void *mem = bfd_xalloc (info->abfd, size);
+ memset (mem, 0, size);
+ return mem;
}
/* Set the source filename. This implicitly starts a new compilation
@@ -681,13 +699,11 @@ debug_set_filename (void *handle, const char *name)
if (name == NULL)
name = "";
- nfile = (struct debug_file *) xmalloc (sizeof *nfile);
- memset (nfile, 0, sizeof *nfile);
+ nfile = debug_xzalloc (info, sizeof (*nfile));
nfile->filename = name;
- nunit = (struct debug_unit *) xmalloc (sizeof *nunit);
- memset (nunit, 0, sizeof *nunit);
+ nunit = debug_xzalloc (info, sizeof (*nunit));
nunit->files = nfile;
info->current_file = nfile;
@@ -713,7 +729,7 @@ debug_set_filename (void *handle, const char *name)
include files in a single compilation unit. */
bool
-debug_start_source (void *handle, const char *name, bool *name_used)
+debug_start_source (void *handle, const char *name)
{
struct debug_handle *info = (struct debug_handle *) handle;
struct debug_file *f, **pf;
@@ -736,11 +752,8 @@ debug_start_source (void *handle, const char *name, bool *name_used)
}
}
- f = (struct debug_file *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
-
+ f = debug_xzalloc (info, sizeof (*f));
f->filename = name;
- *name_used = true;
for (pf = &info->current_file->next;
*pf != NULL;
@@ -782,13 +795,11 @@ debug_record_function (void *handle, const char *name,
return false;
}
- f = (struct debug_function *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
+ f = debug_xzalloc (info, sizeof (*f));
f->return_type = return_type;
- b = (struct debug_block *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
+ b = debug_xzalloc (info, sizeof (*b));
b->start = addr;
b->end = (bfd_vma) -1;
@@ -834,8 +845,7 @@ debug_record_parameter (void *handle, const char *name, debug_type type,
return false;
}
- p = (struct debug_parameter *) xmalloc (sizeof *p);
- memset (p, 0, sizeof *p);
+ p = debug_xzalloc (info, sizeof (*p));
p->name = name;
p->type = type;
@@ -900,8 +910,7 @@ debug_start_block (void *handle, bfd_vma addr)
return false;
}
- b = (struct debug_block *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
+ b = debug_xzalloc (info, sizeof (*b));
b->parent = info->current_block;
b->start = addr;
@@ -988,8 +997,7 @@ debug_record_line (void *handle, unsigned long lineno, bfd_vma addr)
it in the right place, and make it the new current_lineno
structure. */
- l = (struct debug_lineno *) xmalloc (sizeof *l);
- memset (l, 0, sizeof *l);
+ l = debug_xzalloc (info, sizeof (*l));
l->file = info->current_file;
l->linenos[0] = lineno;
@@ -1090,8 +1098,7 @@ debug_record_typed_const (void *handle, const char *name, debug_type type,
if (n == NULL)
return false;
- tc = (struct debug_typed_constant *) xmalloc (sizeof *tc);
- memset (tc, 0, sizeof *tc);
+ tc = debug_xzalloc (info, sizeof (*tc));
tc->type = type;
tc->val = val;
@@ -1157,8 +1164,7 @@ debug_record_variable (void *handle, const char *name, debug_type type,
if (n == NULL)
return false;
- v = (struct debug_variable *) xmalloc (sizeof *v);
- memset (v, 0, sizeof *v);
+ v = debug_xzalloc (info, sizeof (*v));
v->kind = kind;
v->type = type;
@@ -1172,13 +1178,12 @@ debug_record_variable (void *handle, const char *name, debug_type type,
/* Make a type with a given kind and size. */
static struct debug_type_s *
-debug_make_type (struct debug_handle *info ATTRIBUTE_UNUSED,
+debug_make_type (struct debug_handle *info,
enum debug_type_kind kind, unsigned int size)
{
struct debug_type_s *t;
- t = (struct debug_type_s *) xmalloc (sizeof *t);
- memset (t, 0, sizeof *t);
+ t = debug_xzalloc (info, sizeof (*t));
t->kind = kind;
t->size = size;
@@ -1200,8 +1205,7 @@ debug_make_indirect_type (void *handle, debug_type *slot, const char *tag)
if (t == NULL)
return DEBUG_TYPE_NULL;
- i = (struct debug_indirect_type *) xmalloc (sizeof *i);
- memset (i, 0, sizeof *i);
+ i = debug_xzalloc (info, sizeof (*i));
i->slot = slot;
i->tag = tag;
@@ -1289,8 +1293,7 @@ debug_make_struct_type (void *handle, bool structp, bfd_vma size,
if (t == NULL)
return DEBUG_TYPE_NULL;
- c = (struct debug_class_type *) xmalloc (sizeof *c);
- memset (c, 0, sizeof *c);
+ c = debug_xzalloc (info, sizeof (*c));
c->fields = fields;
@@ -1322,8 +1325,7 @@ debug_make_object_type (void *handle, bool structp, bfd_vma size,
if (t == NULL)
return DEBUG_TYPE_NULL;
- c = (struct debug_class_type *) xmalloc (sizeof *c);
- memset (c, 0, sizeof *c);
+ c = debug_xzalloc (info, sizeof (*c));
c->fields = fields;
c->baseclasses = baseclasses;
@@ -1353,8 +1355,7 @@ debug_make_enum_type (void *handle, const char **names,
if (t == NULL)
return DEBUG_TYPE_NULL;
- e = (struct debug_enum_type *) xmalloc (sizeof *e);
- memset (e, 0, sizeof *e);
+ e = debug_xzalloc (info, sizeof (*e));
e->names = names;
e->values = values;
@@ -1407,8 +1408,7 @@ debug_make_function_type (void *handle, debug_type type,
if (t == NULL)
return DEBUG_TYPE_NULL;
- f = (struct debug_function_type *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
+ f = debug_xzalloc (info, sizeof (*f));
f->return_type = type;
f->arg_types = arg_types;
@@ -1456,8 +1456,7 @@ debug_make_range_type (void *handle, debug_type type, bfd_signed_vma lower,
if (t == NULL)
return DEBUG_TYPE_NULL;
- r = (struct debug_range_type *) xmalloc (sizeof *r);
- memset (r, 0, sizeof *r);
+ r = debug_xzalloc (info, sizeof (*r));
r->type = type;
r->lower = lower;
@@ -1490,8 +1489,7 @@ debug_make_array_type (void *handle, debug_type element_type,
if (t == NULL)
return DEBUG_TYPE_NULL;
- a = (struct debug_array_type *) xmalloc (sizeof *a);
- memset (a, 0, sizeof *a);
+ a = debug_xzalloc (info, sizeof (*a));
a->element_type = element_type;
a->range_type = range_type;
@@ -1522,8 +1520,7 @@ debug_make_set_type (void *handle, debug_type type, bool bitstringp)
if (t == NULL)
return DEBUG_TYPE_NULL;
- s = (struct debug_set_type *) xmalloc (sizeof *s);
- memset (s, 0, sizeof *s);
+ s = debug_xzalloc (info, sizeof (*s));
s->type = type;
s->bitstringp = bitstringp;
@@ -1553,8 +1550,7 @@ debug_make_offset_type (void *handle, debug_type base_type,
if (t == NULL)
return DEBUG_TYPE_NULL;
- o = (struct debug_offset_type *) xmalloc (sizeof *o);
- memset (o, 0, sizeof *o);
+ o = debug_xzalloc (info, sizeof (*o));
o->base_type = base_type;
o->target_type = target_type;
@@ -1584,8 +1580,7 @@ debug_make_method_type (void *handle, debug_type return_type,
if (t == NULL)
return DEBUG_TYPE_NULL;
- m = (struct debug_method_type *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
+ m = debug_xzalloc (info, sizeof (*m));
m->return_type = return_type;
m->domain_type = domain_type;
@@ -1678,14 +1673,14 @@ debug_make_undefined_tagged_type (void *handle, const char *name,
argument is the visibility of the base class. */
debug_baseclass
-debug_make_baseclass (void *handle ATTRIBUTE_UNUSED, debug_type type,
+debug_make_baseclass (void *handle, debug_type type,
bfd_vma bitpos, bool is_virtual,
enum debug_visibility visibility)
{
+ struct debug_handle *info = (struct debug_handle *) handle;
struct debug_baseclass_s *b;
- b = (struct debug_baseclass_s *) xmalloc (sizeof *b);
- memset (b, 0, sizeof *b);
+ b = debug_xzalloc (info, sizeof (*b));
b->type = type;
b->bitpos = bitpos;
@@ -1702,14 +1697,14 @@ debug_make_baseclass (void *handle ATTRIBUTE_UNUSED, debug_type type,
of the field. */
debug_field
-debug_make_field (void *handle ATTRIBUTE_UNUSED, const char *name,
+debug_make_field (void *handle, const char *name,
debug_type type, bfd_vma bitpos, bfd_vma bitsize,
enum debug_visibility visibility)
{
+ struct debug_handle *info = (struct debug_handle *) handle;
struct debug_field_s *f;
- f = (struct debug_field_s *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
+ f = debug_xzalloc (info, sizeof (*f));
f->name = name;
f->type = type;
@@ -1728,14 +1723,14 @@ debug_make_field (void *handle ATTRIBUTE_UNUSED, const char *name,
member. */
debug_field
-debug_make_static_member (void *handle ATTRIBUTE_UNUSED, const char *name,
+debug_make_static_member (void *handle, const char *name,
debug_type type, const char *physname,
enum debug_visibility visibility)
{
+ struct debug_handle *info = (struct debug_handle *) handle;
struct debug_field_s *f;
- f = (struct debug_field_s *) xmalloc (sizeof *f);
- memset (f, 0, sizeof *f);
+ f = debug_xzalloc (info, sizeof (*f));
f->name = name;
f->type = type;
@@ -1750,13 +1745,13 @@ debug_make_static_member (void *handle ATTRIBUTE_UNUSED, const char *name,
argument is a NULL terminated array of method variants. */
debug_method
-debug_make_method (void *handle ATTRIBUTE_UNUSED, const char *name,
+debug_make_method (void *handle, const char *name,
debug_method_variant *variants)
{
+ struct debug_handle *info = (struct debug_handle *) handle;
struct debug_method_s *m;
- m = (struct debug_method_s *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
+ m = debug_xzalloc (info, sizeof (*m));
m->name = name;
m->variants = variants;
@@ -1774,16 +1769,16 @@ debug_make_method (void *handle ATTRIBUTE_UNUSED, const char *name,
necessary? Could we just use debug_make_const_type? */
debug_method_variant
-debug_make_method_variant (void *handle ATTRIBUTE_UNUSED,
+debug_make_method_variant (void *handle,
const char *physname, debug_type type,
enum debug_visibility visibility,
bool constp, bool volatilep,
bfd_vma voffset, debug_type context)
{
+ struct debug_handle *info = (struct debug_handle *) handle;
struct debug_method_variant_s *m;
- m = (struct debug_method_variant_s *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
+ m = debug_xzalloc (info, sizeof (*m));
m->physname = physname;
m->type = type;
@@ -1801,15 +1796,15 @@ debug_make_method_variant (void *handle ATTRIBUTE_UNUSED,
since a static method can not also be virtual. */
debug_method_variant
-debug_make_static_method_variant (void *handle ATTRIBUTE_UNUSED,
+debug_make_static_method_variant (void *handle,
const char *physname, debug_type type,
enum debug_visibility visibility,
bool constp, bool volatilep)
{
+ struct debug_handle *info = (struct debug_handle *) handle;
struct debug_method_variant_s *m;
- m = (struct debug_method_variant_s *) xmalloc (sizeof *m);
- memset (m, 0, sizeof *m);
+ m = debug_xzalloc (info, sizeof (*m));
m->physname = physname;
m->type = type;
@@ -1845,8 +1840,7 @@ debug_name_type (void *handle, const char *name, debug_type type)
if (t == NULL)
return DEBUG_TYPE_NULL;
- n = (struct debug_named_type *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
+ n = debug_xzalloc (info, sizeof (*n));
n->type = type;
@@ -1898,8 +1892,7 @@ debug_tag_type (void *handle, const char *name, debug_type type)
if (t == NULL)
return DEBUG_TYPE_NULL;
- n = (struct debug_named_type *) xmalloc (sizeof *n);
- memset (n, 0, sizeof *n);
+ n = debug_xzalloc (info, sizeof (*n));
n->type = type;
@@ -2989,8 +2982,7 @@ debug_set_class_id (struct debug_handle *info, const char *tag,
++info->class_id;
c->id = info->class_id;
- l = (struct debug_class_id *) xmalloc (sizeof *l);
- memset (l, 0, sizeof *l);
+ l = debug_xzalloc (info, sizeof (*l));
l->type = type;
l->tag = tag;