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