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