xref: /netbsd-src/external/gpl3/binutils/dist/binutils/prdbg.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* prdbg.c -- Print out generic debugging information.
2    Copyright (C) 1995-2024 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor <ian@cygnus.com>.
4    Tags style generation written by Salvador E. Tropea <set@computer.org>.
5 
6    This file is part of GNU Binutils.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21    02110-1301, USA.  */
22 
23 /* This file prints out the generic debugging information, by
24    supplying a set of routines to debug_write.  */
25 
26 #include "sysdep.h"
27 #include <assert.h>
28 #include "bfd.h"
29 #include "libiberty.h"
30 #include "demangle.h"
31 #include "debug.h"
32 #include "budbg.h"
33 
34 /* This is the structure we use as a handle for these routines.  */
35 
36 struct pr_handle
37 {
38   /* File to print information to.  */
39   FILE *f;
40   /* Current indentation level.  */
41   unsigned int indent;
42   /* Type stack.  */
43   struct pr_stack *stack;
44   /* Parameter number we are about to output.  */
45   int parameter;
46   /* The following are used only by the tags code (tg_).  */
47   /* Name of the file we are using.  */
48   char *filename;
49   /* The BFD.  */
50   bfd *abfd;
51   /* The symbols table for this BFD.  */
52   asymbol **syms;
53   /* Pointer to a function to demangle symbols.  */
54   char *(*demangler) (bfd *, const char *, int);
55 };
56 
57 /* The type stack.  */
58 
59 struct pr_stack
60 {
61   /* Next element on the stack.  */
62   struct pr_stack *next;
63   /* This element.  */
64   char *type;
65   /* Current visibility of fields if this is a class.  */
66   enum debug_visibility visibility;
67   /* Name of the current method we are handling.  */
68   char *method;
69   /* The following are used only by the tags code (tg_).  */
70   /* Type for the container (struct, union, class, union class).  */
71   const char *flavor;
72   /* A comma separated list of parent classes.  */
73   char *parents;
74 };
75 
76 static bool pr_start_compilation_unit (void *, const char *);
77 static bool pr_start_source (void *, const char *);
78 static bool pr_empty_type (void *);
79 static bool pr_void_type (void *);
80 static bool pr_int_type (void *, unsigned int, bool);
81 static bool pr_float_type (void *, unsigned int);
82 static bool pr_complex_type (void *, unsigned int);
83 static bool pr_bool_type (void *, unsigned int);
84 static bool pr_enum_type
85   (void *, const char *, const char **, bfd_signed_vma *);
86 static bool pr_pointer_type (void *);
87 static bool pr_function_type (void *, int, bool);
88 static bool pr_reference_type (void *);
89 static bool pr_range_type (void *, bfd_signed_vma, bfd_signed_vma);
90 static bool pr_array_type (void *, bfd_signed_vma, bfd_signed_vma, bool);
91 static bool pr_set_type (void *, bool);
92 static bool pr_offset_type (void *);
93 static bool pr_method_type (void *, bool, int, bool);
94 static bool pr_const_type (void *);
95 static bool pr_volatile_type (void *);
96 static bool pr_start_struct_type
97   (void *, const char *, unsigned int, bool, unsigned int);
98 static bool pr_struct_field
99   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
100 static bool pr_end_struct_type (void *);
101 static bool pr_start_class_type
102   (void *, const char *, unsigned int, bool, unsigned int, bool, bool);
103 static bool pr_class_static_member
104   (void *, const char *, const char *, enum debug_visibility);
105 static bool pr_class_baseclass
106   (void *, bfd_vma, bool, enum debug_visibility);
107 static bool pr_class_start_method (void *, const char *);
108 static bool pr_class_method_variant
109   (void *, const char *, enum debug_visibility, bool, bool, bfd_vma, bool);
110 static bool pr_class_static_method_variant
111   (void *, const char *, enum debug_visibility, bool, bool);
112 static bool pr_class_end_method (void *);
113 static bool pr_end_class_type (void *);
114 static bool pr_typedef_type (void *, const char *);
115 static bool pr_tag_type
116   (void *, const char *, unsigned int, enum debug_type_kind);
117 static bool pr_typdef (void *, const char *);
118 static bool pr_tag (void *, const char *);
119 static bool pr_int_constant (void *, const char *, bfd_vma);
120 static bool pr_float_constant (void *, const char *, double);
121 static bool pr_typed_constant (void *, const char *, bfd_vma);
122 static bool pr_variable (void *, const char *, enum debug_var_kind, bfd_vma);
123 static bool pr_start_function (void *, const char *, bool);
124 static bool pr_function_parameter
125   (void *, const char *, enum debug_parm_kind, bfd_vma);
126 static bool pr_start_block (void *, bfd_vma);
127 static bool pr_end_block (void *, bfd_vma);
128 static bool pr_end_function (void *);
129 static bool pr_lineno (void *, const char *, unsigned long, bfd_vma);
130 
131 static const char *visibility_name (enum debug_visibility);
132 
133 /* Tags style replacements.  */
134 static bool tg_start_compilation_unit (void *, const char *);
135 static bool tg_start_source (void *, const char *);
136 static bool tg_enum_type
137   (void *, const char *, const char **, bfd_signed_vma *);
138 static bool tg_start_struct_type
139   (void *, const char *, unsigned int, bool, unsigned int);
140 static bool pr_struct_field
141   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
142 static bool tg_struct_field
143   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
144 static bool tg_struct_field
145   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
146 static bool tg_end_struct_type (void *);
147 static bool tg_start_class_type
148   (void *, const char *, unsigned int, bool, unsigned int, bool, bool);
149 static bool tg_class_static_member
150   (void *, const char *, const char *, enum debug_visibility);
151 static bool tg_class_baseclass (void *, bfd_vma, bool, enum debug_visibility);
152 static bool tg_class_method_variant
153   (void *, const char *, enum debug_visibility, bool, bool, bfd_vma, bool);
154 static bool tg_class_static_method_variant
155   (void *, const char *, enum debug_visibility, bool, bool);
156 static bool tg_end_class_type (void *);
157 static bool tg_tag_type
158   (void *, const char *, unsigned int, enum debug_type_kind);
159 static bool tg_typdef (void *, const char *);
160 static bool tg_tag (void *, const char *);
161 static bool tg_int_constant (void *, const char *, bfd_vma);
162 static bool tg_float_constant (void *, const char *, double);
163 static bool tg_typed_constant (void *, const char *, bfd_vma);
164 static bool tg_variable (void *, const char *, enum debug_var_kind, bfd_vma);
165 static bool tg_start_function (void *, const char *, bool);
166 static bool tg_function_parameter
167   (void *, const char *, enum debug_parm_kind, bfd_vma);
168 static bool tg_start_block (void *, bfd_vma);
169 static bool tg_end_block (void *, bfd_vma);
170 static bool tg_lineno (void *, const char *, unsigned long, bfd_vma);
171 
172 static const struct debug_write_fns pr_fns =
173 {
174   pr_start_compilation_unit,
175   pr_start_source,
176   pr_empty_type,
177   pr_void_type,
178   pr_int_type,
179   pr_float_type,
180   pr_complex_type,
181   pr_bool_type,
182   pr_enum_type,
183   pr_pointer_type,
184   pr_function_type,
185   pr_reference_type,
186   pr_range_type,
187   pr_array_type,
188   pr_set_type,
189   pr_offset_type,
190   pr_method_type,
191   pr_const_type,
192   pr_volatile_type,
193   pr_start_struct_type,
194   pr_struct_field,
195   pr_end_struct_type,
196   pr_start_class_type,
197   pr_class_static_member,
198   pr_class_baseclass,
199   pr_class_start_method,
200   pr_class_method_variant,
201   pr_class_static_method_variant,
202   pr_class_end_method,
203   pr_end_class_type,
204   pr_typedef_type,
205   pr_tag_type,
206   pr_typdef,
207   pr_tag,
208   pr_int_constant,
209   pr_float_constant,
210   pr_typed_constant,
211   pr_variable,
212   pr_start_function,
213   pr_function_parameter,
214   pr_start_block,
215   pr_end_block,
216   pr_end_function,
217   pr_lineno
218 };
219 
220 static const struct debug_write_fns tg_fns =
221 {
222   tg_start_compilation_unit,
223   tg_start_source,
224   pr_empty_type,		/* Same, push_type.  */
225   pr_void_type,			/* Same, push_type.  */
226   pr_int_type,			/* Same, push_type.  */
227   pr_float_type,		/* Same, push_type.  */
228   pr_complex_type,		/* Same, push_type.  */
229   pr_bool_type,			/* Same, push_type.  */
230   tg_enum_type,
231   pr_pointer_type,		/* Same, changes to pointer.  */
232   pr_function_type,		/* Same, push_type.  */
233   pr_reference_type,		/* Same, changes to reference.  */
234   pr_range_type,		/* FIXME: What's that?.  */
235   pr_array_type,		/* Same, push_type.  */
236   pr_set_type,			/* FIXME: What's that?.  */
237   pr_offset_type,		/* FIXME: What's that?.  */
238   pr_method_type,		/* Same.  */
239   pr_const_type,		/* Same, changes to const.  */
240   pr_volatile_type,		/* Same, changes to volatile.  */
241   tg_start_struct_type,
242   tg_struct_field,
243   tg_end_struct_type,
244   tg_start_class_type,
245   tg_class_static_member,
246   tg_class_baseclass,
247   pr_class_start_method,	/* Same, remembers that's a method.  */
248   tg_class_method_variant,
249   tg_class_static_method_variant,
250   pr_class_end_method,		/* Same, forgets that's a method.  */
251   tg_end_class_type,
252   pr_typedef_type,		/* Same, just push type.  */
253   tg_tag_type,
254   tg_typdef,
255   tg_tag,
256   tg_int_constant,		/* Untested.  */
257   tg_float_constant,		/* Untested.  */
258   tg_typed_constant,		/* Untested.  */
259   tg_variable,
260   tg_start_function,
261   tg_function_parameter,
262   tg_start_block,
263   tg_end_block,
264   pr_end_function,		/* Same, does nothing.  */
265   tg_lineno
266 };
267 
268 static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
269 
270 /* Print out the generic debugging information recorded in dhandle.  */
271 
272 bool
print_debugging_info(FILE * f,void * dhandle,bfd * abfd,asymbol ** syms,char * (* demangler)(struct bfd *,const char *,int),bool as_tags)273 print_debugging_info (FILE *f, void *dhandle, bfd *abfd, asymbol **syms,
274 		      char * (*demangler) (struct bfd *, const char *, int),
275 		      bool as_tags)
276 {
277   struct pr_handle info;
278 
279   info.f = f;
280   info.indent = 0;
281   info.stack = NULL;
282   info.parameter = 0;
283   info.filename = NULL;
284   info.abfd = abfd;
285   info.syms = syms;
286   info.demangler = demangler;
287 
288   if (as_tags)
289     {
290       fputs ("!_TAG_FILE_FORMAT\t2\t/extended format/\n", f);
291       fputs ("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted/\n", f);
292       fputs ("!_TAG_PROGRAM_AUTHOR\tIan Lance Taylor, Salvador E. Tropea and others\t//\n", f);
293       fputs ("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f);
294     }
295 
296   bool ret = debug_write (dhandle, as_tags ? &tg_fns : &pr_fns, &info);
297   while (info.stack != NULL)
298     {
299       struct pr_stack *s = info.stack;
300       info.stack = s->next;
301       free (s->type);
302       free (s->method);
303       free (s->parents);
304       free (s);
305     }
306   free (info.filename);
307   return ret;
308 }
309 
310 /* Indent to the current indentation level.  */
311 
312 static void
indent(struct pr_handle * info)313 indent (struct pr_handle *info)
314 {
315   unsigned int i;
316 
317   for (i = 0; i < info->indent; i++)
318     putc (' ', info->f);
319 }
320 
321 /* Push a type on the type stack.  */
322 
323 static bool
push_type(struct pr_handle * info,const char * type)324 push_type (struct pr_handle *info, const char *type)
325 {
326   struct pr_stack *n;
327 
328   if (type == NULL)
329     return false;
330 
331   n = xmalloc (sizeof *n);
332   memset (n, 0, sizeof *n);
333 
334   n->type = xstrdup (type);
335   n->visibility = DEBUG_VISIBILITY_IGNORE;
336   n->method = NULL;
337   n->next = info->stack;
338   info->stack = n;
339 
340   return true;
341 }
342 
343 /* Prepend a string onto the type on the top of the type stack.  */
344 
345 static bool
prepend_type(struct pr_handle * info,const char * s)346 prepend_type (struct pr_handle *info, const char *s)
347 {
348   char *n;
349 
350   assert (info->stack != NULL);
351 
352   n = xmalloc (strlen (s) + strlen (info->stack->type) + 1);
353   sprintf (n, "%s%s", s, info->stack->type);
354   free (info->stack->type);
355   info->stack->type = n;
356 
357   return true;
358 }
359 
360 /* Append a string to the type on the top of the type stack.  */
361 
362 static bool
append_type(struct pr_handle * info,const char * s)363 append_type (struct pr_handle *info, const char *s)
364 {
365   unsigned int len;
366 
367   if (s == NULL)
368     return false;
369 
370   assert (info->stack != NULL);
371 
372   len = strlen (info->stack->type);
373   info->stack->type = xrealloc (info->stack->type, len + strlen (s) + 1);
374   strcpy (info->stack->type + len, s);
375 
376   return true;
377 }
378 
379 /* Append a string to the parents on the top of the type stack.  */
380 
381 static bool
append_parent(struct pr_handle * info,const char * s)382 append_parent (struct pr_handle *info, const char *s)
383 {
384   unsigned int len;
385 
386   if (s == NULL)
387     return false;
388 
389   assert (info->stack != NULL);
390 
391   len = info->stack->parents ? strlen (info->stack->parents) : 0;
392   info->stack->parents = xrealloc (info->stack->parents, len + strlen (s) + 1);
393   strcpy (info->stack->parents + len, s);
394 
395   return true;
396 }
397 
398 /* We use an underscore to indicate where the name should go in a type
399    string.  This function substitutes a string for the underscore.  If
400    there is no underscore, the name follows the type.  */
401 
402 static bool
substitute_type(struct pr_handle * info,const char * s)403 substitute_type (struct pr_handle *info, const char *s)
404 {
405   char *u;
406 
407   assert (info->stack != NULL);
408 
409   u = strchr (info->stack->type, '|');
410   if (u != NULL)
411     {
412       char *n;
413 
414       n = xmalloc (strlen (info->stack->type) + strlen (s));
415 
416       memcpy (n, info->stack->type, u - info->stack->type);
417       strcpy (n + (u - info->stack->type), s);
418       strcat (n, u + 1);
419 
420       free (info->stack->type);
421       info->stack->type = n;
422 
423       return true;
424     }
425 
426   if (strchr (s, '|') != NULL
427       && (strchr (info->stack->type, '{') != NULL
428 	  || strchr (info->stack->type, '(') != NULL))
429     {
430       if (! prepend_type (info, "(")
431 	  || ! append_type (info, ")"))
432 	return false;
433     }
434 
435   if (*s == '\0')
436     return true;
437 
438   return (append_type (info, " ")
439 	  && append_type (info, s));
440 }
441 
442 /* Indent the type at the top of the stack by appending spaces.  */
443 
444 static bool
indent_type(struct pr_handle * info)445 indent_type (struct pr_handle *info)
446 {
447   unsigned int i;
448 
449   for (i = 0; i < info->indent; i++)
450     {
451       if (! append_type (info, " "))
452 	return false;
453     }
454 
455   return true;
456 }
457 
458 /* Pop a type from the type stack.  */
459 
460 static char *
pop_type(struct pr_handle * info)461 pop_type (struct pr_handle *info)
462 {
463   struct pr_stack *o;
464   char *ret;
465 
466   assert (info->stack != NULL);
467 
468   o = info->stack;
469   info->stack = o->next;
470   ret = o->type;
471   free (o);
472 
473   return ret;
474 }
475 
476 /* Print a VMA value into a string.  */
477 
478 static void
print_vma(bfd_vma vma,char * buf,bool unsignedp,bool hexp)479 print_vma (bfd_vma vma, char *buf, bool unsignedp, bool hexp)
480 {
481   if (hexp)
482     sprintf (buf, "%#" PRIx64, (uint64_t) vma);
483   else if (unsignedp)
484     sprintf (buf, "%" PRIu64, (uint64_t) vma);
485   else
486     sprintf (buf, "%" PRId64, (int64_t) vma);
487 }
488 
489 /* Start a new compilation unit.  */
490 
491 static bool
pr_start_compilation_unit(void * p,const char * filename)492 pr_start_compilation_unit (void *p, const char *filename)
493 {
494   struct pr_handle *info = (struct pr_handle *) p;
495 
496   assert (info->indent == 0);
497 
498   fprintf (info->f, "%s:\n", filename);
499 
500   return true;
501 }
502 
503 /* Start a source file within a compilation unit.  */
504 
505 static bool
pr_start_source(void * p,const char * filename)506 pr_start_source (void *p, const char *filename)
507 {
508   struct pr_handle *info = (struct pr_handle *) p;
509 
510   assert (info->indent == 0);
511 
512   fprintf (info->f, " %s:\n", filename);
513 
514   return true;
515 }
516 
517 /* Push an empty type onto the type stack.  */
518 
519 static bool
pr_empty_type(void * p)520 pr_empty_type (void *p)
521 {
522   struct pr_handle *info = (struct pr_handle *) p;
523 
524   return push_type (info, "<undefined>");
525 }
526 
527 /* Push a void type onto the type stack.  */
528 
529 static bool
pr_void_type(void * p)530 pr_void_type (void *p)
531 {
532   struct pr_handle *info = (struct pr_handle *) p;
533 
534   return push_type (info, "void");
535 }
536 
537 /* Push an integer type onto the type stack.  */
538 
539 static bool
pr_int_type(void * p,unsigned int size,bool unsignedp)540 pr_int_type (void *p, unsigned int size, bool unsignedp)
541 {
542   struct pr_handle *info = (struct pr_handle *) p;
543   char ab[40];
544 
545   sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
546   return push_type (info, ab);
547 }
548 
549 /* Push a floating type onto the type stack.  */
550 
551 static bool
pr_float_type(void * p,unsigned int size)552 pr_float_type (void *p, unsigned int size)
553 {
554   struct pr_handle *info = (struct pr_handle *) p;
555   char ab[40];
556 
557   if (size == 4)
558     return push_type (info, "float");
559   else if (size == 8)
560     return push_type (info, "double");
561 
562   sprintf (ab, "float%d", size * 8);
563   return push_type (info, ab);
564 }
565 
566 /* Push a complex type onto the type stack.  */
567 
568 static bool
pr_complex_type(void * p,unsigned int size)569 pr_complex_type (void *p, unsigned int size)
570 {
571   struct pr_handle *info = (struct pr_handle *) p;
572 
573   if (! pr_float_type (p, size))
574     return false;
575 
576   return prepend_type (info, "complex ");
577 }
578 
579 /* Push a bool type onto the type stack.  */
580 
581 static bool
pr_bool_type(void * p,unsigned int size)582 pr_bool_type (void *p, unsigned int size)
583 {
584   struct pr_handle *info = (struct pr_handle *) p;
585   char ab[40];
586 
587   sprintf (ab, "bool%d", size * 8);
588 
589   return push_type (info, ab);
590 }
591 
592 /* Push an enum type onto the type stack.  */
593 
594 static bool
pr_enum_type(void * p,const char * tag,const char ** names,bfd_signed_vma * values)595 pr_enum_type (void *p, const char *tag, const char **names,
596 	      bfd_signed_vma *values)
597 {
598   struct pr_handle *info = (struct pr_handle *) p;
599   unsigned int i;
600   bfd_signed_vma val;
601 
602   if (! push_type (info, "enum "))
603     return false;
604   if (tag != NULL)
605     {
606       if (! append_type (info, tag)
607 	  || ! append_type (info, " "))
608 	return false;
609     }
610   if (! append_type (info, "{ "))
611     return false;
612 
613   if (names == NULL)
614     {
615       if (! append_type (info, "/* undefined */"))
616 	return false;
617     }
618   else
619     {
620       val = 0;
621       for (i = 0; names[i] != NULL; i++)
622 	{
623 	  if (i > 0)
624 	    {
625 	      if (! append_type (info, ", "))
626 		return false;
627 	    }
628 
629 	  if (! append_type (info, names[i]))
630 	    return false;
631 
632 	  if (values[i] != val)
633 	    {
634 	      char ab[22];
635 
636 	      print_vma (values[i], ab, false, false);
637 	      if (! append_type (info, " = ")
638 		  || ! append_type (info, ab))
639 		return false;
640 	      val = values[i];
641 	    }
642 
643 	  ++val;
644 	}
645     }
646 
647   return append_type (info, " }");
648 }
649 
650 /* Turn the top type on the stack into a pointer.  */
651 
652 static bool
pr_pointer_type(void * p)653 pr_pointer_type (void *p)
654 {
655   struct pr_handle *info = (struct pr_handle *) p;
656   char *s;
657 
658   assert (info->stack != NULL);
659 
660   s = strchr (info->stack->type, '|');
661   if (s != NULL && s[1] == '[')
662     return substitute_type (info, "(*|)");
663   return substitute_type (info, "*|");
664 }
665 
666 /* Turn the top type on the stack into a function returning that type.  */
667 
668 static bool
pr_function_type(void * p,int argcount,bool varargs)669 pr_function_type (void *p, int argcount, bool varargs)
670 {
671   struct pr_handle *info = (struct pr_handle *) p;
672   char **arg_types;
673   unsigned int len;
674   char *s;
675 
676   assert (info->stack != NULL);
677 
678   len = 10;
679 
680   if (argcount <= 0)
681     {
682       arg_types = NULL;
683       len += 15;
684     }
685   else
686     {
687       int i;
688 
689       arg_types = xmalloc (argcount * sizeof (*arg_types));
690       for (i = argcount - 1; i >= 0; i--)
691 	{
692 	  if (!substitute_type (info, "")
693 	      || (arg_types[i] = pop_type (info)) == NULL)
694 	    {
695 	      for (int j = i + 1; j < argcount; j++)
696 		free (arg_types[j]);
697 	      free (arg_types);
698 	      return false;
699 	    }
700 	  len += strlen (arg_types[i]) + 2;
701 	}
702       if (varargs)
703 	len += 5;
704     }
705 
706   /* Now the return type is on the top of the stack.  */
707 
708   s = xmalloc (len);
709   strcpy (s, "(|) (");
710 
711   if (argcount < 0)
712     strcat (s, "/* unknown */");
713   else
714     {
715       int i;
716 
717       for (i = 0; i < argcount; i++)
718 	{
719 	  if (i > 0)
720 	    strcat (s, ", ");
721 	  strcat (s, arg_types[i]);
722 	  free (arg_types[i]);
723 	}
724       if (varargs)
725 	{
726 	  if (i > 0)
727 	    strcat (s, ", ");
728 	  strcat (s, "...");
729 	}
730       free (arg_types);
731     }
732 
733   strcat (s, ")");
734 
735   bool ret = substitute_type (info, s);
736   free (s);
737   return ret;
738 }
739 
740 /* Turn the top type on the stack into a reference to that type.  */
741 
742 static bool
pr_reference_type(void * p)743 pr_reference_type (void *p)
744 {
745   struct pr_handle *info = (struct pr_handle *) p;
746 
747   assert (info->stack != NULL);
748 
749   return substitute_type (info, "&|");
750 }
751 
752 /* Make a range type.  */
753 
754 static bool
pr_range_type(void * p,bfd_signed_vma lower,bfd_signed_vma upper)755 pr_range_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper)
756 {
757   struct pr_handle *info = (struct pr_handle *) p;
758   char abl[22], abu[22];
759 
760   assert (info->stack != NULL);
761 
762   if (! substitute_type (info, ""))
763     return false;
764 
765   print_vma (lower, abl, false, false);
766   print_vma (upper, abu, false, false);
767 
768   return (prepend_type (info, "range (")
769 	  && append_type (info, "):")
770 	  && append_type (info, abl)
771 	  && append_type (info, ":")
772 	  && append_type (info, abu));
773 }
774 
775 /* Make an array type.  */
776 
777 static bool
pr_array_type(void * p,bfd_signed_vma lower,bfd_signed_vma upper,bool stringp)778 pr_array_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper,
779 	       bool stringp)
780 {
781   struct pr_handle *info = (struct pr_handle *) p;
782   char *range_type;
783   char abl[22], abu[22], ab[50];
784 
785   range_type = pop_type (info);
786   if (range_type == NULL)
787     return false;
788 
789   if (lower == 0)
790     {
791       if (upper == -1)
792 	sprintf (ab, "|[]");
793       else
794 	{
795 	  print_vma (upper + 1, abu, false, false);
796 	  sprintf (ab, "|[%s]", abu);
797 	}
798     }
799   else
800     {
801       print_vma (lower, abl, false, false);
802       print_vma (upper, abu, false, false);
803       sprintf (ab, "|[%s:%s]", abl, abu);
804     }
805 
806   if (! substitute_type (info, ab))
807     goto fail;
808 
809   if (strcmp (range_type, "int") != 0)
810     {
811       if (! append_type (info, ":")
812 	  || ! append_type (info, range_type))
813 	goto fail;
814     }
815 
816   if (stringp)
817     {
818       if (! append_type (info, " /* string */"))
819 	goto fail;
820     }
821 
822   free (range_type);
823   return true;
824 
825  fail:
826   free (range_type);
827   return false;
828 }
829 
830 /* Make a set type.  */
831 
832 static bool
pr_set_type(void * p,bool bitstringp)833 pr_set_type (void *p, bool bitstringp)
834 {
835   struct pr_handle *info = (struct pr_handle *) p;
836 
837   if (! substitute_type (info, ""))
838     return false;
839 
840   if (! prepend_type (info, "set { ")
841       || ! append_type (info, " }"))
842     return false;
843 
844   if (bitstringp)
845     {
846       if (! append_type (info, "/* bitstring */"))
847 	return false;
848     }
849 
850   return true;
851 }
852 
853 /* Make an offset type.  */
854 
855 static bool
pr_offset_type(void * p)856 pr_offset_type (void *p)
857 {
858   struct pr_handle *info = (struct pr_handle *) p;
859   char *t;
860 
861   if (! substitute_type (info, ""))
862     return false;
863 
864   t = pop_type (info);
865   if (t == NULL)
866     return false;
867 
868   bool ret = (substitute_type (info, "")
869 	      && prepend_type (info, " ")
870 	      && prepend_type (info, t)
871 	      && append_type (info, "::|"));
872   free (t);
873   return ret;
874 }
875 
876 /* Make a method type.  */
877 
878 static bool
pr_method_type(void * p,bool domain,int argcount,bool varargs)879 pr_method_type (void *p, bool domain, int argcount, bool varargs)
880 {
881   struct pr_handle *info = (struct pr_handle *) p;
882   unsigned int len;
883   char *domain_type = NULL, *free_domain = NULL;
884   char **arg_types;
885   char *s;
886 
887   len = 10;
888 
889   if (domain)
890     {
891       if (! substitute_type (info, ""))
892 	return false;
893       domain_type = pop_type (info);
894       if (domain_type == NULL)
895 	return false;
896       free_domain = domain_type;
897       if (startswith (domain_type, "class ")
898 	  && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
899 	domain_type += sizeof "class " - 1;
900       else if (startswith (domain_type, "union class ")
901 	       && (strchr (domain_type + sizeof "union class " - 1, ' ')
902 		   == NULL))
903 	domain_type += sizeof "union class " - 1;
904       len += strlen (domain_type);
905     }
906 
907   if (argcount <= 0)
908     {
909       arg_types = NULL;
910       len += 15;
911     }
912   else
913     {
914       int i;
915 
916       arg_types = xmalloc (argcount * sizeof (*arg_types));
917       for (i = argcount - 1; i >= 0; i--)
918 	{
919 	  if (!substitute_type (info, "")
920 	      || (arg_types[i] = pop_type (info)) == NULL)
921 	    {
922 	      for (int j = i + 1; j < argcount; ++j)
923 		free (arg_types[j]);
924 	      free (arg_types);
925 	      return false;
926 	    }
927 	  len += strlen (arg_types[i]) + 2;
928 	}
929       if (varargs)
930 	len += 5;
931     }
932 
933   /* Now the return type is on the top of the stack.  */
934 
935   s = xmalloc (len);
936   *s = 0;
937   if (domain)
938     {
939       strcpy (s, domain_type);
940       free (free_domain);
941     }
942   strcat (s, "::| (");
943 
944   if (argcount < 0)
945     strcat (s, "/* unknown */");
946   else
947     {
948       int i;
949 
950       for (i = 0; i < argcount; i++)
951 	{
952 	  if (i > 0)
953 	    strcat (s, ", ");
954 	  strcat (s, arg_types[i]);
955 	  free (arg_types[i]);
956 	}
957       if (varargs)
958 	{
959 	  if (i > 0)
960 	    strcat (s, ", ");
961 	  strcat (s, "...");
962 	}
963       free (arg_types);
964     }
965 
966   strcat (s, ")");
967 
968   bool ret = substitute_type (info, s);
969   free (s);
970   return ret;
971 }
972 
973 /* Make a const qualified type.  */
974 
975 static bool
pr_const_type(void * p)976 pr_const_type (void *p)
977 {
978   struct pr_handle *info = (struct pr_handle *) p;
979 
980   return substitute_type (info, "const |");
981 }
982 
983 /* Make a volatile qualified type.  */
984 
985 static bool
pr_volatile_type(void * p)986 pr_volatile_type (void *p)
987 {
988   struct pr_handle *info = (struct pr_handle *) p;
989 
990   return substitute_type (info, "volatile |");
991 }
992 
993 /* Start accumulating a struct type.  */
994 
995 static bool
pr_start_struct_type(void * p,const char * tag,unsigned int id,bool structp,unsigned int size)996 pr_start_struct_type (void *p, const char *tag, unsigned int id,
997 		      bool structp, unsigned int size)
998 {
999   struct pr_handle *info = (struct pr_handle *) p;
1000 
1001   info->indent += 2;
1002 
1003   if (! push_type (info, structp ? "struct " : "union "))
1004     return false;
1005   if (tag != NULL)
1006     {
1007       if (! append_type (info, tag))
1008 	return false;
1009     }
1010   else
1011     {
1012       char idbuf[20];
1013 
1014       sprintf (idbuf, "%%anon%u", id);
1015       if (! append_type (info, idbuf))
1016 	return false;
1017     }
1018 
1019   if (! append_type (info, " {"))
1020     return false;
1021   if (size != 0 || tag != NULL)
1022     {
1023       char ab[30];
1024 
1025       if (! append_type (info, " /*"))
1026 	return false;
1027 
1028       if (size != 0)
1029 	{
1030 	  sprintf (ab, " size %u", size);
1031 	  if (! append_type (info, ab))
1032 	    return false;
1033 	}
1034       if (tag != NULL)
1035 	{
1036 	  sprintf (ab, " id %u", id);
1037 	  if (! append_type (info, ab))
1038 	    return false;
1039 	}
1040       if (! append_type (info, " */"))
1041 	return false;
1042     }
1043   if (! append_type (info, "\n"))
1044     return false;
1045 
1046   info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
1047 
1048   return indent_type (info);
1049 }
1050 
1051 /* Output the visibility of a field in a struct.  */
1052 
1053 static bool
pr_fix_visibility(struct pr_handle * info,enum debug_visibility visibility)1054 pr_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
1055 {
1056   const char *s = NULL;
1057   char *t;
1058   unsigned int len;
1059 
1060   assert (info->stack != NULL);
1061 
1062   if (info->stack->visibility == visibility)
1063     return true;
1064 
1065   switch (visibility)
1066     {
1067     case DEBUG_VISIBILITY_PUBLIC:
1068       s = "public";
1069       break;
1070     case DEBUG_VISIBILITY_PRIVATE:
1071       s = "private";
1072       break;
1073     case DEBUG_VISIBILITY_PROTECTED:
1074       s = "protected";
1075       break;
1076     case DEBUG_VISIBILITY_IGNORE:
1077       s = "/* ignore */";
1078       break;
1079     default:
1080       abort ();
1081       return false;
1082     }
1083 
1084   /* Trim off a trailing space in the struct string, to make the
1085      output look a bit better, then stick on the visibility string.  */
1086 
1087   t = info->stack->type;
1088   len = strlen (t);
1089   assert (t[len - 1] == ' ');
1090   t[len - 1] = '\0';
1091 
1092   if (! append_type (info, s)
1093       || ! append_type (info, ":\n")
1094       || ! indent_type (info))
1095     return false;
1096 
1097   info->stack->visibility = visibility;
1098 
1099   return true;
1100 }
1101 
1102 /* Add a field to a struct type.  */
1103 
1104 static bool
pr_struct_field(void * p,const char * name,bfd_vma bitpos,bfd_vma bitsize,enum debug_visibility visibility)1105 pr_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize,
1106 		 enum debug_visibility visibility)
1107 {
1108   struct pr_handle *info = (struct pr_handle *) p;
1109   char ab[22];
1110   char *t;
1111 
1112   if (! substitute_type (info, name))
1113     return false;
1114 
1115   if (! append_type (info, "; /* "))
1116     return false;
1117 
1118   if (bitsize != 0)
1119     {
1120       print_vma (bitsize, ab, true, false);
1121       if (! append_type (info, "bitsize ")
1122 	  || ! append_type (info, ab)
1123 	  || ! append_type (info, ", "))
1124 	return false;
1125     }
1126 
1127   print_vma (bitpos, ab, true, false);
1128   if (! append_type (info, "bitpos ")
1129       || ! append_type (info, ab)
1130       || ! append_type (info, " */\n")
1131       || ! indent_type (info))
1132     return false;
1133 
1134   t = pop_type (info);
1135   if (t == NULL)
1136     return false;
1137 
1138   bool ret = pr_fix_visibility (info, visibility) && append_type (info, t);
1139   free (t);
1140   return ret;
1141 }
1142 
1143 /* Finish a struct type.  */
1144 
1145 static bool
pr_end_struct_type(void * p)1146 pr_end_struct_type (void *p)
1147 {
1148   struct pr_handle *info = (struct pr_handle *) p;
1149   char *s;
1150 
1151   assert (info->stack != NULL);
1152   assert (info->indent >= 2);
1153 
1154   info->indent -= 2;
1155 
1156   /* Change the trailing indentation to have a close brace.  */
1157   s = info->stack->type + strlen (info->stack->type) - 2;
1158   assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
1159 
1160   *s++ = '}';
1161   *s = '\0';
1162 
1163   return true;
1164 }
1165 
1166 /* Start a class type.  */
1167 
1168 static bool
pr_start_class_type(void * p,const char * tag,unsigned int id,bool structp,unsigned int size,bool vptr,bool ownvptr)1169 pr_start_class_type (void *p, const char *tag, unsigned int id,
1170 		     bool structp, unsigned int size,
1171 		     bool vptr, bool ownvptr)
1172 {
1173   struct pr_handle *info = (struct pr_handle *) p;
1174   char *tv = NULL;
1175   bool ret = false;
1176 
1177   info->indent += 2;
1178 
1179   if (vptr && ! ownvptr)
1180     {
1181       tv = pop_type (info);
1182       if (tv == NULL)
1183 	return false;
1184     }
1185 
1186   if (! push_type (info, structp ? "class " : "union class "))
1187     goto out;
1188   if (tag != NULL)
1189     {
1190       if (! append_type (info, tag))
1191 	goto out;
1192     }
1193   else
1194     {
1195       char idbuf[20];
1196 
1197       sprintf (idbuf, "%%anon%u", id);
1198       if (! append_type (info, idbuf))
1199 	goto out;
1200     }
1201 
1202   if (! append_type (info, " {"))
1203     goto out;
1204   if (size != 0 || vptr || ownvptr || tag != NULL)
1205     {
1206       if (! append_type (info, " /*"))
1207 	goto out;
1208 
1209       if (size != 0)
1210 	{
1211 	  char ab[20];
1212 
1213 	  sprintf (ab, "%u", size);
1214 	  if (! append_type (info, " size ")
1215 	      || ! append_type (info, ab))
1216 	    goto out;
1217 	}
1218 
1219       if (vptr)
1220 	{
1221 	  if (! append_type (info, " vtable "))
1222 	    goto out;
1223 	  if (ownvptr)
1224 	    {
1225 	      if (! append_type (info, "self "))
1226 		goto out;
1227 	    }
1228 	  else
1229 	    {
1230 	      if (! append_type (info, tv)
1231 		  || ! append_type (info, " "))
1232 		goto out;
1233 	    }
1234 	}
1235 
1236       if (tag != NULL)
1237 	{
1238 	  char ab[30];
1239 
1240 	  sprintf (ab, " id %u", id);
1241 	  if (! append_type (info, ab))
1242 	    goto out;
1243 	}
1244 
1245       if (! append_type (info, " */"))
1246 	goto out;
1247     }
1248 
1249   info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
1250 
1251   ret = append_type (info, "\n") && indent_type (info);
1252  out:
1253   free (tv);
1254   return ret;
1255 }
1256 
1257 /* Add a static member to a class.  */
1258 
1259 static bool
pr_class_static_member(void * p,const char * name,const char * physname,enum debug_visibility visibility)1260 pr_class_static_member (void *p, const char *name, const char *physname,
1261 			enum debug_visibility visibility)
1262 {
1263   struct pr_handle *info = (struct pr_handle *) p;
1264   char *t;
1265 
1266   if (! substitute_type (info, name))
1267     return false;
1268 
1269   if (! prepend_type (info, "static ")
1270       || ! append_type (info, "; /* ")
1271       || ! append_type (info, physname)
1272       || ! append_type (info, " */\n")
1273       || ! indent_type (info))
1274     return false;
1275 
1276   t = pop_type (info);
1277   if (t == NULL)
1278     return false;
1279 
1280   bool ret = pr_fix_visibility (info, visibility) && append_type (info, t);
1281   free (t);
1282   return ret;
1283 }
1284 
1285 /* Add a base class to a class.  */
1286 
1287 static bool
pr_class_baseclass(void * p,bfd_vma bitpos,bool is_virtual,enum debug_visibility visibility)1288 pr_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual,
1289 		    enum debug_visibility visibility)
1290 {
1291   struct pr_handle *info = (struct pr_handle *) p;
1292   char *t;
1293   const char *prefix;
1294   char ab[22];
1295   char *s, *l, *n;
1296 
1297   assert (info->stack != NULL && info->stack->next != NULL);
1298 
1299   if (! substitute_type (info, ""))
1300     return false;
1301 
1302   t = pop_type (info);
1303   if (t == NULL)
1304     return false;
1305 
1306   /* Push it back on to take advantage of the prepend_type and
1307      append_type routines.  */
1308   if (! push_type (info, t + (startswith (t, "class ")
1309 			      ? sizeof "class " - 1 : 0)))
1310     {
1311       free (t);
1312       return false;
1313     }
1314   free (t);
1315 
1316   if (is_virtual)
1317     {
1318       if (! prepend_type (info, "virtual "))
1319 	return false;
1320     }
1321 
1322   switch (visibility)
1323     {
1324     case DEBUG_VISIBILITY_PUBLIC:
1325       prefix = "public ";
1326       break;
1327     case DEBUG_VISIBILITY_PROTECTED:
1328       prefix = "protected ";
1329       break;
1330     case DEBUG_VISIBILITY_PRIVATE:
1331       prefix = "private ";
1332       break;
1333     default:
1334       prefix = "/* unknown visibility */ ";
1335       break;
1336     }
1337 
1338   if (! prepend_type (info, prefix))
1339     return false;
1340 
1341   if (bitpos != 0)
1342     {
1343       print_vma (bitpos, ab, true, false);
1344       if (! append_type (info, " /* bitpos ")
1345 	  || ! append_type (info, ab)
1346 	  || ! append_type (info, " */"))
1347 	return false;
1348     }
1349 
1350   /* Now the top of the stack is something like "public A / * bitpos
1351      10 * /".  The next element on the stack is something like "class
1352      xx { / * size 8 * /\n...".  We want to substitute the top of the
1353      stack in before the {.  */
1354   s = strchr (info->stack->next->type, '{');
1355   assert (s != NULL);
1356   --s;
1357 
1358   /* If there is already a ':', then we already have a baseclass, and
1359      we must append this one after a comma.  */
1360   for (l = info->stack->next->type; l != s; l++)
1361     if (*l == ':')
1362       break;
1363   if (! prepend_type (info, l == s ? " : " : ", "))
1364     return false;
1365 
1366   t = pop_type (info);
1367   if (t == NULL)
1368     return false;
1369 
1370   n = xmalloc (strlen (info->stack->type) + strlen (t) + 1);
1371   memcpy (n, info->stack->type, s - info->stack->type);
1372   strcpy (n + (s - info->stack->type), t);
1373   strcat (n, s);
1374 
1375   free (info->stack->type);
1376   info->stack->type = n;
1377 
1378   free (t);
1379 
1380   return true;
1381 }
1382 
1383 /* Start adding a method to a class.  */
1384 
1385 static bool
pr_class_start_method(void * p,const char * name)1386 pr_class_start_method (void *p, const char *name)
1387 {
1388   struct pr_handle *info = (struct pr_handle *) p;
1389 
1390   assert (info->stack != NULL);
1391   free (info->stack->method);
1392   info->stack->method = xstrdup (name);
1393   return true;
1394 }
1395 
1396 /* Add a variant to a method.  */
1397 
1398 static bool
pr_class_method_variant(void * p,const char * physname,enum debug_visibility visibility,bool constp,bool volatilep,bfd_vma voffset,bool context)1399 pr_class_method_variant (void *p, const char *physname,
1400 			 enum debug_visibility visibility,
1401 			 bool constp, bool volatilep,
1402 			 bfd_vma voffset, bool context)
1403 {
1404   struct pr_handle *info = (struct pr_handle *) p;
1405   char *method_type;
1406   char *context_type;
1407   bool ret = false;
1408 
1409   assert (info->stack != NULL);
1410   assert (info->stack->next != NULL);
1411 
1412   /* Put the const and volatile qualifiers on the type.  */
1413   if (volatilep)
1414     {
1415       if (! append_type (info, " volatile"))
1416 	return false;
1417     }
1418   if (constp)
1419     {
1420       if (! append_type (info, " const"))
1421 	return false;
1422     }
1423 
1424   /* Stick the name of the method into its type.  */
1425   if (! substitute_type (info,
1426 			 (context
1427 			  ? info->stack->next->next->method
1428 			  : info->stack->next->method)))
1429     return false;
1430 
1431   /* Get the type.  */
1432   method_type = pop_type (info);
1433   if (method_type == NULL)
1434     return false;
1435 
1436   /* Pull off the context type if there is one.  */
1437   if (! context)
1438     context_type = NULL;
1439   else
1440     {
1441       context_type = pop_type (info);
1442       if (context_type == NULL)
1443 	goto out;
1444     }
1445 
1446   /* Now the top of the stack is the class.  */
1447 
1448   if (! pr_fix_visibility (info, visibility))
1449     goto out;
1450 
1451   if (! append_type (info, method_type)
1452       || ! append_type (info, " /* ")
1453       || ! append_type (info, physname)
1454       || ! append_type (info, " "))
1455     goto out;
1456   if (context || voffset != 0)
1457     {
1458       char ab[22];
1459 
1460       if (context)
1461 	{
1462 	  if (! append_type (info, "context ")
1463 	      || ! append_type (info, context_type)
1464 	      || ! append_type (info, " "))
1465 	    goto out;
1466 	}
1467       print_vma (voffset, ab, true, false);
1468       if (! append_type (info, "voffset ")
1469 	  || ! append_type (info, ab))
1470 	goto out;
1471     }
1472 
1473   ret = append_type (info, " */;\n") && indent_type (info);
1474  out:
1475   free (method_type);
1476   free (context_type);
1477   return ret;
1478 }
1479 
1480 /* Add a static variant to a method.  */
1481 
1482 static bool
pr_class_static_method_variant(void * p,const char * physname,enum debug_visibility visibility,bool constp,bool volatilep)1483 pr_class_static_method_variant (void *p, const char *physname,
1484 				enum debug_visibility visibility,
1485 				bool constp, bool volatilep)
1486 {
1487   struct pr_handle *info = (struct pr_handle *) p;
1488   char *method_type;
1489 
1490   assert (info->stack != NULL);
1491   assert (info->stack->next != NULL);
1492   assert (info->stack->next->method != NULL);
1493 
1494   /* Put the const and volatile qualifiers on the type.  */
1495   if (volatilep)
1496     {
1497       if (! append_type (info, " volatile"))
1498 	return false;
1499     }
1500   if (constp)
1501     {
1502       if (! append_type (info, " const"))
1503 	return false;
1504     }
1505 
1506   /* Mark it as static.  */
1507   if (! prepend_type (info, "static "))
1508     return false;
1509 
1510   /* Stick the name of the method into its type.  */
1511   if (! substitute_type (info, info->stack->next->method))
1512     return false;
1513 
1514   /* Get the type.  */
1515   method_type = pop_type (info);
1516   if (method_type == NULL)
1517     return false;
1518 
1519   /* Now the top of the stack is the class.  */
1520 
1521   bool ret = (pr_fix_visibility (info, visibility)
1522 	      && append_type (info, method_type)
1523 	      && append_type (info, " /* ")
1524 	      && append_type (info, physname)
1525 	      && append_type (info, " */;\n")
1526 	      && indent_type (info));
1527   free (method_type);
1528   return ret;
1529 }
1530 
1531 /* Finish up a method.  */
1532 
1533 static bool
pr_class_end_method(void * p)1534 pr_class_end_method (void *p)
1535 {
1536   struct pr_handle *info = (struct pr_handle *) p;
1537 
1538   free (info->stack->method);
1539   info->stack->method = NULL;
1540   return true;
1541 }
1542 
1543 /* Finish up a class.  */
1544 
1545 static bool
pr_end_class_type(void * p)1546 pr_end_class_type (void *p)
1547 {
1548   return pr_end_struct_type (p);
1549 }
1550 
1551 /* Push a type on the stack using a typedef name.  */
1552 
1553 static bool
pr_typedef_type(void * p,const char * name)1554 pr_typedef_type (void *p, const char *name)
1555 {
1556   struct pr_handle *info = (struct pr_handle *) p;
1557 
1558   return push_type (info, name);
1559 }
1560 
1561 /* Push a type on the stack using a tag name.  */
1562 
1563 static bool
pr_tag_type(void * p,const char * name,unsigned int id,enum debug_type_kind kind)1564 pr_tag_type (void *p, const char *name, unsigned int id,
1565 	     enum debug_type_kind kind)
1566 {
1567   struct pr_handle *info = (struct pr_handle *) p;
1568   const char *t, *tag;
1569   char idbuf[22];
1570 
1571   switch (kind)
1572     {
1573     case DEBUG_KIND_STRUCT:
1574       t = "struct ";
1575       break;
1576     case DEBUG_KIND_UNION:
1577       t = "union ";
1578       break;
1579     case DEBUG_KIND_ENUM:
1580       t = "enum ";
1581       break;
1582     case DEBUG_KIND_CLASS:
1583       t = "class ";
1584       break;
1585     case DEBUG_KIND_UNION_CLASS:
1586       t = "union class ";
1587       break;
1588     default:
1589       /* PR 25625: Corrupt input can trigger this case.  */
1590       return false;
1591     }
1592 
1593   if (! push_type (info, t))
1594     return false;
1595   if (name != NULL)
1596     tag = name;
1597   else
1598     {
1599       sprintf (idbuf, "%%anon%u", id);
1600       tag = idbuf;
1601     }
1602 
1603   if (! append_type (info, tag))
1604     return false;
1605   if (name != NULL && kind != DEBUG_KIND_ENUM)
1606     {
1607       sprintf (idbuf, " /* id %u */", id);
1608       if (! append_type (info, idbuf))
1609 	return false;
1610     }
1611 
1612   return true;
1613 }
1614 
1615 /* Output a typedef.  */
1616 
1617 static bool
pr_typdef(void * p,const char * name)1618 pr_typdef (void *p, const char *name)
1619 {
1620   struct pr_handle *info = (struct pr_handle *) p;
1621   char *s;
1622 
1623   if (! substitute_type (info, name))
1624     return false;
1625 
1626   s = pop_type (info);
1627   if (s == NULL)
1628     return false;
1629 
1630   indent (info);
1631   fprintf (info->f, "typedef %s;\n", s);
1632 
1633   free (s);
1634 
1635   return true;
1636 }
1637 
1638 /* Output a tag.  The tag should already be in the string on the
1639    stack, so all we have to do here is print it out.  */
1640 
1641 static bool
pr_tag(void * p,const char * name ATTRIBUTE_UNUSED)1642 pr_tag (void *p, const char *name ATTRIBUTE_UNUSED)
1643 {
1644   struct pr_handle *info = (struct pr_handle *) p;
1645   char *t;
1646 
1647   t = pop_type (info);
1648   if (t == NULL)
1649     return false;
1650 
1651   indent (info);
1652   fprintf (info->f, "%s;\n", t);
1653 
1654   free (t);
1655 
1656   return true;
1657 }
1658 
1659 /* Output an integer constant.  */
1660 
1661 static bool
pr_int_constant(void * p,const char * name,bfd_vma val)1662 pr_int_constant (void *p, const char *name, bfd_vma val)
1663 {
1664   struct pr_handle *info = (struct pr_handle *) p;
1665   char ab[22];
1666 
1667   indent (info);
1668   print_vma (val, ab, false, false);
1669   fprintf (info->f, "const int %s = %s;\n", name, ab);
1670   return true;
1671 }
1672 
1673 /* Output a floating point constant.  */
1674 
1675 static bool
pr_float_constant(void * p,const char * name,double val)1676 pr_float_constant (void *p, const char *name, double val)
1677 {
1678   struct pr_handle *info = (struct pr_handle *) p;
1679 
1680   indent (info);
1681   fprintf (info->f, "const double %s = %g;\n", name, val);
1682   return true;
1683 }
1684 
1685 /* Output a typed constant.  */
1686 
1687 static bool
pr_typed_constant(void * p,const char * name,bfd_vma val)1688 pr_typed_constant (void *p, const char *name, bfd_vma val)
1689 {
1690   struct pr_handle *info = (struct pr_handle *) p;
1691   char *t;
1692   char ab[22];
1693 
1694   t = pop_type (info);
1695   if (t == NULL)
1696     return false;
1697 
1698   indent (info);
1699   print_vma (val, ab, false, false);
1700   fprintf (info->f, "const %s %s = %s;\n", t, name, ab);
1701 
1702   free (t);
1703 
1704   return true;
1705 }
1706 
1707 /* Output a variable.  */
1708 
1709 static bool
pr_variable(void * p,const char * name,enum debug_var_kind kind,bfd_vma val)1710 pr_variable (void *p, const char *name, enum debug_var_kind kind,
1711 	     bfd_vma val)
1712 {
1713   struct pr_handle *info = (struct pr_handle *) p;
1714   char *t;
1715   char ab[22];
1716 
1717   if (! substitute_type (info, name))
1718     return false;
1719 
1720   t = pop_type (info);
1721   if (t == NULL)
1722     return false;
1723 
1724   indent (info);
1725   switch (kind)
1726     {
1727     case DEBUG_STATIC:
1728     case DEBUG_LOCAL_STATIC:
1729       fprintf (info->f, "static ");
1730       break;
1731     case DEBUG_REGISTER:
1732       fprintf (info->f, "register ");
1733       break;
1734     default:
1735       break;
1736     }
1737   print_vma (val, ab, true, true);
1738   fprintf (info->f, "%s /* %s */;\n", t, ab);
1739 
1740   free (t);
1741 
1742   return true;
1743 }
1744 
1745 /* Start outputting a function.  */
1746 
1747 static bool
pr_start_function(void * p,const char * name,bool global)1748 pr_start_function (void *p, const char *name, bool global)
1749 {
1750   struct pr_handle *info = (struct pr_handle *) p;
1751   char *t;
1752 
1753   if (! substitute_type (info, name))
1754     return false;
1755 
1756   t = pop_type (info);
1757   if (t == NULL)
1758     return false;
1759 
1760   indent (info);
1761   if (! global)
1762     fprintf (info->f, "static ");
1763   fprintf (info->f, "%s (", t);
1764 
1765   free (t);
1766 
1767   info->parameter = 1;
1768 
1769   return true;
1770 }
1771 
1772 /* Output a function parameter.  */
1773 
1774 static bool
pr_function_parameter(void * p,const char * name,enum debug_parm_kind kind,bfd_vma val)1775 pr_function_parameter (void *p, const char *name,
1776 		       enum debug_parm_kind kind, bfd_vma val)
1777 {
1778   struct pr_handle *info = (struct pr_handle *) p;
1779   char *t;
1780   char ab[22];
1781 
1782   if (kind == DEBUG_PARM_REFERENCE
1783       || kind == DEBUG_PARM_REF_REG)
1784     {
1785       if (! pr_reference_type (p))
1786 	return false;
1787     }
1788 
1789   if (! substitute_type (info, name))
1790     return false;
1791 
1792   t = pop_type (info);
1793   if (t == NULL)
1794     return false;
1795 
1796   if (info->parameter != 1)
1797     fprintf (info->f, ", ");
1798 
1799   if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
1800     fprintf (info->f, "register ");
1801 
1802   print_vma (val, ab, true, true);
1803   fprintf (info->f, "%s /* %s */", t, ab);
1804 
1805   free (t);
1806 
1807   ++info->parameter;
1808 
1809   return true;
1810 }
1811 
1812 /* Start writing out a block.  */
1813 
1814 static bool
pr_start_block(void * p,bfd_vma addr)1815 pr_start_block (void *p, bfd_vma addr)
1816 {
1817   struct pr_handle *info = (struct pr_handle *) p;
1818   char ab[22];
1819 
1820   if (info->parameter > 0)
1821     {
1822       fprintf (info->f, ")\n");
1823       info->parameter = 0;
1824     }
1825 
1826   indent (info);
1827   print_vma (addr, ab, true, true);
1828   fprintf (info->f, "{ /* %s */\n", ab);
1829 
1830   info->indent += 2;
1831 
1832   return true;
1833 }
1834 
1835 /* Write out line number information.  */
1836 
1837 static bool
pr_lineno(void * p,const char * filename,unsigned long lineno,bfd_vma addr)1838 pr_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr)
1839 {
1840   struct pr_handle *info = (struct pr_handle *) p;
1841   char ab[22];
1842 
1843   indent (info);
1844   print_vma (addr, ab, true, true);
1845   fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab);
1846 
1847   return true;
1848 }
1849 
1850 /* Finish writing out a block.  */
1851 
1852 static bool
pr_end_block(void * p,bfd_vma addr)1853 pr_end_block (void *p, bfd_vma addr)
1854 {
1855   struct pr_handle *info = (struct pr_handle *) p;
1856   char ab[22];
1857 
1858   info->indent -= 2;
1859 
1860   indent (info);
1861   print_vma (addr, ab, true, true);
1862   fprintf (info->f, "} /* %s */\n", ab);
1863 
1864   return true;
1865 }
1866 
1867 /* Finish writing out a function.  */
1868 
1869 static bool
pr_end_function(void * p ATTRIBUTE_UNUSED)1870 pr_end_function (void *p ATTRIBUTE_UNUSED)
1871 {
1872   return true;
1873 }
1874 
1875 /* Tags style generation functions start here.  */
1876 
1877 /* Variables for address to line translation.  */
1878 static bfd_vma pc;
1879 static const char *filename;
1880 static const char *functionname;
1881 static unsigned int line;
1882 static bool found;
1883 
1884 /* Look for an address in a section.  This is called via
1885    bfd_map_over_sections.  */
1886 
1887 static void
find_address_in_section(bfd * abfd,asection * section,void * data)1888 find_address_in_section (bfd *abfd, asection *section, void *data)
1889 {
1890   bfd_vma vma;
1891   bfd_size_type size;
1892   asymbol **syms = (asymbol **) data;
1893 
1894   if (found)
1895     return;
1896 
1897   if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
1898     return;
1899 
1900   vma = bfd_section_vma (section);
1901   if (pc < vma)
1902     return;
1903 
1904   size = bfd_section_size (section);
1905   if (pc >= vma + size)
1906     return;
1907 
1908   found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
1909 				 &filename, &functionname, &line);
1910 }
1911 
1912 static void
translate_addresses(bfd * abfd,char * addr_hex,FILE * f,asymbol ** syms)1913 translate_addresses (bfd *abfd, char *addr_hex, FILE *f, asymbol **syms)
1914 {
1915   pc = bfd_scan_vma (addr_hex, NULL, 16);
1916   found = false;
1917   bfd_map_over_sections (abfd, find_address_in_section, syms);
1918 
1919   if (! found)
1920     fprintf (f, "??");
1921   else
1922     fprintf (f, "%u", line);
1923 }
1924 
1925 /* Start a new compilation unit.  */
1926 
1927 static bool
tg_start_compilation_unit(void * p,const char * fname ATTRIBUTE_UNUSED)1928 tg_start_compilation_unit (void * p, const char *fname ATTRIBUTE_UNUSED)
1929 {
1930   struct pr_handle *info = (struct pr_handle *) p;
1931 
1932   free (info->filename);
1933   /* Should it be relative? best way to do it here?.  */
1934   info->filename = xstrdup (fname);
1935 
1936   return true;
1937 }
1938 
1939 /* Start a source file within a compilation unit.  */
1940 
1941 static bool
tg_start_source(void * p,const char * fname)1942 tg_start_source (void *p, const char *fname)
1943 {
1944   struct pr_handle *info = (struct pr_handle *) p;
1945 
1946   free (info->filename);
1947   /* Should it be relative? best way to do it here?.  */
1948   info->filename = xstrdup (fname);
1949 
1950   return true;
1951 }
1952 
1953 /* Push an enum type onto the type stack.  */
1954 
1955 static bool
tg_enum_type(void * p,const char * tag,const char ** names,bfd_signed_vma * values)1956 tg_enum_type (void *p, const char *tag, const char **names,
1957 	      bfd_signed_vma *values)
1958 {
1959   struct pr_handle *info = (struct pr_handle *) p;
1960   unsigned int i;
1961   const char *name;
1962   char ab[22];
1963 
1964   if (! pr_enum_type (p, tag, names, values))
1965     return false;
1966 
1967   name = tag ? tag : "unknown";
1968   /* Generate an entry for the enum.  */
1969   if (tag)
1970     fprintf (info->f, "%s\t%s\t0;\"\tkind:e\ttype:%s\n", tag,
1971 	     info->filename, info->stack->type);
1972 
1973   /* Generate entries for the values.  */
1974   if (names != NULL)
1975     {
1976       for (i = 0; names[i] != NULL; i++)
1977 	{
1978 	  print_vma (values[i], ab, false, false);
1979 	  fprintf (info->f, "%s\t%s\t0;\"\tkind:g\tenum:%s\tvalue:%s\n",
1980 		   names[i], info->filename, name, ab);
1981 	}
1982     }
1983 
1984   return true;
1985 }
1986 
1987 /* Start accumulating a struct type.  */
1988 
1989 static bool
tg_start_struct_type(void * p,const char * tag,unsigned int id,bool structp,unsigned int size ATTRIBUTE_UNUSED)1990 tg_start_struct_type (void *p, const char *tag, unsigned int id,
1991 		      bool structp,
1992 		      unsigned int size ATTRIBUTE_UNUSED)
1993 {
1994   struct pr_handle *info = (struct pr_handle *) p;
1995   const char *name;
1996   char idbuf[20];
1997 
1998   if (tag != NULL)
1999     name = tag;
2000   else
2001     {
2002       name = idbuf;
2003       sprintf (idbuf, "%%anon%u", id);
2004     }
2005 
2006   if (! push_type (info, name))
2007     return false;
2008 
2009   info->stack->flavor = structp ? "struct" : "union";
2010 
2011   fprintf (info->f, "%s\t%s\t0;\"\tkind:%c\n", name, info->filename,
2012 	   info->stack->flavor[0]);
2013 
2014   info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
2015 
2016   return indent_type (info);
2017 }
2018 
2019 /* Output the visibility of a field in a struct.  */
2020 
2021 static bool
tg_fix_visibility(struct pr_handle * info,enum debug_visibility visibility)2022 tg_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
2023 {
2024   assert (info->stack != NULL);
2025 
2026   if (info->stack->visibility == visibility)
2027     return true;
2028 
2029   assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
2030 
2031   info->stack->visibility = visibility;
2032 
2033   return true;
2034 }
2035 
2036 /* Add a field to a struct type.  */
2037 
2038 static bool
tg_struct_field(void * p,const char * name,bfd_vma bitpos ATTRIBUTE_UNUSED,bfd_vma bitsize ATTRIBUTE_UNUSED,enum debug_visibility visibility)2039 tg_struct_field (void *p, const char *name, bfd_vma bitpos ATTRIBUTE_UNUSED,
2040 		 bfd_vma bitsize ATTRIBUTE_UNUSED,
2041 		 enum debug_visibility visibility)
2042 {
2043   struct pr_handle *info = (struct pr_handle *) p;
2044   char *t;
2045 
2046   t = pop_type (info);
2047   if (t == NULL)
2048     return false;
2049 
2050   if (! tg_fix_visibility (info, visibility))
2051     {
2052       free (t);
2053       return false;
2054     }
2055 
2056   /* It happens, a bug? */
2057   if (! name[0])
2058     {
2059       free (t);
2060       return true;
2061     }
2062 
2063   fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n",
2064 	   name, info->filename, t, info->stack->flavor, info->stack->type,
2065 	   visibility_name (visibility));
2066 
2067   free (t);
2068 
2069   return true;
2070 }
2071 
2072 /* Finish a struct type.  */
2073 
2074 static bool
tg_end_struct_type(void * p ATTRIBUTE_UNUSED)2075 tg_end_struct_type (void *p ATTRIBUTE_UNUSED)
2076 {
2077   assert (((struct pr_handle *) p)->stack != NULL);
2078 
2079   return true;
2080 }
2081 
2082 /* Start a class type.  */
2083 
2084 static bool
tg_start_class_type(void * p,const char * tag,unsigned int id,bool structp,unsigned int size,bool vptr,bool ownvptr)2085 tg_start_class_type (void *p, const char *tag, unsigned int id,
2086 		     bool structp, unsigned int size,
2087 		     bool vptr, bool ownvptr)
2088 {
2089   struct pr_handle *info = (struct pr_handle *) p;
2090   char *tv = NULL;
2091   const char *name;
2092   char idbuf[20];
2093   bool ret = false;
2094 
2095   info->indent += 2;
2096 
2097   if (vptr && ! ownvptr)
2098     {
2099       tv = pop_type (info);
2100       if (tv == NULL)
2101 	return false;
2102     }
2103 
2104   if (tag != NULL)
2105     name = tag;
2106   else
2107     {
2108       sprintf (idbuf, "%%anon%u", id);
2109       name = idbuf;
2110     }
2111 
2112   if (! push_type (info, name))
2113     goto out;
2114 
2115   info->stack->flavor = structp ? "class" : "union class";
2116   free (info->stack->parents);
2117   info->stack->parents = NULL;
2118 
2119   if (size != 0 || vptr || ownvptr || tag != NULL)
2120     {
2121       if (vptr)
2122 	{
2123 	  if (! append_type (info, " vtable "))
2124 	    goto out;
2125 	  if (ownvptr)
2126 	    {
2127 	      if (! append_type (info, "self "))
2128 		goto out;
2129 	    }
2130 	  else
2131 	    {
2132 	      if (! append_type (info, tv)
2133 		  || ! append_type (info, " "))
2134 		goto out;
2135 	    }
2136 	}
2137     }
2138 
2139   info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
2140 
2141   ret = true;
2142  out:
2143   free (tv);
2144   return ret;
2145 }
2146 
2147 /* Add a static member to a class.  */
2148 
2149 static bool
tg_class_static_member(void * p,const char * name,const char * physname ATTRIBUTE_UNUSED,enum debug_visibility visibility)2150 tg_class_static_member (void *p, const char *name,
2151 			const char *physname ATTRIBUTE_UNUSED,
2152 			enum debug_visibility visibility)
2153 {
2154   struct pr_handle *info = (struct pr_handle *) p;
2155   char *t;
2156   int len_var, len_class;
2157   char *full_name;
2158 
2159   len_var = strlen (name);
2160   len_class = strlen (info->stack->next->type);
2161   full_name = xmalloc (len_var + len_class + 3);
2162   sprintf (full_name, "%s::%s", info->stack->next->type, name);
2163 
2164   if (! substitute_type (info, full_name))
2165     {
2166       free (full_name);
2167       return false;
2168     }
2169 
2170   if (! prepend_type (info, "static "))
2171     {
2172       free (full_name);
2173       return false;
2174     }
2175 
2176   t = pop_type (info);
2177   if (t == NULL)
2178     {
2179       free (full_name);
2180       return false;
2181     }
2182 
2183   if (! tg_fix_visibility (info, visibility))
2184     {
2185       free (t);
2186       free (full_name);
2187       return false;
2188     }
2189 
2190   fprintf (info->f, "%s\t%s\t0;\"\tkind:x\ttype:%s\tclass:%s\taccess:%s\n",
2191 	   name, info->filename, t, info->stack->type,
2192 	   visibility_name (visibility));
2193   free (t);
2194   free (full_name);
2195 
2196   return true;
2197 }
2198 
2199 /* Add a base class to a class.  */
2200 
2201 static bool
tg_class_baseclass(void * p,bfd_vma bitpos ATTRIBUTE_UNUSED,bool is_virtual,enum debug_visibility visibility)2202 tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED,
2203 		    bool is_virtual, enum debug_visibility visibility)
2204 {
2205   struct pr_handle *info = (struct pr_handle *) p;
2206   char *t;
2207   const char *prefix;
2208 
2209   assert (info->stack != NULL && info->stack->next != NULL);
2210 
2211   t = pop_type (info);
2212   if (t == NULL)
2213     return false;
2214 
2215   /* Push it back on to take advantage of the prepend_type and
2216      append_type routines.  */
2217   if (! push_type (info, t + (startswith (t, "class ")
2218 			      ? sizeof "class " - 1 : 0)))
2219     {
2220       free (t);
2221       return false;
2222     }
2223   free (t);
2224 
2225   if (is_virtual)
2226     {
2227       if (! prepend_type (info, "virtual "))
2228 	return false;
2229     }
2230 
2231   switch (visibility)
2232     {
2233     case DEBUG_VISIBILITY_PUBLIC:
2234       prefix = "public ";
2235       break;
2236     case DEBUG_VISIBILITY_PROTECTED:
2237       prefix = "protected ";
2238       break;
2239     case DEBUG_VISIBILITY_PRIVATE:
2240       prefix = "private ";
2241       break;
2242     default:
2243       prefix = "/* unknown visibility */ ";
2244       break;
2245     }
2246 
2247   if (! prepend_type (info, prefix))
2248     return false;
2249 
2250   t = pop_type (info);
2251   if (t == NULL)
2252     return false;
2253 
2254   bool ret = ((!info->stack->parents || append_parent (info, ", "))
2255 	      && append_parent (info, t));
2256   free (t);
2257   return ret;
2258 }
2259 
2260 /* Add a variant to a method.  */
2261 
2262 static bool
tg_class_method_variant(void * p,const char * physname ATTRIBUTE_UNUSED,enum debug_visibility visibility,bool constp,bool volatilep,bfd_vma voffset ATTRIBUTE_UNUSED,bool context)2263 tg_class_method_variant (void *p, const char *physname ATTRIBUTE_UNUSED,
2264 			 enum debug_visibility visibility,
2265 			 bool constp, bool volatilep,
2266 			 bfd_vma voffset ATTRIBUTE_UNUSED,
2267 			 bool context)
2268 {
2269   struct pr_handle *info = (struct pr_handle *) p;
2270   char *method_type;
2271   char *context_type;
2272   char *method_name;
2273 
2274   assert (info->stack != NULL);
2275   assert (info->stack->next != NULL);
2276 
2277   /* Put the const and volatile qualifiers on the type.  */
2278   if (volatilep)
2279     {
2280       if (! append_type (info, " volatile"))
2281 	return false;
2282     }
2283   if (constp)
2284     {
2285       if (! append_type (info, " const"))
2286 	return false;
2287     }
2288 
2289   method_name = strdup (context ? info->stack->next->next->method
2290 			: info->stack->next->method);
2291 
2292   /* Stick the name of the method into its type.  */
2293   if (! substitute_type (info, method_name))
2294     {
2295       free (method_name);
2296       return false;
2297     }
2298 
2299   /* Get the type.  */
2300   method_type = pop_type (info);
2301   if (method_type == NULL)
2302     {
2303       free (method_name);
2304       return false;
2305     }
2306 
2307   /* Pull off the context type if there is one.  */
2308   if (! context)
2309     context_type = NULL;
2310   else
2311     {
2312       context_type = pop_type (info);
2313       if (context_type == NULL)
2314 	{
2315 	  free (method_type);
2316 	  free (method_name);
2317 	  return false;
2318 	}
2319     }
2320 
2321   /* Now the top of the stack is the class.  */
2322   if (! tg_fix_visibility (info, visibility))
2323     {
2324       free (method_type);
2325       free (method_name);
2326       free (context_type);
2327       return false;
2328     }
2329 
2330   fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\n",
2331 	   method_name, info->filename, method_type, info->stack->type);
2332   free (method_type);
2333   free (method_name);
2334   free (context_type);
2335 
2336   return true;
2337 }
2338 
2339 /* Add a static variant to a method.  */
2340 
2341 static bool
tg_class_static_method_variant(void * p,const char * physname ATTRIBUTE_UNUSED,enum debug_visibility visibility,bool constp,bool volatilep)2342 tg_class_static_method_variant (void *p,
2343 				const char *physname ATTRIBUTE_UNUSED,
2344 				enum debug_visibility visibility,
2345 				bool constp, bool volatilep)
2346 {
2347   struct pr_handle *info = (struct pr_handle *) p;
2348   char *method_type;
2349   char *method_name;
2350 
2351   assert (info->stack != NULL);
2352   assert (info->stack->next != NULL);
2353   assert (info->stack->next->method != NULL);
2354 
2355   /* Put the const and volatile qualifiers on the type.  */
2356   if (volatilep)
2357     {
2358       if (! append_type (info, " volatile"))
2359 	return false;
2360     }
2361   if (constp)
2362     {
2363       if (! append_type (info, " const"))
2364 	return false;
2365     }
2366 
2367   /* Mark it as static.  */
2368   if (! prepend_type (info, "static "))
2369     return false;
2370 
2371   method_name = strdup (info->stack->next->method);
2372   /* Stick the name of the method into its type.  */
2373   if (! substitute_type (info, info->stack->next->method))
2374     {
2375       free (method_name);
2376       return false;
2377     }
2378 
2379   /* Get the type.  */
2380   method_type = pop_type (info);
2381   if (method_type == NULL)
2382     {
2383       free (method_name);
2384       return false;
2385     }
2386 
2387   /* Now the top of the stack is the class.  */
2388   if (! tg_fix_visibility (info, visibility))
2389     {
2390       free (method_type);
2391       free (method_name);
2392       return false;
2393     }
2394 
2395   fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\taccess:%s\n",
2396 	   method_name, info->filename, method_type, info->stack->type,
2397 	   visibility_name (visibility));
2398   free (method_type);
2399   free (method_name);
2400 
2401   return true;
2402 }
2403 
2404 /* Finish up a class.  */
2405 
2406 static bool
tg_end_class_type(void * p)2407 tg_end_class_type (void *p)
2408 {
2409   struct pr_handle *info = (struct pr_handle *) p;
2410 
2411   fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type,
2412 	   info->filename, info->stack->flavor);
2413   if (info->stack->parents)
2414     {
2415       fprintf  (info->f, "\tinherits:%s", info->stack->parents);
2416       free (info->stack->parents);
2417       info->stack->parents = NULL;
2418     }
2419   fputc ('\n', info->f);
2420 
2421   return tg_end_struct_type (p);
2422 }
2423 
2424 /* Push a type on the stack using a tag name.  */
2425 
2426 static bool
tg_tag_type(void * p,const char * name,unsigned int id,enum debug_type_kind kind)2427 tg_tag_type (void *p, const char *name, unsigned int id,
2428 	     enum debug_type_kind kind)
2429 {
2430   struct pr_handle *info = (struct pr_handle *) p;
2431   const char *t, *tag;
2432   char idbuf[20];
2433 
2434   switch (kind)
2435     {
2436     case DEBUG_KIND_STRUCT:
2437       t = "struct ";
2438       break;
2439     case DEBUG_KIND_UNION:
2440       t = "union ";
2441       break;
2442     case DEBUG_KIND_ENUM:
2443       t = "enum ";
2444       break;
2445     case DEBUG_KIND_CLASS:
2446       t = "class ";
2447       break;
2448     case DEBUG_KIND_UNION_CLASS:
2449       t = "union class ";
2450       break;
2451     default:
2452       abort ();
2453       return false;
2454     }
2455 
2456   if (! push_type (info, t))
2457     return false;
2458   if (name != NULL)
2459     tag = name;
2460   else
2461     {
2462       sprintf (idbuf, "%%anon%u", id);
2463       tag = idbuf;
2464     }
2465 
2466   if (! append_type (info, tag))
2467     return false;
2468 
2469   return true;
2470 }
2471 
2472 /* Output a typedef.  */
2473 
2474 static bool
tg_typdef(void * p,const char * name)2475 tg_typdef (void *p, const char *name)
2476 {
2477   struct pr_handle *info = (struct pr_handle *) p;
2478   char *s;
2479 
2480   s = pop_type (info);
2481   if (s == NULL)
2482     return false;
2483 
2484   fprintf (info->f, "%s\t%s\t0;\"\tkind:t\ttype:%s\n", name,
2485 	   info->filename, s);
2486 
2487   free (s);
2488 
2489   return true;
2490 }
2491 
2492 /* Output a tag.  The tag should already be in the string on the
2493    stack, so all we have to do here is print it out.  */
2494 
2495 static bool
tg_tag(void * p ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED)2496 tg_tag (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED)
2497 {
2498   struct pr_handle *info = (struct pr_handle *) p;
2499   char *t;
2500 
2501   t = pop_type (info);
2502   if (t == NULL)
2503     return false;
2504   free (t);
2505 
2506   return true;
2507 }
2508 
2509 /* Output an integer constant.  */
2510 
2511 static bool
tg_int_constant(void * p,const char * name,bfd_vma val)2512 tg_int_constant (void *p, const char *name, bfd_vma val)
2513 {
2514   struct pr_handle *info = (struct pr_handle *) p;
2515   char ab[22];
2516 
2517   indent (info);
2518   print_vma (val, ab, false, false);
2519   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const int\tvalue:%s\n",
2520 	   name, info->filename, ab);
2521   return true;
2522 }
2523 
2524 /* Output a floating point constant.  */
2525 
2526 static bool
tg_float_constant(void * p,const char * name,double val)2527 tg_float_constant (void *p, const char *name, double val)
2528 {
2529   struct pr_handle *info = (struct pr_handle *) p;
2530 
2531   indent (info);
2532   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const double\tvalue:%g\n",
2533 	   name, info->filename, val);
2534   return true;
2535 }
2536 
2537 /* Output a typed constant.  */
2538 
2539 static bool
tg_typed_constant(void * p,const char * name,bfd_vma val)2540 tg_typed_constant (void *p, const char *name, bfd_vma val)
2541 {
2542   struct pr_handle *info = (struct pr_handle *) p;
2543   char *t;
2544   char ab[22];
2545 
2546   t = pop_type (info);
2547   if (t == NULL)
2548     return false;
2549 
2550   indent (info);
2551   print_vma (val, ab, false, false);
2552   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const %s\tvalue:%s\n",
2553 	   name, info->filename, t, ab);
2554 
2555   free (t);
2556 
2557   return true;
2558 }
2559 
2560 /* Output a variable.  */
2561 
2562 static bool
tg_variable(void * p,const char * name,enum debug_var_kind kind,bfd_vma val ATTRIBUTE_UNUSED)2563 tg_variable (void *p, const char *name, enum debug_var_kind kind,
2564 	     bfd_vma val ATTRIBUTE_UNUSED)
2565 {
2566   struct pr_handle *info = (struct pr_handle *) p;
2567   char *t, *dname, *from_class;
2568 
2569   t = pop_type (info);
2570   if (t == NULL)
2571     return false;
2572 
2573   dname = NULL;
2574   if (info->demangler)
2575     dname = info->demangler (info->abfd, name, demangle_flags);
2576 
2577   from_class = NULL;
2578   if (dname != NULL)
2579     {
2580       char *sep;
2581       sep = strstr (dname, "::");
2582       if (sep)
2583 	{
2584 	  *sep = 0;
2585 	  name = sep + 2;
2586 	  from_class = dname;
2587 	}
2588       else
2589 	/* Obscure types as vts and type_info nodes.  */
2590 	name = dname;
2591     }
2592 
2593   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:%s", name, info->filename, t);
2594 
2595   switch (kind)
2596     {
2597     case DEBUG_STATIC:
2598     case DEBUG_LOCAL_STATIC:
2599       fprintf (info->f, "\tfile:");
2600       break;
2601     case DEBUG_REGISTER:
2602       fprintf (info->f, "\tregister:");
2603       break;
2604     default:
2605       break;
2606     }
2607 
2608   if (from_class)
2609     fprintf (info->f, "\tclass:%s", from_class);
2610 
2611   if (dname)
2612     free (dname);
2613 
2614   fprintf (info->f, "\n");
2615 
2616   free (t);
2617 
2618   return true;
2619 }
2620 
2621 /* Start outputting a function.  */
2622 
2623 static bool
tg_start_function(void * p,const char * name,bool global)2624 tg_start_function (void *p, const char *name, bool global)
2625 {
2626   struct pr_handle *info = (struct pr_handle *) p;
2627   char *dname;
2628 
2629   if (! global)
2630     info->stack->flavor = "static";
2631   else
2632     info->stack->flavor = NULL;
2633 
2634   dname = NULL;
2635   if (info->demangler)
2636     dname = info->demangler (info->abfd, name, demangle_flags);
2637 
2638   if (! substitute_type (info, dname ? dname : name))
2639     return false;
2640 
2641   free (info->stack->method);
2642   info->stack->method = NULL;
2643   if (dname != NULL)
2644     {
2645       char *sep;
2646       sep = strstr (dname, "::");
2647       if (sep)
2648 	{
2649 	  info->stack->method = dname;
2650 	  dname = NULL;
2651 	  *sep = 0;
2652 	  name = sep + 2;
2653 	}
2654       else
2655 	{
2656 	  info->stack->method = xstrdup ("");
2657 	  name = dname;
2658 	}
2659       sep = strchr (name, '(');
2660       if (sep)
2661 	*sep = 0;
2662       /* Obscure functions as type_info function.  */
2663     }
2664 
2665   free (info->stack->parents);
2666   info->stack->parents = strdup (name);
2667   free (dname);
2668 
2669   if (! info->stack->method && ! append_type (info, "("))
2670     return false;
2671 
2672   info->parameter = 1;
2673 
2674   return true;
2675 }
2676 
2677 /* Output a function parameter.  */
2678 
2679 static bool
tg_function_parameter(void * p,const char * name,enum debug_parm_kind kind,bfd_vma val ATTRIBUTE_UNUSED)2680 tg_function_parameter (void *p, const char *name, enum debug_parm_kind kind,
2681 		       bfd_vma val ATTRIBUTE_UNUSED)
2682 {
2683   struct pr_handle *info = (struct pr_handle *) p;
2684   char *t;
2685 
2686   if (kind == DEBUG_PARM_REFERENCE
2687       || kind == DEBUG_PARM_REF_REG)
2688     {
2689       if (! pr_reference_type (p))
2690 	return false;
2691     }
2692 
2693   if (! substitute_type (info, name))
2694     return false;
2695 
2696   t = pop_type (info);
2697   if (t == NULL)
2698     return false;
2699 
2700   if (! info->stack->method)
2701     {
2702       if (info->parameter != 1 && ! append_type (info, ", "))
2703 	{
2704 	  free (t);
2705 	  return false;
2706 	}
2707 
2708       if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
2709 	if (! append_type (info, "register "))
2710 	  {
2711 	    free (t);
2712 	    return false;
2713 	  }
2714 
2715       if (! append_type (info, t))
2716 	{
2717 	  free (t);
2718 	  return false;
2719 	}
2720     }
2721 
2722   free (t);
2723 
2724   ++info->parameter;
2725 
2726   return true;
2727 }
2728 
2729 /* Start writing out a block.  */
2730 
2731 static bool
tg_start_block(void * p,bfd_vma addr)2732 tg_start_block (void *p, bfd_vma addr)
2733 {
2734   struct pr_handle *info = (struct pr_handle *) p;
2735   char ab[22], kind, *partof;
2736   char *t;
2737   bool local;
2738 
2739   if (info->parameter > 0)
2740     {
2741       info->parameter = 0;
2742 
2743       /* Delayed name.  */
2744       fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename);
2745       free (info->stack->parents);
2746       info->stack->parents = NULL;
2747 
2748       print_vma (addr, ab, true, true);
2749       translate_addresses (info->abfd, ab, info->f, info->syms);
2750       local = info->stack->flavor != NULL;
2751       if (info->stack->method && *info->stack->method)
2752 	{
2753 	  kind = 'm';
2754 	  partof = (char *) info->stack->method;
2755 	}
2756       else
2757 	{
2758 	  kind = 'f';
2759 	  partof = NULL;
2760 	  if (! info->stack->method && ! append_type (info, ")"))
2761 	    return false;
2762 	}
2763       t = pop_type (info);
2764       if (t == NULL)
2765 	return false;
2766       fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t);
2767       free (t);
2768       if (local)
2769 	fputs ("\tfile:", info->f);
2770       if (partof)
2771 	fprintf (info->f, "\tclass:%s", partof);
2772       fputc ('\n', info->f);
2773       free (info->stack->method);
2774       info->stack->method = NULL;
2775     }
2776 
2777   return true;
2778 }
2779 
2780 /* Write out line number information.  */
2781 
2782 static bool
tg_lineno(void * p ATTRIBUTE_UNUSED,const char * fname ATTRIBUTE_UNUSED,unsigned long lineno ATTRIBUTE_UNUSED,bfd_vma addr ATTRIBUTE_UNUSED)2783 tg_lineno (void *p ATTRIBUTE_UNUSED, const char *fname ATTRIBUTE_UNUSED,
2784 	   unsigned long lineno ATTRIBUTE_UNUSED,
2785 	   bfd_vma addr ATTRIBUTE_UNUSED)
2786 {
2787   return true;
2788 }
2789 
2790 /* Finish writing out a block.  */
2791 
2792 static bool
tg_end_block(void * p ATTRIBUTE_UNUSED,bfd_vma addr ATTRIBUTE_UNUSED)2793 tg_end_block (void *p ATTRIBUTE_UNUSED, bfd_vma addr ATTRIBUTE_UNUSED)
2794 {
2795   return true;
2796 }
2797 
2798 /* Convert the visibility value into a human readable name.  */
2799 
2800 static const char *
visibility_name(enum debug_visibility visibility)2801 visibility_name (enum debug_visibility visibility)
2802 {
2803   const char *s;
2804 
2805   switch (visibility)
2806     {
2807     case DEBUG_VISIBILITY_PUBLIC:
2808       s = "public";
2809       break;
2810     case DEBUG_VISIBILITY_PRIVATE:
2811       s = "private";
2812       break;
2813     case DEBUG_VISIBILITY_PROTECTED:
2814       s = "protected";
2815       break;
2816     case DEBUG_VISIBILITY_IGNORE:
2817       s = "/* ignore */";
2818       break;
2819     default:
2820       abort ();
2821       return false;
2822     }
2823   return s;
2824 }
2825