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