mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 12:03:41 +08:00
objdump print_debugging_info memory leaks
Fix memory leaks and do a general tidy of the code for printing coff and stabs debug. * prdbg.c: Delete unnneeded forward function declarations. Delete unnecessary casts throughout. Free all strings returned from pop_type throughout file. (struct pr_stack): Delete "num_parents". Replace tests for "num_parents" non-zero with tests of "parents" non-NULL throughout. Free "parents" before assigning, and set to NULL after freeing. Remove const from "method". Always strdup strings assigned to method, and free before assigning. (print_debugging_info): Free info.stack and info.filename.
This commit is contained in:
parent
ff93c7b1a2
commit
a5f3ca4823
320
binutils/prdbg.c
320
binutils/prdbg.c
@ -65,25 +65,14 @@ struct pr_stack
|
||||
/* Current visibility of fields if this is a class. */
|
||||
enum debug_visibility visibility;
|
||||
/* Name of the current method we are handling. */
|
||||
const char *method;
|
||||
char *method;
|
||||
/* The following are used only by the tags code (tg_). */
|
||||
/* Type for the container (struct, union, class, union class). */
|
||||
const char *flavor;
|
||||
/* A comma separated list of parent classes. */
|
||||
char *parents;
|
||||
/* How many parents contains parents. */
|
||||
int num_parents;
|
||||
};
|
||||
|
||||
static void indent (struct pr_handle *);
|
||||
static bool push_type (struct pr_handle *, const char *);
|
||||
static bool prepend_type (struct pr_handle *, const char *);
|
||||
static bool append_type (struct pr_handle *, const char *);
|
||||
static bool substitute_type (struct pr_handle *, const char *);
|
||||
static bool indent_type (struct pr_handle *);
|
||||
static char *pop_type (struct pr_handle *);
|
||||
static void print_vma (bfd_vma, char *, bool, bool);
|
||||
static bool pr_fix_visibility (struct pr_handle *, enum debug_visibility);
|
||||
static bool pr_start_compilation_unit (void *, const char *);
|
||||
static bool pr_start_source (void *, const char *);
|
||||
static bool pr_empty_type (void *);
|
||||
@ -138,13 +127,9 @@ static bool pr_start_block (void *, bfd_vma);
|
||||
static bool pr_end_block (void *, bfd_vma);
|
||||
static bool pr_end_function (void *);
|
||||
static bool pr_lineno (void *, const char *, unsigned long, bfd_vma);
|
||||
static bool append_parent (struct pr_handle *, const char *);
|
||||
/* Only used by tg_ code. */
|
||||
static bool tg_fix_visibility
|
||||
(struct pr_handle *, enum debug_visibility);
|
||||
static void find_address_in_section (bfd *, asection *, void *);
|
||||
static void translate_addresses (bfd *, char *, FILE *, asymbol **);
|
||||
|
||||
static const char *visibility_name (enum debug_visibility);
|
||||
|
||||
/* Tags style replacements. */
|
||||
static bool tg_start_compilation_unit (void *, const char *);
|
||||
static bool tg_start_source (void *, const char *);
|
||||
@ -308,8 +293,18 @@ print_debugging_info (FILE *f, void *dhandle, bfd *abfd, asymbol **syms,
|
||||
fputs ("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f);
|
||||
}
|
||||
|
||||
return as_tags ? debug_write (dhandle, &tg_fns, (void *) & info)
|
||||
: debug_write (dhandle, &pr_fns, (void *) & info);
|
||||
bool ret = debug_write (dhandle, as_tags ? &tg_fns : &pr_fns, &info);
|
||||
while (info.stack != NULL)
|
||||
{
|
||||
struct pr_stack *s = info.stack;
|
||||
info.stack = s->next;
|
||||
free (s->type);
|
||||
free (s->method);
|
||||
free (s->parents);
|
||||
free (s);
|
||||
}
|
||||
free (info.filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Indent to the current indentation level. */
|
||||
@ -333,7 +328,7 @@ push_type (struct pr_handle *info, const char *type)
|
||||
if (type == NULL)
|
||||
return false;
|
||||
|
||||
n = (struct pr_stack *) xmalloc (sizeof *n);
|
||||
n = xmalloc (sizeof *n);
|
||||
memset (n, 0, sizeof *n);
|
||||
|
||||
n->type = xstrdup (type);
|
||||
@ -354,7 +349,7 @@ prepend_type (struct pr_handle *info, const char *s)
|
||||
|
||||
assert (info->stack != NULL);
|
||||
|
||||
n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
|
||||
n = xmalloc (strlen (s) + strlen (info->stack->type) + 1);
|
||||
sprintf (n, "%s%s", s, info->stack->type);
|
||||
free (info->stack->type);
|
||||
info->stack->type = n;
|
||||
@ -375,8 +370,7 @@ append_type (struct pr_handle *info, const char *s)
|
||||
assert (info->stack != NULL);
|
||||
|
||||
len = strlen (info->stack->type);
|
||||
info->stack->type = (char *) xrealloc (info->stack->type,
|
||||
len + strlen (s) + 1);
|
||||
info->stack->type = xrealloc (info->stack->type, len + strlen (s) + 1);
|
||||
strcpy (info->stack->type + len, s);
|
||||
|
||||
return true;
|
||||
@ -395,8 +389,7 @@ append_parent (struct pr_handle *info, const char *s)
|
||||
assert (info->stack != NULL);
|
||||
|
||||
len = info->stack->parents ? strlen (info->stack->parents) : 0;
|
||||
info->stack->parents = (char *) xrealloc (info->stack->parents,
|
||||
len + strlen (s) + 1);
|
||||
info->stack->parents = xrealloc (info->stack->parents, len + strlen (s) + 1);
|
||||
strcpy (info->stack->parents + len, s);
|
||||
|
||||
return true;
|
||||
@ -418,7 +411,7 @@ substitute_type (struct pr_handle *info, const char *s)
|
||||
{
|
||||
char *n;
|
||||
|
||||
n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
|
||||
n = xmalloc (strlen (info->stack->type) + strlen (s));
|
||||
|
||||
memcpy (n, info->stack->type, u - info->stack->type);
|
||||
strcpy (n + (u - info->stack->type), s);
|
||||
@ -693,17 +686,14 @@ pr_function_type (void *p, int argcount, bool varargs)
|
||||
{
|
||||
int i;
|
||||
|
||||
arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
|
||||
arg_types = xmalloc (argcount * sizeof (*arg_types));
|
||||
for (i = argcount - 1; i >= 0; i--)
|
||||
{
|
||||
if (! substitute_type (info, ""))
|
||||
{
|
||||
free (arg_types);
|
||||
return false;
|
||||
}
|
||||
arg_types[i] = pop_type (info);
|
||||
if (arg_types[i] == NULL)
|
||||
if (!substitute_type (info, "")
|
||||
|| (arg_types[i] = pop_type (info)) == NULL)
|
||||
{
|
||||
for (int j = i + 1; j < argcount; j++)
|
||||
free (arg_types[j]);
|
||||
free (arg_types);
|
||||
return false;
|
||||
}
|
||||
@ -715,7 +705,7 @@ pr_function_type (void *p, int argcount, bool varargs)
|
||||
|
||||
/* Now the return type is on the top of the stack. */
|
||||
|
||||
s = (char *) xmalloc (len);
|
||||
s = xmalloc (len);
|
||||
strcpy (s, "(|) (");
|
||||
|
||||
if (argcount < 0)
|
||||
@ -729,6 +719,7 @@ pr_function_type (void *p, int argcount, bool varargs)
|
||||
if (i > 0)
|
||||
strcat (s, ", ");
|
||||
strcat (s, arg_types[i]);
|
||||
free (arg_types[i]);
|
||||
}
|
||||
if (varargs)
|
||||
{
|
||||
@ -736,8 +727,7 @@ pr_function_type (void *p, int argcount, bool varargs)
|
||||
strcat (s, ", ");
|
||||
strcat (s, "...");
|
||||
}
|
||||
if (argcount > 0)
|
||||
free (arg_types);
|
||||
free (arg_types);
|
||||
}
|
||||
|
||||
strcat (s, ")");
|
||||
@ -814,22 +804,27 @@ pr_array_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper,
|
||||
}
|
||||
|
||||
if (! substitute_type (info, ab))
|
||||
return false;
|
||||
goto fail;
|
||||
|
||||
if (strcmp (range_type, "int") != 0)
|
||||
{
|
||||
if (! append_type (info, ":")
|
||||
|| ! append_type (info, range_type))
|
||||
return false;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (stringp)
|
||||
{
|
||||
if (! append_type (info, " /* string */"))
|
||||
return false;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
free (range_type);
|
||||
return true;
|
||||
|
||||
fail:
|
||||
free (range_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Make a set type. */
|
||||
@ -870,10 +865,12 @@ pr_offset_type (void *p)
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
return (substitute_type (info, "")
|
||||
&& prepend_type (info, " ")
|
||||
&& prepend_type (info, t)
|
||||
&& append_type (info, "::|"));
|
||||
bool ret = (substitute_type (info, "")
|
||||
&& prepend_type (info, " ")
|
||||
&& prepend_type (info, t)
|
||||
&& append_type (info, "::|"));
|
||||
free (t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make a method type. */
|
||||
@ -883,21 +880,20 @@ pr_method_type (void *p, bool domain, int argcount, bool varargs)
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
unsigned int len;
|
||||
char *domain_type;
|
||||
char *domain_type = NULL, *free_domain = NULL;
|
||||
char **arg_types;
|
||||
char *s;
|
||||
|
||||
len = 10;
|
||||
|
||||
if (! domain)
|
||||
domain_type = NULL;
|
||||
else
|
||||
if (domain)
|
||||
{
|
||||
if (! substitute_type (info, ""))
|
||||
return false;
|
||||
domain_type = pop_type (info);
|
||||
if (domain_type == NULL)
|
||||
return false;
|
||||
free_domain = domain_type;
|
||||
if (startswith (domain_type, "class ")
|
||||
&& strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
|
||||
domain_type += sizeof "class " - 1;
|
||||
@ -917,17 +913,14 @@ pr_method_type (void *p, bool domain, int argcount, bool varargs)
|
||||
{
|
||||
int i;
|
||||
|
||||
arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
|
||||
arg_types = xmalloc (argcount * sizeof (*arg_types));
|
||||
for (i = argcount - 1; i >= 0; i--)
|
||||
{
|
||||
if (! substitute_type (info, ""))
|
||||
{
|
||||
free (arg_types);
|
||||
return false;
|
||||
}
|
||||
arg_types[i] = pop_type (info);
|
||||
if (arg_types[i] == NULL)
|
||||
if (!substitute_type (info, "")
|
||||
|| (arg_types[i] = pop_type (info)) == NULL)
|
||||
{
|
||||
for (int j = i + 1; j < argcount; ++j)
|
||||
free (arg_types[j]);
|
||||
free (arg_types);
|
||||
return false;
|
||||
}
|
||||
@ -939,11 +932,13 @@ pr_method_type (void *p, bool domain, int argcount, bool varargs)
|
||||
|
||||
/* Now the return type is on the top of the stack. */
|
||||
|
||||
s = (char *) xmalloc (len);
|
||||
if (! domain)
|
||||
*s = '\0';
|
||||
else
|
||||
strcpy (s, domain_type);
|
||||
s = xmalloc (len);
|
||||
*s = 0;
|
||||
if (domain)
|
||||
{
|
||||
strcpy (s, domain_type);
|
||||
free (free_domain);
|
||||
}
|
||||
strcat (s, "::| (");
|
||||
|
||||
if (argcount < 0)
|
||||
@ -957,6 +952,7 @@ pr_method_type (void *p, bool domain, int argcount, bool varargs)
|
||||
if (i > 0)
|
||||
strcat (s, ", ");
|
||||
strcat (s, arg_types[i]);
|
||||
free (arg_types[i]);
|
||||
}
|
||||
if (varargs)
|
||||
{
|
||||
@ -964,18 +960,14 @@ pr_method_type (void *p, bool domain, int argcount, bool varargs)
|
||||
strcat (s, ", ");
|
||||
strcat (s, "...");
|
||||
}
|
||||
if (argcount > 0)
|
||||
free (arg_types);
|
||||
free (arg_types);
|
||||
}
|
||||
|
||||
strcat (s, ")");
|
||||
|
||||
if (! substitute_type (info, s))
|
||||
return false;
|
||||
|
||||
bool ret = substitute_type (info, s);
|
||||
free (s);
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Make a const qualified type. */
|
||||
@ -1143,10 +1135,9 @@ pr_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize,
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
return append_type (info, t);
|
||||
bool ret = pr_fix_visibility (info, visibility) && append_type (info, t);
|
||||
free (t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Finish a struct type. */
|
||||
@ -1181,6 +1172,7 @@ pr_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
char *tv = NULL;
|
||||
bool ret = false;
|
||||
|
||||
info->indent += 2;
|
||||
|
||||
@ -1192,11 +1184,11 @@ pr_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
}
|
||||
|
||||
if (! push_type (info, structp ? "class " : "union class "))
|
||||
return false;
|
||||
goto out;
|
||||
if (tag != NULL)
|
||||
{
|
||||
if (! append_type (info, tag))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1204,15 +1196,15 @@ pr_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
|
||||
sprintf (idbuf, "%%anon%u", id);
|
||||
if (! append_type (info, idbuf))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (! append_type (info, " {"))
|
||||
return false;
|
||||
goto out;
|
||||
if (size != 0 || vptr || ownvptr || tag != NULL)
|
||||
{
|
||||
if (! append_type (info, " /*"))
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
@ -1221,23 +1213,23 @@ pr_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
sprintf (ab, "%u", size);
|
||||
if (! append_type (info, " size ")
|
||||
|| ! append_type (info, ab))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (vptr)
|
||||
{
|
||||
if (! append_type (info, " vtable "))
|
||||
return false;
|
||||
goto out;
|
||||
if (ownvptr)
|
||||
{
|
||||
if (! append_type (info, "self "))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! append_type (info, tv)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1247,17 +1239,19 @@ pr_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
|
||||
sprintf (ab, " id %u", id);
|
||||
if (! append_type (info, ab))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (! append_type (info, " */"))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
|
||||
|
||||
return (append_type (info, "\n")
|
||||
&& indent_type (info));
|
||||
ret = append_type (info, "\n") && indent_type (info);
|
||||
out:
|
||||
free (tv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add a static member to a class. */
|
||||
@ -1283,10 +1277,9 @@ pr_class_static_member (void *p, const char *name, const char *physname,
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
return append_type (info, t);
|
||||
bool ret = pr_fix_visibility (info, visibility) && append_type (info, t);
|
||||
free (t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add a base class to a class. */
|
||||
@ -1310,13 +1303,15 @@ pr_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual,
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (startswith (t, "class "))
|
||||
t += sizeof "class " - 1;
|
||||
|
||||
/* Push it back on to take advantage of the prepend_type and
|
||||
append_type routines. */
|
||||
if (! push_type (info, t))
|
||||
return false;
|
||||
if (! push_type (info, t + (startswith (t, "class ")
|
||||
? sizeof "class " - 1 : 0)))
|
||||
{
|
||||
free (t);
|
||||
return false;
|
||||
}
|
||||
free (t);
|
||||
|
||||
if (is_virtual)
|
||||
{
|
||||
@ -1372,7 +1367,7 @@ pr_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual,
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
|
||||
n = xmalloc (strlen (info->stack->type) + strlen (t) + 1);
|
||||
memcpy (n, info->stack->type, s - info->stack->type);
|
||||
strcpy (n + (s - info->stack->type), t);
|
||||
strcat (n, s);
|
||||
@ -1393,7 +1388,8 @@ pr_class_start_method (void *p, const char *name)
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
|
||||
assert (info->stack != NULL);
|
||||
info->stack->method = name;
|
||||
free (info->stack->method);
|
||||
info->stack->method = xstrdup (name);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1408,6 +1404,7 @@ pr_class_method_variant (void *p, const char *physname,
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
char *method_type;
|
||||
char *context_type;
|
||||
bool ret = false;
|
||||
|
||||
assert (info->stack != NULL);
|
||||
assert (info->stack->next != NULL);
|
||||
@ -1443,19 +1440,19 @@ pr_class_method_variant (void *p, const char *physname,
|
||||
{
|
||||
context_type = pop_type (info);
|
||||
if (context_type == NULL)
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Now the top of the stack is the class. */
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
if (! append_type (info, method_type)
|
||||
|| ! append_type (info, " /* ")
|
||||
|| ! append_type (info, physname)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
goto out;
|
||||
if (context || voffset != 0)
|
||||
{
|
||||
char ab[22];
|
||||
@ -1465,16 +1462,19 @@ pr_class_method_variant (void *p, const char *physname,
|
||||
if (! append_type (info, "context ")
|
||||
|| ! append_type (info, context_type)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
print_vma (voffset, ab, true, false);
|
||||
if (! append_type (info, "voffset ")
|
||||
|| ! append_type (info, ab))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return (append_type (info, " */;\n")
|
||||
&& indent_type (info));
|
||||
ret = append_type (info, " */;\n") && indent_type (info);
|
||||
out:
|
||||
free (method_type);
|
||||
free (context_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add a static variant to a method. */
|
||||
@ -1518,14 +1518,14 @@ pr_class_static_method_variant (void *p, const char *physname,
|
||||
|
||||
/* Now the top of the stack is the class. */
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
return (append_type (info, method_type)
|
||||
&& append_type (info, " /* ")
|
||||
&& append_type (info, physname)
|
||||
&& append_type (info, " */;\n")
|
||||
&& indent_type (info));
|
||||
bool ret = (pr_fix_visibility (info, visibility)
|
||||
&& append_type (info, method_type)
|
||||
&& append_type (info, " /* ")
|
||||
&& append_type (info, physname)
|
||||
&& append_type (info, " */;\n")
|
||||
&& indent_type (info));
|
||||
free (method_type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Finish up a method. */
|
||||
@ -1535,6 +1535,7 @@ pr_class_end_method (void *p)
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
|
||||
free (info->stack->method);
|
||||
info->stack->method = NULL;
|
||||
return true;
|
||||
}
|
||||
@ -1761,6 +1762,8 @@ pr_start_function (void *p, const char *name, bool global)
|
||||
fprintf (info->f, "static ");
|
||||
fprintf (info->f, "%s (", t);
|
||||
|
||||
free (t);
|
||||
|
||||
info->parameter = 1;
|
||||
|
||||
return true;
|
||||
@ -1928,7 +1931,7 @@ tg_start_compilation_unit (void * p, const char *fname ATTRIBUTE_UNUSED)
|
||||
|
||||
free (info->filename);
|
||||
/* Should it be relative? best way to do it here?. */
|
||||
info->filename = strdup (fname);
|
||||
info->filename = xstrdup (fname);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1942,7 +1945,7 @@ tg_start_source (void *p, const char *fname)
|
||||
|
||||
free (info->filename);
|
||||
/* Should it be relative? best way to do it here?. */
|
||||
info->filename = strdup (fname);
|
||||
info->filename = xstrdup (fname);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2045,16 +2048,24 @@ tg_struct_field (void *p, const char *name, bfd_vma bitpos ATTRIBUTE_UNUSED,
|
||||
return false;
|
||||
|
||||
if (! tg_fix_visibility (info, visibility))
|
||||
return false;
|
||||
{
|
||||
free (t);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* It happens, a bug? */
|
||||
if (! name[0])
|
||||
return true;
|
||||
{
|
||||
free (t);
|
||||
return true;
|
||||
}
|
||||
|
||||
fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n",
|
||||
name, info->filename, t, info->stack->flavor, info->stack->type,
|
||||
visibility_name (visibility));
|
||||
|
||||
free (t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2079,6 +2090,7 @@ tg_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
char *tv = NULL;
|
||||
const char *name;
|
||||
char idbuf[20];
|
||||
bool ret = false;
|
||||
|
||||
info->indent += 2;
|
||||
|
||||
@ -2098,35 +2110,38 @@ tg_start_class_type (void *p, const char *tag, unsigned int id,
|
||||
}
|
||||
|
||||
if (! push_type (info, name))
|
||||
return false;
|
||||
goto out;
|
||||
|
||||
info->stack->flavor = structp ? "class" : "union class";
|
||||
free (info->stack->parents);
|
||||
info->stack->parents = NULL;
|
||||
info->stack->num_parents = 0;
|
||||
|
||||
if (size != 0 || vptr || ownvptr || tag != NULL)
|
||||
{
|
||||
if (vptr)
|
||||
{
|
||||
if (! append_type (info, " vtable "))
|
||||
return false;
|
||||
goto out;
|
||||
if (ownvptr)
|
||||
{
|
||||
if (! append_type (info, "self "))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! append_type (info, tv)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
|
||||
|
||||
return true;
|
||||
ret = true;
|
||||
out:
|
||||
free (tv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add a static member to a class. */
|
||||
@ -2143,9 +2158,7 @@ tg_class_static_member (void *p, const char *name,
|
||||
|
||||
len_var = strlen (name);
|
||||
len_class = strlen (info->stack->next->type);
|
||||
full_name = (char *) xmalloc (len_var + len_class + 3);
|
||||
if (! full_name)
|
||||
return false;
|
||||
full_name = xmalloc (len_var + len_class + 3);
|
||||
sprintf (full_name, "%s::%s", info->stack->next->type, name);
|
||||
|
||||
if (! substitute_type (info, full_name))
|
||||
@ -2199,13 +2212,15 @@ tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED,
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (startswith (t, "class "))
|
||||
t += sizeof "class " - 1;
|
||||
|
||||
/* Push it back on to take advantage of the prepend_type and
|
||||
append_type routines. */
|
||||
if (! push_type (info, t))
|
||||
return false;
|
||||
if (! push_type (info, t + (startswith (t, "class ")
|
||||
? sizeof "class " - 1 : 0)))
|
||||
{
|
||||
free (t);
|
||||
return false;
|
||||
}
|
||||
free (t);
|
||||
|
||||
if (is_virtual)
|
||||
{
|
||||
@ -2236,16 +2251,10 @@ tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED,
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (info->stack->num_parents && ! append_parent (info, ", "))
|
||||
return false;
|
||||
|
||||
if (! append_parent (info, t))
|
||||
return false;
|
||||
info->stack->num_parents++;
|
||||
|
||||
bool ret = ((!info->stack->parents || append_parent (info, ", "))
|
||||
&& append_parent (info, t));
|
||||
free (t);
|
||||
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add a variant to a method. */
|
||||
@ -2401,10 +2410,11 @@ tg_end_class_type (void *p)
|
||||
|
||||
fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type,
|
||||
info->filename, info->stack->flavor);
|
||||
if (info->stack->num_parents)
|
||||
if (info->stack->parents)
|
||||
{
|
||||
fprintf (info->f, "\tinherits:%s", info->stack->parents);
|
||||
free (info->stack->parents);
|
||||
info->stack->parents = NULL;
|
||||
}
|
||||
fputc ('\n', info->f);
|
||||
|
||||
@ -2628,6 +2638,7 @@ tg_start_function (void *p, const char *name, bool global)
|
||||
if (! substitute_type (info, dname ? dname : name))
|
||||
return false;
|
||||
|
||||
free (info->stack->method);
|
||||
info->stack->method = NULL;
|
||||
if (dname != NULL)
|
||||
{
|
||||
@ -2636,12 +2647,13 @@ tg_start_function (void *p, const char *name, bool global)
|
||||
if (sep)
|
||||
{
|
||||
info->stack->method = dname;
|
||||
dname = NULL;
|
||||
*sep = 0;
|
||||
name = sep + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->stack->method = "";
|
||||
info->stack->method = xstrdup ("");
|
||||
name = dname;
|
||||
}
|
||||
sep = strchr (name, '(');
|
||||
@ -2650,7 +2662,9 @@ tg_start_function (void *p, const char *name, bool global)
|
||||
/* Obscure functions as type_info function. */
|
||||
}
|
||||
|
||||
free (info->stack->parents);
|
||||
info->stack->parents = strdup (name);
|
||||
free (dname);
|
||||
|
||||
if (! info->stack->method && ! append_type (info, "("))
|
||||
return false;
|
||||
@ -2686,14 +2700,23 @@ tg_function_parameter (void *p, const char *name, enum debug_parm_kind kind,
|
||||
if (! info->stack->method)
|
||||
{
|
||||
if (info->parameter != 1 && ! append_type (info, ", "))
|
||||
return false;
|
||||
{
|
||||
free (t);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
|
||||
if (! append_type (info, "register "))
|
||||
return false;
|
||||
{
|
||||
free (t);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! append_type (info, t))
|
||||
return false;
|
||||
{
|
||||
free (t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
free (t);
|
||||
@ -2720,6 +2743,7 @@ tg_start_block (void *p, bfd_vma addr)
|
||||
/* Delayed name. */
|
||||
fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename);
|
||||
free (info->stack->parents);
|
||||
info->stack->parents = NULL;
|
||||
|
||||
print_vma (addr, ab, true, true);
|
||||
translate_addresses (info->abfd, ab, info->f, info->syms);
|
||||
@ -2740,14 +2764,14 @@ tg_start_block (void *p, bfd_vma addr)
|
||||
if (t == NULL)
|
||||
return false;
|
||||
fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t);
|
||||
free (t);
|
||||
if (local)
|
||||
fputs ("\tfile:", info->f);
|
||||
if (partof)
|
||||
{
|
||||
fprintf (info->f, "\tclass:%s", partof);
|
||||
free (partof);
|
||||
}
|
||||
fprintf (info->f, "\tclass:%s", partof);
|
||||
fputc ('\n', info->f);
|
||||
free (info->stack->method);
|
||||
info->stack->method = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user