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