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