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