/* 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 *);
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 *);
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;
}
\f
/* Indent to the current indentation level. */
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);
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;
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;
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;
{
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);
{
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;
}
/* Now the return type is on the top of the stack. */
- s = (char *) xmalloc (len);
+ s = xmalloc (len);
strcpy (s, "(|) (");
if (argcount < 0)
if (i > 0)
strcat (s, ", ");
strcat (s, arg_types[i]);
+ free (arg_types[i]);
}
if (varargs)
{
strcat (s, ", ");
strcat (s, "...");
}
- if (argcount > 0)
- free (arg_types);
+ free (arg_types);
}
strcat (s, ")");
}
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. */
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. */
{
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;
{
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;
}
/* 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)
if (i > 0)
strcat (s, ", ");
strcat (s, arg_types[i]);
+ free (arg_types[i]);
}
if (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. */
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. */
{
struct pr_handle *info = (struct pr_handle *) p;
char *tv = NULL;
+ bool ret = false;
info->indent += 2;
}
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
{
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)
{
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;
}
}
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. */
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. */
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)
{
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);
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;
}
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);
{
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];
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. */
/* 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. */
{
struct pr_handle *info = (struct pr_handle *) p;
+ free (info->stack->method);
info->stack->method = NULL;
return true;
}
fprintf (info->f, "static ");
fprintf (info->f, "%s (", t);
+ free (t);
+
info->parameter = 1;
return true;
free (info->filename);
/* Should it be relative? best way to do it here?. */
- info->filename = strdup (fname);
+ info->filename = xstrdup (fname);
return true;
}
free (info->filename);
/* Should it be relative? best way to do it here?. */
- info->filename = strdup (fname);
+ info->filename = xstrdup (fname);
return true;
}
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;
}
char *tv = NULL;
const char *name;
char idbuf[20];
+ bool ret = false;
info->indent += 2;
}
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. */
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))
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)
{
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. */
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);
if (! substitute_type (info, dname ? dname : name))
return false;
+ free (info->stack->method);
info->stack->method = NULL;
if (dname != NULL)
{
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, '(');
/* 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;
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);
/* 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);
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;