133965Sjdp/* wrstabs.c -- Output stabs debugging information 2218822Sdim Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007 3130561Sobrien Free Software Foundation, Inc. 433965Sjdp Written by Ian Lance Taylor <ian@cygnus.com>. 533965Sjdp 633965Sjdp This file is part of GNU Binutils. 733965Sjdp 833965Sjdp This program is free software; you can redistribute it and/or modify 933965Sjdp it under the terms of the GNU General Public License as published by 1033965Sjdp the Free Software Foundation; either version 2 of the License, or 1133965Sjdp (at your option) any later version. 1233965Sjdp 1333965Sjdp This program is distributed in the hope that it will be useful, 1433965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1533965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965Sjdp GNU General Public License for more details. 1733965Sjdp 1833965Sjdp You should have received a copy of the GNU General Public License 1933965Sjdp along with this program; if not, write to the Free Software 20218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 21218822Sdim 02110-1301, USA. */ 2233965Sjdp 2333965Sjdp/* This file contains code which writes out stabs debugging 2433965Sjdp information. */ 2533965Sjdp 26218822Sdim#include "sysdep.h" 2733965Sjdp#include <assert.h> 2833965Sjdp#include "bfd.h" 2933965Sjdp#include "libiberty.h" 3089857Sobrien#include "safe-ctype.h" 31218822Sdim#include "bucomm.h" 3233965Sjdp#include "debug.h" 3333965Sjdp#include "budbg.h" 3433965Sjdp#include "aout/aout64.h" 3533965Sjdp#include "aout/stab_gnu.h" 3633965Sjdp 3733965Sjdp/* The size of a stabs symbol. This presumes 32 bit values. */ 3833965Sjdp 3933965Sjdp#define STAB_SYMBOL_SIZE (12) 4033965Sjdp 4133965Sjdp/* An entry in a string hash table. */ 4233965Sjdp 4333965Sjdpstruct string_hash_entry 4433965Sjdp{ 4533965Sjdp struct bfd_hash_entry root; 4633965Sjdp /* Next string in this table. */ 4733965Sjdp struct string_hash_entry *next; 4833965Sjdp /* Index in string table. */ 4933965Sjdp long index; 5033965Sjdp /* Size of type if this is a typedef. */ 5133965Sjdp unsigned int size; 5233965Sjdp}; 5333965Sjdp 5433965Sjdp/* A string hash table. */ 5533965Sjdp 5633965Sjdpstruct string_hash_table 5733965Sjdp{ 5833965Sjdp struct bfd_hash_table table; 5933965Sjdp}; 6033965Sjdp 6133965Sjdp/* The type stack. Each element on the stack is a string. */ 6233965Sjdp 6333965Sjdpstruct stab_type_stack 6433965Sjdp{ 6533965Sjdp /* The next element on the stack. */ 6633965Sjdp struct stab_type_stack *next; 6733965Sjdp /* This element as a string. */ 6833965Sjdp char *string; 6933965Sjdp /* The type index of this element. */ 7033965Sjdp long index; 7133965Sjdp /* The size of the type. */ 7233965Sjdp unsigned int size; 7333965Sjdp /* Whether type string defines a new type. */ 74130561Sobrien bfd_boolean definition; 7533965Sjdp /* String defining struct fields. */ 7633965Sjdp char *fields; 7733965Sjdp /* NULL terminated array of strings defining base classes for a 7833965Sjdp class. */ 7933965Sjdp char **baseclasses; 8033965Sjdp /* String defining class methods. */ 8133965Sjdp char *methods; 8233965Sjdp /* String defining vtable pointer for a class. */ 8333965Sjdp char *vtable; 8433965Sjdp}; 8533965Sjdp 8633965Sjdp/* This structure is used to keep track of type indices for tagged 8733965Sjdp types. */ 8833965Sjdp 8933965Sjdpstruct stab_tag 9033965Sjdp{ 9133965Sjdp /* The type index. */ 9233965Sjdp long index; 9333965Sjdp /* The tag name. */ 9433965Sjdp const char *tag; 9533965Sjdp /* The kind of type. This is set to DEBUG_KIND_ILLEGAL when the 9633965Sjdp type is defined. */ 9733965Sjdp enum debug_type_kind kind; 9833965Sjdp /* The size of the struct. */ 9933965Sjdp unsigned int size; 10033965Sjdp}; 10133965Sjdp 10233965Sjdp/* We remember various sorts of type indices. They are not related, 10333965Sjdp but, for convenience, we keep all the information in this 10433965Sjdp structure. */ 10533965Sjdp 10633965Sjdpstruct stab_type_cache 10733965Sjdp{ 10833965Sjdp /* The void type index. */ 10933965Sjdp long void_type; 11033965Sjdp /* Signed integer type indices, indexed by size - 1. */ 11133965Sjdp long signed_integer_types[8]; 11233965Sjdp /* Unsigned integer type indices, indexed by size - 1. */ 11333965Sjdp long unsigned_integer_types[8]; 11433965Sjdp /* Floating point types, indexed by size - 1. */ 11533965Sjdp long float_types[16]; 11633965Sjdp /* Pointers to types, indexed by the type index. */ 11733965Sjdp long *pointer_types; 11833965Sjdp size_t pointer_types_alloc; 11933965Sjdp /* Functions returning types, indexed by the type index. */ 12033965Sjdp long *function_types; 12133965Sjdp size_t function_types_alloc; 12233965Sjdp /* References to types, indexed by the type index. */ 12333965Sjdp long *reference_types; 12433965Sjdp size_t reference_types_alloc; 12533965Sjdp /* Struct/union/class type indices, indexed by the struct id. */ 12633965Sjdp struct stab_tag *struct_types; 12733965Sjdp size_t struct_types_alloc; 12833965Sjdp}; 12933965Sjdp 13033965Sjdp/* This is the handle passed through debug_write. */ 13133965Sjdp 13233965Sjdpstruct stab_write_handle 13333965Sjdp{ 13433965Sjdp /* The BFD. */ 13533965Sjdp bfd *abfd; 13633965Sjdp /* This buffer holds the symbols. */ 13733965Sjdp bfd_byte *symbols; 13833965Sjdp size_t symbols_size; 13933965Sjdp size_t symbols_alloc; 14033965Sjdp /* This is a list of hash table entries for the strings. */ 14133965Sjdp struct string_hash_entry *strings; 14233965Sjdp /* The last string hash table entry. */ 14333965Sjdp struct string_hash_entry *last_string; 14433965Sjdp /* The size of the strings. */ 14533965Sjdp size_t strings_size; 14633965Sjdp /* This hash table eliminates duplicate strings. */ 14733965Sjdp struct string_hash_table strhash; 14833965Sjdp /* The type stack. */ 14933965Sjdp struct stab_type_stack *type_stack; 15033965Sjdp /* The next type index. */ 15133965Sjdp long type_index; 15233965Sjdp /* The type cache. */ 15333965Sjdp struct stab_type_cache type_cache; 15433965Sjdp /* A mapping from typedef names to type indices. */ 15533965Sjdp struct string_hash_table typedef_hash; 15633965Sjdp /* If this is not -1, it is the offset to the most recent N_SO 15733965Sjdp symbol, and the value of that symbol needs to be set. */ 15833965Sjdp long so_offset; 15933965Sjdp /* If this is not -1, it is the offset to the most recent N_FUN 16033965Sjdp symbol, and the value of that symbol needs to be set. */ 16133965Sjdp long fun_offset; 16233965Sjdp /* The last text section address seen. */ 16333965Sjdp bfd_vma last_text_address; 16433965Sjdp /* The block nesting depth. */ 16533965Sjdp unsigned int nesting; 16633965Sjdp /* The function address. */ 16733965Sjdp bfd_vma fnaddr; 16833965Sjdp /* A pending LBRAC symbol. */ 16933965Sjdp bfd_vma pending_lbrac; 17033965Sjdp /* The current line number file name. */ 17133965Sjdp const char *lineno_filename; 17233965Sjdp}; 17333965Sjdp 17433965Sjdpstatic struct bfd_hash_entry *string_hash_newfunc 175130561Sobrien (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); 176130561Sobrienstatic bfd_boolean stab_write_symbol 177130561Sobrien (struct stab_write_handle *, int, int, bfd_vma, const char *); 178130561Sobrienstatic bfd_boolean stab_push_string 179130561Sobrien (struct stab_write_handle *, const char *, long, bfd_boolean, unsigned int); 180130561Sobrienstatic bfd_boolean stab_push_defined_type 181130561Sobrien (struct stab_write_handle *, long, unsigned int); 182130561Sobrienstatic char *stab_pop_type (struct stab_write_handle *); 183130561Sobrienstatic bfd_boolean stab_modify_type 184130561Sobrien (struct stab_write_handle *, int, unsigned int, long **, size_t *); 18533965Sjdpstatic long stab_get_struct_index 186130561Sobrien (struct stab_write_handle *, const char *, unsigned int, 187130561Sobrien enum debug_type_kind, unsigned int *); 188130561Sobrienstatic bfd_boolean stab_class_method_var 189130561Sobrien (struct stab_write_handle *, const char *, enum debug_visibility, 190130561Sobrien bfd_boolean, bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean); 191130561Sobrienstatic bfd_boolean stab_start_compilation_unit (void *, const char *); 192130561Sobrienstatic bfd_boolean stab_start_source (void *, const char *); 193130561Sobrienstatic bfd_boolean stab_empty_type (void *); 194130561Sobrienstatic bfd_boolean stab_void_type (void *); 195130561Sobrienstatic bfd_boolean stab_int_type (void *, unsigned int, bfd_boolean); 196130561Sobrienstatic bfd_boolean stab_float_type (void *, unsigned int); 197130561Sobrienstatic bfd_boolean stab_complex_type (void *, unsigned int); 198130561Sobrienstatic bfd_boolean stab_bool_type (void *, unsigned int); 199130561Sobrienstatic bfd_boolean stab_enum_type 200130561Sobrien (void *, const char *, const char **, bfd_signed_vma *); 201130561Sobrienstatic bfd_boolean stab_pointer_type (void *); 202130561Sobrienstatic bfd_boolean stab_function_type (void *, int, bfd_boolean); 203130561Sobrienstatic bfd_boolean stab_reference_type (void *); 204130561Sobrienstatic bfd_boolean stab_range_type (void *, bfd_signed_vma, bfd_signed_vma); 205130561Sobrienstatic bfd_boolean stab_array_type 206130561Sobrien (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean); 207130561Sobrienstatic bfd_boolean stab_set_type (void *, bfd_boolean); 208130561Sobrienstatic bfd_boolean stab_offset_type (void *); 209130561Sobrienstatic bfd_boolean stab_method_type (void *, bfd_boolean, int, bfd_boolean); 210130561Sobrienstatic bfd_boolean stab_const_type (void *); 211130561Sobrienstatic bfd_boolean stab_volatile_type (void *); 212130561Sobrienstatic bfd_boolean stab_start_struct_type 213130561Sobrien (void *, const char *, unsigned int, bfd_boolean, unsigned int); 214130561Sobrienstatic bfd_boolean stab_struct_field 215130561Sobrien (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); 216130561Sobrienstatic bfd_boolean stab_end_struct_type (void *); 217130561Sobrienstatic bfd_boolean stab_start_class_type 218130561Sobrien (void *, const char *, unsigned int, bfd_boolean, unsigned int, 219130561Sobrien bfd_boolean, bfd_boolean); 220130561Sobrienstatic bfd_boolean stab_class_static_member 221130561Sobrien (void *, const char *, const char *, enum debug_visibility); 222130561Sobrienstatic bfd_boolean stab_class_baseclass 223130561Sobrien (void *, bfd_vma, bfd_boolean, enum debug_visibility); 224130561Sobrienstatic bfd_boolean stab_class_start_method (void *, const char *); 225130561Sobrienstatic bfd_boolean stab_class_method_variant 226130561Sobrien (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, 227130561Sobrien bfd_vma, bfd_boolean); 228130561Sobrienstatic bfd_boolean stab_class_static_method_variant 229130561Sobrien (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean); 230130561Sobrienstatic bfd_boolean stab_class_end_method (void *); 231130561Sobrienstatic bfd_boolean stab_end_class_type (void *); 232130561Sobrienstatic bfd_boolean stab_typedef_type (void *, const char *); 233130561Sobrienstatic bfd_boolean stab_tag_type 234130561Sobrien (void *, const char *, unsigned int, enum debug_type_kind); 235130561Sobrienstatic bfd_boolean stab_typdef (void *, const char *); 236130561Sobrienstatic bfd_boolean stab_tag (void *, const char *); 237130561Sobrienstatic bfd_boolean stab_int_constant (void *, const char *, bfd_vma); 238130561Sobrienstatic bfd_boolean stab_float_constant (void *, const char *, double); 239130561Sobrienstatic bfd_boolean stab_typed_constant (void *, const char *, bfd_vma); 240130561Sobrienstatic bfd_boolean stab_variable 241130561Sobrien (void *, const char *, enum debug_var_kind, bfd_vma); 242130561Sobrienstatic bfd_boolean stab_start_function (void *, const char *, bfd_boolean); 243130561Sobrienstatic bfd_boolean stab_function_parameter 244130561Sobrien (void *, const char *, enum debug_parm_kind, bfd_vma); 245130561Sobrienstatic bfd_boolean stab_start_block (void *, bfd_vma); 246130561Sobrienstatic bfd_boolean stab_end_block (void *, bfd_vma); 247130561Sobrienstatic bfd_boolean stab_end_function (void *); 248130561Sobrienstatic bfd_boolean stab_lineno (void *, const char *, unsigned long, bfd_vma); 24933965Sjdp 25033965Sjdpstatic const struct debug_write_fns stab_fns = 25133965Sjdp{ 25233965Sjdp stab_start_compilation_unit, 25333965Sjdp stab_start_source, 25433965Sjdp stab_empty_type, 25533965Sjdp stab_void_type, 25633965Sjdp stab_int_type, 25733965Sjdp stab_float_type, 25833965Sjdp stab_complex_type, 25933965Sjdp stab_bool_type, 26033965Sjdp stab_enum_type, 26133965Sjdp stab_pointer_type, 26233965Sjdp stab_function_type, 26333965Sjdp stab_reference_type, 26433965Sjdp stab_range_type, 26533965Sjdp stab_array_type, 26633965Sjdp stab_set_type, 26733965Sjdp stab_offset_type, 26833965Sjdp stab_method_type, 26933965Sjdp stab_const_type, 27033965Sjdp stab_volatile_type, 27133965Sjdp stab_start_struct_type, 27233965Sjdp stab_struct_field, 27333965Sjdp stab_end_struct_type, 27433965Sjdp stab_start_class_type, 27533965Sjdp stab_class_static_member, 27633965Sjdp stab_class_baseclass, 27733965Sjdp stab_class_start_method, 27833965Sjdp stab_class_method_variant, 27933965Sjdp stab_class_static_method_variant, 28033965Sjdp stab_class_end_method, 28133965Sjdp stab_end_class_type, 28233965Sjdp stab_typedef_type, 28333965Sjdp stab_tag_type, 28433965Sjdp stab_typdef, 28533965Sjdp stab_tag, 28633965Sjdp stab_int_constant, 28733965Sjdp stab_float_constant, 28833965Sjdp stab_typed_constant, 28933965Sjdp stab_variable, 29033965Sjdp stab_start_function, 29133965Sjdp stab_function_parameter, 29233965Sjdp stab_start_block, 29333965Sjdp stab_end_block, 29433965Sjdp stab_end_function, 29533965Sjdp stab_lineno 29633965Sjdp}; 29733965Sjdp 29833965Sjdp/* Routine to create an entry in a string hash table. */ 29933965Sjdp 30033965Sjdpstatic struct bfd_hash_entry * 301130561Sobrienstring_hash_newfunc (struct bfd_hash_entry *entry, 302130561Sobrien struct bfd_hash_table *table, const char *string) 30333965Sjdp{ 30433965Sjdp struct string_hash_entry *ret = (struct string_hash_entry *) entry; 30533965Sjdp 30633965Sjdp /* Allocate the structure if it has not already been allocated by a 30733965Sjdp subclass. */ 30833965Sjdp if (ret == (struct string_hash_entry *) NULL) 30933965Sjdp ret = ((struct string_hash_entry *) 31033965Sjdp bfd_hash_allocate (table, sizeof (struct string_hash_entry))); 31133965Sjdp if (ret == (struct string_hash_entry *) NULL) 31233965Sjdp return NULL; 31333965Sjdp 31433965Sjdp /* Call the allocation method of the superclass. */ 31533965Sjdp ret = ((struct string_hash_entry *) 31633965Sjdp bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 31733965Sjdp 31833965Sjdp if (ret) 31933965Sjdp { 32033965Sjdp /* Initialize the local fields. */ 32133965Sjdp ret->next = NULL; 32233965Sjdp ret->index = -1; 32333965Sjdp ret->size = 0; 32433965Sjdp } 32533965Sjdp 32633965Sjdp return (struct bfd_hash_entry *) ret; 32733965Sjdp} 32833965Sjdp 32933965Sjdp/* Look up an entry in a string hash table. */ 33033965Sjdp 33133965Sjdp#define string_hash_lookup(t, string, create, copy) \ 33233965Sjdp ((struct string_hash_entry *) \ 33333965Sjdp bfd_hash_lookup (&(t)->table, (string), (create), (copy))) 33433965Sjdp 33533965Sjdp/* Add a symbol to the stabs debugging information we are building. */ 33633965Sjdp 337130561Sobrienstatic bfd_boolean 338130561Sobrienstab_write_symbol (struct stab_write_handle *info, int type, int desc, 339130561Sobrien bfd_vma value, const char *string) 34033965Sjdp{ 34133965Sjdp bfd_size_type strx; 34233965Sjdp bfd_byte sym[STAB_SYMBOL_SIZE]; 34333965Sjdp 34433965Sjdp if (string == NULL) 34533965Sjdp strx = 0; 34633965Sjdp else 34733965Sjdp { 34833965Sjdp struct string_hash_entry *h; 34933965Sjdp 350130561Sobrien h = string_hash_lookup (&info->strhash, string, TRUE, TRUE); 35133965Sjdp if (h == NULL) 35233965Sjdp { 35360484Sobrien non_fatal (_("string_hash_lookup failed: %s"), 35460484Sobrien bfd_errmsg (bfd_get_error ())); 355130561Sobrien return FALSE; 35633965Sjdp } 35733965Sjdp if (h->index != -1) 35833965Sjdp strx = h->index; 35933965Sjdp else 36033965Sjdp { 36133965Sjdp strx = info->strings_size; 36233965Sjdp h->index = strx; 36333965Sjdp if (info->last_string == NULL) 36433965Sjdp info->strings = h; 36533965Sjdp else 36633965Sjdp info->last_string->next = h; 36733965Sjdp info->last_string = h; 36833965Sjdp info->strings_size += strlen (string) + 1; 36933965Sjdp } 37033965Sjdp } 37133965Sjdp 37233965Sjdp /* This presumes 32 bit values. */ 37333965Sjdp bfd_put_32 (info->abfd, strx, sym); 37433965Sjdp bfd_put_8 (info->abfd, type, sym + 4); 37533965Sjdp bfd_put_8 (info->abfd, 0, sym + 5); 37633965Sjdp bfd_put_16 (info->abfd, desc, sym + 6); 37733965Sjdp bfd_put_32 (info->abfd, value, sym + 8); 37833965Sjdp 37933965Sjdp if (info->symbols_size + STAB_SYMBOL_SIZE > info->symbols_alloc) 38033965Sjdp { 38133965Sjdp info->symbols_alloc *= 2; 38233965Sjdp info->symbols = (bfd_byte *) xrealloc (info->symbols, 38333965Sjdp info->symbols_alloc); 38433965Sjdp } 38533965Sjdp 38633965Sjdp memcpy (info->symbols + info->symbols_size, sym, STAB_SYMBOL_SIZE); 38733965Sjdp 38833965Sjdp info->symbols_size += STAB_SYMBOL_SIZE; 38933965Sjdp 390130561Sobrien return TRUE; 39133965Sjdp} 39233965Sjdp 39333965Sjdp/* Push a string on to the type stack. */ 39433965Sjdp 395130561Sobrienstatic bfd_boolean 396130561Sobrienstab_push_string (struct stab_write_handle *info, const char *string, 397130561Sobrien long index, bfd_boolean definition, unsigned int size) 39833965Sjdp{ 39933965Sjdp struct stab_type_stack *s; 40033965Sjdp 40133965Sjdp s = (struct stab_type_stack *) xmalloc (sizeof *s); 40233965Sjdp s->string = xstrdup (string); 40333965Sjdp s->index = index; 40433965Sjdp s->definition = definition; 40533965Sjdp s->size = size; 40633965Sjdp 40733965Sjdp s->fields = NULL; 40833965Sjdp s->baseclasses = NULL; 40933965Sjdp s->methods = NULL; 41033965Sjdp s->vtable = NULL; 41133965Sjdp 41233965Sjdp s->next = info->type_stack; 41333965Sjdp info->type_stack = s; 41433965Sjdp 415130561Sobrien return TRUE; 41633965Sjdp} 41733965Sjdp 41833965Sjdp/* Push a type index which has already been defined. */ 41933965Sjdp 420130561Sobrienstatic bfd_boolean 421130561Sobrienstab_push_defined_type (struct stab_write_handle *info, long index, 422130561Sobrien unsigned int size) 42333965Sjdp{ 42433965Sjdp char buf[20]; 42533965Sjdp 42633965Sjdp sprintf (buf, "%ld", index); 427130561Sobrien return stab_push_string (info, buf, index, FALSE, size); 42833965Sjdp} 42933965Sjdp 43033965Sjdp/* Pop a type off the type stack. The caller is responsible for 43133965Sjdp freeing the string. */ 43233965Sjdp 43333965Sjdpstatic char * 434130561Sobrienstab_pop_type (struct stab_write_handle *info) 43533965Sjdp{ 43633965Sjdp struct stab_type_stack *s; 43733965Sjdp char *ret; 43833965Sjdp 43933965Sjdp s = info->type_stack; 44033965Sjdp assert (s != NULL); 44133965Sjdp 44233965Sjdp info->type_stack = s->next; 44333965Sjdp 44433965Sjdp ret = s->string; 44533965Sjdp 44633965Sjdp free (s); 44733965Sjdp 44833965Sjdp return ret; 44933965Sjdp} 45033965Sjdp 45133965Sjdp/* The general routine to write out stabs in sections debugging 45233965Sjdp information. This accumulates the stabs symbols and the strings in 45333965Sjdp two obstacks. We can't easily write out the information as we go 45433965Sjdp along, because we need to know the section sizes before we can 45533965Sjdp write out the section contents. ABFD is the BFD and DHANDLE is the 45633965Sjdp handle for the debugging information. This sets *PSYMS to point to 45733965Sjdp the symbols, *PSYMSIZE the size of the symbols, *PSTRINGS to the 45833965Sjdp strings, and *PSTRINGSIZE to the size of the strings. */ 45933965Sjdp 460130561Sobrienbfd_boolean 461130561Sobrienwrite_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle, 462130561Sobrien bfd_byte **psyms, 463130561Sobrien bfd_size_type *psymsize, 464130561Sobrien bfd_byte **pstrings, 465130561Sobrien bfd_size_type *pstringsize) 46633965Sjdp{ 46733965Sjdp struct stab_write_handle info; 46833965Sjdp struct string_hash_entry *h; 46933965Sjdp bfd_byte *p; 47033965Sjdp 47133965Sjdp info.abfd = abfd; 47233965Sjdp 47333965Sjdp info.symbols_size = 0; 47433965Sjdp info.symbols_alloc = 500; 47533965Sjdp info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc); 47633965Sjdp 47733965Sjdp info.strings = NULL; 47833965Sjdp info.last_string = NULL; 47933965Sjdp /* Reserve 1 byte for a null byte. */ 48033965Sjdp info.strings_size = 1; 48133965Sjdp 482218822Sdim if (!bfd_hash_table_init (&info.strhash.table, string_hash_newfunc, 483218822Sdim sizeof (struct string_hash_entry)) 484218822Sdim || !bfd_hash_table_init (&info.typedef_hash.table, string_hash_newfunc, 485218822Sdim sizeof (struct string_hash_entry))) 48633965Sjdp { 48760484Sobrien non_fatal ("bfd_hash_table_init_failed: %s", 48860484Sobrien bfd_errmsg (bfd_get_error ())); 489130561Sobrien return FALSE; 49033965Sjdp } 49133965Sjdp 49233965Sjdp info.type_stack = NULL; 49333965Sjdp info.type_index = 1; 49433965Sjdp memset (&info.type_cache, 0, sizeof info.type_cache); 49533965Sjdp info.so_offset = -1; 49633965Sjdp info.fun_offset = -1; 49733965Sjdp info.last_text_address = 0; 49833965Sjdp info.nesting = 0; 49933965Sjdp info.fnaddr = 0; 50033965Sjdp info.pending_lbrac = (bfd_vma) -1; 50133965Sjdp 50233965Sjdp /* The initial symbol holds the string size. */ 50333965Sjdp if (! stab_write_symbol (&info, 0, 0, 0, (const char *) NULL)) 504130561Sobrien return FALSE; 50533965Sjdp 50633965Sjdp /* Output an initial N_SO symbol. */ 50733965Sjdp info.so_offset = info.symbols_size; 50833965Sjdp if (! stab_write_symbol (&info, N_SO, 0, 0, bfd_get_filename (abfd))) 509130561Sobrien return FALSE; 51033965Sjdp 511130561Sobrien if (! debug_write (dhandle, &stab_fns, (void *) &info)) 512130561Sobrien return FALSE; 51333965Sjdp 51433965Sjdp assert (info.pending_lbrac == (bfd_vma) -1); 51533965Sjdp 51633965Sjdp /* Output a trailing N_SO. */ 51733965Sjdp if (! stab_write_symbol (&info, N_SO, 0, info.last_text_address, 51833965Sjdp (const char *) NULL)) 519130561Sobrien return FALSE; 52033965Sjdp 52133965Sjdp /* Put the string size in the initial symbol. */ 52233965Sjdp bfd_put_32 (abfd, info.strings_size, info.symbols + 8); 52333965Sjdp 52433965Sjdp *psyms = info.symbols; 52533965Sjdp *psymsize = info.symbols_size; 52633965Sjdp 52733965Sjdp *pstringsize = info.strings_size; 52833965Sjdp *pstrings = (bfd_byte *) xmalloc (info.strings_size); 52933965Sjdp 53033965Sjdp p = *pstrings; 53133965Sjdp *p++ = '\0'; 53233965Sjdp for (h = info.strings; h != NULL; h = h->next) 53333965Sjdp { 53438889Sjdp strcpy ((char *) p, h->root.string); 53538889Sjdp p += strlen ((char *) p) + 1; 53633965Sjdp } 53733965Sjdp 538130561Sobrien return TRUE; 53933965Sjdp} 54033965Sjdp 54133965Sjdp/* Start writing out information for a compilation unit. */ 54233965Sjdp 543130561Sobrienstatic bfd_boolean 544130561Sobrienstab_start_compilation_unit (void *p, const char *filename) 54533965Sjdp{ 54633965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 54733965Sjdp 54833965Sjdp /* We would normally output an N_SO symbol here. However, that 54933965Sjdp would force us to reset all of our type information. I think we 55033965Sjdp will be better off just outputting an N_SOL symbol, and not 55133965Sjdp worrying about splitting information between files. */ 55233965Sjdp 55333965Sjdp info->lineno_filename = filename; 55433965Sjdp 55533965Sjdp return stab_write_symbol (info, N_SOL, 0, 0, filename); 55633965Sjdp} 55733965Sjdp 55833965Sjdp/* Start writing out information for a particular source file. */ 55933965Sjdp 560130561Sobrienstatic bfd_boolean 561130561Sobrienstab_start_source (void *p, const char *filename) 56233965Sjdp{ 56333965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 56433965Sjdp 56533965Sjdp /* FIXME: The symbol's value is supposed to be the text section 56633965Sjdp address. However, we would have to fill it in later, and gdb 56733965Sjdp doesn't care, so we don't bother with it. */ 56833965Sjdp 56933965Sjdp info->lineno_filename = filename; 57033965Sjdp 57133965Sjdp return stab_write_symbol (info, N_SOL, 0, 0, filename); 57233965Sjdp} 57333965Sjdp 57433965Sjdp/* Push an empty type. This shouldn't normally happen. We just use a 57533965Sjdp void type. */ 57633965Sjdp 577130561Sobrienstatic bfd_boolean 578130561Sobrienstab_empty_type (void *p) 57933965Sjdp{ 58033965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 58133965Sjdp 58233965Sjdp /* We don't call stab_void_type if the type is not yet defined, 58333965Sjdp because that might screw up the typedef. */ 58433965Sjdp 58533965Sjdp if (info->type_cache.void_type != 0) 58633965Sjdp return stab_push_defined_type (info, info->type_cache.void_type, 0); 58733965Sjdp else 58833965Sjdp { 58933965Sjdp long index; 59033965Sjdp char buf[40]; 59133965Sjdp 59233965Sjdp index = info->type_index; 59333965Sjdp ++info->type_index; 59433965Sjdp 59533965Sjdp sprintf (buf, "%ld=%ld", index, index); 59633965Sjdp 597130561Sobrien return stab_push_string (info, buf, index, FALSE, 0); 59833965Sjdp } 59933965Sjdp} 60033965Sjdp 60133965Sjdp/* Push a void type. */ 60233965Sjdp 603130561Sobrienstatic bfd_boolean 604130561Sobrienstab_void_type (void *p) 60533965Sjdp{ 60633965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 60733965Sjdp 60833965Sjdp if (info->type_cache.void_type != 0) 60933965Sjdp return stab_push_defined_type (info, info->type_cache.void_type, 0); 61033965Sjdp else 61133965Sjdp { 61233965Sjdp long index; 61333965Sjdp char buf[40]; 61433965Sjdp 61533965Sjdp index = info->type_index; 61633965Sjdp ++info->type_index; 61733965Sjdp 61833965Sjdp info->type_cache.void_type = index; 61933965Sjdp 62033965Sjdp sprintf (buf, "%ld=%ld", index, index); 62133965Sjdp 622130561Sobrien return stab_push_string (info, buf, index, TRUE, 0); 62333965Sjdp } 62433965Sjdp} 62533965Sjdp 62633965Sjdp/* Push an integer type. */ 62733965Sjdp 628130561Sobrienstatic bfd_boolean 629130561Sobrienstab_int_type (void *p, unsigned int size, bfd_boolean unsignedp) 63033965Sjdp{ 63133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 63233965Sjdp long *cache; 63333965Sjdp 63433965Sjdp if (size <= 0 || (size > sizeof (long) && size != 8)) 63533965Sjdp { 63660484Sobrien non_fatal (_("stab_int_type: bad size %u"), size); 637130561Sobrien return FALSE; 63833965Sjdp } 63933965Sjdp 64033965Sjdp if (unsignedp) 64133965Sjdp cache = info->type_cache.signed_integer_types; 64233965Sjdp else 64333965Sjdp cache = info->type_cache.unsigned_integer_types; 64433965Sjdp 64533965Sjdp if (cache[size - 1] != 0) 64633965Sjdp return stab_push_defined_type (info, cache[size - 1], size); 64733965Sjdp else 64833965Sjdp { 64933965Sjdp long index; 65033965Sjdp char buf[100]; 65133965Sjdp 65233965Sjdp index = info->type_index; 65333965Sjdp ++info->type_index; 65433965Sjdp 65533965Sjdp cache[size - 1] = index; 65633965Sjdp 65733965Sjdp sprintf (buf, "%ld=r%ld;", index, index); 65833965Sjdp if (unsignedp) 65933965Sjdp { 66033965Sjdp strcat (buf, "0;"); 66133965Sjdp if (size < sizeof (long)) 66233965Sjdp sprintf (buf + strlen (buf), "%ld;", ((long) 1 << (size * 8)) - 1); 66333965Sjdp else if (size == sizeof (long)) 66433965Sjdp strcat (buf, "-1;"); 66533965Sjdp else if (size == 8) 66633965Sjdp strcat (buf, "01777777777777777777777;"); 66733965Sjdp else 66833965Sjdp abort (); 66933965Sjdp } 67033965Sjdp else 67133965Sjdp { 67233965Sjdp if (size <= sizeof (long)) 67333965Sjdp sprintf (buf + strlen (buf), "%ld;%ld;", 67433965Sjdp (long) - ((unsigned long) 1 << (size * 8 - 1)), 67533965Sjdp (long) (((unsigned long) 1 << (size * 8 - 1)) - 1)); 67633965Sjdp else if (size == 8) 67733965Sjdp strcat (buf, "01000000000000000000000;0777777777777777777777;"); 67833965Sjdp else 67933965Sjdp abort (); 68033965Sjdp } 68133965Sjdp 682130561Sobrien return stab_push_string (info, buf, index, TRUE, size); 68333965Sjdp } 68433965Sjdp} 68533965Sjdp 68633965Sjdp/* Push a floating point type. */ 68733965Sjdp 688130561Sobrienstatic bfd_boolean 689130561Sobrienstab_float_type (void *p, unsigned int size) 69033965Sjdp{ 69133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 69233965Sjdp 69333965Sjdp if (size > 0 69433965Sjdp && size - 1 < (sizeof info->type_cache.float_types 69533965Sjdp / sizeof info->type_cache.float_types[0]) 69633965Sjdp && info->type_cache.float_types[size - 1] != 0) 69733965Sjdp return stab_push_defined_type (info, 69833965Sjdp info->type_cache.float_types[size - 1], 69933965Sjdp size); 70033965Sjdp else 70133965Sjdp { 70233965Sjdp long index; 70333965Sjdp char *int_type; 70433965Sjdp char buf[50]; 70533965Sjdp 70633965Sjdp /* Floats are defined as a subrange of int. */ 707130561Sobrien if (! stab_int_type (info, 4, FALSE)) 708130561Sobrien return FALSE; 70933965Sjdp int_type = stab_pop_type (info); 71033965Sjdp 71133965Sjdp index = info->type_index; 71233965Sjdp ++info->type_index; 71333965Sjdp 71433965Sjdp if (size > 0 71533965Sjdp && size - 1 < (sizeof info->type_cache.float_types 71633965Sjdp / sizeof info->type_cache.float_types[0])) 71733965Sjdp info->type_cache.float_types[size - 1] = index; 71833965Sjdp 71933965Sjdp sprintf (buf, "%ld=r%s;%u;0;", index, int_type, size); 72033965Sjdp 72133965Sjdp free (int_type); 72233965Sjdp 723130561Sobrien return stab_push_string (info, buf, index, TRUE, size); 72433965Sjdp } 72533965Sjdp} 72633965Sjdp 72733965Sjdp/* Push a complex type. */ 72833965Sjdp 729130561Sobrienstatic bfd_boolean 730130561Sobrienstab_complex_type (void *p, unsigned int size) 73133965Sjdp{ 73233965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 73333965Sjdp char buf[50]; 73433965Sjdp long index; 73533965Sjdp 73633965Sjdp index = info->type_index; 73733965Sjdp ++info->type_index; 73833965Sjdp 73933965Sjdp sprintf (buf, "%ld=r%ld;%u;0;", index, index, size); 74033965Sjdp 741130561Sobrien return stab_push_string (info, buf, index, TRUE, size * 2); 74233965Sjdp} 74333965Sjdp 744130561Sobrien/* Push a bfd_boolean type. We use an XCOFF predefined type, since gdb 74533965Sjdp always recognizes them. */ 74633965Sjdp 747130561Sobrienstatic bfd_boolean 748130561Sobrienstab_bool_type (void *p, unsigned int size) 74933965Sjdp{ 75033965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 75133965Sjdp long index; 75233965Sjdp 75333965Sjdp switch (size) 75433965Sjdp { 75533965Sjdp case 1: 75633965Sjdp index = -21; 75733965Sjdp break; 75833965Sjdp 75933965Sjdp case 2: 76033965Sjdp index = -22; 76133965Sjdp break; 762104834Sobrien 76333965Sjdp default: 76433965Sjdp case 4: 76533965Sjdp index = -16; 76633965Sjdp break; 76733965Sjdp 76833965Sjdp case 8: 76933965Sjdp index = -33; 77033965Sjdp break; 77133965Sjdp } 77233965Sjdp 77333965Sjdp return stab_push_defined_type (info, index, size); 77433965Sjdp} 77533965Sjdp 77633965Sjdp/* Push an enum type. */ 77733965Sjdp 778130561Sobrienstatic bfd_boolean 779130561Sobrienstab_enum_type (void *p, const char *tag, const char **names, 780130561Sobrien bfd_signed_vma *vals) 78133965Sjdp{ 78233965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 78333965Sjdp size_t len; 78433965Sjdp const char **pn; 78533965Sjdp char *buf; 78633965Sjdp long index = 0; 78733965Sjdp bfd_signed_vma *pv; 78833965Sjdp 78933965Sjdp if (names == NULL) 79033965Sjdp { 79133965Sjdp assert (tag != NULL); 79233965Sjdp 79333965Sjdp buf = (char *) xmalloc (10 + strlen (tag)); 79433965Sjdp sprintf (buf, "xe%s:", tag); 79533965Sjdp /* FIXME: The size is just a guess. */ 796130561Sobrien if (! stab_push_string (info, buf, 0, FALSE, 4)) 797130561Sobrien return FALSE; 79833965Sjdp free (buf); 799130561Sobrien return TRUE; 80033965Sjdp } 80133965Sjdp 80233965Sjdp len = 10; 80333965Sjdp if (tag != NULL) 80433965Sjdp len += strlen (tag); 80533965Sjdp for (pn = names; *pn != NULL; pn++) 80633965Sjdp len += strlen (*pn) + 20; 80733965Sjdp 80833965Sjdp buf = (char *) xmalloc (len); 80933965Sjdp 81033965Sjdp if (tag == NULL) 81133965Sjdp strcpy (buf, "e"); 81233965Sjdp else 81333965Sjdp { 81433965Sjdp index = info->type_index; 81533965Sjdp ++info->type_index; 81633965Sjdp sprintf (buf, "%s:T%ld=e", tag, index); 81733965Sjdp } 81833965Sjdp 81933965Sjdp for (pn = names, pv = vals; *pn != NULL; pn++, pv++) 82033965Sjdp sprintf (buf + strlen (buf), "%s:%ld,", *pn, (long) *pv); 82133965Sjdp strcat (buf, ";"); 82233965Sjdp 82333965Sjdp if (tag == NULL) 82433965Sjdp { 82533965Sjdp /* FIXME: The size is just a guess. */ 826130561Sobrien if (! stab_push_string (info, buf, 0, FALSE, 4)) 827130561Sobrien return FALSE; 82833965Sjdp } 82933965Sjdp else 83033965Sjdp { 83133965Sjdp /* FIXME: The size is just a guess. */ 83233965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf) 83333965Sjdp || ! stab_push_defined_type (info, index, 4)) 834130561Sobrien return FALSE; 83533965Sjdp } 83633965Sjdp 83733965Sjdp free (buf); 83833965Sjdp 839130561Sobrien return TRUE; 84033965Sjdp} 84133965Sjdp 84233965Sjdp/* Push a modification of the top type on the stack. Cache the 84333965Sjdp results in CACHE and CACHE_ALLOC. */ 84433965Sjdp 845130561Sobrienstatic bfd_boolean 846130561Sobrienstab_modify_type (struct stab_write_handle *info, int mod, 847130561Sobrien unsigned int size, long **cache, size_t *cache_alloc) 84833965Sjdp{ 84933965Sjdp long targindex; 85033965Sjdp long index; 85133965Sjdp char *s, *buf; 85233965Sjdp 85333965Sjdp assert (info->type_stack != NULL); 85433965Sjdp targindex = info->type_stack->index; 85533965Sjdp 85633965Sjdp if (targindex <= 0 85733965Sjdp || cache == NULL) 85833965Sjdp { 859130561Sobrien bfd_boolean definition; 86033965Sjdp 86133965Sjdp /* Either the target type has no index, or we aren't caching 86233965Sjdp this modifier. Either way we have no way of recording the 86333965Sjdp new type, so we don't bother to define one. */ 86433965Sjdp definition = info->type_stack->definition; 86533965Sjdp s = stab_pop_type (info); 86633965Sjdp buf = (char *) xmalloc (strlen (s) + 2); 86733965Sjdp sprintf (buf, "%c%s", mod, s); 86833965Sjdp free (s); 86933965Sjdp if (! stab_push_string (info, buf, 0, definition, size)) 870130561Sobrien return FALSE; 87133965Sjdp free (buf); 87233965Sjdp } 87333965Sjdp else 87433965Sjdp { 87538889Sjdp if ((size_t) targindex >= *cache_alloc) 87633965Sjdp { 87733965Sjdp size_t alloc; 87833965Sjdp 87933965Sjdp alloc = *cache_alloc; 88033965Sjdp if (alloc == 0) 88133965Sjdp alloc = 10; 88238889Sjdp while ((size_t) targindex >= alloc) 88333965Sjdp alloc *= 2; 88433965Sjdp *cache = (long *) xrealloc (*cache, alloc * sizeof (long)); 88533965Sjdp memset (*cache + *cache_alloc, 0, 88633965Sjdp (alloc - *cache_alloc) * sizeof (long)); 88733965Sjdp *cache_alloc = alloc; 88833965Sjdp } 88933965Sjdp 89033965Sjdp index = (*cache)[targindex]; 89133965Sjdp if (index != 0 && ! info->type_stack->definition) 89233965Sjdp { 89333965Sjdp /* We have already defined a modification of this type, and 89433965Sjdp the entry on the type stack is not a definition, so we 89533965Sjdp can safely discard it (we may have a definition on the 89633965Sjdp stack, even if we already defined a modification, if it 89733965Sjdp is a struct which we did not define at the time it was 89833965Sjdp referenced). */ 89933965Sjdp free (stab_pop_type (info)); 90033965Sjdp if (! stab_push_defined_type (info, index, size)) 901130561Sobrien return FALSE; 90233965Sjdp } 90333965Sjdp else 90433965Sjdp { 90533965Sjdp index = info->type_index; 90633965Sjdp ++info->type_index; 90733965Sjdp 90833965Sjdp s = stab_pop_type (info); 90933965Sjdp buf = (char *) xmalloc (strlen (s) + 20); 91033965Sjdp sprintf (buf, "%ld=%c%s", index, mod, s); 91133965Sjdp free (s); 91233965Sjdp 91333965Sjdp (*cache)[targindex] = index; 91433965Sjdp 915130561Sobrien if (! stab_push_string (info, buf, index, TRUE, size)) 916130561Sobrien return FALSE; 91733965Sjdp 91833965Sjdp free (buf); 91933965Sjdp } 92033965Sjdp } 92133965Sjdp 922130561Sobrien return TRUE; 923104834Sobrien} 92433965Sjdp 92533965Sjdp/* Push a pointer type. */ 92633965Sjdp 927130561Sobrienstatic bfd_boolean 928130561Sobrienstab_pointer_type (void *p) 92933965Sjdp{ 93033965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 93133965Sjdp 93233965Sjdp /* FIXME: The size should depend upon the architecture. */ 93333965Sjdp return stab_modify_type (info, '*', 4, &info->type_cache.pointer_types, 93433965Sjdp &info->type_cache.pointer_types_alloc); 93533965Sjdp} 93633965Sjdp 93733965Sjdp/* Push a function type. */ 93833965Sjdp 939130561Sobrienstatic bfd_boolean 940130561Sobrienstab_function_type (void *p, int argcount, 941130561Sobrien bfd_boolean varargs ATTRIBUTE_UNUSED) 94233965Sjdp{ 94333965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 94433965Sjdp int i; 94533965Sjdp 94633965Sjdp /* We have no way to represent the argument types, so we just 94733965Sjdp discard them. However, if they define new types, we must output 94833965Sjdp them. We do this by producing empty typedefs. */ 94933965Sjdp for (i = 0; i < argcount; i++) 95033965Sjdp { 95133965Sjdp if (! info->type_stack->definition) 95233965Sjdp free (stab_pop_type (info)); 95333965Sjdp else 95433965Sjdp { 95533965Sjdp char *s, *buf; 95633965Sjdp 95733965Sjdp s = stab_pop_type (info); 95833965Sjdp 95933965Sjdp buf = (char *) xmalloc (strlen (s) + 3); 96033965Sjdp sprintf (buf, ":t%s", s); 96133965Sjdp free (s); 96233965Sjdp 96333965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) 964130561Sobrien return FALSE; 96533965Sjdp 96633965Sjdp free (buf); 96733965Sjdp } 96833965Sjdp } 96933965Sjdp 97033965Sjdp return stab_modify_type (info, 'f', 0, &info->type_cache.function_types, 97133965Sjdp &info->type_cache.function_types_alloc); 97233965Sjdp} 97333965Sjdp 97433965Sjdp/* Push a reference type. */ 97533965Sjdp 976130561Sobrienstatic bfd_boolean 977130561Sobrienstab_reference_type (void *p) 97833965Sjdp{ 97933965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 98033965Sjdp 98133965Sjdp /* FIXME: The size should depend upon the architecture. */ 98233965Sjdp return stab_modify_type (info, '&', 4, &info->type_cache.reference_types, 98333965Sjdp &info->type_cache.reference_types_alloc); 98433965Sjdp} 98533965Sjdp 98633965Sjdp/* Push a range type. */ 98733965Sjdp 988130561Sobrienstatic bfd_boolean 989130561Sobrienstab_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high) 99033965Sjdp{ 99133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 992130561Sobrien bfd_boolean definition; 99333965Sjdp unsigned int size; 99433965Sjdp char *s, *buf; 99533965Sjdp 99633965Sjdp definition = info->type_stack->definition; 99733965Sjdp size = info->type_stack->size; 99833965Sjdp 99933965Sjdp s = stab_pop_type (info); 100033965Sjdp buf = (char *) xmalloc (strlen (s) + 100); 100133965Sjdp sprintf (buf, "r%s;%ld;%ld;", s, (long) low, (long) high); 100233965Sjdp free (s); 100333965Sjdp 100433965Sjdp if (! stab_push_string (info, buf, 0, definition, size)) 1005130561Sobrien return FALSE; 100633965Sjdp 100733965Sjdp free (buf); 100833965Sjdp 1009130561Sobrien return TRUE; 101033965Sjdp} 101133965Sjdp 101233965Sjdp/* Push an array type. */ 101333965Sjdp 1014130561Sobrienstatic bfd_boolean 1015130561Sobrienstab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high, 1016130561Sobrien bfd_boolean stringp) 101733965Sjdp{ 101833965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1019130561Sobrien bfd_boolean definition; 102033965Sjdp unsigned int element_size; 102133965Sjdp char *range, *element, *buf; 102233965Sjdp long index; 102333965Sjdp unsigned int size; 102433965Sjdp 102533965Sjdp definition = info->type_stack->definition; 102633965Sjdp range = stab_pop_type (info); 102733965Sjdp 102833965Sjdp definition = definition || info->type_stack->definition; 102933965Sjdp element_size = info->type_stack->size; 103033965Sjdp element = stab_pop_type (info); 103133965Sjdp 103233965Sjdp buf = (char *) xmalloc (strlen (range) + strlen (element) + 100); 103333965Sjdp 103433965Sjdp if (! stringp) 103533965Sjdp { 103633965Sjdp index = 0; 103733965Sjdp *buf = '\0'; 103833965Sjdp } 103933965Sjdp else 104033965Sjdp { 104133965Sjdp /* We need to define a type in order to include the string 104233965Sjdp attribute. */ 104333965Sjdp index = info->type_index; 104433965Sjdp ++info->type_index; 1045130561Sobrien definition = TRUE; 104633965Sjdp sprintf (buf, "%ld=@S;", index); 104733965Sjdp } 104833965Sjdp 104933965Sjdp sprintf (buf + strlen (buf), "ar%s;%ld;%ld;%s", 105033965Sjdp range, (long) low, (long) high, element); 105133965Sjdp free (range); 105233965Sjdp free (element); 105333965Sjdp 105433965Sjdp if (high < low) 105533965Sjdp size = 0; 105633965Sjdp else 105733965Sjdp size = element_size * ((high - low) + 1); 105833965Sjdp if (! stab_push_string (info, buf, index, definition, size)) 1059130561Sobrien return FALSE; 106033965Sjdp 106133965Sjdp free (buf); 106233965Sjdp 1063130561Sobrien return TRUE; 106433965Sjdp} 106533965Sjdp 106633965Sjdp/* Push a set type. */ 106733965Sjdp 1068130561Sobrienstatic bfd_boolean 1069130561Sobrienstab_set_type (void *p, bfd_boolean bitstringp) 107033965Sjdp{ 107133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1072130561Sobrien bfd_boolean definition; 107333965Sjdp char *s, *buf; 107433965Sjdp long index; 107533965Sjdp 107633965Sjdp definition = info->type_stack->definition; 107733965Sjdp 107833965Sjdp s = stab_pop_type (info); 107933965Sjdp buf = (char *) xmalloc (strlen (s) + 30); 108033965Sjdp 108133965Sjdp if (! bitstringp) 108233965Sjdp { 108333965Sjdp *buf = '\0'; 108433965Sjdp index = 0; 108533965Sjdp } 108633965Sjdp else 108733965Sjdp { 108833965Sjdp /* We need to define a type in order to include the string 108933965Sjdp attribute. */ 109033965Sjdp index = info->type_index; 109133965Sjdp ++info->type_index; 1092130561Sobrien definition = TRUE; 109333965Sjdp sprintf (buf, "%ld=@S;", index); 109433965Sjdp } 109533965Sjdp 109633965Sjdp sprintf (buf + strlen (buf), "S%s", s); 109733965Sjdp free (s); 109833965Sjdp 109933965Sjdp if (! stab_push_string (info, buf, index, definition, 0)) 1100130561Sobrien return FALSE; 110133965Sjdp 110233965Sjdp free (buf); 110333965Sjdp 1104130561Sobrien return TRUE; 110533965Sjdp} 110633965Sjdp 110733965Sjdp/* Push an offset type. */ 110833965Sjdp 1109130561Sobrienstatic bfd_boolean 1110130561Sobrienstab_offset_type (void *p) 111133965Sjdp{ 111233965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1113130561Sobrien bfd_boolean definition; 111433965Sjdp char *target, *base, *buf; 111533965Sjdp 111633965Sjdp definition = info->type_stack->definition; 111733965Sjdp target = stab_pop_type (info); 111833965Sjdp 111933965Sjdp definition = definition || info->type_stack->definition; 112033965Sjdp base = stab_pop_type (info); 112133965Sjdp 112233965Sjdp buf = (char *) xmalloc (strlen (target) + strlen (base) + 3); 112333965Sjdp sprintf (buf, "@%s,%s", base, target); 112433965Sjdp free (base); 112533965Sjdp free (target); 112633965Sjdp 112733965Sjdp if (! stab_push_string (info, buf, 0, definition, 0)) 1128130561Sobrien return FALSE; 112933965Sjdp 113033965Sjdp free (buf); 113133965Sjdp 1132130561Sobrien return TRUE; 113333965Sjdp} 113433965Sjdp 113533965Sjdp/* Push a method type. */ 113633965Sjdp 1137130561Sobrienstatic bfd_boolean 1138130561Sobrienstab_method_type (void *p, bfd_boolean domainp, int argcount, 1139130561Sobrien bfd_boolean varargs) 114033965Sjdp{ 114133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1142130561Sobrien bfd_boolean definition; 114333965Sjdp char *domain, *return_type, *buf; 114433965Sjdp char **args; 114533965Sjdp int i; 114633965Sjdp size_t len; 114733965Sjdp 114833965Sjdp /* We don't bother with stub method types, because that would 114933965Sjdp require a mangler for C++ argument types. This will waste space 115033965Sjdp in the debugging output. */ 115133965Sjdp 115233965Sjdp /* We need a domain. I'm not sure DOMAINP can ever be false, 115333965Sjdp anyhow. */ 115433965Sjdp if (! domainp) 115533965Sjdp { 115633965Sjdp if (! stab_empty_type (p)) 1157130561Sobrien return FALSE; 115833965Sjdp } 115933965Sjdp 116033965Sjdp definition = info->type_stack->definition; 116133965Sjdp domain = stab_pop_type (info); 116233965Sjdp 116333965Sjdp /* A non-varargs function is indicated by making the last parameter 116433965Sjdp type be void. */ 116533965Sjdp 116633965Sjdp if (argcount < 0) 116733965Sjdp { 116833965Sjdp args = NULL; 116933965Sjdp argcount = 0; 117033965Sjdp } 117133965Sjdp else if (argcount == 0) 117233965Sjdp { 117333965Sjdp if (varargs) 117433965Sjdp args = NULL; 117533965Sjdp else 117633965Sjdp { 117733965Sjdp args = (char **) xmalloc (1 * sizeof (*args)); 117833965Sjdp if (! stab_empty_type (p)) 1179130561Sobrien return FALSE; 118033965Sjdp definition = definition || info->type_stack->definition; 118133965Sjdp args[0] = stab_pop_type (info); 118233965Sjdp argcount = 1; 118333965Sjdp } 118433965Sjdp } 118533965Sjdp else 118633965Sjdp { 118733965Sjdp args = (char **) xmalloc ((argcount + 1) * sizeof (*args)); 118833965Sjdp for (i = argcount - 1; i >= 0; i--) 118933965Sjdp { 119033965Sjdp definition = definition || info->type_stack->definition; 119133965Sjdp args[i] = stab_pop_type (info); 119233965Sjdp } 119333965Sjdp if (! varargs) 119433965Sjdp { 119533965Sjdp if (! stab_empty_type (p)) 1196130561Sobrien return FALSE; 119733965Sjdp definition = definition || info->type_stack->definition; 119833965Sjdp args[argcount] = stab_pop_type (info); 119933965Sjdp ++argcount; 120033965Sjdp } 120133965Sjdp } 120233965Sjdp 120333965Sjdp definition = definition || info->type_stack->definition; 120433965Sjdp return_type = stab_pop_type (info); 120533965Sjdp 120633965Sjdp len = strlen (domain) + strlen (return_type) + 10; 120733965Sjdp for (i = 0; i < argcount; i++) 120833965Sjdp len += strlen (args[i]); 120933965Sjdp 121033965Sjdp buf = (char *) xmalloc (len); 121133965Sjdp 121233965Sjdp sprintf (buf, "#%s,%s", domain, return_type); 121333965Sjdp free (domain); 121433965Sjdp free (return_type); 121533965Sjdp for (i = 0; i < argcount; i++) 121633965Sjdp { 121733965Sjdp strcat (buf, ","); 121833965Sjdp strcat (buf, args[i]); 121933965Sjdp free (args[i]); 122033965Sjdp } 122133965Sjdp strcat (buf, ";"); 122233965Sjdp 122333965Sjdp if (args != NULL) 122433965Sjdp free (args); 122533965Sjdp 122633965Sjdp if (! stab_push_string (info, buf, 0, definition, 0)) 1227130561Sobrien return FALSE; 122833965Sjdp 122933965Sjdp free (buf); 123033965Sjdp 1231130561Sobrien return TRUE; 123233965Sjdp} 123333965Sjdp 123433965Sjdp/* Push a const version of a type. */ 123533965Sjdp 1236130561Sobrienstatic bfd_boolean 1237130561Sobrienstab_const_type (void *p) 123833965Sjdp{ 123933965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 124033965Sjdp 124133965Sjdp return stab_modify_type (info, 'k', info->type_stack->size, 124233965Sjdp (long **) NULL, (size_t *) NULL); 124333965Sjdp} 124433965Sjdp 124533965Sjdp/* Push a volatile version of a type. */ 124633965Sjdp 1247130561Sobrienstatic bfd_boolean 1248130561Sobrienstab_volatile_type (void *p) 124933965Sjdp{ 125033965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 125133965Sjdp 125233965Sjdp return stab_modify_type (info, 'B', info->type_stack->size, 125333965Sjdp (long **) NULL, (size_t *) NULL); 125433965Sjdp} 125533965Sjdp 125633965Sjdp/* Get the type index to use for a struct/union/class ID. This should 125733965Sjdp return -1 if it fails. */ 125833965Sjdp 125933965Sjdpstatic long 1260130561Sobrienstab_get_struct_index (struct stab_write_handle *info, const char *tag, 1261130561Sobrien unsigned int id, enum debug_type_kind kind, 1262130561Sobrien unsigned int *psize) 126333965Sjdp{ 126433965Sjdp if (id >= info->type_cache.struct_types_alloc) 126533965Sjdp { 126633965Sjdp size_t alloc; 126733965Sjdp 126833965Sjdp alloc = info->type_cache.struct_types_alloc; 126933965Sjdp if (alloc == 0) 127033965Sjdp alloc = 10; 127133965Sjdp while (id >= alloc) 127233965Sjdp alloc *= 2; 127333965Sjdp info->type_cache.struct_types = 127433965Sjdp (struct stab_tag *) xrealloc (info->type_cache.struct_types, 127533965Sjdp alloc * sizeof (struct stab_tag)); 127633965Sjdp memset ((info->type_cache.struct_types 127733965Sjdp + info->type_cache.struct_types_alloc), 127833965Sjdp 0, 127933965Sjdp ((alloc - info->type_cache.struct_types_alloc) 128033965Sjdp * sizeof (struct stab_tag))); 128133965Sjdp info->type_cache.struct_types_alloc = alloc; 128233965Sjdp } 128333965Sjdp 128433965Sjdp if (info->type_cache.struct_types[id].index == 0) 128533965Sjdp { 128633965Sjdp info->type_cache.struct_types[id].index = info->type_index; 128733965Sjdp ++info->type_index; 128833965Sjdp info->type_cache.struct_types[id].tag = tag; 128933965Sjdp info->type_cache.struct_types[id].kind = kind; 129033965Sjdp } 129133965Sjdp 129233965Sjdp if (kind == DEBUG_KIND_ILLEGAL) 129333965Sjdp { 129433965Sjdp /* This is a definition of the struct. */ 129533965Sjdp info->type_cache.struct_types[id].kind = kind; 129633965Sjdp info->type_cache.struct_types[id].size = *psize; 129733965Sjdp } 129833965Sjdp else 129933965Sjdp *psize = info->type_cache.struct_types[id].size; 130033965Sjdp 130133965Sjdp return info->type_cache.struct_types[id].index; 130233965Sjdp} 130333965Sjdp 130433965Sjdp/* Start outputting a struct. We ignore the tag, and handle it in 130533965Sjdp stab_tag. */ 130633965Sjdp 1307130561Sobrienstatic bfd_boolean 1308130561Sobrienstab_start_struct_type (void *p, const char *tag, unsigned int id, 1309130561Sobrien bfd_boolean structp, unsigned int size) 131033965Sjdp{ 131133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 131233965Sjdp long index; 1313130561Sobrien bfd_boolean definition; 131433965Sjdp char *buf; 131533965Sjdp 131633965Sjdp buf = (char *) xmalloc (40); 131733965Sjdp 131833965Sjdp if (id == 0) 131933965Sjdp { 132033965Sjdp index = 0; 132133965Sjdp *buf = '\0'; 1322130561Sobrien definition = FALSE; 132333965Sjdp } 132433965Sjdp else 132533965Sjdp { 132633965Sjdp index = stab_get_struct_index (info, tag, id, DEBUG_KIND_ILLEGAL, 132733965Sjdp &size); 132833965Sjdp if (index < 0) 1329130561Sobrien return FALSE; 133033965Sjdp sprintf (buf, "%ld=", index); 1331130561Sobrien definition = TRUE; 133233965Sjdp } 133333965Sjdp 133433965Sjdp sprintf (buf + strlen (buf), "%c%u", 133533965Sjdp structp ? 's' : 'u', 133633965Sjdp size); 133733965Sjdp 133833965Sjdp if (! stab_push_string (info, buf, index, definition, size)) 1339130561Sobrien return FALSE; 134033965Sjdp 134133965Sjdp info->type_stack->fields = (char *) xmalloc (1); 134233965Sjdp info->type_stack->fields[0] = '\0'; 134333965Sjdp 1344130561Sobrien return TRUE; 134533965Sjdp} 134633965Sjdp 134733965Sjdp/* Add a field to a struct. */ 134833965Sjdp 1349130561Sobrienstatic bfd_boolean 1350130561Sobrienstab_struct_field (void *p, const char *name, bfd_vma bitpos, 1351130561Sobrien bfd_vma bitsize, enum debug_visibility visibility) 135233965Sjdp{ 135333965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1354130561Sobrien bfd_boolean definition; 135533965Sjdp unsigned int size; 135633965Sjdp char *s, *n; 135733965Sjdp const char *vis; 135833965Sjdp 135933965Sjdp definition = info->type_stack->definition; 136033965Sjdp size = info->type_stack->size; 136133965Sjdp s = stab_pop_type (info); 136233965Sjdp 136333965Sjdp /* Add this field to the end of the current struct fields, which is 136433965Sjdp currently on the top of the stack. */ 136533965Sjdp 136633965Sjdp assert (info->type_stack->fields != NULL); 136733965Sjdp n = (char *) xmalloc (strlen (info->type_stack->fields) 136833965Sjdp + strlen (name) 136933965Sjdp + strlen (s) 137033965Sjdp + 50); 137133965Sjdp 137233965Sjdp switch (visibility) 137333965Sjdp { 137433965Sjdp default: 137533965Sjdp abort (); 137633965Sjdp 137733965Sjdp case DEBUG_VISIBILITY_PUBLIC: 137833965Sjdp vis = ""; 137933965Sjdp break; 138033965Sjdp 138133965Sjdp case DEBUG_VISIBILITY_PRIVATE: 138233965Sjdp vis = "/0"; 138333965Sjdp break; 138433965Sjdp 138533965Sjdp case DEBUG_VISIBILITY_PROTECTED: 138633965Sjdp vis = "/1"; 138733965Sjdp break; 138833965Sjdp } 138933965Sjdp 139033965Sjdp if (bitsize == 0) 139133965Sjdp { 139233965Sjdp bitsize = size * 8; 139333965Sjdp if (bitsize == 0) 139460484Sobrien non_fatal (_("%s: warning: unknown size for field `%s' in struct"), 139560484Sobrien bfd_get_filename (info->abfd), name); 139633965Sjdp } 139733965Sjdp 139833965Sjdp sprintf (n, "%s%s:%s%s,%ld,%ld;", info->type_stack->fields, name, vis, s, 139933965Sjdp (long) bitpos, (long) bitsize); 140033965Sjdp 140133965Sjdp free (info->type_stack->fields); 140233965Sjdp info->type_stack->fields = n; 140333965Sjdp 140433965Sjdp if (definition) 1405130561Sobrien info->type_stack->definition = TRUE; 140633965Sjdp 1407130561Sobrien return TRUE; 140833965Sjdp} 140933965Sjdp 141033965Sjdp/* Finish up a struct. */ 141133965Sjdp 1412130561Sobrienstatic bfd_boolean 1413130561Sobrienstab_end_struct_type (void *p) 141433965Sjdp{ 141533965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1416130561Sobrien bfd_boolean definition; 141733965Sjdp long index; 141833965Sjdp unsigned int size; 141933965Sjdp char *fields, *first, *buf; 142033965Sjdp 142133965Sjdp assert (info->type_stack != NULL && info->type_stack->fields != NULL); 142233965Sjdp 142333965Sjdp definition = info->type_stack->definition; 142433965Sjdp index = info->type_stack->index; 142533965Sjdp size = info->type_stack->size; 142633965Sjdp fields = info->type_stack->fields; 142733965Sjdp first = stab_pop_type (info); 142833965Sjdp 142933965Sjdp buf = (char *) xmalloc (strlen (first) + strlen (fields) + 2); 143033965Sjdp sprintf (buf, "%s%s;", first, fields); 143133965Sjdp free (first); 143233965Sjdp free (fields); 143333965Sjdp 143433965Sjdp if (! stab_push_string (info, buf, index, definition, size)) 1435130561Sobrien return FALSE; 143633965Sjdp 143733965Sjdp free (buf); 143833965Sjdp 1439130561Sobrien return TRUE; 144033965Sjdp} 144133965Sjdp 144233965Sjdp/* Start outputting a class. */ 144333965Sjdp 1444130561Sobrienstatic bfd_boolean 1445130561Sobrienstab_start_class_type (void *p, const char *tag, unsigned int id, bfd_boolean structp, unsigned int size, bfd_boolean vptr, bfd_boolean ownvptr) 144633965Sjdp{ 144733965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1448130561Sobrien bfd_boolean definition; 144933965Sjdp char *vstring; 145033965Sjdp 145133965Sjdp if (! vptr || ownvptr) 145233965Sjdp { 1453130561Sobrien definition = FALSE; 145433965Sjdp vstring = NULL; 145533965Sjdp } 145633965Sjdp else 145733965Sjdp { 145833965Sjdp definition = info->type_stack->definition; 145933965Sjdp vstring = stab_pop_type (info); 146033965Sjdp } 146133965Sjdp 146233965Sjdp if (! stab_start_struct_type (p, tag, id, structp, size)) 1463130561Sobrien return FALSE; 146433965Sjdp 146533965Sjdp if (vptr) 146633965Sjdp { 146733965Sjdp char *vtable; 146833965Sjdp 146933965Sjdp if (ownvptr) 147033965Sjdp { 147133965Sjdp assert (info->type_stack->index > 0); 147233965Sjdp vtable = (char *) xmalloc (20); 147333965Sjdp sprintf (vtable, "~%%%ld", info->type_stack->index); 147433965Sjdp } 147533965Sjdp else 147633965Sjdp { 147733965Sjdp vtable = (char *) xmalloc (strlen (vstring) + 3); 147833965Sjdp sprintf (vtable, "~%%%s", vstring); 147933965Sjdp free (vstring); 148033965Sjdp } 148133965Sjdp 148233965Sjdp info->type_stack->vtable = vtable; 148333965Sjdp } 148433965Sjdp 148533965Sjdp if (definition) 1486130561Sobrien info->type_stack->definition = TRUE; 148733965Sjdp 1488130561Sobrien return TRUE; 148933965Sjdp} 149033965Sjdp 149133965Sjdp/* Add a static member to the class on the type stack. */ 149233965Sjdp 1493130561Sobrienstatic bfd_boolean 1494130561Sobrienstab_class_static_member (void *p, const char *name, const char *physname, 1495130561Sobrien enum debug_visibility visibility) 149633965Sjdp{ 149733965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1498130561Sobrien bfd_boolean definition; 149933965Sjdp char *s, *n; 150033965Sjdp const char *vis; 150133965Sjdp 150233965Sjdp definition = info->type_stack->definition; 150333965Sjdp s = stab_pop_type (info); 150433965Sjdp 150533965Sjdp /* Add this field to the end of the current struct fields, which is 150633965Sjdp currently on the top of the stack. */ 150733965Sjdp 150833965Sjdp assert (info->type_stack->fields != NULL); 150933965Sjdp n = (char *) xmalloc (strlen (info->type_stack->fields) 151033965Sjdp + strlen (name) 151133965Sjdp + strlen (s) 151233965Sjdp + strlen (physname) 151333965Sjdp + 10); 151433965Sjdp 151533965Sjdp switch (visibility) 151633965Sjdp { 151733965Sjdp default: 151833965Sjdp abort (); 151933965Sjdp 152033965Sjdp case DEBUG_VISIBILITY_PUBLIC: 152133965Sjdp vis = ""; 152233965Sjdp break; 152333965Sjdp 152433965Sjdp case DEBUG_VISIBILITY_PRIVATE: 152533965Sjdp vis = "/0"; 152633965Sjdp break; 152733965Sjdp 152833965Sjdp case DEBUG_VISIBILITY_PROTECTED: 152933965Sjdp vis = "/1"; 153033965Sjdp break; 153133965Sjdp } 153233965Sjdp 153333965Sjdp sprintf (n, "%s%s:%s%s:%s;", info->type_stack->fields, name, vis, s, 153433965Sjdp physname); 153533965Sjdp 153633965Sjdp free (info->type_stack->fields); 153733965Sjdp info->type_stack->fields = n; 153833965Sjdp 153933965Sjdp if (definition) 1540130561Sobrien info->type_stack->definition = TRUE; 154133965Sjdp 1542130561Sobrien return TRUE; 154333965Sjdp} 154433965Sjdp 154533965Sjdp/* Add a base class to the class on the type stack. */ 154633965Sjdp 1547130561Sobrienstatic bfd_boolean 1548130561Sobrienstab_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual, 1549130561Sobrien enum debug_visibility visibility) 155033965Sjdp{ 155133965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 1552130561Sobrien bfd_boolean definition; 155333965Sjdp char *s; 155433965Sjdp char *buf; 155533965Sjdp unsigned int c; 155633965Sjdp char **baseclasses; 155733965Sjdp 155833965Sjdp definition = info->type_stack->definition; 155933965Sjdp s = stab_pop_type (info); 156033965Sjdp 156133965Sjdp /* Build the base class specifier. */ 156233965Sjdp 156333965Sjdp buf = (char *) xmalloc (strlen (s) + 25); 156433965Sjdp buf[0] = virtual ? '1' : '0'; 156533965Sjdp switch (visibility) 156633965Sjdp { 156733965Sjdp default: 156833965Sjdp abort (); 156933965Sjdp 157033965Sjdp case DEBUG_VISIBILITY_PRIVATE: 157133965Sjdp buf[1] = '0'; 157233965Sjdp break; 157333965Sjdp 157433965Sjdp case DEBUG_VISIBILITY_PROTECTED: 157533965Sjdp buf[1] = '1'; 157633965Sjdp break; 157733965Sjdp 157833965Sjdp case DEBUG_VISIBILITY_PUBLIC: 157933965Sjdp buf[1] = '2'; 158033965Sjdp break; 158133965Sjdp } 158233965Sjdp 158333965Sjdp sprintf (buf + 2, "%ld,%s;", (long) bitpos, s); 158433965Sjdp free (s); 158533965Sjdp 158633965Sjdp /* Add the new baseclass to the existing ones. */ 158733965Sjdp 158833965Sjdp assert (info->type_stack != NULL && info->type_stack->fields != NULL); 158933965Sjdp 159033965Sjdp if (info->type_stack->baseclasses == NULL) 159133965Sjdp c = 0; 159233965Sjdp else 159333965Sjdp { 159433965Sjdp c = 0; 159533965Sjdp while (info->type_stack->baseclasses[c] != NULL) 159633965Sjdp ++c; 159733965Sjdp } 159833965Sjdp 159933965Sjdp baseclasses = (char **) xrealloc (info->type_stack->baseclasses, 160033965Sjdp (c + 2) * sizeof (*baseclasses)); 160133965Sjdp baseclasses[c] = buf; 160233965Sjdp baseclasses[c + 1] = NULL; 160333965Sjdp 160433965Sjdp info->type_stack->baseclasses = baseclasses; 160533965Sjdp 160633965Sjdp if (definition) 1607130561Sobrien info->type_stack->definition = TRUE; 160833965Sjdp 1609130561Sobrien return TRUE; 161033965Sjdp} 161133965Sjdp 161233965Sjdp/* Start adding a method to the class on the type stack. */ 161333965Sjdp 1614130561Sobrienstatic bfd_boolean 1615130561Sobrienstab_class_start_method (void *p, const char *name) 161633965Sjdp{ 161733965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 161833965Sjdp char *m; 161933965Sjdp 162033965Sjdp assert (info->type_stack != NULL && info->type_stack->fields != NULL); 162133965Sjdp 162233965Sjdp if (info->type_stack->methods == NULL) 162333965Sjdp { 162433965Sjdp m = (char *) xmalloc (strlen (name) + 3); 162533965Sjdp *m = '\0'; 162633965Sjdp } 162733965Sjdp else 162833965Sjdp { 162933965Sjdp m = (char *) xrealloc (info->type_stack->methods, 163033965Sjdp (strlen (info->type_stack->methods) 163133965Sjdp + strlen (name) 163233965Sjdp + 4)); 163333965Sjdp } 163433965Sjdp 163533965Sjdp sprintf (m + strlen (m), "%s::", name); 163633965Sjdp 163733965Sjdp info->type_stack->methods = m; 163833965Sjdp 1639130561Sobrien return TRUE; 164033965Sjdp} 164133965Sjdp 164233965Sjdp/* Add a variant, either static or not, to the current method. */ 164333965Sjdp 1644130561Sobrienstatic bfd_boolean 1645130561Sobrienstab_class_method_var (struct stab_write_handle *info, const char *physname, 1646130561Sobrien enum debug_visibility visibility, 1647130561Sobrien bfd_boolean staticp, bfd_boolean constp, 1648130561Sobrien bfd_boolean volatilep, bfd_vma voffset, 1649130561Sobrien bfd_boolean contextp) 165033965Sjdp{ 1651130561Sobrien bfd_boolean definition; 165233965Sjdp char *type; 165333965Sjdp char *context = NULL; 165433965Sjdp char visc, qualc, typec; 165533965Sjdp 165633965Sjdp definition = info->type_stack->definition; 165733965Sjdp type = stab_pop_type (info); 165833965Sjdp 165933965Sjdp if (contextp) 166033965Sjdp { 166133965Sjdp definition = definition || info->type_stack->definition; 166233965Sjdp context = stab_pop_type (info); 166333965Sjdp } 166433965Sjdp 166533965Sjdp assert (info->type_stack != NULL && info->type_stack->methods != NULL); 166633965Sjdp 166733965Sjdp switch (visibility) 166833965Sjdp { 166933965Sjdp default: 167033965Sjdp abort (); 167133965Sjdp 167233965Sjdp case DEBUG_VISIBILITY_PRIVATE: 167333965Sjdp visc = '0'; 167433965Sjdp break; 167533965Sjdp 167633965Sjdp case DEBUG_VISIBILITY_PROTECTED: 167733965Sjdp visc = '1'; 167833965Sjdp break; 167933965Sjdp 168033965Sjdp case DEBUG_VISIBILITY_PUBLIC: 168133965Sjdp visc = '2'; 168233965Sjdp break; 168333965Sjdp } 168433965Sjdp 168533965Sjdp if (constp) 168633965Sjdp { 168733965Sjdp if (volatilep) 168833965Sjdp qualc = 'D'; 168933965Sjdp else 169033965Sjdp qualc = 'B'; 169133965Sjdp } 169233965Sjdp else 169333965Sjdp { 169433965Sjdp if (volatilep) 169533965Sjdp qualc = 'C'; 169633965Sjdp else 169733965Sjdp qualc = 'A'; 169833965Sjdp } 169933965Sjdp 170033965Sjdp if (staticp) 170133965Sjdp typec = '?'; 170233965Sjdp else if (! contextp) 170333965Sjdp typec = '.'; 170433965Sjdp else 170533965Sjdp typec = '*'; 170633965Sjdp 170733965Sjdp info->type_stack->methods = 170833965Sjdp (char *) xrealloc (info->type_stack->methods, 170933965Sjdp (strlen (info->type_stack->methods) 171033965Sjdp + strlen (type) 171133965Sjdp + strlen (physname) 171233965Sjdp + (contextp ? strlen (context) : 0) 171333965Sjdp + 40)); 171433965Sjdp 171533965Sjdp sprintf (info->type_stack->methods + strlen (info->type_stack->methods), 171633965Sjdp "%s:%s;%c%c%c", type, physname, visc, qualc, typec); 171733965Sjdp free (type); 171833965Sjdp 171933965Sjdp if (contextp) 172033965Sjdp { 172133965Sjdp sprintf (info->type_stack->methods + strlen (info->type_stack->methods), 172233965Sjdp "%ld;%s;", (long) voffset, context); 172333965Sjdp free (context); 172433965Sjdp } 172533965Sjdp 172633965Sjdp if (definition) 1727130561Sobrien info->type_stack->definition = TRUE; 172833965Sjdp 1729130561Sobrien return TRUE; 173033965Sjdp} 173133965Sjdp 173233965Sjdp/* Add a variant to the current method. */ 173333965Sjdp 1734130561Sobrienstatic bfd_boolean 1735130561Sobrienstab_class_method_variant (void *p, const char *physname, 1736130561Sobrien enum debug_visibility visibility, 1737130561Sobrien bfd_boolean constp, bfd_boolean volatilep, 1738130561Sobrien bfd_vma voffset, bfd_boolean contextp) 173933965Sjdp{ 174033965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 174133965Sjdp 1742130561Sobrien return stab_class_method_var (info, physname, visibility, FALSE, constp, 174333965Sjdp volatilep, voffset, contextp); 174433965Sjdp} 174533965Sjdp 174633965Sjdp/* Add a static variant to the current method. */ 174733965Sjdp 1748130561Sobrienstatic bfd_boolean 1749130561Sobrienstab_class_static_method_variant (void *p, const char *physname, 1750130561Sobrien enum debug_visibility visibility, 1751130561Sobrien bfd_boolean constp, bfd_boolean volatilep) 175233965Sjdp{ 175333965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 175433965Sjdp 1755130561Sobrien return stab_class_method_var (info, physname, visibility, TRUE, constp, 1756130561Sobrien volatilep, 0, FALSE); 175733965Sjdp} 175833965Sjdp 175933965Sjdp/* Finish up a method. */ 176033965Sjdp 1761130561Sobrienstatic bfd_boolean 1762130561Sobrienstab_class_end_method (void *p) 176333965Sjdp{ 176433965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 176533965Sjdp 176633965Sjdp assert (info->type_stack != NULL && info->type_stack->methods != NULL); 176733965Sjdp 176833965Sjdp /* We allocated enough room on info->type_stack->methods to add the 176933965Sjdp trailing semicolon. */ 177033965Sjdp strcat (info->type_stack->methods, ";"); 177133965Sjdp 1772130561Sobrien return TRUE; 177333965Sjdp} 177433965Sjdp 177533965Sjdp/* Finish up a class. */ 177633965Sjdp 1777130561Sobrienstatic bfd_boolean 1778130561Sobrienstab_end_class_type (void *p) 177933965Sjdp{ 178033965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 178133965Sjdp size_t len; 178238889Sjdp unsigned int i = 0; 178333965Sjdp char *buf; 178433965Sjdp 178533965Sjdp assert (info->type_stack != NULL && info->type_stack->fields != NULL); 178633965Sjdp 178733965Sjdp /* Work out the size we need to allocate for the class definition. */ 178833965Sjdp 178933965Sjdp len = (strlen (info->type_stack->string) 179033965Sjdp + strlen (info->type_stack->fields) 179133965Sjdp + 10); 179233965Sjdp if (info->type_stack->baseclasses != NULL) 179333965Sjdp { 179433965Sjdp len += 20; 179533965Sjdp for (i = 0; info->type_stack->baseclasses[i] != NULL; i++) 179633965Sjdp len += strlen (info->type_stack->baseclasses[i]); 179733965Sjdp } 179833965Sjdp if (info->type_stack->methods != NULL) 179933965Sjdp len += strlen (info->type_stack->methods); 180033965Sjdp if (info->type_stack->vtable != NULL) 180133965Sjdp len += strlen (info->type_stack->vtable); 180233965Sjdp 180333965Sjdp /* Build the class definition. */ 180433965Sjdp 180533965Sjdp buf = (char *) xmalloc (len); 180633965Sjdp 180733965Sjdp strcpy (buf, info->type_stack->string); 180833965Sjdp 180933965Sjdp if (info->type_stack->baseclasses != NULL) 181033965Sjdp { 181133965Sjdp sprintf (buf + strlen (buf), "!%u,", i); 181233965Sjdp for (i = 0; info->type_stack->baseclasses[i] != NULL; i++) 181333965Sjdp { 181433965Sjdp strcat (buf, info->type_stack->baseclasses[i]); 181533965Sjdp free (info->type_stack->baseclasses[i]); 181633965Sjdp } 181733965Sjdp free (info->type_stack->baseclasses); 181833965Sjdp info->type_stack->baseclasses = NULL; 181933965Sjdp } 182033965Sjdp 182133965Sjdp strcat (buf, info->type_stack->fields); 182233965Sjdp free (info->type_stack->fields); 182333965Sjdp info->type_stack->fields = NULL; 182433965Sjdp 182533965Sjdp if (info->type_stack->methods != NULL) 182633965Sjdp { 182733965Sjdp strcat (buf, info->type_stack->methods); 182833965Sjdp free (info->type_stack->methods); 182933965Sjdp info->type_stack->methods = NULL; 183033965Sjdp } 183133965Sjdp 183233965Sjdp strcat (buf, ";"); 183333965Sjdp 183433965Sjdp if (info->type_stack->vtable != NULL) 183533965Sjdp { 183633965Sjdp strcat (buf, info->type_stack->vtable); 183733965Sjdp free (info->type_stack->vtable); 183833965Sjdp info->type_stack->vtable = NULL; 183933965Sjdp } 184033965Sjdp 184133965Sjdp /* Replace the string on the top of the stack with the complete 184233965Sjdp class definition. */ 184333965Sjdp free (info->type_stack->string); 184433965Sjdp info->type_stack->string = buf; 184533965Sjdp 1846130561Sobrien return TRUE; 184733965Sjdp} 184833965Sjdp 184933965Sjdp/* Push a typedef which was previously defined. */ 185033965Sjdp 1851130561Sobrienstatic bfd_boolean 1852130561Sobrienstab_typedef_type (void *p, const char *name) 185333965Sjdp{ 185433965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 185533965Sjdp struct string_hash_entry *h; 185633965Sjdp 1857130561Sobrien h = string_hash_lookup (&info->typedef_hash, name, FALSE, FALSE); 185833965Sjdp assert (h != NULL && h->index > 0); 185933965Sjdp 186033965Sjdp return stab_push_defined_type (info, h->index, h->size); 186133965Sjdp} 186233965Sjdp 186333965Sjdp/* Push a struct, union or class tag. */ 186433965Sjdp 1865130561Sobrienstatic bfd_boolean 1866130561Sobrienstab_tag_type (void *p, const char *name, unsigned int id, 1867130561Sobrien enum debug_type_kind kind) 186833965Sjdp{ 186933965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 187033965Sjdp long index; 1871218822Sdim unsigned int size = 0; 187233965Sjdp 187333965Sjdp index = stab_get_struct_index (info, name, id, kind, &size); 187433965Sjdp if (index < 0) 1875130561Sobrien return FALSE; 187633965Sjdp 187733965Sjdp return stab_push_defined_type (info, index, size); 187833965Sjdp} 187933965Sjdp 188033965Sjdp/* Define a typedef. */ 188133965Sjdp 1882130561Sobrienstatic bfd_boolean 1883130561Sobrienstab_typdef (void *p, const char *name) 188433965Sjdp{ 188533965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 188633965Sjdp long index; 188733965Sjdp unsigned int size; 188833965Sjdp char *s, *buf; 188933965Sjdp struct string_hash_entry *h; 189033965Sjdp 189133965Sjdp index = info->type_stack->index; 189233965Sjdp size = info->type_stack->size; 189333965Sjdp s = stab_pop_type (info); 189433965Sjdp 189533965Sjdp buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); 189633965Sjdp 189733965Sjdp if (index > 0) 189833965Sjdp sprintf (buf, "%s:t%s", name, s); 189933965Sjdp else 190033965Sjdp { 190133965Sjdp index = info->type_index; 190233965Sjdp ++info->type_index; 190333965Sjdp sprintf (buf, "%s:t%ld=%s", name, index, s); 190433965Sjdp } 190533965Sjdp 190633965Sjdp free (s); 190733965Sjdp 190833965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) 1909130561Sobrien return FALSE; 191033965Sjdp 191133965Sjdp free (buf); 191233965Sjdp 1913130561Sobrien h = string_hash_lookup (&info->typedef_hash, name, TRUE, FALSE); 191433965Sjdp if (h == NULL) 191533965Sjdp { 191660484Sobrien non_fatal (_("string_hash_lookup failed: %s"), 191760484Sobrien bfd_errmsg (bfd_get_error ())); 1918130561Sobrien return FALSE; 191933965Sjdp } 192033965Sjdp 192133965Sjdp /* I don't think we care about redefinitions. */ 192233965Sjdp 192333965Sjdp h->index = index; 192433965Sjdp h->size = size; 192533965Sjdp 1926130561Sobrien return TRUE; 192733965Sjdp} 192833965Sjdp 192933965Sjdp/* Define a tag. */ 193033965Sjdp 1931130561Sobrienstatic bfd_boolean 1932130561Sobrienstab_tag (void *p, const char *tag) 193333965Sjdp{ 193433965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 193533965Sjdp char *s, *buf; 193633965Sjdp 193733965Sjdp s = stab_pop_type (info); 193833965Sjdp 193933965Sjdp buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3); 194033965Sjdp 194133965Sjdp sprintf (buf, "%s:T%s", tag, s); 194233965Sjdp free (s); 194333965Sjdp 194433965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) 1945130561Sobrien return FALSE; 194633965Sjdp 194733965Sjdp free (buf); 194833965Sjdp 1949130561Sobrien return TRUE; 195033965Sjdp} 195133965Sjdp 195233965Sjdp/* Define an integer constant. */ 195333965Sjdp 1954130561Sobrienstatic bfd_boolean 1955130561Sobrienstab_int_constant (void *p, const char *name, bfd_vma val) 195633965Sjdp{ 195733965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 195833965Sjdp char *buf; 195933965Sjdp 196033965Sjdp buf = (char *) xmalloc (strlen (name) + 20); 196133965Sjdp sprintf (buf, "%s:c=i%ld", name, (long) val); 196233965Sjdp 196333965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) 1964130561Sobrien return FALSE; 196533965Sjdp 196633965Sjdp free (buf); 196733965Sjdp 1968130561Sobrien return TRUE; 196933965Sjdp} 197033965Sjdp 197133965Sjdp/* Define a floating point constant. */ 197233965Sjdp 1973130561Sobrienstatic bfd_boolean 1974130561Sobrienstab_float_constant (void *p, const char *name, double val) 197533965Sjdp{ 197633965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 197733965Sjdp char *buf; 197833965Sjdp 197933965Sjdp buf = (char *) xmalloc (strlen (name) + 20); 198033965Sjdp sprintf (buf, "%s:c=f%g", name, val); 198133965Sjdp 198233965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) 1983130561Sobrien return FALSE; 198433965Sjdp 198533965Sjdp free (buf); 198633965Sjdp 1987130561Sobrien return TRUE; 198833965Sjdp} 198933965Sjdp 199033965Sjdp/* Define a typed constant. */ 199133965Sjdp 1992130561Sobrienstatic bfd_boolean 1993130561Sobrienstab_typed_constant (void *p, const char *name, bfd_vma val) 199433965Sjdp{ 199533965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 199633965Sjdp char *s, *buf; 199733965Sjdp 199833965Sjdp s = stab_pop_type (info); 199933965Sjdp 200033965Sjdp buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); 200133965Sjdp sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val); 200233965Sjdp free (s); 200333965Sjdp 200433965Sjdp if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) 2005130561Sobrien return FALSE; 200633965Sjdp 200733965Sjdp free (buf); 200833965Sjdp 2009130561Sobrien return TRUE; 201033965Sjdp} 201133965Sjdp 201233965Sjdp/* Record a variable. */ 201333965Sjdp 2014130561Sobrienstatic bfd_boolean 2015130561Sobrienstab_variable (void *p, const char *name, enum debug_var_kind kind, 2016130561Sobrien bfd_vma val) 201733965Sjdp{ 201833965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 201933965Sjdp char *s, *buf; 202033965Sjdp int stab_type; 202133965Sjdp const char *kindstr; 202233965Sjdp 202333965Sjdp s = stab_pop_type (info); 202433965Sjdp 202533965Sjdp switch (kind) 202633965Sjdp { 202733965Sjdp default: 202833965Sjdp abort (); 202933965Sjdp 203033965Sjdp case DEBUG_GLOBAL: 203133965Sjdp stab_type = N_GSYM; 203233965Sjdp kindstr = "G"; 203333965Sjdp break; 203433965Sjdp 203533965Sjdp case DEBUG_STATIC: 203633965Sjdp stab_type = N_STSYM; 203733965Sjdp kindstr = "S"; 203833965Sjdp break; 203933965Sjdp 204033965Sjdp case DEBUG_LOCAL_STATIC: 204133965Sjdp stab_type = N_STSYM; 204233965Sjdp kindstr = "V"; 204333965Sjdp break; 204433965Sjdp 204533965Sjdp case DEBUG_LOCAL: 204633965Sjdp stab_type = N_LSYM; 204733965Sjdp kindstr = ""; 204833965Sjdp 204933965Sjdp /* Make sure that this is a type reference or definition. */ 205089857Sobrien if (! ISDIGIT (*s)) 205133965Sjdp { 205233965Sjdp char *n; 205333965Sjdp long index; 205433965Sjdp 205533965Sjdp index = info->type_index; 205633965Sjdp ++info->type_index; 205733965Sjdp n = (char *) xmalloc (strlen (s) + 20); 205833965Sjdp sprintf (n, "%ld=%s", index, s); 205933965Sjdp free (s); 206033965Sjdp s = n; 206133965Sjdp } 206233965Sjdp break; 206333965Sjdp 206433965Sjdp case DEBUG_REGISTER: 206533965Sjdp stab_type = N_RSYM; 206633965Sjdp kindstr = "r"; 206733965Sjdp break; 206833965Sjdp } 206933965Sjdp 207033965Sjdp buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); 207133965Sjdp sprintf (buf, "%s:%s%s", name, kindstr, s); 207233965Sjdp free (s); 207333965Sjdp 207433965Sjdp if (! stab_write_symbol (info, stab_type, 0, val, buf)) 2075130561Sobrien return FALSE; 207633965Sjdp 207733965Sjdp free (buf); 207833965Sjdp 2079130561Sobrien return TRUE; 208033965Sjdp} 208133965Sjdp 208233965Sjdp/* Start outputting a function. */ 208333965Sjdp 2084130561Sobrienstatic bfd_boolean 2085130561Sobrienstab_start_function (void *p, const char *name, bfd_boolean globalp) 208633965Sjdp{ 208733965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 208833965Sjdp char *rettype, *buf; 208933965Sjdp 209033965Sjdp assert (info->nesting == 0 && info->fun_offset == -1); 209133965Sjdp 209233965Sjdp rettype = stab_pop_type (info); 209333965Sjdp 209433965Sjdp buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3); 209533965Sjdp sprintf (buf, "%s:%c%s", name, 209633965Sjdp globalp ? 'F' : 'f', 209733965Sjdp rettype); 209833965Sjdp 209933965Sjdp /* We don't know the value now, so we set it in start_block. */ 210033965Sjdp info->fun_offset = info->symbols_size; 210133965Sjdp 210233965Sjdp if (! stab_write_symbol (info, N_FUN, 0, 0, buf)) 2103130561Sobrien return FALSE; 210433965Sjdp 210533965Sjdp free (buf); 210633965Sjdp 2107130561Sobrien return TRUE; 210833965Sjdp} 210933965Sjdp 211033965Sjdp/* Output a function parameter. */ 211133965Sjdp 2112130561Sobrienstatic bfd_boolean 2113130561Sobrienstab_function_parameter (void *p, const char *name, enum debug_parm_kind kind, bfd_vma val) 211433965Sjdp{ 211533965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 211633965Sjdp char *s, *buf; 211733965Sjdp int stab_type; 211833965Sjdp char kindc; 211933965Sjdp 212033965Sjdp s = stab_pop_type (info); 212133965Sjdp 212233965Sjdp switch (kind) 212333965Sjdp { 212433965Sjdp default: 212533965Sjdp abort (); 212633965Sjdp 212733965Sjdp case DEBUG_PARM_STACK: 212833965Sjdp stab_type = N_PSYM; 212933965Sjdp kindc = 'p'; 213033965Sjdp break; 213133965Sjdp 213233965Sjdp case DEBUG_PARM_REG: 213333965Sjdp stab_type = N_RSYM; 213433965Sjdp kindc = 'P'; 213533965Sjdp break; 213633965Sjdp 213733965Sjdp case DEBUG_PARM_REFERENCE: 213833965Sjdp stab_type = N_PSYM; 213933965Sjdp kindc = 'v'; 214033965Sjdp break; 214133965Sjdp 214233965Sjdp case DEBUG_PARM_REF_REG: 214333965Sjdp stab_type = N_RSYM; 214433965Sjdp kindc = 'a'; 214533965Sjdp break; 214633965Sjdp } 214733965Sjdp 214833965Sjdp buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); 214933965Sjdp sprintf (buf, "%s:%c%s", name, kindc, s); 215033965Sjdp free (s); 215133965Sjdp 215233965Sjdp if (! stab_write_symbol (info, stab_type, 0, val, buf)) 2153130561Sobrien return FALSE; 215433965Sjdp 215533965Sjdp free (buf); 215633965Sjdp 2157130561Sobrien return TRUE; 215833965Sjdp} 215933965Sjdp 216033965Sjdp/* Start a block. */ 216133965Sjdp 2162130561Sobrienstatic bfd_boolean 2163130561Sobrienstab_start_block (void *p, bfd_vma addr) 216433965Sjdp{ 216533965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 216633965Sjdp 216733965Sjdp /* Fill in any slots which have been waiting for the first known 216833965Sjdp text address. */ 216933965Sjdp 217033965Sjdp if (info->so_offset != -1) 217133965Sjdp { 217233965Sjdp bfd_put_32 (info->abfd, addr, info->symbols + info->so_offset + 8); 217333965Sjdp info->so_offset = -1; 217433965Sjdp } 217533965Sjdp 217633965Sjdp if (info->fun_offset != -1) 217733965Sjdp { 217833965Sjdp bfd_put_32 (info->abfd, addr, info->symbols + info->fun_offset + 8); 217933965Sjdp info->fun_offset = -1; 218033965Sjdp } 218133965Sjdp 218233965Sjdp ++info->nesting; 218333965Sjdp 218433965Sjdp /* We will be called with a top level block surrounding the 218533965Sjdp function, but stabs information does not output that block, so we 218633965Sjdp ignore it. */ 218733965Sjdp 218833965Sjdp if (info->nesting == 1) 218933965Sjdp { 219033965Sjdp info->fnaddr = addr; 2191130561Sobrien return TRUE; 219233965Sjdp } 219333965Sjdp 219433965Sjdp /* We have to output the LBRAC symbol after any variables which are 219533965Sjdp declared inside the block. We postpone the LBRAC until the next 219633965Sjdp start_block or end_block. */ 219733965Sjdp 219833965Sjdp /* If we have postponed an LBRAC, output it now. */ 219933965Sjdp if (info->pending_lbrac != (bfd_vma) -1) 220033965Sjdp { 220133965Sjdp if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac, 220233965Sjdp (const char *) NULL)) 2203130561Sobrien return FALSE; 220433965Sjdp } 220533965Sjdp 220633965Sjdp /* Remember the address and output it later. */ 220733965Sjdp 220833965Sjdp info->pending_lbrac = addr - info->fnaddr; 220933965Sjdp 2210130561Sobrien return TRUE; 221133965Sjdp} 221233965Sjdp 221333965Sjdp/* End a block. */ 221433965Sjdp 2215130561Sobrienstatic bfd_boolean 2216130561Sobrienstab_end_block (void *p, bfd_vma addr) 221733965Sjdp{ 221833965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 221933965Sjdp 222033965Sjdp if (addr > info->last_text_address) 222133965Sjdp info->last_text_address = addr; 222233965Sjdp 222333965Sjdp /* If we have postponed an LBRAC, output it now. */ 222433965Sjdp if (info->pending_lbrac != (bfd_vma) -1) 222533965Sjdp { 222633965Sjdp if (! stab_write_symbol (info, N_LBRAC, 0, info->pending_lbrac, 222733965Sjdp (const char *) NULL)) 2228130561Sobrien return FALSE; 222933965Sjdp info->pending_lbrac = (bfd_vma) -1; 223033965Sjdp } 223133965Sjdp 223233965Sjdp assert (info->nesting > 0); 223333965Sjdp 223433965Sjdp --info->nesting; 223533965Sjdp 223633965Sjdp /* We ignore the outermost block. */ 223733965Sjdp if (info->nesting == 0) 2238130561Sobrien return TRUE; 223933965Sjdp 224033965Sjdp return stab_write_symbol (info, N_RBRAC, 0, addr - info->fnaddr, 224133965Sjdp (const char *) NULL); 224233965Sjdp} 224333965Sjdp 224433965Sjdp/* End a function. */ 224533965Sjdp 2246130561Sobrienstatic bfd_boolean 2247130561Sobrienstab_end_function (void *p ATTRIBUTE_UNUSED) 224833965Sjdp{ 2249130561Sobrien return TRUE; 225033965Sjdp} 225133965Sjdp 225233965Sjdp/* Output a line number. */ 225333965Sjdp 2254130561Sobrienstatic bfd_boolean 2255130561Sobrienstab_lineno (void *p, const char *file, unsigned long lineno, bfd_vma addr) 225633965Sjdp{ 225733965Sjdp struct stab_write_handle *info = (struct stab_write_handle *) p; 225833965Sjdp 225933965Sjdp assert (info->lineno_filename != NULL); 226033965Sjdp 226133965Sjdp if (addr > info->last_text_address) 226233965Sjdp info->last_text_address = addr; 226333965Sjdp 226433965Sjdp if (strcmp (file, info->lineno_filename) != 0) 226533965Sjdp { 226633965Sjdp if (! stab_write_symbol (info, N_SOL, 0, addr, file)) 2267130561Sobrien return FALSE; 226833965Sjdp info->lineno_filename = file; 226933965Sjdp } 227033965Sjdp 227133965Sjdp return stab_write_symbol (info, N_SLINE, lineno, addr - info->fnaddr, 227233965Sjdp (const char *) NULL); 227333965Sjdp} 2274