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