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