Coverage Report

Created: 2026-05-11 07:54

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