xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/wrstabs.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* wrstabs.c -- Output stabs debugging information
2*3d8817e4Smiod    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod    Written by Ian Lance Taylor <ian@cygnus.com>.
5*3d8817e4Smiod 
6*3d8817e4Smiod    This file is part of GNU Binutils.
7*3d8817e4Smiod 
8*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
9*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
11*3d8817e4Smiod    (at your option) any later version.
12*3d8817e4Smiod 
13*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
14*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*3d8817e4Smiod    GNU General Public License for more details.
17*3d8817e4Smiod 
18*3d8817e4Smiod    You should have received a copy of the GNU General Public License
19*3d8817e4Smiod    along with this program; if not, write to the Free Software
20*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21*3d8817e4Smiod    02110-1301, USA.  */
22*3d8817e4Smiod 
23*3d8817e4Smiod /* This file contains code which writes out stabs debugging
24*3d8817e4Smiod    information.  */
25*3d8817e4Smiod 
26*3d8817e4Smiod #include <stdio.h>
27*3d8817e4Smiod #include <assert.h>
28*3d8817e4Smiod 
29*3d8817e4Smiod #include "bfd.h"
30*3d8817e4Smiod #include "bucomm.h"
31*3d8817e4Smiod #include "libiberty.h"
32*3d8817e4Smiod #include "safe-ctype.h"
33*3d8817e4Smiod #include "debug.h"
34*3d8817e4Smiod #include "budbg.h"
35*3d8817e4Smiod #include "aout/aout64.h"
36*3d8817e4Smiod #include "aout/stab_gnu.h"
37*3d8817e4Smiod 
38*3d8817e4Smiod /* The size of a stabs symbol.  This presumes 32 bit values.  */
39*3d8817e4Smiod 
40*3d8817e4Smiod #define STAB_SYMBOL_SIZE (12)
41*3d8817e4Smiod 
42*3d8817e4Smiod /* An entry in a string hash table.  */
43*3d8817e4Smiod 
44*3d8817e4Smiod struct string_hash_entry
45*3d8817e4Smiod {
46*3d8817e4Smiod   struct bfd_hash_entry root;
47*3d8817e4Smiod   /* Next string in this table.  */
48*3d8817e4Smiod   struct string_hash_entry *next;
49*3d8817e4Smiod   /* Index in string table.  */
50*3d8817e4Smiod   long index;
51*3d8817e4Smiod   /* Size of type if this is a typedef.  */
52*3d8817e4Smiod   unsigned int size;
53*3d8817e4Smiod };
54*3d8817e4Smiod 
55*3d8817e4Smiod /* A string hash table.  */
56*3d8817e4Smiod 
57*3d8817e4Smiod struct string_hash_table
58*3d8817e4Smiod {
59*3d8817e4Smiod   struct bfd_hash_table table;
60*3d8817e4Smiod };
61*3d8817e4Smiod 
62*3d8817e4Smiod /* The type stack.  Each element on the stack is a string.  */
63*3d8817e4Smiod 
64*3d8817e4Smiod struct stab_type_stack
65*3d8817e4Smiod {
66*3d8817e4Smiod   /* The next element on the stack.  */
67*3d8817e4Smiod   struct stab_type_stack *next;
68*3d8817e4Smiod   /* This element as a string.  */
69*3d8817e4Smiod   char *string;
70*3d8817e4Smiod   /* The type index of this element.  */
71*3d8817e4Smiod   long index;
72*3d8817e4Smiod   /* The size of the type.  */
73*3d8817e4Smiod   unsigned int size;
74*3d8817e4Smiod   /* Whether type string defines a new type.  */
75*3d8817e4Smiod   bfd_boolean definition;
76*3d8817e4Smiod   /* String defining struct fields.  */
77*3d8817e4Smiod   char *fields;
78*3d8817e4Smiod   /* NULL terminated array of strings defining base classes for a
79*3d8817e4Smiod      class.  */
80*3d8817e4Smiod   char **baseclasses;
81*3d8817e4Smiod   /* String defining class methods.  */
82*3d8817e4Smiod   char *methods;
83*3d8817e4Smiod   /* String defining vtable pointer for a class.  */
84*3d8817e4Smiod   char *vtable;
85*3d8817e4Smiod };
86*3d8817e4Smiod 
87*3d8817e4Smiod /* This structure is used to keep track of type indices for tagged
88*3d8817e4Smiod    types.  */
89*3d8817e4Smiod 
90*3d8817e4Smiod struct stab_tag
91*3d8817e4Smiod {
92*3d8817e4Smiod   /* The type index.  */
93*3d8817e4Smiod   long index;
94*3d8817e4Smiod   /* The tag name.  */
95*3d8817e4Smiod   const char *tag;
96*3d8817e4Smiod   /* The kind of type.  This is set to DEBUG_KIND_ILLEGAL when the
97*3d8817e4Smiod      type is defined.  */
98*3d8817e4Smiod   enum debug_type_kind kind;
99*3d8817e4Smiod   /* The size of the struct.  */
100*3d8817e4Smiod   unsigned int size;
101*3d8817e4Smiod };
102*3d8817e4Smiod 
103*3d8817e4Smiod /* We remember various sorts of type indices.  They are not related,
104*3d8817e4Smiod    but, for convenience, we keep all the information in this
105*3d8817e4Smiod    structure.  */
106*3d8817e4Smiod 
107*3d8817e4Smiod struct stab_type_cache
108*3d8817e4Smiod {
109*3d8817e4Smiod   /* The void type index.  */
110*3d8817e4Smiod   long void_type;
111*3d8817e4Smiod   /* Signed integer type indices, indexed by size - 1.  */
112*3d8817e4Smiod   long signed_integer_types[8];
113*3d8817e4Smiod   /* Unsigned integer type indices, indexed by size - 1.  */
114*3d8817e4Smiod   long unsigned_integer_types[8];
115*3d8817e4Smiod   /* Floating point types, indexed by size - 1.  */
116*3d8817e4Smiod   long float_types[16];
117*3d8817e4Smiod   /* Pointers to types, indexed by the type index.  */
118*3d8817e4Smiod   long *pointer_types;
119*3d8817e4Smiod   size_t pointer_types_alloc;
120*3d8817e4Smiod   /* Functions returning types, indexed by the type index.  */
121*3d8817e4Smiod   long *function_types;
122*3d8817e4Smiod   size_t function_types_alloc;
123*3d8817e4Smiod   /* References to types, indexed by the type index.  */
124*3d8817e4Smiod   long *reference_types;
125*3d8817e4Smiod   size_t reference_types_alloc;
126*3d8817e4Smiod   /* Struct/union/class type indices, indexed by the struct id.  */
127*3d8817e4Smiod   struct stab_tag *struct_types;
128*3d8817e4Smiod   size_t struct_types_alloc;
129*3d8817e4Smiod };
130*3d8817e4Smiod 
131*3d8817e4Smiod /* This is the handle passed through debug_write.  */
132*3d8817e4Smiod 
133*3d8817e4Smiod struct stab_write_handle
134*3d8817e4Smiod {
135*3d8817e4Smiod   /* The BFD.  */
136*3d8817e4Smiod   bfd *abfd;
137*3d8817e4Smiod   /* This buffer holds the symbols.  */
138*3d8817e4Smiod   bfd_byte *symbols;
139*3d8817e4Smiod   size_t symbols_size;
140*3d8817e4Smiod   size_t symbols_alloc;
141*3d8817e4Smiod   /* This is a list of hash table entries for the strings.  */
142*3d8817e4Smiod   struct string_hash_entry *strings;
143*3d8817e4Smiod   /* The last string hash table entry.  */
144*3d8817e4Smiod   struct string_hash_entry *last_string;
145*3d8817e4Smiod   /* The size of the strings.  */
146*3d8817e4Smiod   size_t strings_size;
147*3d8817e4Smiod   /* This hash table eliminates duplicate strings.  */
148*3d8817e4Smiod   struct string_hash_table strhash;
149*3d8817e4Smiod   /* The type stack.  */
150*3d8817e4Smiod   struct stab_type_stack *type_stack;
151*3d8817e4Smiod   /* The next type index.  */
152*3d8817e4Smiod   long type_index;
153*3d8817e4Smiod   /* The type cache.  */
154*3d8817e4Smiod   struct stab_type_cache type_cache;
155*3d8817e4Smiod   /* A mapping from typedef names to type indices.  */
156*3d8817e4Smiod   struct string_hash_table typedef_hash;
157*3d8817e4Smiod   /* If this is not -1, it is the offset to the most recent N_SO
158*3d8817e4Smiod      symbol, and the value of that symbol needs to be set.  */
159*3d8817e4Smiod   long so_offset;
160*3d8817e4Smiod   /* If this is not -1, it is the offset to the most recent N_FUN
161*3d8817e4Smiod      symbol, and the value of that symbol needs to be set.  */
162*3d8817e4Smiod   long fun_offset;
163*3d8817e4Smiod   /* The last text section address seen.  */
164*3d8817e4Smiod   bfd_vma last_text_address;
165*3d8817e4Smiod   /* The block nesting depth.  */
166*3d8817e4Smiod   unsigned int nesting;
167*3d8817e4Smiod   /* The function address.  */
168*3d8817e4Smiod   bfd_vma fnaddr;
169*3d8817e4Smiod   /* A pending LBRAC symbol.  */
170*3d8817e4Smiod   bfd_vma pending_lbrac;
171*3d8817e4Smiod   /* The current line number file name.  */
172*3d8817e4Smiod   const char *lineno_filename;
173*3d8817e4Smiod };
174*3d8817e4Smiod 
175*3d8817e4Smiod static struct bfd_hash_entry *string_hash_newfunc
176*3d8817e4Smiod   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
177*3d8817e4Smiod static bfd_boolean stab_write_symbol
178*3d8817e4Smiod   (struct stab_write_handle *, int, int, bfd_vma, const char *);
179*3d8817e4Smiod static bfd_boolean stab_push_string
180*3d8817e4Smiod   (struct stab_write_handle *, const char *, long, bfd_boolean, unsigned int);
181*3d8817e4Smiod static bfd_boolean stab_push_defined_type
182*3d8817e4Smiod   (struct stab_write_handle *, long, unsigned int);
183*3d8817e4Smiod static char *stab_pop_type (struct stab_write_handle *);
184*3d8817e4Smiod static bfd_boolean stab_modify_type
185*3d8817e4Smiod   (struct stab_write_handle *, int, unsigned int, long **, size_t *);
186*3d8817e4Smiod static long stab_get_struct_index
187*3d8817e4Smiod   (struct stab_write_handle *, const char *, unsigned int,
188*3d8817e4Smiod    enum debug_type_kind, unsigned int *);
189*3d8817e4Smiod static bfd_boolean stab_class_method_var
190*3d8817e4Smiod   (struct stab_write_handle *, const char *, enum debug_visibility,
191*3d8817e4Smiod    bfd_boolean, bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean);
192*3d8817e4Smiod static bfd_boolean stab_start_compilation_unit (void *, const char *);
193*3d8817e4Smiod static bfd_boolean stab_start_source (void *, const char *);
194*3d8817e4Smiod static bfd_boolean stab_empty_type (void *);
195*3d8817e4Smiod static bfd_boolean stab_void_type (void *);
196*3d8817e4Smiod static bfd_boolean stab_int_type (void *, unsigned int, bfd_boolean);
197*3d8817e4Smiod static bfd_boolean stab_float_type (void *, unsigned int);
198*3d8817e4Smiod static bfd_boolean stab_complex_type (void *, unsigned int);
199*3d8817e4Smiod static bfd_boolean stab_bool_type (void *, unsigned int);
200*3d8817e4Smiod static bfd_boolean stab_enum_type
201*3d8817e4Smiod   (void *, const char *, const char **, bfd_signed_vma *);
202*3d8817e4Smiod static bfd_boolean stab_pointer_type (void *);
203*3d8817e4Smiod static bfd_boolean stab_function_type (void *, int, bfd_boolean);
204*3d8817e4Smiod static bfd_boolean stab_reference_type (void *);
205*3d8817e4Smiod static bfd_boolean stab_range_type (void *, bfd_signed_vma, bfd_signed_vma);
206*3d8817e4Smiod static bfd_boolean stab_array_type
207*3d8817e4Smiod   (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean);
208*3d8817e4Smiod static bfd_boolean stab_set_type (void *, bfd_boolean);
209*3d8817e4Smiod static bfd_boolean stab_offset_type (void *);
210*3d8817e4Smiod static bfd_boolean stab_method_type (void *, bfd_boolean, int, bfd_boolean);
211*3d8817e4Smiod static bfd_boolean stab_const_type (void *);
212*3d8817e4Smiod static bfd_boolean stab_volatile_type (void *);
213*3d8817e4Smiod static bfd_boolean stab_start_struct_type
214*3d8817e4Smiod   (void *, const char *, unsigned int, bfd_boolean, unsigned int);
215*3d8817e4Smiod static bfd_boolean stab_struct_field
216*3d8817e4Smiod   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
217*3d8817e4Smiod static bfd_boolean stab_end_struct_type (void *);
218*3d8817e4Smiod static bfd_boolean stab_start_class_type
219*3d8817e4Smiod   (void *, const char *, unsigned int, bfd_boolean, unsigned int,
220*3d8817e4Smiod    bfd_boolean, bfd_boolean);
221*3d8817e4Smiod static bfd_boolean stab_class_static_member
222*3d8817e4Smiod   (void *, const char *, const char *, enum debug_visibility);
223*3d8817e4Smiod static bfd_boolean stab_class_baseclass
224*3d8817e4Smiod   (void *, bfd_vma, bfd_boolean, enum debug_visibility);
225*3d8817e4Smiod static bfd_boolean stab_class_start_method (void *, const char *);
226*3d8817e4Smiod static bfd_boolean stab_class_method_variant
227*3d8817e4Smiod   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
228*3d8817e4Smiod    bfd_vma, bfd_boolean);
229*3d8817e4Smiod static bfd_boolean stab_class_static_method_variant
230*3d8817e4Smiod   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean);
231*3d8817e4Smiod static bfd_boolean stab_class_end_method (void *);
232*3d8817e4Smiod static bfd_boolean stab_end_class_type (void *);
233*3d8817e4Smiod static bfd_boolean stab_typedef_type (void *, const char *);
234*3d8817e4Smiod static bfd_boolean stab_tag_type
235*3d8817e4Smiod   (void *, const char *, unsigned int, enum debug_type_kind);
236*3d8817e4Smiod static bfd_boolean stab_typdef (void *, const char *);
237*3d8817e4Smiod static bfd_boolean stab_tag (void *, const char *);
238*3d8817e4Smiod static bfd_boolean stab_int_constant (void *, const char *, bfd_vma);
239*3d8817e4Smiod static bfd_boolean stab_float_constant (void *, const char *, double);
240*3d8817e4Smiod static bfd_boolean stab_typed_constant (void *, const char *, bfd_vma);
241*3d8817e4Smiod static bfd_boolean stab_variable
242*3d8817e4Smiod   (void *, const char *, enum debug_var_kind, bfd_vma);
243*3d8817e4Smiod static bfd_boolean stab_start_function (void *, const char *, bfd_boolean);
244*3d8817e4Smiod static bfd_boolean stab_function_parameter
245*3d8817e4Smiod   (void *, const char *, enum debug_parm_kind, bfd_vma);
246*3d8817e4Smiod static bfd_boolean stab_start_block (void *, bfd_vma);
247*3d8817e4Smiod static bfd_boolean stab_end_block (void *, bfd_vma);
248*3d8817e4Smiod static bfd_boolean stab_end_function (void *);
249*3d8817e4Smiod static bfd_boolean stab_lineno (void *, const char *, unsigned long, bfd_vma);
250*3d8817e4Smiod 
251*3d8817e4Smiod static const struct debug_write_fns stab_fns =
252*3d8817e4Smiod {
253*3d8817e4Smiod   stab_start_compilation_unit,
254*3d8817e4Smiod   stab_start_source,
255*3d8817e4Smiod   stab_empty_type,
256*3d8817e4Smiod   stab_void_type,
257*3d8817e4Smiod   stab_int_type,
258*3d8817e4Smiod   stab_float_type,
259*3d8817e4Smiod   stab_complex_type,
260*3d8817e4Smiod   stab_bool_type,
261*3d8817e4Smiod   stab_enum_type,
262*3d8817e4Smiod   stab_pointer_type,
263*3d8817e4Smiod   stab_function_type,
264*3d8817e4Smiod   stab_reference_type,
265*3d8817e4Smiod   stab_range_type,
266*3d8817e4Smiod   stab_array_type,
267*3d8817e4Smiod   stab_set_type,
268*3d8817e4Smiod   stab_offset_type,
269*3d8817e4Smiod   stab_method_type,
270*3d8817e4Smiod   stab_const_type,
271*3d8817e4Smiod   stab_volatile_type,
272*3d8817e4Smiod   stab_start_struct_type,
273*3d8817e4Smiod   stab_struct_field,
274*3d8817e4Smiod   stab_end_struct_type,
275*3d8817e4Smiod   stab_start_class_type,
276*3d8817e4Smiod   stab_class_static_member,
277*3d8817e4Smiod   stab_class_baseclass,
278*3d8817e4Smiod   stab_class_start_method,
279*3d8817e4Smiod   stab_class_method_variant,
280*3d8817e4Smiod   stab_class_static_method_variant,
281*3d8817e4Smiod   stab_class_end_method,
282*3d8817e4Smiod   stab_end_class_type,
283*3d8817e4Smiod   stab_typedef_type,
284*3d8817e4Smiod   stab_tag_type,
285*3d8817e4Smiod   stab_typdef,
286*3d8817e4Smiod   stab_tag,
287*3d8817e4Smiod   stab_int_constant,
288*3d8817e4Smiod   stab_float_constant,
289*3d8817e4Smiod   stab_typed_constant,
290*3d8817e4Smiod   stab_variable,
291*3d8817e4Smiod   stab_start_function,
292*3d8817e4Smiod   stab_function_parameter,
293*3d8817e4Smiod   stab_start_block,
294*3d8817e4Smiod   stab_end_block,
295*3d8817e4Smiod   stab_end_function,
296*3d8817e4Smiod   stab_lineno
297*3d8817e4Smiod };
298*3d8817e4Smiod 
299*3d8817e4Smiod /* Routine to create an entry in a string hash table.  */
300*3d8817e4Smiod 
301*3d8817e4Smiod static struct bfd_hash_entry *
string_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)302*3d8817e4Smiod string_hash_newfunc (struct bfd_hash_entry *entry,
303*3d8817e4Smiod 		     struct bfd_hash_table *table, const char *string)
304*3d8817e4Smiod {
305*3d8817e4Smiod   struct string_hash_entry *ret = (struct string_hash_entry *) entry;
306*3d8817e4Smiod 
307*3d8817e4Smiod   /* Allocate the structure if it has not already been allocated by a
308*3d8817e4Smiod      subclass.  */
309*3d8817e4Smiod   if (ret == (struct string_hash_entry *) NULL)
310*3d8817e4Smiod     ret = ((struct string_hash_entry *)
311*3d8817e4Smiod 	   bfd_hash_allocate (table, sizeof (struct string_hash_entry)));
312*3d8817e4Smiod   if (ret == (struct string_hash_entry *) NULL)
313*3d8817e4Smiod     return NULL;
314*3d8817e4Smiod 
315*3d8817e4Smiod   /* Call the allocation method of the superclass.  */
316*3d8817e4Smiod   ret = ((struct string_hash_entry *)
317*3d8817e4Smiod 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
318*3d8817e4Smiod 
319*3d8817e4Smiod   if (ret)
320*3d8817e4Smiod     {
321*3d8817e4Smiod       /* Initialize the local fields.  */
322*3d8817e4Smiod       ret->next = NULL;
323*3d8817e4Smiod       ret->index = -1;
324*3d8817e4Smiod       ret->size = 0;
325*3d8817e4Smiod     }
326*3d8817e4Smiod 
327*3d8817e4Smiod   return (struct bfd_hash_entry *) ret;
328*3d8817e4Smiod }
329*3d8817e4Smiod 
330*3d8817e4Smiod /* Look up an entry in a string hash table.  */
331*3d8817e4Smiod 
332*3d8817e4Smiod #define string_hash_lookup(t, string, create, copy) \
333*3d8817e4Smiod   ((struct string_hash_entry *) \
334*3d8817e4Smiod    bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
335*3d8817e4Smiod 
336*3d8817e4Smiod /* Add a symbol to the stabs debugging information we are building.  */
337*3d8817e4Smiod 
338*3d8817e4Smiod static bfd_boolean
stab_write_symbol(struct stab_write_handle * info,int type,int desc,bfd_vma value,const char * string)339*3d8817e4Smiod stab_write_symbol (struct stab_write_handle *info, int type, int desc,
340*3d8817e4Smiod 		   bfd_vma value, const char *string)
341*3d8817e4Smiod {
342*3d8817e4Smiod   bfd_size_type strx;
343*3d8817e4Smiod   bfd_byte sym[STAB_SYMBOL_SIZE];
344*3d8817e4Smiod 
345*3d8817e4Smiod   if (string == NULL)
346*3d8817e4Smiod     strx = 0;
347*3d8817e4Smiod   else
348*3d8817e4Smiod     {
349*3d8817e4Smiod       struct string_hash_entry *h;
350*3d8817e4Smiod 
351*3d8817e4Smiod       h = string_hash_lookup (&info->strhash, string, TRUE, TRUE);
352*3d8817e4Smiod       if (h == NULL)
353*3d8817e4Smiod 	{
354*3d8817e4Smiod 	  non_fatal (_("string_hash_lookup failed: %s"),
355*3d8817e4Smiod 		     bfd_errmsg (bfd_get_error ()));
356*3d8817e4Smiod 	  return FALSE;
357*3d8817e4Smiod 	}
358*3d8817e4Smiod       if (h->index != -1)
359*3d8817e4Smiod 	strx = h->index;
360*3d8817e4Smiod       else
361*3d8817e4Smiod 	{
362*3d8817e4Smiod 	  strx = info->strings_size;
363*3d8817e4Smiod 	  h->index = strx;
364*3d8817e4Smiod 	  if (info->last_string == NULL)
365*3d8817e4Smiod 	    info->strings = h;
366*3d8817e4Smiod 	  else
367*3d8817e4Smiod 	    info->last_string->next = h;
368*3d8817e4Smiod 	  info->last_string = h;
369*3d8817e4Smiod 	  info->strings_size += strlen (string) + 1;
370*3d8817e4Smiod 	}
371*3d8817e4Smiod     }
372*3d8817e4Smiod 
373*3d8817e4Smiod   /* This presumes 32 bit values.  */
374*3d8817e4Smiod   bfd_put_32 (info->abfd, strx, sym);
375*3d8817e4Smiod   bfd_put_8 (info->abfd, type, sym + 4);
376*3d8817e4Smiod   bfd_put_8 (info->abfd, 0, sym + 5);
377*3d8817e4Smiod   bfd_put_16 (info->abfd, desc, sym + 6);
378*3d8817e4Smiod   bfd_put_32 (info->abfd, value, sym + 8);
379*3d8817e4Smiod 
380*3d8817e4Smiod   if (info->symbols_size + STAB_SYMBOL_SIZE > info->symbols_alloc)
381*3d8817e4Smiod     {
382*3d8817e4Smiod       info->symbols_alloc *= 2;
383*3d8817e4Smiod       info->symbols = (bfd_byte *) xrealloc (info->symbols,
384*3d8817e4Smiod 					     info->symbols_alloc);
385*3d8817e4Smiod     }
386*3d8817e4Smiod 
387*3d8817e4Smiod   memcpy (info->symbols + info->symbols_size, sym, STAB_SYMBOL_SIZE);
388*3d8817e4Smiod 
389*3d8817e4Smiod   info->symbols_size += STAB_SYMBOL_SIZE;
390*3d8817e4Smiod 
391*3d8817e4Smiod   return TRUE;
392*3d8817e4Smiod }
393*3d8817e4Smiod 
394*3d8817e4Smiod /* Push a string on to the type stack.  */
395*3d8817e4Smiod 
396*3d8817e4Smiod static bfd_boolean
stab_push_string(struct stab_write_handle * info,const char * string,long index,bfd_boolean definition,unsigned int size)397*3d8817e4Smiod stab_push_string (struct stab_write_handle *info, const char *string,
398*3d8817e4Smiod 		  long index, bfd_boolean definition, unsigned int size)
399*3d8817e4Smiod {
400*3d8817e4Smiod   struct stab_type_stack *s;
401*3d8817e4Smiod 
402*3d8817e4Smiod   s = (struct stab_type_stack *) xmalloc (sizeof *s);
403*3d8817e4Smiod   s->string = xstrdup (string);
404*3d8817e4Smiod   s->index = index;
405*3d8817e4Smiod   s->definition = definition;
406*3d8817e4Smiod   s->size = size;
407*3d8817e4Smiod 
408*3d8817e4Smiod   s->fields = NULL;
409*3d8817e4Smiod   s->baseclasses = NULL;
410*3d8817e4Smiod   s->methods = NULL;
411*3d8817e4Smiod   s->vtable = NULL;
412*3d8817e4Smiod 
413*3d8817e4Smiod   s->next = info->type_stack;
414*3d8817e4Smiod   info->type_stack = s;
415*3d8817e4Smiod 
416*3d8817e4Smiod   return TRUE;
417*3d8817e4Smiod }
418*3d8817e4Smiod 
419*3d8817e4Smiod /* Push a type index which has already been defined.  */
420*3d8817e4Smiod 
421*3d8817e4Smiod static bfd_boolean
stab_push_defined_type(struct stab_write_handle * info,long index,unsigned int size)422*3d8817e4Smiod stab_push_defined_type (struct stab_write_handle *info, long index,
423*3d8817e4Smiod 			unsigned int size)
424*3d8817e4Smiod {
425*3d8817e4Smiod   char buf[20];
426*3d8817e4Smiod 
427*3d8817e4Smiod   sprintf (buf, "%ld", index);
428*3d8817e4Smiod   return stab_push_string (info, buf, index, FALSE, size);
429*3d8817e4Smiod }
430*3d8817e4Smiod 
431*3d8817e4Smiod /* Pop a type off the type stack.  The caller is responsible for
432*3d8817e4Smiod    freeing the string.  */
433*3d8817e4Smiod 
434*3d8817e4Smiod static char *
stab_pop_type(struct stab_write_handle * info)435*3d8817e4Smiod stab_pop_type (struct stab_write_handle *info)
436*3d8817e4Smiod {
437*3d8817e4Smiod   struct stab_type_stack *s;
438*3d8817e4Smiod   char *ret;
439*3d8817e4Smiod 
440*3d8817e4Smiod   s = info->type_stack;
441*3d8817e4Smiod   assert (s != NULL);
442*3d8817e4Smiod 
443*3d8817e4Smiod   info->type_stack = s->next;
444*3d8817e4Smiod 
445*3d8817e4Smiod   ret = s->string;
446*3d8817e4Smiod 
447*3d8817e4Smiod   free (s);
448*3d8817e4Smiod 
449*3d8817e4Smiod   return ret;
450*3d8817e4Smiod }
451*3d8817e4Smiod 
452*3d8817e4Smiod /* The general routine to write out stabs in sections debugging
453*3d8817e4Smiod    information.  This accumulates the stabs symbols and the strings in
454*3d8817e4Smiod    two obstacks.  We can't easily write out the information as we go
455*3d8817e4Smiod    along, because we need to know the section sizes before we can
456*3d8817e4Smiod    write out the section contents.  ABFD is the BFD and DHANDLE is the
457*3d8817e4Smiod    handle for the debugging information.  This sets *PSYMS to point to
458*3d8817e4Smiod    the symbols, *PSYMSIZE the size of the symbols, *PSTRINGS to the
459*3d8817e4Smiod    strings, and *PSTRINGSIZE to the size of the strings.  */
460*3d8817e4Smiod 
461*3d8817e4Smiod bfd_boolean
write_stabs_in_sections_debugging_info(bfd * abfd,void * dhandle,bfd_byte ** psyms,bfd_size_type * psymsize,bfd_byte ** pstrings,bfd_size_type * pstringsize)462*3d8817e4Smiod write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle,
463*3d8817e4Smiod 					bfd_byte **psyms,
464*3d8817e4Smiod 					bfd_size_type *psymsize,
465*3d8817e4Smiod 					bfd_byte **pstrings,
466*3d8817e4Smiod 					bfd_size_type *pstringsize)
467*3d8817e4Smiod {
468*3d8817e4Smiod   struct stab_write_handle info;
469*3d8817e4Smiod   struct string_hash_entry *h;
470*3d8817e4Smiod   bfd_byte *p;
471*3d8817e4Smiod 
472*3d8817e4Smiod   info.abfd = abfd;
473*3d8817e4Smiod 
474*3d8817e4Smiod   info.symbols_size = 0;
475*3d8817e4Smiod   info.symbols_alloc = 500;
476*3d8817e4Smiod   info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc);
477*3d8817e4Smiod 
478*3d8817e4Smiod   info.strings = NULL;
479*3d8817e4Smiod   info.last_string = NULL;
480*3d8817e4Smiod   /* Reserve 1 byte for a null byte.  */
481*3d8817e4Smiod   info.strings_size = 1;
482*3d8817e4Smiod 
483*3d8817e4Smiod   if (!bfd_hash_table_init (&info.strhash.table, string_hash_newfunc,
484*3d8817e4Smiod 			    sizeof (struct string_hash_entry))
485*3d8817e4Smiod       || !bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc,
486*3d8817e4Smiod 			       sizeof (struct string_hash_entry)))
487*3d8817e4Smiod     {
488*3d8817e4Smiod       non_fatal ("bfd_hash_table_init_failed: %s",
489*3d8817e4Smiod 		 bfd_errmsg (bfd_get_error ()));
490*3d8817e4Smiod       return FALSE;
491*3d8817e4Smiod     }
492*3d8817e4Smiod 
493*3d8817e4Smiod   info.type_stack = NULL;
494*3d8817e4Smiod   info.type_index = 1;
495*3d8817e4Smiod   memset (&info.type_cache, 0, sizeof info.type_cache);
496*3d8817e4Smiod   info.so_offset = -1;
497*3d8817e4Smiod   info.fun_offset = -1;
498*3d8817e4Smiod   info.last_text_address = 0;
499*3d8817e4Smiod   info.nesting = 0;
500*3d8817e4Smiod   info.fnaddr = 0;
501*3d8817e4Smiod   info.pending_lbrac = (bfd_vma) -1;
502*3d8817e4Smiod 
503*3d8817e4Smiod   /* The initial symbol holds the string size.  */
504*3d8817e4Smiod   if (! stab_write_symbol (&info, 0, 0, 0, (const char *) NULL))
505*3d8817e4Smiod     return FALSE;
506*3d8817e4Smiod 
507*3d8817e4Smiod   /* Output an initial N_SO symbol.  */
508*3d8817e4Smiod   info.so_offset = info.symbols_size;
509*3d8817e4Smiod   if (! stab_write_symbol (&info, N_SO, 0, 0, bfd_get_filename (abfd)))
510*3d8817e4Smiod     return FALSE;
511*3d8817e4Smiod 
512*3d8817e4Smiod   if (! debug_write (dhandle, &stab_fns, (void *) &info))
513*3d8817e4Smiod     return FALSE;
514*3d8817e4Smiod 
515*3d8817e4Smiod   assert (info.pending_lbrac == (bfd_vma) -1);
516*3d8817e4Smiod 
517*3d8817e4Smiod   /* Output a trailing N_SO.  */
518*3d8817e4Smiod   if (! stab_write_symbol (&info, N_SO, 0, info.last_text_address,
519*3d8817e4Smiod 			   (const char *) NULL))
520*3d8817e4Smiod     return FALSE;
521*3d8817e4Smiod 
522*3d8817e4Smiod   /* Put the string size in the initial symbol.  */
523*3d8817e4Smiod   bfd_put_32 (abfd, info.strings_size, info.symbols + 8);
524*3d8817e4Smiod 
525*3d8817e4Smiod   *psyms = info.symbols;
526*3d8817e4Smiod   *psymsize = info.symbols_size;
527*3d8817e4Smiod 
528*3d8817e4Smiod   *pstringsize = info.strings_size;
529*3d8817e4Smiod   *pstrings = (bfd_byte *) xmalloc (info.strings_size);
530*3d8817e4Smiod 
531*3d8817e4Smiod   p = *pstrings;
532*3d8817e4Smiod   *p++ = '\0';
533*3d8817e4Smiod   for (h = info.strings; h != NULL; h = h->next)
534*3d8817e4Smiod     {
535*3d8817e4Smiod       strcpy ((char *) p, h->root.string);
536*3d8817e4Smiod       p += strlen ((char *) p) + 1;
537*3d8817e4Smiod     }
538*3d8817e4Smiod 
539*3d8817e4Smiod   return TRUE;
540*3d8817e4Smiod }
541*3d8817e4Smiod 
542*3d8817e4Smiod /* Start writing out information for a compilation unit.  */
543*3d8817e4Smiod 
544*3d8817e4Smiod static bfd_boolean
stab_start_compilation_unit(void * p,const char * filename)545*3d8817e4Smiod stab_start_compilation_unit (void *p, const char *filename)
546*3d8817e4Smiod {
547*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
548*3d8817e4Smiod 
549*3d8817e4Smiod   /* We would normally output an N_SO symbol here.  However, that
550*3d8817e4Smiod      would force us to reset all of our type information.  I think we
551*3d8817e4Smiod      will be better off just outputting an N_SOL symbol, and not
552*3d8817e4Smiod      worrying about splitting information between files.  */
553*3d8817e4Smiod 
554*3d8817e4Smiod   info->lineno_filename = filename;
555*3d8817e4Smiod 
556*3d8817e4Smiod   return stab_write_symbol (info, N_SOL, 0, 0, filename);
557*3d8817e4Smiod }
558*3d8817e4Smiod 
559*3d8817e4Smiod /* Start writing out information for a particular source file.  */
560*3d8817e4Smiod 
561*3d8817e4Smiod static bfd_boolean
stab_start_source(void * p,const char * filename)562*3d8817e4Smiod stab_start_source (void *p, const char *filename)
563*3d8817e4Smiod {
564*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
565*3d8817e4Smiod 
566*3d8817e4Smiod   /* FIXME: The symbol's value is supposed to be the text section
567*3d8817e4Smiod      address.  However, we would have to fill it in later, and gdb
568*3d8817e4Smiod      doesn't care, so we don't bother with it.  */
569*3d8817e4Smiod 
570*3d8817e4Smiod   info->lineno_filename = filename;
571*3d8817e4Smiod 
572*3d8817e4Smiod   return stab_write_symbol (info, N_SOL, 0, 0, filename);
573*3d8817e4Smiod }
574*3d8817e4Smiod 
575*3d8817e4Smiod /* Push an empty type.  This shouldn't normally happen.  We just use a
576*3d8817e4Smiod    void type.  */
577*3d8817e4Smiod 
578*3d8817e4Smiod static bfd_boolean
stab_empty_type(void * p)579*3d8817e4Smiod stab_empty_type (void *p)
580*3d8817e4Smiod {
581*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
582*3d8817e4Smiod 
583*3d8817e4Smiod   /* We don't call stab_void_type if the type is not yet defined,
584*3d8817e4Smiod      because that might screw up the typedef.  */
585*3d8817e4Smiod 
586*3d8817e4Smiod   if (info->type_cache.void_type != 0)
587*3d8817e4Smiod     return stab_push_defined_type (info, info->type_cache.void_type, 0);
588*3d8817e4Smiod   else
589*3d8817e4Smiod     {
590*3d8817e4Smiod       long index;
591*3d8817e4Smiod       char buf[40];
592*3d8817e4Smiod 
593*3d8817e4Smiod       index = info->type_index;
594*3d8817e4Smiod       ++info->type_index;
595*3d8817e4Smiod 
596*3d8817e4Smiod       sprintf (buf, "%ld=%ld", index, index);
597*3d8817e4Smiod 
598*3d8817e4Smiod       return stab_push_string (info, buf, index, FALSE, 0);
599*3d8817e4Smiod     }
600*3d8817e4Smiod }
601*3d8817e4Smiod 
602*3d8817e4Smiod /* Push a void type.  */
603*3d8817e4Smiod 
604*3d8817e4Smiod static bfd_boolean
stab_void_type(void * p)605*3d8817e4Smiod stab_void_type (void *p)
606*3d8817e4Smiod {
607*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
608*3d8817e4Smiod 
609*3d8817e4Smiod   if (info->type_cache.void_type != 0)
610*3d8817e4Smiod     return stab_push_defined_type (info, info->type_cache.void_type, 0);
611*3d8817e4Smiod   else
612*3d8817e4Smiod     {
613*3d8817e4Smiod       long index;
614*3d8817e4Smiod       char buf[40];
615*3d8817e4Smiod 
616*3d8817e4Smiod       index = info->type_index;
617*3d8817e4Smiod       ++info->type_index;
618*3d8817e4Smiod 
619*3d8817e4Smiod       info->type_cache.void_type = index;
620*3d8817e4Smiod 
621*3d8817e4Smiod       sprintf (buf, "%ld=%ld", index, index);
622*3d8817e4Smiod 
623*3d8817e4Smiod       return stab_push_string (info, buf, index, TRUE, 0);
624*3d8817e4Smiod     }
625*3d8817e4Smiod }
626*3d8817e4Smiod 
627*3d8817e4Smiod /* Push an integer type.  */
628*3d8817e4Smiod 
629*3d8817e4Smiod static bfd_boolean
stab_int_type(void * p,unsigned int size,bfd_boolean unsignedp)630*3d8817e4Smiod stab_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
631*3d8817e4Smiod {
632*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
633*3d8817e4Smiod   long *cache;
634*3d8817e4Smiod 
635*3d8817e4Smiod   if (size <= 0 || (size > sizeof (long) && size != 8))
636*3d8817e4Smiod     {
637*3d8817e4Smiod       non_fatal (_("stab_int_type: bad size %u"), size);
638*3d8817e4Smiod       return FALSE;
639*3d8817e4Smiod     }
640*3d8817e4Smiod 
641*3d8817e4Smiod   if (unsignedp)
642*3d8817e4Smiod     cache = info->type_cache.signed_integer_types;
643*3d8817e4Smiod   else
644*3d8817e4Smiod     cache = info->type_cache.unsigned_integer_types;
645*3d8817e4Smiod 
646*3d8817e4Smiod   if (cache[size - 1] != 0)
647*3d8817e4Smiod     return stab_push_defined_type (info, cache[size - 1], size);
648*3d8817e4Smiod   else
649*3d8817e4Smiod     {
650*3d8817e4Smiod       long index;
651*3d8817e4Smiod       char buf[100];
652*3d8817e4Smiod 
653*3d8817e4Smiod       index = info->type_index;
654*3d8817e4Smiod       ++info->type_index;
655*3d8817e4Smiod 
656*3d8817e4Smiod       cache[size - 1] = index;
657*3d8817e4Smiod 
658*3d8817e4Smiod       sprintf (buf, "%ld=r%ld;", index, index);
659*3d8817e4Smiod       if (unsignedp)
660*3d8817e4Smiod 	{
661*3d8817e4Smiod 	  strcat (buf, "0;");
662*3d8817e4Smiod 	  if (size < sizeof (long))
663*3d8817e4Smiod 	    sprintf (buf + strlen (buf), "%ld;", ((long) 1 << (size * 8)) - 1);
664*3d8817e4Smiod 	  else if (size == sizeof (long))
665*3d8817e4Smiod 	    strcat (buf, "-1;");
666*3d8817e4Smiod 	  else if (size == 8)
667*3d8817e4Smiod 	    strcat (buf, "01777777777777777777777;");
668*3d8817e4Smiod 	  else
669*3d8817e4Smiod 	    abort ();
670*3d8817e4Smiod 	}
671*3d8817e4Smiod       else
672*3d8817e4Smiod 	{
673*3d8817e4Smiod 	  if (size <= sizeof (long))
674*3d8817e4Smiod 	    sprintf (buf + strlen (buf), "%ld;%ld;",
675*3d8817e4Smiod 		     (long) - ((unsigned long) 1 << (size * 8 - 1)),
676*3d8817e4Smiod 		     (long) (((unsigned long) 1 << (size * 8 - 1)) - 1));
677*3d8817e4Smiod 	  else if (size == 8)
678*3d8817e4Smiod 	    strcat (buf, "01000000000000000000000;0777777777777777777777;");
679*3d8817e4Smiod 	  else
680*3d8817e4Smiod 	    abort ();
681*3d8817e4Smiod 	}
682*3d8817e4Smiod 
683*3d8817e4Smiod       return stab_push_string (info, buf, index, TRUE, size);
684*3d8817e4Smiod     }
685*3d8817e4Smiod }
686*3d8817e4Smiod 
687*3d8817e4Smiod /* Push a floating point type.  */
688*3d8817e4Smiod 
689*3d8817e4Smiod static bfd_boolean
stab_float_type(void * p,unsigned int size)690*3d8817e4Smiod stab_float_type (void *p, unsigned int size)
691*3d8817e4Smiod {
692*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
693*3d8817e4Smiod 
694*3d8817e4Smiod   if (size > 0
695*3d8817e4Smiod       && size - 1 < (sizeof info->type_cache.float_types
696*3d8817e4Smiod 		     / sizeof info->type_cache.float_types[0])
697*3d8817e4Smiod       && info->type_cache.float_types[size - 1] != 0)
698*3d8817e4Smiod     return stab_push_defined_type (info,
699*3d8817e4Smiod 				   info->type_cache.float_types[size - 1],
700*3d8817e4Smiod 				   size);
701*3d8817e4Smiod   else
702*3d8817e4Smiod     {
703*3d8817e4Smiod       long index;
704*3d8817e4Smiod       char *int_type;
705*3d8817e4Smiod       char buf[50];
706*3d8817e4Smiod 
707*3d8817e4Smiod       /* Floats are defined as a subrange of int.  */
708*3d8817e4Smiod       if (! stab_int_type (info, 4, FALSE))
709*3d8817e4Smiod 	return FALSE;
710*3d8817e4Smiod       int_type = stab_pop_type (info);
711*3d8817e4Smiod 
712*3d8817e4Smiod       index = info->type_index;
713*3d8817e4Smiod       ++info->type_index;
714*3d8817e4Smiod 
715*3d8817e4Smiod       if (size > 0
716*3d8817e4Smiod 	  && size - 1 < (sizeof info->type_cache.float_types
717*3d8817e4Smiod 			 / sizeof info->type_cache.float_types[0]))
718*3d8817e4Smiod 	info->type_cache.float_types[size - 1] = index;
719*3d8817e4Smiod 
720*3d8817e4Smiod       sprintf (buf, "%ld=r%s;%u;0;", index, int_type, size);
721*3d8817e4Smiod 
722*3d8817e4Smiod       free (int_type);
723*3d8817e4Smiod 
724*3d8817e4Smiod       return stab_push_string (info, buf, index, TRUE, size);
725*3d8817e4Smiod     }
726*3d8817e4Smiod }
727*3d8817e4Smiod 
728*3d8817e4Smiod /* Push a complex type.  */
729*3d8817e4Smiod 
730*3d8817e4Smiod static bfd_boolean
stab_complex_type(void * p,unsigned int size)731*3d8817e4Smiod stab_complex_type (void *p, unsigned int size)
732*3d8817e4Smiod {
733*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
734*3d8817e4Smiod   char buf[50];
735*3d8817e4Smiod   long index;
736*3d8817e4Smiod 
737*3d8817e4Smiod   index = info->type_index;
738*3d8817e4Smiod   ++info->type_index;
739*3d8817e4Smiod 
740*3d8817e4Smiod   sprintf (buf, "%ld=r%ld;%u;0;", index, index, size);
741*3d8817e4Smiod 
742*3d8817e4Smiod   return stab_push_string (info, buf, index, TRUE, size * 2);
743*3d8817e4Smiod }
744*3d8817e4Smiod 
745*3d8817e4Smiod /* Push a bfd_boolean type.  We use an XCOFF predefined type, since gdb
746*3d8817e4Smiod    always recognizes them.  */
747*3d8817e4Smiod 
748*3d8817e4Smiod static bfd_boolean
stab_bool_type(void * p,unsigned int size)749*3d8817e4Smiod stab_bool_type (void *p, unsigned int size)
750*3d8817e4Smiod {
751*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
752*3d8817e4Smiod   long index;
753*3d8817e4Smiod 
754*3d8817e4Smiod   switch (size)
755*3d8817e4Smiod     {
756*3d8817e4Smiod     case 1:
757*3d8817e4Smiod       index = -21;
758*3d8817e4Smiod       break;
759*3d8817e4Smiod 
760*3d8817e4Smiod     case 2:
761*3d8817e4Smiod       index = -22;
762*3d8817e4Smiod       break;
763*3d8817e4Smiod 
764*3d8817e4Smiod     default:
765*3d8817e4Smiod     case 4:
766*3d8817e4Smiod       index = -16;
767*3d8817e4Smiod       break;
768*3d8817e4Smiod 
769*3d8817e4Smiod     case 8:
770*3d8817e4Smiod       index = -33;
771*3d8817e4Smiod       break;
772*3d8817e4Smiod     }
773*3d8817e4Smiod 
774*3d8817e4Smiod   return stab_push_defined_type (info, index, size);
775*3d8817e4Smiod }
776*3d8817e4Smiod 
777*3d8817e4Smiod /* Push an enum type.  */
778*3d8817e4Smiod 
779*3d8817e4Smiod static bfd_boolean
stab_enum_type(void * p,const char * tag,const char ** names,bfd_signed_vma * vals)780*3d8817e4Smiod stab_enum_type (void *p, const char *tag, const char **names,
781*3d8817e4Smiod 		bfd_signed_vma *vals)
782*3d8817e4Smiod {
783*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
784*3d8817e4Smiod   size_t len;
785*3d8817e4Smiod   const char **pn;
786*3d8817e4Smiod   char *buf;
787*3d8817e4Smiod   long index = 0;
788*3d8817e4Smiod   bfd_signed_vma *pv;
789*3d8817e4Smiod 
790*3d8817e4Smiod   if (names == NULL)
791*3d8817e4Smiod     {
792*3d8817e4Smiod       assert (tag != NULL);
793*3d8817e4Smiod 
794*3d8817e4Smiod       buf = (char *) xmalloc (10 + strlen (tag));
795*3d8817e4Smiod       sprintf (buf, "xe%s:", tag);
796*3d8817e4Smiod       /* FIXME: The size is just a guess.  */
797*3d8817e4Smiod       if (! stab_push_string (info, buf, 0, FALSE, 4))
798*3d8817e4Smiod 	return FALSE;
799*3d8817e4Smiod       free (buf);
800*3d8817e4Smiod       return TRUE;
801*3d8817e4Smiod     }
802*3d8817e4Smiod 
803*3d8817e4Smiod   len = 10;
804*3d8817e4Smiod   if (tag != NULL)
805*3d8817e4Smiod     len += strlen (tag);
806*3d8817e4Smiod   for (pn = names; *pn != NULL; pn++)
807*3d8817e4Smiod     len += strlen (*pn) + 20;
808*3d8817e4Smiod 
809*3d8817e4Smiod   buf = (char *) xmalloc (len);
810*3d8817e4Smiod 
811*3d8817e4Smiod   if (tag == NULL)
812*3d8817e4Smiod     strcpy (buf, "e");
813*3d8817e4Smiod   else
814*3d8817e4Smiod     {
815*3d8817e4Smiod       index = info->type_index;
816*3d8817e4Smiod       ++info->type_index;
817*3d8817e4Smiod       sprintf (buf, "%s:T%ld=e", tag, index);
818*3d8817e4Smiod     }
819*3d8817e4Smiod 
820*3d8817e4Smiod   for (pn = names, pv = vals; *pn != NULL; pn++, pv++)
821*3d8817e4Smiod     sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv);
822*3d8817e4Smiod   strcat (buf, ";");
823*3d8817e4Smiod 
824*3d8817e4Smiod   if (tag == NULL)
825*3d8817e4Smiod     {
826*3d8817e4Smiod       /* FIXME: The size is just a guess.  */
827*3d8817e4Smiod       if (! stab_push_string (info, buf, 0, FALSE, 4))
828*3d8817e4Smiod 	return FALSE;
829*3d8817e4Smiod     }
830*3d8817e4Smiod   else
831*3d8817e4Smiod     {
832*3d8817e4Smiod       /* FIXME: The size is just a guess.  */
833*3d8817e4Smiod       if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)
834*3d8817e4Smiod 	  || ! stab_push_defined_type (info, index, 4))
835*3d8817e4Smiod 	return FALSE;
836*3d8817e4Smiod     }
837*3d8817e4Smiod 
838*3d8817e4Smiod   free (buf);
839*3d8817e4Smiod 
840*3d8817e4Smiod   return TRUE;
841*3d8817e4Smiod }
842*3d8817e4Smiod 
843*3d8817e4Smiod /* Push a modification of the top type on the stack.  Cache the
844*3d8817e4Smiod    results in CACHE and CACHE_ALLOC.  */
845*3d8817e4Smiod 
846*3d8817e4Smiod static bfd_boolean
stab_modify_type(struct stab_write_handle * info,int mod,unsigned int size,long ** cache,size_t * cache_alloc)847*3d8817e4Smiod stab_modify_type (struct stab_write_handle *info, int mod,
848*3d8817e4Smiod 		  unsigned int size, long **cache, size_t *cache_alloc)
849*3d8817e4Smiod {
850*3d8817e4Smiod   long targindex;
851*3d8817e4Smiod   long index;
852*3d8817e4Smiod   char *s, *buf;
853*3d8817e4Smiod 
854*3d8817e4Smiod   assert (info->type_stack != NULL);
855*3d8817e4Smiod   targindex = info->type_stack->index;
856*3d8817e4Smiod 
857*3d8817e4Smiod   if (targindex <= 0
858*3d8817e4Smiod       || cache == NULL)
859*3d8817e4Smiod     {
860*3d8817e4Smiod       bfd_boolean definition;
861*3d8817e4Smiod 
862*3d8817e4Smiod       /* Either the target type has no index, or we aren't caching
863*3d8817e4Smiod          this modifier.  Either way we have no way of recording the
864*3d8817e4Smiod          new type, so we don't bother to define one.  */
865*3d8817e4Smiod       definition = info->type_stack->definition;
866*3d8817e4Smiod       s = stab_pop_type (info);
867*3d8817e4Smiod       buf = (char *) xmalloc (strlen (s) + 2);
868*3d8817e4Smiod       sprintf (buf, "%c%s", mod, s);
869*3d8817e4Smiod       free (s);
870*3d8817e4Smiod       if (! stab_push_string (info, buf, 0, definition, size))
871*3d8817e4Smiod 	return FALSE;
872*3d8817e4Smiod       free (buf);
873*3d8817e4Smiod     }
874*3d8817e4Smiod   else
875*3d8817e4Smiod     {
876*3d8817e4Smiod       if ((size_t) targindex >= *cache_alloc)
877*3d8817e4Smiod 	{
878*3d8817e4Smiod 	  size_t alloc;
879*3d8817e4Smiod 
880*3d8817e4Smiod 	  alloc = *cache_alloc;
881*3d8817e4Smiod 	  if (alloc == 0)
882*3d8817e4Smiod 	    alloc = 10;
883*3d8817e4Smiod 	  while ((size_t) targindex >= alloc)
884*3d8817e4Smiod 	    alloc *= 2;
885*3d8817e4Smiod 	  *cache = (long *) xrealloc (*cache, alloc * sizeof (long));
886*3d8817e4Smiod 	  memset (*cache + *cache_alloc, 0,
887*3d8817e4Smiod 		  (alloc - *cache_alloc) * sizeof (long));
888*3d8817e4Smiod 	  *cache_alloc = alloc;
889*3d8817e4Smiod 	}
890*3d8817e4Smiod 
891*3d8817e4Smiod       index = (*cache)[targindex];
892*3d8817e4Smiod       if (index != 0 && ! info->type_stack->definition)
893*3d8817e4Smiod 	{
894*3d8817e4Smiod 	  /* We have already defined a modification of this type, and
895*3d8817e4Smiod              the entry on the type stack is not a definition, so we
896*3d8817e4Smiod              can safely discard it (we may have a definition on the
897*3d8817e4Smiod              stack, even if we already defined a modification, if it
898*3d8817e4Smiod              is a struct which we did not define at the time it was
899*3d8817e4Smiod              referenced).  */
900*3d8817e4Smiod 	  free (stab_pop_type (info));
901*3d8817e4Smiod 	  if (! stab_push_defined_type (info, index, size))
902*3d8817e4Smiod 	    return FALSE;
903*3d8817e4Smiod 	}
904*3d8817e4Smiod       else
905*3d8817e4Smiod 	{
906*3d8817e4Smiod 	  index = info->type_index;
907*3d8817e4Smiod 	  ++info->type_index;
908*3d8817e4Smiod 
909*3d8817e4Smiod 	  s = stab_pop_type (info);
910*3d8817e4Smiod 	  buf = (char *) xmalloc (strlen (s) + 20);
911*3d8817e4Smiod 	  sprintf (buf, "%ld=%c%s", index, mod, s);
912*3d8817e4Smiod 	  free (s);
913*3d8817e4Smiod 
914*3d8817e4Smiod 	  (*cache)[targindex] = index;
915*3d8817e4Smiod 
916*3d8817e4Smiod 	  if (! stab_push_string (info, buf, index, TRUE, size))
917*3d8817e4Smiod 	    return FALSE;
918*3d8817e4Smiod 
919*3d8817e4Smiod 	  free (buf);
920*3d8817e4Smiod 	}
921*3d8817e4Smiod     }
922*3d8817e4Smiod 
923*3d8817e4Smiod   return TRUE;
924*3d8817e4Smiod }
925*3d8817e4Smiod 
926*3d8817e4Smiod /* Push a pointer type.  */
927*3d8817e4Smiod 
928*3d8817e4Smiod static bfd_boolean
stab_pointer_type(void * p)929*3d8817e4Smiod stab_pointer_type (void *p)
930*3d8817e4Smiod {
931*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
932*3d8817e4Smiod 
933*3d8817e4Smiod   /* FIXME: The size should depend upon the architecture.  */
934*3d8817e4Smiod   return stab_modify_type (info, '*', 4, &info->type_cache.pointer_types,
935*3d8817e4Smiod 			   &info->type_cache.pointer_types_alloc);
936*3d8817e4Smiod }
937*3d8817e4Smiod 
938*3d8817e4Smiod /* Push a function type.  */
939*3d8817e4Smiod 
940*3d8817e4Smiod static bfd_boolean
stab_function_type(void * p,int argcount,bfd_boolean varargs ATTRIBUTE_UNUSED)941*3d8817e4Smiod stab_function_type (void *p, int argcount,
942*3d8817e4Smiod 		    bfd_boolean varargs ATTRIBUTE_UNUSED)
943*3d8817e4Smiod {
944*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
945*3d8817e4Smiod   int i;
946*3d8817e4Smiod 
947*3d8817e4Smiod   /* We have no way to represent the argument types, so we just
948*3d8817e4Smiod      discard them.  However, if they define new types, we must output
949*3d8817e4Smiod      them.  We do this by producing empty typedefs.  */
950*3d8817e4Smiod   for (i = 0; i < argcount; i++)
951*3d8817e4Smiod     {
952*3d8817e4Smiod       if (! info->type_stack->definition)
953*3d8817e4Smiod 	free (stab_pop_type (info));
954*3d8817e4Smiod       else
955*3d8817e4Smiod 	{
956*3d8817e4Smiod 	  char *s, *buf;
957*3d8817e4Smiod 
958*3d8817e4Smiod 	  s = stab_pop_type (info);
959*3d8817e4Smiod 
960*3d8817e4Smiod 	  buf = (char *) xmalloc (strlen (s) + 3);
961*3d8817e4Smiod 	  sprintf (buf, ":t%s", s);
962*3d8817e4Smiod 	  free (s);
963*3d8817e4Smiod 
964*3d8817e4Smiod 	  if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
965*3d8817e4Smiod 	    return FALSE;
966*3d8817e4Smiod 
967*3d8817e4Smiod 	  free (buf);
968*3d8817e4Smiod 	}
969*3d8817e4Smiod     }
970*3d8817e4Smiod 
971*3d8817e4Smiod   return stab_modify_type (info, 'f', 0, &info->type_cache.function_types,
972*3d8817e4Smiod 			   &info->type_cache.function_types_alloc);
973*3d8817e4Smiod }
974*3d8817e4Smiod 
975*3d8817e4Smiod /* Push a reference type.  */
976*3d8817e4Smiod 
977*3d8817e4Smiod static bfd_boolean
stab_reference_type(void * p)978*3d8817e4Smiod stab_reference_type (void *p)
979*3d8817e4Smiod {
980*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
981*3d8817e4Smiod 
982*3d8817e4Smiod   /* FIXME: The size should depend upon the architecture.  */
983*3d8817e4Smiod   return stab_modify_type (info, '&', 4, &info->type_cache.reference_types,
984*3d8817e4Smiod 			   &info->type_cache.reference_types_alloc);
985*3d8817e4Smiod }
986*3d8817e4Smiod 
987*3d8817e4Smiod /* Push a range type.  */
988*3d8817e4Smiod 
989*3d8817e4Smiod static bfd_boolean
stab_range_type(void * p,bfd_signed_vma low,bfd_signed_vma high)990*3d8817e4Smiod stab_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high)
991*3d8817e4Smiod {
992*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
993*3d8817e4Smiod   bfd_boolean definition;
994*3d8817e4Smiod   unsigned int size;
995*3d8817e4Smiod   char *s, *buf;
996*3d8817e4Smiod 
997*3d8817e4Smiod   definition = info->type_stack->definition;
998*3d8817e4Smiod   size = info->type_stack->size;
999*3d8817e4Smiod 
1000*3d8817e4Smiod   s = stab_pop_type (info);
1001*3d8817e4Smiod   buf = (char *) xmalloc (strlen (s) + 100);
1002*3d8817e4Smiod   sprintf (buf, "r%s;%ld;%ld;", s, (long) low, (long) high);
1003*3d8817e4Smiod   free (s);
1004*3d8817e4Smiod 
1005*3d8817e4Smiod   if (! stab_push_string (info, buf, 0, definition, size))
1006*3d8817e4Smiod     return FALSE;
1007*3d8817e4Smiod 
1008*3d8817e4Smiod   free (buf);
1009*3d8817e4Smiod 
1010*3d8817e4Smiod   return TRUE;
1011*3d8817e4Smiod }
1012*3d8817e4Smiod 
1013*3d8817e4Smiod /* Push an array type.  */
1014*3d8817e4Smiod 
1015*3d8817e4Smiod static bfd_boolean
stab_array_type(void * p,bfd_signed_vma low,bfd_signed_vma high,bfd_boolean stringp)1016*3d8817e4Smiod stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high,
1017*3d8817e4Smiod 		 bfd_boolean stringp)
1018*3d8817e4Smiod {
1019*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1020*3d8817e4Smiod   bfd_boolean definition;
1021*3d8817e4Smiod   unsigned int element_size;
1022*3d8817e4Smiod   char *range, *element, *buf;
1023*3d8817e4Smiod   long index;
1024*3d8817e4Smiod   unsigned int size;
1025*3d8817e4Smiod 
1026*3d8817e4Smiod   definition = info->type_stack->definition;
1027*3d8817e4Smiod   range = stab_pop_type (info);
1028*3d8817e4Smiod 
1029*3d8817e4Smiod   definition = definition || info->type_stack->definition;
1030*3d8817e4Smiod   element_size = info->type_stack->size;
1031*3d8817e4Smiod   element = stab_pop_type (info);
1032*3d8817e4Smiod 
1033*3d8817e4Smiod   buf = (char *) xmalloc (strlen (range) + strlen (element) + 100);
1034*3d8817e4Smiod 
1035*3d8817e4Smiod   if (! stringp)
1036*3d8817e4Smiod     {
1037*3d8817e4Smiod       index = 0;
1038*3d8817e4Smiod       *buf = '\0';
1039*3d8817e4Smiod     }
1040*3d8817e4Smiod   else
1041*3d8817e4Smiod     {
1042*3d8817e4Smiod       /* We need to define a type in order to include the string
1043*3d8817e4Smiod          attribute.  */
1044*3d8817e4Smiod       index = info->type_index;
1045*3d8817e4Smiod       ++info->type_index;
1046*3d8817e4Smiod       definition = TRUE;
1047*3d8817e4Smiod       sprintf (buf, "%ld=@S;", index);
1048*3d8817e4Smiod     }
1049*3d8817e4Smiod 
1050*3d8817e4Smiod   sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s",
1051*3d8817e4Smiod 	   range, (long) low, (long) high, element);
1052*3d8817e4Smiod   free (range);
1053*3d8817e4Smiod   free (element);
1054*3d8817e4Smiod 
1055*3d8817e4Smiod   if (high < low)
1056*3d8817e4Smiod     size = 0;
1057*3d8817e4Smiod   else
1058*3d8817e4Smiod     size = element_size * ((high - low) + 1);
1059*3d8817e4Smiod   if (! stab_push_string (info, buf, index, definition, size))
1060*3d8817e4Smiod     return FALSE;
1061*3d8817e4Smiod 
1062*3d8817e4Smiod   free (buf);
1063*3d8817e4Smiod 
1064*3d8817e4Smiod   return TRUE;
1065*3d8817e4Smiod }
1066*3d8817e4Smiod 
1067*3d8817e4Smiod /* Push a set type.  */
1068*3d8817e4Smiod 
1069*3d8817e4Smiod static bfd_boolean
stab_set_type(void * p,bfd_boolean bitstringp)1070*3d8817e4Smiod stab_set_type (void *p, bfd_boolean bitstringp)
1071*3d8817e4Smiod {
1072*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1073*3d8817e4Smiod   bfd_boolean definition;
1074*3d8817e4Smiod   char *s, *buf;
1075*3d8817e4Smiod   long index;
1076*3d8817e4Smiod 
1077*3d8817e4Smiod   definition = info->type_stack->definition;
1078*3d8817e4Smiod 
1079*3d8817e4Smiod   s = stab_pop_type (info);
1080*3d8817e4Smiod   buf = (char *) xmalloc (strlen (s) + 30);
1081*3d8817e4Smiod 
1082*3d8817e4Smiod   if (! bitstringp)
1083*3d8817e4Smiod     {
1084*3d8817e4Smiod       *buf = '\0';
1085*3d8817e4Smiod       index = 0;
1086*3d8817e4Smiod     }
1087*3d8817e4Smiod   else
1088*3d8817e4Smiod     {
1089*3d8817e4Smiod       /* We need to define a type in order to include the string
1090*3d8817e4Smiod          attribute.  */
1091*3d8817e4Smiod       index = info->type_index;
1092*3d8817e4Smiod       ++info->type_index;
1093*3d8817e4Smiod       definition = TRUE;
1094*3d8817e4Smiod       sprintf (buf, "%ld=@S;", index);
1095*3d8817e4Smiod     }
1096*3d8817e4Smiod 
1097*3d8817e4Smiod   sprintf (buf + strlen (buf), "S%s", s);
1098*3d8817e4Smiod   free (s);
1099*3d8817e4Smiod 
1100*3d8817e4Smiod   if (! stab_push_string (info, buf, index, definition, 0))
1101*3d8817e4Smiod     return FALSE;
1102*3d8817e4Smiod 
1103*3d8817e4Smiod   free (buf);
1104*3d8817e4Smiod 
1105*3d8817e4Smiod   return TRUE;
1106*3d8817e4Smiod }
1107*3d8817e4Smiod 
1108*3d8817e4Smiod /* Push an offset type.  */
1109*3d8817e4Smiod 
1110*3d8817e4Smiod static bfd_boolean
stab_offset_type(void * p)1111*3d8817e4Smiod stab_offset_type (void *p)
1112*3d8817e4Smiod {
1113*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1114*3d8817e4Smiod   bfd_boolean definition;
1115*3d8817e4Smiod   char *target, *base, *buf;
1116*3d8817e4Smiod 
1117*3d8817e4Smiod   definition = info->type_stack->definition;
1118*3d8817e4Smiod   target = stab_pop_type (info);
1119*3d8817e4Smiod 
1120*3d8817e4Smiod   definition = definition || info->type_stack->definition;
1121*3d8817e4Smiod   base = stab_pop_type (info);
1122*3d8817e4Smiod 
1123*3d8817e4Smiod   buf = (char *) xmalloc (strlen (target) + strlen (base) + 3);
1124*3d8817e4Smiod   sprintf (buf, "@%s,%s", base, target);
1125*3d8817e4Smiod   free (base);
1126*3d8817e4Smiod   free (target);
1127*3d8817e4Smiod 
1128*3d8817e4Smiod   if (! stab_push_string (info, buf, 0, definition, 0))
1129*3d8817e4Smiod     return FALSE;
1130*3d8817e4Smiod 
1131*3d8817e4Smiod   free (buf);
1132*3d8817e4Smiod 
1133*3d8817e4Smiod   return TRUE;
1134*3d8817e4Smiod }
1135*3d8817e4Smiod 
1136*3d8817e4Smiod /* Push a method type.  */
1137*3d8817e4Smiod 
1138*3d8817e4Smiod static bfd_boolean
stab_method_type(void * p,bfd_boolean domainp,int argcount,bfd_boolean varargs)1139*3d8817e4Smiod stab_method_type (void *p, bfd_boolean domainp, int argcount,
1140*3d8817e4Smiod 		  bfd_boolean varargs)
1141*3d8817e4Smiod {
1142*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1143*3d8817e4Smiod   bfd_boolean definition;
1144*3d8817e4Smiod   char *domain, *return_type, *buf;
1145*3d8817e4Smiod   char **args;
1146*3d8817e4Smiod   int i;
1147*3d8817e4Smiod   size_t len;
1148*3d8817e4Smiod 
1149*3d8817e4Smiod   /* We don't bother with stub method types, because that would
1150*3d8817e4Smiod      require a mangler for C++ argument types.  This will waste space
1151*3d8817e4Smiod      in the debugging output.  */
1152*3d8817e4Smiod 
1153*3d8817e4Smiod   /* We need a domain.  I'm not sure DOMAINP can ever be false,
1154*3d8817e4Smiod      anyhow.  */
1155*3d8817e4Smiod   if (! domainp)
1156*3d8817e4Smiod     {
1157*3d8817e4Smiod       if (! stab_empty_type (p))
1158*3d8817e4Smiod 	return FALSE;
1159*3d8817e4Smiod     }
1160*3d8817e4Smiod 
1161*3d8817e4Smiod   definition = info->type_stack->definition;
1162*3d8817e4Smiod   domain = stab_pop_type (info);
1163*3d8817e4Smiod 
1164*3d8817e4Smiod   /* A non-varargs function is indicated by making the last parameter
1165*3d8817e4Smiod      type be void.  */
1166*3d8817e4Smiod 
1167*3d8817e4Smiod   if (argcount < 0)
1168*3d8817e4Smiod     {
1169*3d8817e4Smiod       args = NULL;
1170*3d8817e4Smiod       argcount = 0;
1171*3d8817e4Smiod     }
1172*3d8817e4Smiod   else if (argcount == 0)
1173*3d8817e4Smiod     {
1174*3d8817e4Smiod       if (varargs)
1175*3d8817e4Smiod 	args = NULL;
1176*3d8817e4Smiod       else
1177*3d8817e4Smiod 	{
1178*3d8817e4Smiod 	  args = (char **) xmalloc (1 * sizeof (*args));
1179*3d8817e4Smiod 	  if (! stab_empty_type (p))
1180*3d8817e4Smiod 	    return FALSE;
1181*3d8817e4Smiod 	  definition = definition || info->type_stack->definition;
1182*3d8817e4Smiod 	  args[0] = stab_pop_type (info);
1183*3d8817e4Smiod 	  argcount = 1;
1184*3d8817e4Smiod 	}
1185*3d8817e4Smiod     }
1186*3d8817e4Smiod   else
1187*3d8817e4Smiod     {
1188*3d8817e4Smiod       args = (char **) xmalloc ((argcount + 1) * sizeof (*args));
1189*3d8817e4Smiod       for (i = argcount - 1; i >= 0; i--)
1190*3d8817e4Smiod 	{
1191*3d8817e4Smiod 	  definition = definition || info->type_stack->definition;
1192*3d8817e4Smiod 	  args[i] = stab_pop_type (info);
1193*3d8817e4Smiod 	}
1194*3d8817e4Smiod       if (! varargs)
1195*3d8817e4Smiod 	{
1196*3d8817e4Smiod 	  if (! stab_empty_type (p))
1197*3d8817e4Smiod 	    return FALSE;
1198*3d8817e4Smiod 	  definition = definition || info->type_stack->definition;
1199*3d8817e4Smiod 	  args[argcount] = stab_pop_type (info);
1200*3d8817e4Smiod 	  ++argcount;
1201*3d8817e4Smiod 	}
1202*3d8817e4Smiod     }
1203*3d8817e4Smiod 
1204*3d8817e4Smiod   definition = definition || info->type_stack->definition;
1205*3d8817e4Smiod   return_type = stab_pop_type (info);
1206*3d8817e4Smiod 
1207*3d8817e4Smiod   len = strlen (domain) + strlen (return_type) + 10;
1208*3d8817e4Smiod   for (i = 0; i < argcount; i++)
1209*3d8817e4Smiod     len += strlen (args[i]);
1210*3d8817e4Smiod 
1211*3d8817e4Smiod   buf = (char *) xmalloc (len);
1212*3d8817e4Smiod 
1213*3d8817e4Smiod   sprintf (buf, "#%s,%s", domain, return_type);
1214*3d8817e4Smiod   free (domain);
1215*3d8817e4Smiod   free (return_type);
1216*3d8817e4Smiod   for (i = 0; i < argcount; i++)
1217*3d8817e4Smiod     {
1218*3d8817e4Smiod       strcat (buf, ",");
1219*3d8817e4Smiod       strcat (buf, args[i]);
1220*3d8817e4Smiod       free (args[i]);
1221*3d8817e4Smiod     }
1222*3d8817e4Smiod   strcat (buf, ";");
1223*3d8817e4Smiod 
1224*3d8817e4Smiod   if (args != NULL)
1225*3d8817e4Smiod     free (args);
1226*3d8817e4Smiod 
1227*3d8817e4Smiod   if (! stab_push_string (info, buf, 0, definition, 0))
1228*3d8817e4Smiod     return FALSE;
1229*3d8817e4Smiod 
1230*3d8817e4Smiod   free (buf);
1231*3d8817e4Smiod 
1232*3d8817e4Smiod   return TRUE;
1233*3d8817e4Smiod }
1234*3d8817e4Smiod 
1235*3d8817e4Smiod /* Push a const version of a type.  */
1236*3d8817e4Smiod 
1237*3d8817e4Smiod static bfd_boolean
stab_const_type(void * p)1238*3d8817e4Smiod stab_const_type (void *p)
1239*3d8817e4Smiod {
1240*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1241*3d8817e4Smiod 
1242*3d8817e4Smiod   return stab_modify_type (info, 'k', info->type_stack->size,
1243*3d8817e4Smiod 			   (long **) NULL, (size_t *) NULL);
1244*3d8817e4Smiod }
1245*3d8817e4Smiod 
1246*3d8817e4Smiod /* Push a volatile version of a type.  */
1247*3d8817e4Smiod 
1248*3d8817e4Smiod static bfd_boolean
stab_volatile_type(void * p)1249*3d8817e4Smiod stab_volatile_type (void *p)
1250*3d8817e4Smiod {
1251*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1252*3d8817e4Smiod 
1253*3d8817e4Smiod   return stab_modify_type (info, 'B', info->type_stack->size,
1254*3d8817e4Smiod 			   (long **) NULL, (size_t *) NULL);
1255*3d8817e4Smiod }
1256*3d8817e4Smiod 
1257*3d8817e4Smiod /* Get the type index to use for a struct/union/class ID.  This should
1258*3d8817e4Smiod    return -1 if it fails.  */
1259*3d8817e4Smiod 
1260*3d8817e4Smiod static long
stab_get_struct_index(struct stab_write_handle * info,const char * tag,unsigned int id,enum debug_type_kind kind,unsigned int * psize)1261*3d8817e4Smiod stab_get_struct_index (struct stab_write_handle *info, const char *tag,
1262*3d8817e4Smiod 		       unsigned int id, enum debug_type_kind kind,
1263*3d8817e4Smiod 		       unsigned int *psize)
1264*3d8817e4Smiod {
1265*3d8817e4Smiod   if (id >= info->type_cache.struct_types_alloc)
1266*3d8817e4Smiod     {
1267*3d8817e4Smiod       size_t alloc;
1268*3d8817e4Smiod 
1269*3d8817e4Smiod       alloc = info->type_cache.struct_types_alloc;
1270*3d8817e4Smiod       if (alloc == 0)
1271*3d8817e4Smiod 	alloc = 10;
1272*3d8817e4Smiod       while (id >= alloc)
1273*3d8817e4Smiod 	alloc *= 2;
1274*3d8817e4Smiod       info->type_cache.struct_types =
1275*3d8817e4Smiod 	(struct stab_tag *) xrealloc (info->type_cache.struct_types,
1276*3d8817e4Smiod 				      alloc * sizeof (struct stab_tag));
1277*3d8817e4Smiod       memset ((info->type_cache.struct_types
1278*3d8817e4Smiod 	       + info->type_cache.struct_types_alloc),
1279*3d8817e4Smiod 	      0,
1280*3d8817e4Smiod 	      ((alloc - info->type_cache.struct_types_alloc)
1281*3d8817e4Smiod 	       * sizeof (struct stab_tag)));
1282*3d8817e4Smiod       info->type_cache.struct_types_alloc = alloc;
1283*3d8817e4Smiod     }
1284*3d8817e4Smiod 
1285*3d8817e4Smiod   if (info->type_cache.struct_types[id].index == 0)
1286*3d8817e4Smiod     {
1287*3d8817e4Smiod       info->type_cache.struct_types[id].index = info->type_index;
1288*3d8817e4Smiod       ++info->type_index;
1289*3d8817e4Smiod       info->type_cache.struct_types[id].tag = tag;
1290*3d8817e4Smiod       info->type_cache.struct_types[id].kind = kind;
1291*3d8817e4Smiod     }
1292*3d8817e4Smiod 
1293*3d8817e4Smiod   if (kind == DEBUG_KIND_ILLEGAL)
1294*3d8817e4Smiod     {
1295*3d8817e4Smiod       /* This is a definition of the struct.  */
1296*3d8817e4Smiod       info->type_cache.struct_types[id].kind = kind;
1297*3d8817e4Smiod       info->type_cache.struct_types[id].size = *psize;
1298*3d8817e4Smiod     }
1299*3d8817e4Smiod   else
1300*3d8817e4Smiod     *psize = info->type_cache.struct_types[id].size;
1301*3d8817e4Smiod 
1302*3d8817e4Smiod   return info->type_cache.struct_types[id].index;
1303*3d8817e4Smiod }
1304*3d8817e4Smiod 
1305*3d8817e4Smiod /* Start outputting a struct.  We ignore the tag, and handle it in
1306*3d8817e4Smiod    stab_tag.  */
1307*3d8817e4Smiod 
1308*3d8817e4Smiod static bfd_boolean
stab_start_struct_type(void * p,const char * tag,unsigned int id,bfd_boolean structp,unsigned int size)1309*3d8817e4Smiod stab_start_struct_type (void *p, const char *tag, unsigned int id,
1310*3d8817e4Smiod 			bfd_boolean structp, unsigned int size)
1311*3d8817e4Smiod {
1312*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1313*3d8817e4Smiod   long index;
1314*3d8817e4Smiod   bfd_boolean definition;
1315*3d8817e4Smiod   char *buf;
1316*3d8817e4Smiod 
1317*3d8817e4Smiod   buf = (char *) xmalloc (40);
1318*3d8817e4Smiod 
1319*3d8817e4Smiod   if (id == 0)
1320*3d8817e4Smiod     {
1321*3d8817e4Smiod       index = 0;
1322*3d8817e4Smiod       *buf = '\0';
1323*3d8817e4Smiod       definition = FALSE;
1324*3d8817e4Smiod     }
1325*3d8817e4Smiod   else
1326*3d8817e4Smiod     {
1327*3d8817e4Smiod       index = stab_get_struct_index (info, tag, id, DEBUG_KIND_ILLEGAL,
1328*3d8817e4Smiod 				     &size);
1329*3d8817e4Smiod       if (index < 0)
1330*3d8817e4Smiod 	return FALSE;
1331*3d8817e4Smiod       sprintf (buf, "%ld=", index);
1332*3d8817e4Smiod       definition = TRUE;
1333*3d8817e4Smiod     }
1334*3d8817e4Smiod 
1335*3d8817e4Smiod   sprintf (buf + strlen (buf), "%c%u",
1336*3d8817e4Smiod 	   structp ? 's' : 'u',
1337*3d8817e4Smiod 	   size);
1338*3d8817e4Smiod 
1339*3d8817e4Smiod   if (! stab_push_string (info, buf, index, definition, size))
1340*3d8817e4Smiod     return FALSE;
1341*3d8817e4Smiod 
1342*3d8817e4Smiod   info->type_stack->fields = (char *) xmalloc (1);
1343*3d8817e4Smiod   info->type_stack->fields[0] = '\0';
1344*3d8817e4Smiod 
1345*3d8817e4Smiod   return TRUE;
1346*3d8817e4Smiod }
1347*3d8817e4Smiod 
1348*3d8817e4Smiod /* Add a field to a struct.  */
1349*3d8817e4Smiod 
1350*3d8817e4Smiod static bfd_boolean
stab_struct_field(void * p,const char * name,bfd_vma bitpos,bfd_vma bitsize,enum debug_visibility visibility)1351*3d8817e4Smiod stab_struct_field (void *p, const char *name, bfd_vma bitpos,
1352*3d8817e4Smiod 		   bfd_vma bitsize, enum debug_visibility visibility)
1353*3d8817e4Smiod {
1354*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1355*3d8817e4Smiod   bfd_boolean definition;
1356*3d8817e4Smiod   unsigned int size;
1357*3d8817e4Smiod   char *s, *n;
1358*3d8817e4Smiod   const char *vis;
1359*3d8817e4Smiod 
1360*3d8817e4Smiod   definition = info->type_stack->definition;
1361*3d8817e4Smiod   size = info->type_stack->size;
1362*3d8817e4Smiod   s = stab_pop_type (info);
1363*3d8817e4Smiod 
1364*3d8817e4Smiod   /* Add this field to the end of the current struct fields, which is
1365*3d8817e4Smiod      currently on the top of the stack.  */
1366*3d8817e4Smiod 
1367*3d8817e4Smiod   assert (info->type_stack->fields != NULL);
1368*3d8817e4Smiod   n = (char *) xmalloc (strlen (info->type_stack->fields)
1369*3d8817e4Smiod 			+ strlen (name)
1370*3d8817e4Smiod 			+ strlen (s)
1371*3d8817e4Smiod 			+ 50);
1372*3d8817e4Smiod 
1373*3d8817e4Smiod   switch (visibility)
1374*3d8817e4Smiod     {
1375*3d8817e4Smiod     default:
1376*3d8817e4Smiod       abort ();
1377*3d8817e4Smiod 
1378*3d8817e4Smiod     case DEBUG_VISIBILITY_PUBLIC:
1379*3d8817e4Smiod       vis = "";
1380*3d8817e4Smiod       break;
1381*3d8817e4Smiod 
1382*3d8817e4Smiod     case DEBUG_VISIBILITY_PRIVATE:
1383*3d8817e4Smiod       vis = "/0";
1384*3d8817e4Smiod       break;
1385*3d8817e4Smiod 
1386*3d8817e4Smiod     case DEBUG_VISIBILITY_PROTECTED:
1387*3d8817e4Smiod       vis = "/1";
1388*3d8817e4Smiod       break;
1389*3d8817e4Smiod     }
1390*3d8817e4Smiod 
1391*3d8817e4Smiod   if (bitsize == 0)
1392*3d8817e4Smiod     {
1393*3d8817e4Smiod       bitsize = size * 8;
1394*3d8817e4Smiod       if (bitsize == 0)
1395*3d8817e4Smiod 	non_fatal (_("%s: warning: unknown size for field `%s' in struct"),
1396*3d8817e4Smiod 		   bfd_get_filename (info->abfd), name);
1397*3d8817e4Smiod     }
1398*3d8817e4Smiod 
1399*3d8817e4Smiod   sprintf (n, "%s%s:%s%s,%ld,%ld;", info->type_stack->fields, name, vis, s,
1400*3d8817e4Smiod 	   (long) bitpos, (long) bitsize);
1401*3d8817e4Smiod 
1402*3d8817e4Smiod   free (info->type_stack->fields);
1403*3d8817e4Smiod   info->type_stack->fields = n;
1404*3d8817e4Smiod 
1405*3d8817e4Smiod   if (definition)
1406*3d8817e4Smiod     info->type_stack->definition = TRUE;
1407*3d8817e4Smiod 
1408*3d8817e4Smiod   return TRUE;
1409*3d8817e4Smiod }
1410*3d8817e4Smiod 
1411*3d8817e4Smiod /* Finish up a struct.  */
1412*3d8817e4Smiod 
1413*3d8817e4Smiod static bfd_boolean
stab_end_struct_type(void * p)1414*3d8817e4Smiod stab_end_struct_type (void *p)
1415*3d8817e4Smiod {
1416*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1417*3d8817e4Smiod   bfd_boolean definition;
1418*3d8817e4Smiod   long index;
1419*3d8817e4Smiod   unsigned int size;
1420*3d8817e4Smiod   char *fields, *first, *buf;
1421*3d8817e4Smiod 
1422*3d8817e4Smiod   assert (info->type_stack != NULL && info->type_stack->fields != NULL);
1423*3d8817e4Smiod 
1424*3d8817e4Smiod   definition = info->type_stack->definition;
1425*3d8817e4Smiod   index = info->type_stack->index;
1426*3d8817e4Smiod   size = info->type_stack->size;
1427*3d8817e4Smiod   fields = info->type_stack->fields;
1428*3d8817e4Smiod   first = stab_pop_type (info);
1429*3d8817e4Smiod 
1430*3d8817e4Smiod   buf = (char *) xmalloc (strlen (first) + strlen (fields) + 2);
1431*3d8817e4Smiod   sprintf (buf, "%s%s;", first, fields);
1432*3d8817e4Smiod   free (first);
1433*3d8817e4Smiod   free (fields);
1434*3d8817e4Smiod 
1435*3d8817e4Smiod   if (! stab_push_string (info, buf, index, definition, size))
1436*3d8817e4Smiod     return FALSE;
1437*3d8817e4Smiod 
1438*3d8817e4Smiod   free (buf);
1439*3d8817e4Smiod 
1440*3d8817e4Smiod   return TRUE;
1441*3d8817e4Smiod }
1442*3d8817e4Smiod 
1443*3d8817e4Smiod /* Start outputting a class.  */
1444*3d8817e4Smiod 
1445*3d8817e4Smiod static bfd_boolean
stab_start_class_type(void * p,const char * tag,unsigned int id,bfd_boolean structp,unsigned int size,bfd_boolean vptr,bfd_boolean ownvptr)1446*3d8817e4Smiod stab_start_class_type (void *p, const char *tag, unsigned int id, bfd_boolean structp, unsigned int size, bfd_boolean vptr, bfd_boolean ownvptr)
1447*3d8817e4Smiod {
1448*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1449*3d8817e4Smiod   bfd_boolean definition;
1450*3d8817e4Smiod   char *vstring;
1451*3d8817e4Smiod 
1452*3d8817e4Smiod   if (! vptr || ownvptr)
1453*3d8817e4Smiod     {
1454*3d8817e4Smiod       definition = FALSE;
1455*3d8817e4Smiod       vstring = NULL;
1456*3d8817e4Smiod     }
1457*3d8817e4Smiod   else
1458*3d8817e4Smiod     {
1459*3d8817e4Smiod       definition = info->type_stack->definition;
1460*3d8817e4Smiod       vstring = stab_pop_type (info);
1461*3d8817e4Smiod     }
1462*3d8817e4Smiod 
1463*3d8817e4Smiod   if (! stab_start_struct_type (p, tag, id, structp, size))
1464*3d8817e4Smiod     return FALSE;
1465*3d8817e4Smiod 
1466*3d8817e4Smiod   if (vptr)
1467*3d8817e4Smiod     {
1468*3d8817e4Smiod       char *vtable;
1469*3d8817e4Smiod 
1470*3d8817e4Smiod       if (ownvptr)
1471*3d8817e4Smiod 	{
1472*3d8817e4Smiod 	  assert (info->type_stack->index > 0);
1473*3d8817e4Smiod 	  vtable = (char *) xmalloc (20);
1474*3d8817e4Smiod 	  sprintf (vtable, "~%%%ld", info->type_stack->index);
1475*3d8817e4Smiod 	}
1476*3d8817e4Smiod       else
1477*3d8817e4Smiod 	{
1478*3d8817e4Smiod 	  vtable = (char *) xmalloc (strlen (vstring) + 3);
1479*3d8817e4Smiod 	  sprintf (vtable, "~%%%s", vstring);
1480*3d8817e4Smiod 	  free (vstring);
1481*3d8817e4Smiod 	}
1482*3d8817e4Smiod 
1483*3d8817e4Smiod       info->type_stack->vtable = vtable;
1484*3d8817e4Smiod     }
1485*3d8817e4Smiod 
1486*3d8817e4Smiod   if (definition)
1487*3d8817e4Smiod     info->type_stack->definition = TRUE;
1488*3d8817e4Smiod 
1489*3d8817e4Smiod   return TRUE;
1490*3d8817e4Smiod }
1491*3d8817e4Smiod 
1492*3d8817e4Smiod /* Add a static member to the class on the type stack.  */
1493*3d8817e4Smiod 
1494*3d8817e4Smiod static bfd_boolean
stab_class_static_member(void * p,const char * name,const char * physname,enum debug_visibility visibility)1495*3d8817e4Smiod stab_class_static_member (void *p, const char *name, const char *physname,
1496*3d8817e4Smiod 			  enum debug_visibility visibility)
1497*3d8817e4Smiod {
1498*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1499*3d8817e4Smiod   bfd_boolean definition;
1500*3d8817e4Smiod   char *s, *n;
1501*3d8817e4Smiod   const char *vis;
1502*3d8817e4Smiod 
1503*3d8817e4Smiod   definition = info->type_stack->definition;
1504*3d8817e4Smiod   s = stab_pop_type (info);
1505*3d8817e4Smiod 
1506*3d8817e4Smiod   /* Add this field to the end of the current struct fields, which is
1507*3d8817e4Smiod      currently on the top of the stack.  */
1508*3d8817e4Smiod 
1509*3d8817e4Smiod   assert (info->type_stack->fields != NULL);
1510*3d8817e4Smiod   n = (char *) xmalloc (strlen (info->type_stack->fields)
1511*3d8817e4Smiod 			+ strlen (name)
1512*3d8817e4Smiod 			+ strlen (s)
1513*3d8817e4Smiod 			+ strlen (physname)
1514*3d8817e4Smiod 			+ 10);
1515*3d8817e4Smiod 
1516*3d8817e4Smiod   switch (visibility)
1517*3d8817e4Smiod     {
1518*3d8817e4Smiod     default:
1519*3d8817e4Smiod       abort ();
1520*3d8817e4Smiod 
1521*3d8817e4Smiod     case DEBUG_VISIBILITY_PUBLIC:
1522*3d8817e4Smiod       vis = "";
1523*3d8817e4Smiod       break;
1524*3d8817e4Smiod 
1525*3d8817e4Smiod     case DEBUG_VISIBILITY_PRIVATE:
1526*3d8817e4Smiod       vis = "/0";
1527*3d8817e4Smiod       break;
1528*3d8817e4Smiod 
1529*3d8817e4Smiod     case DEBUG_VISIBILITY_PROTECTED:
1530*3d8817e4Smiod       vis = "/1";
1531*3d8817e4Smiod       break;
1532*3d8817e4Smiod     }
1533*3d8817e4Smiod 
1534*3d8817e4Smiod   sprintf (n, "%s%s:%s%s:%s;", info->type_stack->fields, name, vis, s,
1535*3d8817e4Smiod 	   physname);
1536*3d8817e4Smiod 
1537*3d8817e4Smiod   free (info->type_stack->fields);
1538*3d8817e4Smiod   info->type_stack->fields = n;
1539*3d8817e4Smiod 
1540*3d8817e4Smiod   if (definition)
1541*3d8817e4Smiod     info->type_stack->definition = TRUE;
1542*3d8817e4Smiod 
1543*3d8817e4Smiod   return TRUE;
1544*3d8817e4Smiod }
1545*3d8817e4Smiod 
1546*3d8817e4Smiod /* Add a base class to the class on the type stack.  */
1547*3d8817e4Smiod 
1548*3d8817e4Smiod static bfd_boolean
stab_class_baseclass(void * p,bfd_vma bitpos,bfd_boolean virtual,enum debug_visibility visibility)1549*3d8817e4Smiod stab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
1550*3d8817e4Smiod 		      enum debug_visibility visibility)
1551*3d8817e4Smiod {
1552*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1553*3d8817e4Smiod   bfd_boolean definition;
1554*3d8817e4Smiod   char *s;
1555*3d8817e4Smiod   char *buf;
1556*3d8817e4Smiod   unsigned int c;
1557*3d8817e4Smiod   char **baseclasses;
1558*3d8817e4Smiod 
1559*3d8817e4Smiod   definition = info->type_stack->definition;
1560*3d8817e4Smiod   s = stab_pop_type (info);
1561*3d8817e4Smiod 
1562*3d8817e4Smiod   /* Build the base class specifier.  */
1563*3d8817e4Smiod 
1564*3d8817e4Smiod   buf = (char *) xmalloc (strlen (s) + 25);
1565*3d8817e4Smiod   buf[0] = virtual ? '1' : '0';
1566*3d8817e4Smiod   switch (visibility)
1567*3d8817e4Smiod     {
1568*3d8817e4Smiod     default:
1569*3d8817e4Smiod       abort ();
1570*3d8817e4Smiod 
1571*3d8817e4Smiod     case DEBUG_VISIBILITY_PRIVATE:
1572*3d8817e4Smiod       buf[1] = '0';
1573*3d8817e4Smiod       break;
1574*3d8817e4Smiod 
1575*3d8817e4Smiod     case DEBUG_VISIBILITY_PROTECTED:
1576*3d8817e4Smiod       buf[1] = '1';
1577*3d8817e4Smiod       break;
1578*3d8817e4Smiod 
1579*3d8817e4Smiod     case DEBUG_VISIBILITY_PUBLIC:
1580*3d8817e4Smiod       buf[1] = '2';
1581*3d8817e4Smiod       break;
1582*3d8817e4Smiod     }
1583*3d8817e4Smiod 
1584*3d8817e4Smiod   sprintf (buf + 2, "%ld,%s;", (long) bitpos, s);
1585*3d8817e4Smiod   free (s);
1586*3d8817e4Smiod 
1587*3d8817e4Smiod   /* Add the new baseclass to the existing ones.  */
1588*3d8817e4Smiod 
1589*3d8817e4Smiod   assert (info->type_stack != NULL && info->type_stack->fields != NULL);
1590*3d8817e4Smiod 
1591*3d8817e4Smiod   if (info->type_stack->baseclasses == NULL)
1592*3d8817e4Smiod     c = 0;
1593*3d8817e4Smiod   else
1594*3d8817e4Smiod     {
1595*3d8817e4Smiod       c = 0;
1596*3d8817e4Smiod       while (info->type_stack->baseclasses[c] != NULL)
1597*3d8817e4Smiod 	++c;
1598*3d8817e4Smiod     }
1599*3d8817e4Smiod 
1600*3d8817e4Smiod   baseclasses = (char **) xrealloc (info->type_stack->baseclasses,
1601*3d8817e4Smiod 				    (c + 2) * sizeof (*baseclasses));
1602*3d8817e4Smiod   baseclasses[c] = buf;
1603*3d8817e4Smiod   baseclasses[c + 1] = NULL;
1604*3d8817e4Smiod 
1605*3d8817e4Smiod   info->type_stack->baseclasses = baseclasses;
1606*3d8817e4Smiod 
1607*3d8817e4Smiod   if (definition)
1608*3d8817e4Smiod     info->type_stack->definition = TRUE;
1609*3d8817e4Smiod 
1610*3d8817e4Smiod   return TRUE;
1611*3d8817e4Smiod }
1612*3d8817e4Smiod 
1613*3d8817e4Smiod /* Start adding a method to the class on the type stack.  */
1614*3d8817e4Smiod 
1615*3d8817e4Smiod static bfd_boolean
stab_class_start_method(void * p,const char * name)1616*3d8817e4Smiod stab_class_start_method (void *p, const char *name)
1617*3d8817e4Smiod {
1618*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1619*3d8817e4Smiod   char *m;
1620*3d8817e4Smiod 
1621*3d8817e4Smiod   assert (info->type_stack != NULL && info->type_stack->fields != NULL);
1622*3d8817e4Smiod 
1623*3d8817e4Smiod   if (info->type_stack->methods == NULL)
1624*3d8817e4Smiod     {
1625*3d8817e4Smiod       m = (char *) xmalloc (strlen (name) + 3);
1626*3d8817e4Smiod       *m = '\0';
1627*3d8817e4Smiod     }
1628*3d8817e4Smiod   else
1629*3d8817e4Smiod     {
1630*3d8817e4Smiod       m = (char *) xrealloc (info->type_stack->methods,
1631*3d8817e4Smiod 			     (strlen (info->type_stack->methods)
1632*3d8817e4Smiod 			      + strlen (name)
1633*3d8817e4Smiod 			      + 4));
1634*3d8817e4Smiod     }
1635*3d8817e4Smiod 
1636*3d8817e4Smiod   sprintf (m + strlen (m), "%s::", name);
1637*3d8817e4Smiod 
1638*3d8817e4Smiod   info->type_stack->methods = m;
1639*3d8817e4Smiod 
1640*3d8817e4Smiod   return TRUE;
1641*3d8817e4Smiod }
1642*3d8817e4Smiod 
1643*3d8817e4Smiod /* Add a variant, either static or not, to the current method.  */
1644*3d8817e4Smiod 
1645*3d8817e4Smiod static bfd_boolean
stab_class_method_var(struct stab_write_handle * info,const char * physname,enum debug_visibility visibility,bfd_boolean staticp,bfd_boolean constp,bfd_boolean volatilep,bfd_vma voffset,bfd_boolean contextp)1646*3d8817e4Smiod stab_class_method_var (struct stab_write_handle *info, const char *physname,
1647*3d8817e4Smiod 		       enum debug_visibility visibility,
1648*3d8817e4Smiod 		       bfd_boolean staticp, bfd_boolean constp,
1649*3d8817e4Smiod 		       bfd_boolean volatilep, bfd_vma voffset,
1650*3d8817e4Smiod 		       bfd_boolean contextp)
1651*3d8817e4Smiod {
1652*3d8817e4Smiod   bfd_boolean definition;
1653*3d8817e4Smiod   char *type;
1654*3d8817e4Smiod   char *context = NULL;
1655*3d8817e4Smiod   char visc, qualc, typec;
1656*3d8817e4Smiod 
1657*3d8817e4Smiod   definition = info->type_stack->definition;
1658*3d8817e4Smiod   type = stab_pop_type (info);
1659*3d8817e4Smiod 
1660*3d8817e4Smiod   if (contextp)
1661*3d8817e4Smiod     {
1662*3d8817e4Smiod       definition = definition || info->type_stack->definition;
1663*3d8817e4Smiod       context = stab_pop_type (info);
1664*3d8817e4Smiod     }
1665*3d8817e4Smiod 
1666*3d8817e4Smiod   assert (info->type_stack != NULL && info->type_stack->methods != NULL);
1667*3d8817e4Smiod 
1668*3d8817e4Smiod   switch (visibility)
1669*3d8817e4Smiod     {
1670*3d8817e4Smiod     default:
1671*3d8817e4Smiod       abort ();
1672*3d8817e4Smiod 
1673*3d8817e4Smiod     case DEBUG_VISIBILITY_PRIVATE:
1674*3d8817e4Smiod       visc = '0';
1675*3d8817e4Smiod       break;
1676*3d8817e4Smiod 
1677*3d8817e4Smiod     case DEBUG_VISIBILITY_PROTECTED:
1678*3d8817e4Smiod       visc = '1';
1679*3d8817e4Smiod       break;
1680*3d8817e4Smiod 
1681*3d8817e4Smiod     case DEBUG_VISIBILITY_PUBLIC:
1682*3d8817e4Smiod       visc = '2';
1683*3d8817e4Smiod       break;
1684*3d8817e4Smiod     }
1685*3d8817e4Smiod 
1686*3d8817e4Smiod   if (constp)
1687*3d8817e4Smiod     {
1688*3d8817e4Smiod       if (volatilep)
1689*3d8817e4Smiod 	qualc = 'D';
1690*3d8817e4Smiod       else
1691*3d8817e4Smiod 	qualc = 'B';
1692*3d8817e4Smiod     }
1693*3d8817e4Smiod   else
1694*3d8817e4Smiod     {
1695*3d8817e4Smiod       if (volatilep)
1696*3d8817e4Smiod 	qualc = 'C';
1697*3d8817e4Smiod       else
1698*3d8817e4Smiod 	qualc = 'A';
1699*3d8817e4Smiod     }
1700*3d8817e4Smiod 
1701*3d8817e4Smiod   if (staticp)
1702*3d8817e4Smiod     typec = '?';
1703*3d8817e4Smiod   else if (! contextp)
1704*3d8817e4Smiod     typec = '.';
1705*3d8817e4Smiod   else
1706*3d8817e4Smiod     typec = '*';
1707*3d8817e4Smiod 
1708*3d8817e4Smiod   info->type_stack->methods =
1709*3d8817e4Smiod     (char *) xrealloc (info->type_stack->methods,
1710*3d8817e4Smiod 		       (strlen (info->type_stack->methods)
1711*3d8817e4Smiod 			+ strlen (type)
1712*3d8817e4Smiod 			+ strlen (physname)
1713*3d8817e4Smiod 			+ (contextp ? strlen (context) : 0)
1714*3d8817e4Smiod 			+ 40));
1715*3d8817e4Smiod 
1716*3d8817e4Smiod   sprintf (info->type_stack->methods + strlen (info->type_stack->methods),
1717*3d8817e4Smiod 	   "%s:%s;%c%c%c", type, physname, visc, qualc, typec);
1718*3d8817e4Smiod   free (type);
1719*3d8817e4Smiod 
1720*3d8817e4Smiod   if (contextp)
1721*3d8817e4Smiod     {
1722*3d8817e4Smiod       sprintf (info->type_stack->methods + strlen (info->type_stack->methods),
1723*3d8817e4Smiod 	       "%ld;%s;", (long) voffset, context);
1724*3d8817e4Smiod       free (context);
1725*3d8817e4Smiod     }
1726*3d8817e4Smiod 
1727*3d8817e4Smiod   if (definition)
1728*3d8817e4Smiod     info->type_stack->definition = TRUE;
1729*3d8817e4Smiod 
1730*3d8817e4Smiod   return TRUE;
1731*3d8817e4Smiod }
1732*3d8817e4Smiod 
1733*3d8817e4Smiod /* Add a variant to the current method.  */
1734*3d8817e4Smiod 
1735*3d8817e4Smiod static bfd_boolean
stab_class_method_variant(void * p,const char * physname,enum debug_visibility visibility,bfd_boolean constp,bfd_boolean volatilep,bfd_vma voffset,bfd_boolean contextp)1736*3d8817e4Smiod stab_class_method_variant (void *p, const char *physname,
1737*3d8817e4Smiod 			   enum debug_visibility visibility,
1738*3d8817e4Smiod 			   bfd_boolean constp, bfd_boolean volatilep,
1739*3d8817e4Smiod 			   bfd_vma voffset, bfd_boolean contextp)
1740*3d8817e4Smiod {
1741*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1742*3d8817e4Smiod 
1743*3d8817e4Smiod   return stab_class_method_var (info, physname, visibility, FALSE, constp,
1744*3d8817e4Smiod 				volatilep, voffset, contextp);
1745*3d8817e4Smiod }
1746*3d8817e4Smiod 
1747*3d8817e4Smiod /* Add a static variant to the current method.  */
1748*3d8817e4Smiod 
1749*3d8817e4Smiod static bfd_boolean
stab_class_static_method_variant(void * p,const char * physname,enum debug_visibility visibility,bfd_boolean constp,bfd_boolean volatilep)1750*3d8817e4Smiod stab_class_static_method_variant (void *p, const char *physname,
1751*3d8817e4Smiod 				  enum debug_visibility visibility,
1752*3d8817e4Smiod 				  bfd_boolean constp, bfd_boolean volatilep)
1753*3d8817e4Smiod {
1754*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1755*3d8817e4Smiod 
1756*3d8817e4Smiod   return stab_class_method_var (info, physname, visibility, TRUE, constp,
1757*3d8817e4Smiod 				volatilep, 0, FALSE);
1758*3d8817e4Smiod }
1759*3d8817e4Smiod 
1760*3d8817e4Smiod /* Finish up a method.  */
1761*3d8817e4Smiod 
1762*3d8817e4Smiod static bfd_boolean
stab_class_end_method(void * p)1763*3d8817e4Smiod stab_class_end_method (void *p)
1764*3d8817e4Smiod {
1765*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1766*3d8817e4Smiod 
1767*3d8817e4Smiod   assert (info->type_stack != NULL && info->type_stack->methods != NULL);
1768*3d8817e4Smiod 
1769*3d8817e4Smiod   /* We allocated enough room on info->type_stack->methods to add the
1770*3d8817e4Smiod      trailing semicolon.  */
1771*3d8817e4Smiod   strcat (info->type_stack->methods, ";");
1772*3d8817e4Smiod 
1773*3d8817e4Smiod   return TRUE;
1774*3d8817e4Smiod }
1775*3d8817e4Smiod 
1776*3d8817e4Smiod /* Finish up a class.  */
1777*3d8817e4Smiod 
1778*3d8817e4Smiod static bfd_boolean
stab_end_class_type(void * p)1779*3d8817e4Smiod stab_end_class_type (void *p)
1780*3d8817e4Smiod {
1781*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1782*3d8817e4Smiod   size_t len;
1783*3d8817e4Smiod   unsigned int i = 0;
1784*3d8817e4Smiod   char *buf;
1785*3d8817e4Smiod 
1786*3d8817e4Smiod   assert (info->type_stack != NULL && info->type_stack->fields != NULL);
1787*3d8817e4Smiod 
1788*3d8817e4Smiod   /* Work out the size we need to allocate for the class definition.  */
1789*3d8817e4Smiod 
1790*3d8817e4Smiod   len = (strlen (info->type_stack->string)
1791*3d8817e4Smiod 	 + strlen (info->type_stack->fields)
1792*3d8817e4Smiod 	 + 10);
1793*3d8817e4Smiod   if (info->type_stack->baseclasses != NULL)
1794*3d8817e4Smiod     {
1795*3d8817e4Smiod       len += 20;
1796*3d8817e4Smiod       for (i = 0; info->type_stack->baseclasses[i] != NULL; i++)
1797*3d8817e4Smiod 	len += strlen (info->type_stack->baseclasses[i]);
1798*3d8817e4Smiod     }
1799*3d8817e4Smiod   if (info->type_stack->methods != NULL)
1800*3d8817e4Smiod     len += strlen (info->type_stack->methods);
1801*3d8817e4Smiod   if (info->type_stack->vtable != NULL)
1802*3d8817e4Smiod     len += strlen (info->type_stack->vtable);
1803*3d8817e4Smiod 
1804*3d8817e4Smiod   /* Build the class definition.  */
1805*3d8817e4Smiod 
1806*3d8817e4Smiod   buf = (char *) xmalloc (len);
1807*3d8817e4Smiod 
1808*3d8817e4Smiod   strcpy (buf, info->type_stack->string);
1809*3d8817e4Smiod 
1810*3d8817e4Smiod   if (info->type_stack->baseclasses != NULL)
1811*3d8817e4Smiod     {
1812*3d8817e4Smiod       sprintf (buf + strlen (buf), "!%u,", i);
1813*3d8817e4Smiod       for (i = 0; info->type_stack->baseclasses[i] != NULL; i++)
1814*3d8817e4Smiod 	{
1815*3d8817e4Smiod 	  strcat (buf, info->type_stack->baseclasses[i]);
1816*3d8817e4Smiod 	  free (info->type_stack->baseclasses[i]);
1817*3d8817e4Smiod 	}
1818*3d8817e4Smiod       free (info->type_stack->baseclasses);
1819*3d8817e4Smiod       info->type_stack->baseclasses = NULL;
1820*3d8817e4Smiod     }
1821*3d8817e4Smiod 
1822*3d8817e4Smiod   strcat (buf, info->type_stack->fields);
1823*3d8817e4Smiod   free (info->type_stack->fields);
1824*3d8817e4Smiod   info->type_stack->fields = NULL;
1825*3d8817e4Smiod 
1826*3d8817e4Smiod   if (info->type_stack->methods != NULL)
1827*3d8817e4Smiod     {
1828*3d8817e4Smiod       strcat (buf, info->type_stack->methods);
1829*3d8817e4Smiod       free (info->type_stack->methods);
1830*3d8817e4Smiod       info->type_stack->methods = NULL;
1831*3d8817e4Smiod     }
1832*3d8817e4Smiod 
1833*3d8817e4Smiod   strcat (buf, ";");
1834*3d8817e4Smiod 
1835*3d8817e4Smiod   if (info->type_stack->vtable != NULL)
1836*3d8817e4Smiod     {
1837*3d8817e4Smiod       strcat (buf, info->type_stack->vtable);
1838*3d8817e4Smiod       free (info->type_stack->vtable);
1839*3d8817e4Smiod       info->type_stack->vtable = NULL;
1840*3d8817e4Smiod     }
1841*3d8817e4Smiod 
1842*3d8817e4Smiod   /* Replace the string on the top of the stack with the complete
1843*3d8817e4Smiod      class definition.  */
1844*3d8817e4Smiod   free (info->type_stack->string);
1845*3d8817e4Smiod   info->type_stack->string = buf;
1846*3d8817e4Smiod 
1847*3d8817e4Smiod   return TRUE;
1848*3d8817e4Smiod }
1849*3d8817e4Smiod 
1850*3d8817e4Smiod /* Push a typedef which was previously defined.  */
1851*3d8817e4Smiod 
1852*3d8817e4Smiod static bfd_boolean
stab_typedef_type(void * p,const char * name)1853*3d8817e4Smiod stab_typedef_type (void *p, const char *name)
1854*3d8817e4Smiod {
1855*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1856*3d8817e4Smiod   struct string_hash_entry *h;
1857*3d8817e4Smiod 
1858*3d8817e4Smiod   h = string_hash_lookup (&info->typedef_hash, name, FALSE, FALSE);
1859*3d8817e4Smiod   assert (h != NULL && h->index > 0);
1860*3d8817e4Smiod 
1861*3d8817e4Smiod   return stab_push_defined_type (info, h->index, h->size);
1862*3d8817e4Smiod }
1863*3d8817e4Smiod 
1864*3d8817e4Smiod /* Push a struct, union or class tag.  */
1865*3d8817e4Smiod 
1866*3d8817e4Smiod static bfd_boolean
stab_tag_type(void * p,const char * name,unsigned int id,enum debug_type_kind kind)1867*3d8817e4Smiod stab_tag_type (void *p, const char *name, unsigned int id,
1868*3d8817e4Smiod 	       enum debug_type_kind kind)
1869*3d8817e4Smiod {
1870*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1871*3d8817e4Smiod   long index;
1872*3d8817e4Smiod   unsigned int size;
1873*3d8817e4Smiod 
1874*3d8817e4Smiod   index = stab_get_struct_index (info, name, id, kind, &size);
1875*3d8817e4Smiod   if (index < 0)
1876*3d8817e4Smiod     return FALSE;
1877*3d8817e4Smiod 
1878*3d8817e4Smiod   return stab_push_defined_type (info, index, size);
1879*3d8817e4Smiod }
1880*3d8817e4Smiod 
1881*3d8817e4Smiod /* Define a typedef.  */
1882*3d8817e4Smiod 
1883*3d8817e4Smiod static bfd_boolean
stab_typdef(void * p,const char * name)1884*3d8817e4Smiod stab_typdef (void *p, const char *name)
1885*3d8817e4Smiod {
1886*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1887*3d8817e4Smiod   long index;
1888*3d8817e4Smiod   unsigned int size;
1889*3d8817e4Smiod   char *s, *buf;
1890*3d8817e4Smiod   struct string_hash_entry *h;
1891*3d8817e4Smiod 
1892*3d8817e4Smiod   index = info->type_stack->index;
1893*3d8817e4Smiod   size = info->type_stack->size;
1894*3d8817e4Smiod   s = stab_pop_type (info);
1895*3d8817e4Smiod 
1896*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + strlen (s) + 20);
1897*3d8817e4Smiod 
1898*3d8817e4Smiod   if (index > 0)
1899*3d8817e4Smiod     sprintf (buf, "%s:t%s", name, s);
1900*3d8817e4Smiod   else
1901*3d8817e4Smiod     {
1902*3d8817e4Smiod       index = info->type_index;
1903*3d8817e4Smiod       ++info->type_index;
1904*3d8817e4Smiod       sprintf (buf, "%s:t%ld=%s", name, index, s);
1905*3d8817e4Smiod     }
1906*3d8817e4Smiod 
1907*3d8817e4Smiod   free (s);
1908*3d8817e4Smiod 
1909*3d8817e4Smiod   if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
1910*3d8817e4Smiod     return FALSE;
1911*3d8817e4Smiod 
1912*3d8817e4Smiod   free (buf);
1913*3d8817e4Smiod 
1914*3d8817e4Smiod   h = string_hash_lookup (&info->typedef_hash, name, TRUE, FALSE);
1915*3d8817e4Smiod   if (h == NULL)
1916*3d8817e4Smiod     {
1917*3d8817e4Smiod       non_fatal (_("string_hash_lookup failed: %s"),
1918*3d8817e4Smiod 		 bfd_errmsg (bfd_get_error ()));
1919*3d8817e4Smiod       return FALSE;
1920*3d8817e4Smiod     }
1921*3d8817e4Smiod 
1922*3d8817e4Smiod   /* I don't think we care about redefinitions.  */
1923*3d8817e4Smiod 
1924*3d8817e4Smiod   h->index = index;
1925*3d8817e4Smiod   h->size = size;
1926*3d8817e4Smiod 
1927*3d8817e4Smiod   return TRUE;
1928*3d8817e4Smiod }
1929*3d8817e4Smiod 
1930*3d8817e4Smiod /* Define a tag.  */
1931*3d8817e4Smiod 
1932*3d8817e4Smiod static bfd_boolean
stab_tag(void * p,const char * tag)1933*3d8817e4Smiod stab_tag (void *p, const char *tag)
1934*3d8817e4Smiod {
1935*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1936*3d8817e4Smiod   char *s, *buf;
1937*3d8817e4Smiod 
1938*3d8817e4Smiod   s = stab_pop_type (info);
1939*3d8817e4Smiod 
1940*3d8817e4Smiod   buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3);
1941*3d8817e4Smiod 
1942*3d8817e4Smiod   sprintf (buf, "%s:T%s", tag, s);
1943*3d8817e4Smiod   free (s);
1944*3d8817e4Smiod 
1945*3d8817e4Smiod   if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
1946*3d8817e4Smiod     return FALSE;
1947*3d8817e4Smiod 
1948*3d8817e4Smiod   free (buf);
1949*3d8817e4Smiod 
1950*3d8817e4Smiod   return TRUE;
1951*3d8817e4Smiod }
1952*3d8817e4Smiod 
1953*3d8817e4Smiod /* Define an integer constant.  */
1954*3d8817e4Smiod 
1955*3d8817e4Smiod static bfd_boolean
stab_int_constant(void * p,const char * name,bfd_vma val)1956*3d8817e4Smiod stab_int_constant (void *p, const char *name, bfd_vma val)
1957*3d8817e4Smiod {
1958*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1959*3d8817e4Smiod   char *buf;
1960*3d8817e4Smiod 
1961*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + 20);
1962*3d8817e4Smiod   sprintf (buf, "%s:c=i%ld", name, (long) val);
1963*3d8817e4Smiod 
1964*3d8817e4Smiod   if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
1965*3d8817e4Smiod     return FALSE;
1966*3d8817e4Smiod 
1967*3d8817e4Smiod   free (buf);
1968*3d8817e4Smiod 
1969*3d8817e4Smiod   return TRUE;
1970*3d8817e4Smiod }
1971*3d8817e4Smiod 
1972*3d8817e4Smiod /* Define a floating point constant.  */
1973*3d8817e4Smiod 
1974*3d8817e4Smiod static bfd_boolean
stab_float_constant(void * p,const char * name,double val)1975*3d8817e4Smiod stab_float_constant (void *p, const char *name, double val)
1976*3d8817e4Smiod {
1977*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1978*3d8817e4Smiod   char *buf;
1979*3d8817e4Smiod 
1980*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + 20);
1981*3d8817e4Smiod   sprintf (buf, "%s:c=f%g", name, val);
1982*3d8817e4Smiod 
1983*3d8817e4Smiod   if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
1984*3d8817e4Smiod     return FALSE;
1985*3d8817e4Smiod 
1986*3d8817e4Smiod   free (buf);
1987*3d8817e4Smiod 
1988*3d8817e4Smiod   return TRUE;
1989*3d8817e4Smiod }
1990*3d8817e4Smiod 
1991*3d8817e4Smiod /* Define a typed constant.  */
1992*3d8817e4Smiod 
1993*3d8817e4Smiod static bfd_boolean
stab_typed_constant(void * p,const char * name,bfd_vma val)1994*3d8817e4Smiod stab_typed_constant (void *p, const char *name, bfd_vma val)
1995*3d8817e4Smiod {
1996*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
1997*3d8817e4Smiod   char *s, *buf;
1998*3d8817e4Smiod 
1999*3d8817e4Smiod   s = stab_pop_type (info);
2000*3d8817e4Smiod 
2001*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + strlen (s) + 20);
2002*3d8817e4Smiod   sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val);
2003*3d8817e4Smiod   free (s);
2004*3d8817e4Smiod 
2005*3d8817e4Smiod   if (! stab_write_symbol (info, N_LSYM, 0, 0, buf))
2006*3d8817e4Smiod     return FALSE;
2007*3d8817e4Smiod 
2008*3d8817e4Smiod   free (buf);
2009*3d8817e4Smiod 
2010*3d8817e4Smiod   return TRUE;
2011*3d8817e4Smiod }
2012*3d8817e4Smiod 
2013*3d8817e4Smiod /* Record a variable.  */
2014*3d8817e4Smiod 
2015*3d8817e4Smiod static bfd_boolean
stab_variable(void * p,const char * name,enum debug_var_kind kind,bfd_vma val)2016*3d8817e4Smiod stab_variable (void *p, const char *name, enum debug_var_kind kind,
2017*3d8817e4Smiod 	       bfd_vma val)
2018*3d8817e4Smiod {
2019*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
2020*3d8817e4Smiod   char *s, *buf;
2021*3d8817e4Smiod   int stab_type;
2022*3d8817e4Smiod   const char *kindstr;
2023*3d8817e4Smiod 
2024*3d8817e4Smiod   s = stab_pop_type (info);
2025*3d8817e4Smiod 
2026*3d8817e4Smiod   switch (kind)
2027*3d8817e4Smiod     {
2028*3d8817e4Smiod     default:
2029*3d8817e4Smiod       abort ();
2030*3d8817e4Smiod 
2031*3d8817e4Smiod     case DEBUG_GLOBAL:
2032*3d8817e4Smiod       stab_type = N_GSYM;
2033*3d8817e4Smiod       kindstr = "G";
2034*3d8817e4Smiod       break;
2035*3d8817e4Smiod 
2036*3d8817e4Smiod     case DEBUG_STATIC:
2037*3d8817e4Smiod       stab_type = N_STSYM;
2038*3d8817e4Smiod       kindstr = "S";
2039*3d8817e4Smiod       break;
2040*3d8817e4Smiod 
2041*3d8817e4Smiod     case DEBUG_LOCAL_STATIC:
2042*3d8817e4Smiod       stab_type = N_STSYM;
2043*3d8817e4Smiod       kindstr = "V";
2044*3d8817e4Smiod       break;
2045*3d8817e4Smiod 
2046*3d8817e4Smiod     case DEBUG_LOCAL:
2047*3d8817e4Smiod       stab_type = N_LSYM;
2048*3d8817e4Smiod       kindstr = "";
2049*3d8817e4Smiod 
2050*3d8817e4Smiod       /* Make sure that this is a type reference or definition.  */
2051*3d8817e4Smiod       if (! ISDIGIT (*s))
2052*3d8817e4Smiod 	{
2053*3d8817e4Smiod 	  char *n;
2054*3d8817e4Smiod 	  long index;
2055*3d8817e4Smiod 
2056*3d8817e4Smiod 	  index = info->type_index;
2057*3d8817e4Smiod 	  ++info->type_index;
2058*3d8817e4Smiod 	  n = (char *) xmalloc (strlen (s) + 20);
2059*3d8817e4Smiod 	  sprintf (n, "%ld=%s", index, s);
2060*3d8817e4Smiod 	  free (s);
2061*3d8817e4Smiod 	  s = n;
2062*3d8817e4Smiod 	}
2063*3d8817e4Smiod       break;
2064*3d8817e4Smiod 
2065*3d8817e4Smiod     case DEBUG_REGISTER:
2066*3d8817e4Smiod       stab_type = N_RSYM;
2067*3d8817e4Smiod       kindstr = "r";
2068*3d8817e4Smiod       break;
2069*3d8817e4Smiod     }
2070*3d8817e4Smiod 
2071*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + strlen (s) + 3);
2072*3d8817e4Smiod   sprintf (buf, "%s:%s%s", name, kindstr, s);
2073*3d8817e4Smiod   free (s);
2074*3d8817e4Smiod 
2075*3d8817e4Smiod   if (! stab_write_symbol (info, stab_type, 0, val, buf))
2076*3d8817e4Smiod     return FALSE;
2077*3d8817e4Smiod 
2078*3d8817e4Smiod   free (buf);
2079*3d8817e4Smiod 
2080*3d8817e4Smiod   return TRUE;
2081*3d8817e4Smiod }
2082*3d8817e4Smiod 
2083*3d8817e4Smiod /* Start outputting a function.  */
2084*3d8817e4Smiod 
2085*3d8817e4Smiod static bfd_boolean
stab_start_function(void * p,const char * name,bfd_boolean globalp)2086*3d8817e4Smiod stab_start_function (void *p, const char *name, bfd_boolean globalp)
2087*3d8817e4Smiod {
2088*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
2089*3d8817e4Smiod   char *rettype, *buf;
2090*3d8817e4Smiod 
2091*3d8817e4Smiod   assert (info->nesting == 0 && info->fun_offset == -1);
2092*3d8817e4Smiod 
2093*3d8817e4Smiod   rettype = stab_pop_type (info);
2094*3d8817e4Smiod 
2095*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3);
2096*3d8817e4Smiod   sprintf (buf, "%s:%c%s", name,
2097*3d8817e4Smiod 	   globalp ? 'F' : 'f',
2098*3d8817e4Smiod 	   rettype);
2099*3d8817e4Smiod 
2100*3d8817e4Smiod   /* We don't know the value now, so we set it in start_block.  */
2101*3d8817e4Smiod   info->fun_offset = info->symbols_size;
2102*3d8817e4Smiod 
2103*3d8817e4Smiod   if (! stab_write_symbol (info, N_FUN, 0, 0, buf))
2104*3d8817e4Smiod     return FALSE;
2105*3d8817e4Smiod 
2106*3d8817e4Smiod   free (buf);
2107*3d8817e4Smiod 
2108*3d8817e4Smiod   return TRUE;
2109*3d8817e4Smiod }
2110*3d8817e4Smiod 
2111*3d8817e4Smiod /* Output a function parameter.  */
2112*3d8817e4Smiod 
2113*3d8817e4Smiod static bfd_boolean
stab_function_parameter(void * p,const char * name,enum debug_parm_kind kind,bfd_vma val)2114*3d8817e4Smiod stab_function_parameter (void *p, const char *name, enum debug_parm_kind kind, bfd_vma val)
2115*3d8817e4Smiod {
2116*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
2117*3d8817e4Smiod   char *s, *buf;
2118*3d8817e4Smiod   int stab_type;
2119*3d8817e4Smiod   char kindc;
2120*3d8817e4Smiod 
2121*3d8817e4Smiod   s = stab_pop_type (info);
2122*3d8817e4Smiod 
2123*3d8817e4Smiod   switch (kind)
2124*3d8817e4Smiod     {
2125*3d8817e4Smiod     default:
2126*3d8817e4Smiod       abort ();
2127*3d8817e4Smiod 
2128*3d8817e4Smiod     case DEBUG_PARM_STACK:
2129*3d8817e4Smiod       stab_type = N_PSYM;
2130*3d8817e4Smiod       kindc = 'p';
2131*3d8817e4Smiod       break;
2132*3d8817e4Smiod 
2133*3d8817e4Smiod     case DEBUG_PARM_REG:
2134*3d8817e4Smiod       stab_type = N_RSYM;
2135*3d8817e4Smiod       kindc = 'P';
2136*3d8817e4Smiod       break;
2137*3d8817e4Smiod 
2138*3d8817e4Smiod     case DEBUG_PARM_REFERENCE:
2139*3d8817e4Smiod       stab_type = N_PSYM;
2140*3d8817e4Smiod       kindc = 'v';
2141*3d8817e4Smiod       break;
2142*3d8817e4Smiod 
2143*3d8817e4Smiod     case DEBUG_PARM_REF_REG:
2144*3d8817e4Smiod       stab_type = N_RSYM;
2145*3d8817e4Smiod       kindc = 'a';
2146*3d8817e4Smiod       break;
2147*3d8817e4Smiod     }
2148*3d8817e4Smiod 
2149*3d8817e4Smiod   buf = (char *) xmalloc (strlen (name) + strlen (s) + 3);
2150*3d8817e4Smiod   sprintf (buf, "%s:%c%s", name, kindc, s);
2151*3d8817e4Smiod   free (s);
2152*3d8817e4Smiod 
2153*3d8817e4Smiod   if (! stab_write_symbol (info, stab_type, 0, val, buf))
2154*3d8817e4Smiod     return FALSE;
2155*3d8817e4Smiod 
2156*3d8817e4Smiod   free (buf);
2157*3d8817e4Smiod 
2158*3d8817e4Smiod   return TRUE;
2159*3d8817e4Smiod }
2160*3d8817e4Smiod 
2161*3d8817e4Smiod /* Start a block.  */
2162*3d8817e4Smiod 
2163*3d8817e4Smiod static bfd_boolean
stab_start_block(void * p,bfd_vma addr)2164*3d8817e4Smiod stab_start_block (void *p, bfd_vma addr)
2165*3d8817e4Smiod {
2166*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
2167*3d8817e4Smiod 
2168*3d8817e4Smiod   /* Fill in any slots which have been waiting for the first known
2169*3d8817e4Smiod      text address.  */
2170*3d8817e4Smiod 
2171*3d8817e4Smiod   if (info->so_offset != -1)
2172*3d8817e4Smiod     {
2173*3d8817e4Smiod       bfd_put_32 (info->abfd, addr, info->symbols + info->so_offset + 8);
2174*3d8817e4Smiod       info->so_offset = -1;
2175*3d8817e4Smiod     }
2176*3d8817e4Smiod 
2177*3d8817e4Smiod   if (info->fun_offset != -1)
2178*3d8817e4Smiod     {
2179*3d8817e4Smiod       bfd_put_32 (info->abfd, addr, info->symbols + info->fun_offset + 8);
2180*3d8817e4Smiod       info->fun_offset = -1;
2181*3d8817e4Smiod     }
2182*3d8817e4Smiod 
2183*3d8817e4Smiod   ++info->nesting;
2184*3d8817e4Smiod 
2185*3d8817e4Smiod   /* We will be called with a top level block surrounding the
2186*3d8817e4Smiod      function, but stabs information does not output that block, so we
2187*3d8817e4Smiod      ignore it.  */
2188*3d8817e4Smiod 
2189*3d8817e4Smiod   if (info->nesting == 1)
2190*3d8817e4Smiod     {
2191*3d8817e4Smiod       info->fnaddr = addr;
2192*3d8817e4Smiod       return TRUE;
2193*3d8817e4Smiod     }
2194*3d8817e4Smiod 
2195*3d8817e4Smiod   /* We have to output the LBRAC symbol after any variables which are
2196*3d8817e4Smiod      declared inside the block.  We postpone the LBRAC until the next
2197*3d8817e4Smiod      start_block or end_block.  */
2198*3d8817e4Smiod 
2199*3d8817e4Smiod   /* If we have postponed an LBRAC, output it now.  */
2200*3d8817e4Smiod   if (info->pending_lbrac != (bfd_vma) -1)
2201*3d8817e4Smiod     {
2202*3d8817e4Smiod       if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac,
2203*3d8817e4Smiod 			       (const char *) NULL))
2204*3d8817e4Smiod 	return FALSE;
2205*3d8817e4Smiod     }
2206*3d8817e4Smiod 
2207*3d8817e4Smiod   /* Remember the address and output it later.  */
2208*3d8817e4Smiod 
2209*3d8817e4Smiod   info->pending_lbrac = addr - info->fnaddr;
2210*3d8817e4Smiod 
2211*3d8817e4Smiod   return TRUE;
2212*3d8817e4Smiod }
2213*3d8817e4Smiod 
2214*3d8817e4Smiod /* End a block.  */
2215*3d8817e4Smiod 
2216*3d8817e4Smiod static bfd_boolean
stab_end_block(void * p,bfd_vma addr)2217*3d8817e4Smiod stab_end_block (void *p, bfd_vma addr)
2218*3d8817e4Smiod {
2219*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
2220*3d8817e4Smiod 
2221*3d8817e4Smiod   if (addr > info->last_text_address)
2222*3d8817e4Smiod     info->last_text_address = addr;
2223*3d8817e4Smiod 
2224*3d8817e4Smiod   /* If we have postponed an LBRAC, output it now.  */
2225*3d8817e4Smiod   if (info->pending_lbrac != (bfd_vma) -1)
2226*3d8817e4Smiod     {
2227*3d8817e4Smiod       if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac,
2228*3d8817e4Smiod 			       (const char *) NULL))
2229*3d8817e4Smiod 	return FALSE;
2230*3d8817e4Smiod       info->pending_lbrac = (bfd_vma) -1;
2231*3d8817e4Smiod     }
2232*3d8817e4Smiod 
2233*3d8817e4Smiod   assert (info->nesting > 0);
2234*3d8817e4Smiod 
2235*3d8817e4Smiod   --info->nesting;
2236*3d8817e4Smiod 
2237*3d8817e4Smiod   /* We ignore the outermost block.  */
2238*3d8817e4Smiod   if (info->nesting == 0)
2239*3d8817e4Smiod     return TRUE;
2240*3d8817e4Smiod 
2241*3d8817e4Smiod   return stab_write_symbol (info, N_RBRAC, 0, addr - info->fnaddr,
2242*3d8817e4Smiod 			    (const char *) NULL);
2243*3d8817e4Smiod }
2244*3d8817e4Smiod 
2245*3d8817e4Smiod /* End a function.  */
2246*3d8817e4Smiod 
2247*3d8817e4Smiod static bfd_boolean
stab_end_function(void * p ATTRIBUTE_UNUSED)2248*3d8817e4Smiod stab_end_function (void *p ATTRIBUTE_UNUSED)
2249*3d8817e4Smiod {
2250*3d8817e4Smiod   return TRUE;
2251*3d8817e4Smiod }
2252*3d8817e4Smiod 
2253*3d8817e4Smiod /* Output a line number.  */
2254*3d8817e4Smiod 
2255*3d8817e4Smiod static bfd_boolean
stab_lineno(void * p,const char * file,unsigned long lineno,bfd_vma addr)2256*3d8817e4Smiod stab_lineno (void *p, const char *file, unsigned long lineno, bfd_vma addr)
2257*3d8817e4Smiod {
2258*3d8817e4Smiod   struct stab_write_handle *info = (struct stab_write_handle *) p;
2259*3d8817e4Smiod 
2260*3d8817e4Smiod   assert (info->lineno_filename != NULL);
2261*3d8817e4Smiod 
2262*3d8817e4Smiod   if (addr > info->last_text_address)
2263*3d8817e4Smiod     info->last_text_address = addr;
2264*3d8817e4Smiod 
2265*3d8817e4Smiod   if (strcmp (file, info->lineno_filename) != 0)
2266*3d8817e4Smiod     {
2267*3d8817e4Smiod       if (! stab_write_symbol (info, N_SOL, 0, addr, file))
2268*3d8817e4Smiod 	return FALSE;
2269*3d8817e4Smiod       info->lineno_filename = file;
2270*3d8817e4Smiod     }
2271*3d8817e4Smiod 
2272*3d8817e4Smiod   return stab_write_symbol (info, N_SLINE, lineno, addr - info->fnaddr,
2273*3d8817e4Smiod 			    (const char *) NULL);
2274*3d8817e4Smiod }
2275