133965Sjdp/* ieee.c -- Read and write IEEE-695 debugging information. 2218822Sdim Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2006, 2007 3218822Sdim 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 reads and writes IEEE-695 debugging information. */ 2433965Sjdp 25218822Sdim#include "sysdep.h" 2633965Sjdp#include <assert.h> 2733965Sjdp#include "bfd.h" 2833965Sjdp#include "ieee.h" 2933965Sjdp#include "libiberty.h" 3033965Sjdp#include "debug.h" 3133965Sjdp#include "budbg.h" 3261843Sobrien#include "filenames.h" 3333965Sjdp 3433965Sjdp/* This structure holds an entry on the block stack. */ 3533965Sjdp 3633965Sjdpstruct ieee_block 3733965Sjdp{ 3833965Sjdp /* The kind of block. */ 3933965Sjdp int kind; 4033965Sjdp /* The source file name, for a BB5 block. */ 4133965Sjdp const char *filename; 4233965Sjdp /* The index of the function type, for a BB4 or BB6 block. */ 4333965Sjdp unsigned int fnindx; 44130561Sobrien /* TRUE if this function is being skipped. */ 45130561Sobrien bfd_boolean skip; 4633965Sjdp}; 4733965Sjdp 4833965Sjdp/* This structure is the block stack. */ 4933965Sjdp 5033965Sjdp#define BLOCKSTACK_SIZE (16) 5133965Sjdp 5233965Sjdpstruct ieee_blockstack 5333965Sjdp{ 5433965Sjdp /* The stack pointer. */ 5533965Sjdp struct ieee_block *bsp; 5633965Sjdp /* The stack. */ 5733965Sjdp struct ieee_block stack[BLOCKSTACK_SIZE]; 5833965Sjdp}; 5933965Sjdp 6033965Sjdp/* This structure holds information for a variable. */ 6133965Sjdp 6233965Sjdpstruct ieee_var 6333965Sjdp{ 6433965Sjdp /* Start of name. */ 6533965Sjdp const char *name; 6633965Sjdp /* Length of name. */ 6733965Sjdp unsigned long namlen; 6833965Sjdp /* Type. */ 6933965Sjdp debug_type type; 7033965Sjdp /* Slot if we make an indirect type. */ 7133965Sjdp debug_type *pslot; 7233965Sjdp /* Kind of variable or function. */ 7333965Sjdp enum 7433965Sjdp { 7533965Sjdp IEEE_UNKNOWN, 7633965Sjdp IEEE_EXTERNAL, 7733965Sjdp IEEE_GLOBAL, 7833965Sjdp IEEE_STATIC, 7933965Sjdp IEEE_LOCAL, 8033965Sjdp IEEE_FUNCTION 8133965Sjdp } kind; 8233965Sjdp}; 8333965Sjdp 8433965Sjdp/* This structure holds all the variables. */ 8533965Sjdp 8633965Sjdpstruct ieee_vars 8733965Sjdp{ 8833965Sjdp /* Number of slots allocated. */ 8933965Sjdp unsigned int alloc; 9033965Sjdp /* Variables. */ 9133965Sjdp struct ieee_var *vars; 9233965Sjdp}; 9333965Sjdp 9433965Sjdp/* This structure holds information for a type. We need this because 9533965Sjdp we don't want to represent bitfields as real types. */ 9633965Sjdp 9733965Sjdpstruct ieee_type 9833965Sjdp{ 9933965Sjdp /* Type. */ 10033965Sjdp debug_type type; 10133965Sjdp /* Slot if this is type is referenced before it is defined. */ 10233965Sjdp debug_type *pslot; 10333965Sjdp /* Slots for arguments if we make indirect types for them. */ 10433965Sjdp debug_type *arg_slots; 10533965Sjdp /* If this is a bitfield, this is the size in bits. If this is not 10633965Sjdp a bitfield, this is zero. */ 10733965Sjdp unsigned long bitsize; 10833965Sjdp}; 10933965Sjdp 11033965Sjdp/* This structure holds all the type information. */ 11133965Sjdp 11233965Sjdpstruct ieee_types 11333965Sjdp{ 11433965Sjdp /* Number of slots allocated. */ 11533965Sjdp unsigned int alloc; 11633965Sjdp /* Types. */ 11733965Sjdp struct ieee_type *types; 11833965Sjdp /* Builtin types. */ 11933965Sjdp#define BUILTIN_TYPE_COUNT (60) 12033965Sjdp debug_type builtins[BUILTIN_TYPE_COUNT]; 12133965Sjdp}; 12233965Sjdp 12333965Sjdp/* This structure holds a linked last of structs with their tag names, 12433965Sjdp so that we can convert them to C++ classes if necessary. */ 12533965Sjdp 12633965Sjdpstruct ieee_tag 12733965Sjdp{ 12833965Sjdp /* Next tag. */ 12933965Sjdp struct ieee_tag *next; 13033965Sjdp /* This tag name. */ 13133965Sjdp const char *name; 13233965Sjdp /* The type of the tag. */ 13333965Sjdp debug_type type; 13433965Sjdp /* The tagged type is an indirect type pointing at this slot. */ 13533965Sjdp debug_type slot; 13633965Sjdp /* This is an array of slots used when a field type is converted 13733965Sjdp into a indirect type, in case it needs to be later converted into 13833965Sjdp a reference type. */ 13933965Sjdp debug_type *fslots; 14033965Sjdp}; 14133965Sjdp 14233965Sjdp/* This structure holds the information we pass around to the parsing 14333965Sjdp functions. */ 14433965Sjdp 14533965Sjdpstruct ieee_info 14633965Sjdp{ 14733965Sjdp /* The debugging handle. */ 148130561Sobrien void *dhandle; 14933965Sjdp /* The BFD. */ 15033965Sjdp bfd *abfd; 15133965Sjdp /* The start of the bytes to be parsed. */ 15233965Sjdp const bfd_byte *bytes; 15333965Sjdp /* The end of the bytes to be parsed. */ 15433965Sjdp const bfd_byte *pend; 15533965Sjdp /* The block stack. */ 15633965Sjdp struct ieee_blockstack blockstack; 15733965Sjdp /* Whether we have seen a BB1 or BB2. */ 158130561Sobrien bfd_boolean saw_filename; 15933965Sjdp /* The variables. */ 16033965Sjdp struct ieee_vars vars; 16133965Sjdp /* The global variables, after a global typedef block. */ 16233965Sjdp struct ieee_vars *global_vars; 16333965Sjdp /* The types. */ 16433965Sjdp struct ieee_types types; 16533965Sjdp /* The global types, after a global typedef block. */ 16633965Sjdp struct ieee_types *global_types; 16733965Sjdp /* The list of tagged structs. */ 16833965Sjdp struct ieee_tag *tags; 16933965Sjdp}; 17033965Sjdp 17133965Sjdp/* Basic builtin types, not including the pointers. */ 17233965Sjdp 17333965Sjdpenum builtin_types 17433965Sjdp{ 17533965Sjdp builtin_unknown = 0, 17633965Sjdp builtin_void = 1, 17733965Sjdp builtin_signed_char = 2, 17833965Sjdp builtin_unsigned_char = 3, 17933965Sjdp builtin_signed_short_int = 4, 18033965Sjdp builtin_unsigned_short_int = 5, 18133965Sjdp builtin_signed_long = 6, 18233965Sjdp builtin_unsigned_long = 7, 18333965Sjdp builtin_signed_long_long = 8, 18433965Sjdp builtin_unsigned_long_long = 9, 18533965Sjdp builtin_float = 10, 18633965Sjdp builtin_double = 11, 18733965Sjdp builtin_long_double = 12, 18833965Sjdp builtin_long_long_double = 13, 18933965Sjdp builtin_quoted_string = 14, 19033965Sjdp builtin_instruction_address = 15, 19133965Sjdp builtin_int = 16, 19233965Sjdp builtin_unsigned = 17, 19333965Sjdp builtin_unsigned_int = 18, 19433965Sjdp builtin_char = 19, 19533965Sjdp builtin_long = 20, 19633965Sjdp builtin_short = 21, 19733965Sjdp builtin_unsigned_short = 22, 19833965Sjdp builtin_short_int = 23, 19933965Sjdp builtin_signed_short = 24, 20033965Sjdp builtin_bcd_float = 25 20133965Sjdp}; 20233965Sjdp 20333965Sjdp/* These are the values found in the derivation flags of a 'b' 20433965Sjdp component record of a 'T' type extension record in a C++ pmisc 20533965Sjdp record. These are bitmasks. */ 20633965Sjdp 20733965Sjdp/* Set for a private base class, clear for a public base class. 20833965Sjdp Protected base classes are not supported. */ 20933965Sjdp#define BASEFLAGS_PRIVATE (0x1) 21033965Sjdp/* Set for a virtual base class. */ 21133965Sjdp#define BASEFLAGS_VIRTUAL (0x2) 21233965Sjdp/* Set for a friend class, clear for a base class. */ 21333965Sjdp#define BASEFLAGS_FRIEND (0x10) 21433965Sjdp 21533965Sjdp/* These are the values found in the specs flags of a 'd', 'm', or 'v' 21633965Sjdp component record of a 'T' type extension record in a C++ pmisc 21733965Sjdp record. The same flags are used for a 'M' record in a C++ pmisc 21833965Sjdp record. */ 21933965Sjdp 22033965Sjdp/* The lower two bits hold visibility information. */ 22133965Sjdp#define CXXFLAGS_VISIBILITY (0x3) 22233965Sjdp/* This value in the lower two bits indicates a public member. */ 22333965Sjdp#define CXXFLAGS_VISIBILITY_PUBLIC (0x0) 22433965Sjdp/* This value in the lower two bits indicates a private member. */ 22533965Sjdp#define CXXFLAGS_VISIBILITY_PRIVATE (0x1) 22633965Sjdp/* This value in the lower two bits indicates a protected member. */ 22733965Sjdp#define CXXFLAGS_VISIBILITY_PROTECTED (0x2) 22833965Sjdp/* Set for a static member. */ 22933965Sjdp#define CXXFLAGS_STATIC (0x4) 23033965Sjdp/* Set for a virtual override. */ 23133965Sjdp#define CXXFLAGS_OVERRIDE (0x8) 23233965Sjdp/* Set for a friend function. */ 23333965Sjdp#define CXXFLAGS_FRIEND (0x10) 23433965Sjdp/* Set for a const function. */ 23533965Sjdp#define CXXFLAGS_CONST (0x20) 23633965Sjdp/* Set for a volatile function. */ 23733965Sjdp#define CXXFLAGS_VOLATILE (0x40) 23833965Sjdp/* Set for an overloaded function. */ 23933965Sjdp#define CXXFLAGS_OVERLOADED (0x80) 24033965Sjdp/* Set for an operator function. */ 24133965Sjdp#define CXXFLAGS_OPERATOR (0x100) 24233965Sjdp/* Set for a constructor or destructor. */ 24333965Sjdp#define CXXFLAGS_CTORDTOR (0x400) 24433965Sjdp/* Set for a constructor. */ 24533965Sjdp#define CXXFLAGS_CTOR (0x200) 24633965Sjdp/* Set for an inline function. */ 24733965Sjdp#define CXXFLAGS_INLINE (0x800) 24833965Sjdp 24933965Sjdp/* Local functions. */ 25033965Sjdp 251130561Sobrienstatic void ieee_error (struct ieee_info *, const bfd_byte *, const char *); 252130561Sobrienstatic void ieee_eof (struct ieee_info *); 253130561Sobrienstatic char *savestring (const char *, unsigned long); 254130561Sobrienstatic bfd_boolean ieee_read_number 255130561Sobrien (struct ieee_info *, const bfd_byte **, bfd_vma *); 256130561Sobrienstatic bfd_boolean ieee_read_optional_number 257130561Sobrien (struct ieee_info *, const bfd_byte **, bfd_vma *, bfd_boolean *); 258130561Sobrienstatic bfd_boolean ieee_read_id 259130561Sobrien (struct ieee_info *, const bfd_byte **, const char **, unsigned long *); 260130561Sobrienstatic bfd_boolean ieee_read_optional_id 261130561Sobrien (struct ieee_info *, const bfd_byte **, const char **, unsigned long *, 262130561Sobrien bfd_boolean *); 263130561Sobrienstatic bfd_boolean ieee_read_expression 264130561Sobrien (struct ieee_info *, const bfd_byte **, bfd_vma *); 26533965Sjdpstatic debug_type ieee_builtin_type 266130561Sobrien (struct ieee_info *, const bfd_byte *, unsigned int); 267130561Sobrienstatic bfd_boolean ieee_alloc_type 268130561Sobrien (struct ieee_info *, unsigned int, bfd_boolean); 269130561Sobrienstatic bfd_boolean ieee_read_type_index 270130561Sobrien (struct ieee_info *, const bfd_byte **, debug_type *); 271130561Sobrienstatic int ieee_regno_to_genreg (bfd *, int); 272130561Sobrienstatic int ieee_genreg_to_regno (bfd *, int); 273130561Sobrienstatic bfd_boolean parse_ieee_bb (struct ieee_info *, const bfd_byte **); 274130561Sobrienstatic bfd_boolean parse_ieee_be (struct ieee_info *, const bfd_byte **); 275130561Sobrienstatic bfd_boolean parse_ieee_nn (struct ieee_info *, const bfd_byte **); 276130561Sobrienstatic bfd_boolean parse_ieee_ty (struct ieee_info *, const bfd_byte **); 277130561Sobrienstatic bfd_boolean parse_ieee_atn (struct ieee_info *, const bfd_byte **); 278130561Sobrienstatic bfd_boolean ieee_read_cxx_misc 279130561Sobrien (struct ieee_info *, const bfd_byte **, unsigned long); 280130561Sobrienstatic bfd_boolean ieee_read_cxx_class 281130561Sobrien (struct ieee_info *, const bfd_byte **, unsigned long); 282130561Sobrienstatic bfd_boolean ieee_read_cxx_defaults 283130561Sobrien (struct ieee_info *, const bfd_byte **, unsigned long); 284130561Sobrienstatic bfd_boolean ieee_read_reference 285130561Sobrien (struct ieee_info *, const bfd_byte **); 286130561Sobrienstatic bfd_boolean ieee_require_asn 287130561Sobrien (struct ieee_info *, const bfd_byte **, bfd_vma *); 288130561Sobrienstatic bfd_boolean ieee_require_atn65 289130561Sobrien (struct ieee_info *, const bfd_byte **, const char **, unsigned long *); 29033965Sjdp 29133965Sjdp/* Report an error in the IEEE debugging information. */ 29233965Sjdp 29333965Sjdpstatic void 294130561Sobrienieee_error (struct ieee_info *info, const bfd_byte *p, const char *s) 29533965Sjdp{ 29633965Sjdp if (p != NULL) 29733965Sjdp fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd), 29833965Sjdp (unsigned long) (p - info->bytes), s, *p); 29933965Sjdp else 30033965Sjdp fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s); 30133965Sjdp} 30233965Sjdp 30333965Sjdp/* Report an unexpected EOF in the IEEE debugging information. */ 30433965Sjdp 30533965Sjdpstatic void 306130561Sobrienieee_eof (struct ieee_info *info) 30733965Sjdp{ 30833965Sjdp ieee_error (info, (const bfd_byte *) NULL, 30960484Sobrien _("unexpected end of debugging information")); 31033965Sjdp} 31133965Sjdp 31233965Sjdp/* Save a string in memory. */ 31333965Sjdp 31433965Sjdpstatic char * 315130561Sobriensavestring (const char *start, unsigned long len) 31633965Sjdp{ 31733965Sjdp char *ret; 31833965Sjdp 31933965Sjdp ret = (char *) xmalloc (len + 1); 32033965Sjdp memcpy (ret, start, len); 32133965Sjdp ret[len] = '\0'; 32233965Sjdp return ret; 32333965Sjdp} 32433965Sjdp 32533965Sjdp/* Read a number which must be present in an IEEE file. */ 32633965Sjdp 327130561Sobrienstatic bfd_boolean 328130561Sobrienieee_read_number (struct ieee_info *info, const bfd_byte **pp, bfd_vma *pv) 32933965Sjdp{ 330130561Sobrien return ieee_read_optional_number (info, pp, pv, (bfd_boolean *) NULL); 33133965Sjdp} 33233965Sjdp 33333965Sjdp/* Read a number in an IEEE file. If ppresent is not NULL, the number 334104834Sobrien need not be there. */ 33533965Sjdp 336130561Sobrienstatic bfd_boolean 337130561Sobrienieee_read_optional_number (struct ieee_info *info, const bfd_byte **pp, 338130561Sobrien bfd_vma *pv, bfd_boolean *ppresent) 33933965Sjdp{ 34033965Sjdp ieee_record_enum_type b; 34133965Sjdp 34233965Sjdp if (*pp >= info->pend) 34333965Sjdp { 34433965Sjdp if (ppresent != NULL) 34533965Sjdp { 346130561Sobrien *ppresent = FALSE; 347130561Sobrien return TRUE; 34833965Sjdp } 34933965Sjdp ieee_eof (info); 350130561Sobrien return FALSE; 35133965Sjdp } 35233965Sjdp 35333965Sjdp b = (ieee_record_enum_type) **pp; 35433965Sjdp ++*pp; 35533965Sjdp 35633965Sjdp if (b <= ieee_number_end_enum) 35733965Sjdp { 35833965Sjdp *pv = (bfd_vma) b; 35933965Sjdp if (ppresent != NULL) 360130561Sobrien *ppresent = TRUE; 361130561Sobrien return TRUE; 36233965Sjdp } 36333965Sjdp 36433965Sjdp if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum) 36533965Sjdp { 36633965Sjdp unsigned int i; 36733965Sjdp 36833965Sjdp i = (int) b - (int) ieee_number_repeat_start_enum; 36933965Sjdp if (*pp + i - 1 >= info->pend) 37033965Sjdp { 37133965Sjdp ieee_eof (info); 372130561Sobrien return FALSE; 37333965Sjdp } 37433965Sjdp 37533965Sjdp *pv = 0; 37633965Sjdp for (; i > 0; i--) 37733965Sjdp { 37833965Sjdp *pv <<= 8; 37933965Sjdp *pv += **pp; 38033965Sjdp ++*pp; 38133965Sjdp } 38233965Sjdp 38333965Sjdp if (ppresent != NULL) 384130561Sobrien *ppresent = TRUE; 38533965Sjdp 386130561Sobrien return TRUE; 38733965Sjdp } 38833965Sjdp 38933965Sjdp if (ppresent != NULL) 39033965Sjdp { 39133965Sjdp --*pp; 392130561Sobrien *ppresent = FALSE; 393130561Sobrien return TRUE; 39433965Sjdp } 39533965Sjdp 39660484Sobrien ieee_error (info, *pp - 1, _("invalid number")); 397130561Sobrien return FALSE; 39833965Sjdp} 39933965Sjdp 40033965Sjdp/* Read a required string from an IEEE file. */ 40133965Sjdp 402130561Sobrienstatic bfd_boolean 403130561Sobrienieee_read_id (struct ieee_info *info, const bfd_byte **pp, 404130561Sobrien const char **pname, unsigned long *pnamlen) 40533965Sjdp{ 406130561Sobrien return ieee_read_optional_id (info, pp, pname, pnamlen, (bfd_boolean *) NULL); 40733965Sjdp} 40833965Sjdp 40933965Sjdp/* Read a string from an IEEE file. If ppresent is not NULL, the 41033965Sjdp string is optional. */ 41133965Sjdp 412130561Sobrienstatic bfd_boolean 413130561Sobrienieee_read_optional_id (struct ieee_info *info, const bfd_byte **pp, 414130561Sobrien const char **pname, unsigned long *pnamlen, 415130561Sobrien bfd_boolean *ppresent) 41633965Sjdp{ 41733965Sjdp bfd_byte b; 41833965Sjdp unsigned long len; 41933965Sjdp 42033965Sjdp if (*pp >= info->pend) 42133965Sjdp { 42233965Sjdp ieee_eof (info); 423130561Sobrien return FALSE; 42433965Sjdp } 42533965Sjdp 42633965Sjdp b = **pp; 42733965Sjdp ++*pp; 42833965Sjdp 42933965Sjdp if (b <= 0x7f) 43033965Sjdp len = b; 43133965Sjdp else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum) 43233965Sjdp { 43333965Sjdp len = **pp; 43433965Sjdp ++*pp; 43533965Sjdp } 43633965Sjdp else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum) 43733965Sjdp { 43833965Sjdp len = (**pp << 8) + (*pp)[1]; 43933965Sjdp *pp += 2; 44033965Sjdp } 44133965Sjdp else 44233965Sjdp { 44333965Sjdp if (ppresent != NULL) 44433965Sjdp { 44533965Sjdp --*pp; 446130561Sobrien *ppresent = FALSE; 447130561Sobrien return TRUE; 44833965Sjdp } 44960484Sobrien ieee_error (info, *pp - 1, _("invalid string length")); 450130561Sobrien return FALSE; 45133965Sjdp } 45233965Sjdp 45333965Sjdp if ((unsigned long) (info->pend - *pp) < len) 45433965Sjdp { 45533965Sjdp ieee_eof (info); 456130561Sobrien return FALSE; 45733965Sjdp } 45833965Sjdp 45933965Sjdp *pname = (const char *) *pp; 46033965Sjdp *pnamlen = len; 46133965Sjdp *pp += len; 46233965Sjdp 46333965Sjdp if (ppresent != NULL) 464130561Sobrien *ppresent = TRUE; 46533965Sjdp 466130561Sobrien return TRUE; 46733965Sjdp} 46833965Sjdp 46933965Sjdp/* Read an expression from an IEEE file. Since this code is only used 47033965Sjdp to parse debugging information, I haven't bothered to write a full 47133965Sjdp blown IEEE expression parser. I've only thrown in the things I've 47233965Sjdp seen in debugging information. This can be easily extended if 47333965Sjdp necessary. */ 47433965Sjdp 475130561Sobrienstatic bfd_boolean 476130561Sobrienieee_read_expression (struct ieee_info *info, const bfd_byte **pp, 477130561Sobrien bfd_vma *pv) 47833965Sjdp{ 47933965Sjdp const bfd_byte *expr_start; 48033965Sjdp#define EXPR_STACK_SIZE (10) 48133965Sjdp bfd_vma expr_stack[EXPR_STACK_SIZE]; 48233965Sjdp bfd_vma *esp; 48333965Sjdp 48433965Sjdp expr_start = *pp; 48533965Sjdp 48633965Sjdp esp = expr_stack; 48733965Sjdp 48833965Sjdp while (1) 48933965Sjdp { 49033965Sjdp const bfd_byte *start; 49133965Sjdp bfd_vma val; 492130561Sobrien bfd_boolean present; 49333965Sjdp ieee_record_enum_type c; 49433965Sjdp 49533965Sjdp start = *pp; 49633965Sjdp 49733965Sjdp if (! ieee_read_optional_number (info, pp, &val, &present)) 498130561Sobrien return FALSE; 49933965Sjdp 50033965Sjdp if (present) 50133965Sjdp { 50233965Sjdp if (esp - expr_stack >= EXPR_STACK_SIZE) 50333965Sjdp { 50460484Sobrien ieee_error (info, start, _("expression stack overflow")); 505130561Sobrien return FALSE; 50633965Sjdp } 50733965Sjdp *esp++ = val; 50833965Sjdp continue; 50933965Sjdp } 51033965Sjdp 51133965Sjdp c = (ieee_record_enum_type) **pp; 51233965Sjdp 51333965Sjdp if (c >= ieee_module_beginning_enum) 51433965Sjdp break; 51533965Sjdp 51633965Sjdp ++*pp; 51733965Sjdp 51833965Sjdp if (c == ieee_comma) 51933965Sjdp break; 52033965Sjdp 52133965Sjdp switch (c) 52233965Sjdp { 52333965Sjdp default: 52460484Sobrien ieee_error (info, start, _("unsupported IEEE expression operator")); 52533965Sjdp break; 52633965Sjdp 52733965Sjdp case ieee_variable_R_enum: 52833965Sjdp { 52933965Sjdp bfd_vma indx; 53033965Sjdp asection *s; 53133965Sjdp 53233965Sjdp if (! ieee_read_number (info, pp, &indx)) 533130561Sobrien return FALSE; 53433965Sjdp for (s = info->abfd->sections; s != NULL; s = s->next) 53533965Sjdp if ((bfd_vma) s->target_index == indx) 53633965Sjdp break; 53733965Sjdp if (s == NULL) 53833965Sjdp { 53960484Sobrien ieee_error (info, start, _("unknown section")); 540130561Sobrien return FALSE; 54133965Sjdp } 54277298Sobrien 54333965Sjdp if (esp - expr_stack >= EXPR_STACK_SIZE) 54433965Sjdp { 54560484Sobrien ieee_error (info, start, _("expression stack overflow")); 546130561Sobrien return FALSE; 54733965Sjdp } 54833965Sjdp 54933965Sjdp *esp++ = bfd_get_section_vma (info->abfd, s); 55033965Sjdp } 55133965Sjdp break; 55233965Sjdp 55333965Sjdp case ieee_function_plus_enum: 55433965Sjdp case ieee_function_minus_enum: 55533965Sjdp { 55633965Sjdp bfd_vma v1, v2; 55733965Sjdp 55833965Sjdp if (esp - expr_stack < 2) 55933965Sjdp { 56060484Sobrien ieee_error (info, start, _("expression stack underflow")); 561130561Sobrien return FALSE; 56233965Sjdp } 56333965Sjdp 56433965Sjdp v1 = *--esp; 56533965Sjdp v2 = *--esp; 56633965Sjdp *esp++ = v1 + v2; 56733965Sjdp } 56833965Sjdp break; 56933965Sjdp } 57033965Sjdp } 57133965Sjdp 57233965Sjdp if (esp - 1 != expr_stack) 57333965Sjdp { 57460484Sobrien ieee_error (info, expr_start, _("expression stack mismatch")); 575130561Sobrien return FALSE; 57633965Sjdp } 57733965Sjdp 57833965Sjdp *pv = *--esp; 57933965Sjdp 580130561Sobrien return TRUE; 58133965Sjdp} 58233965Sjdp 58333965Sjdp/* Return an IEEE builtin type. */ 58433965Sjdp 58533965Sjdpstatic debug_type 586130561Sobrienieee_builtin_type (struct ieee_info *info, const bfd_byte *p, 587130561Sobrien unsigned int indx) 58833965Sjdp{ 589130561Sobrien void *dhandle; 59033965Sjdp debug_type type; 59133965Sjdp const char *name; 59233965Sjdp 59333965Sjdp if (indx < BUILTIN_TYPE_COUNT 59433965Sjdp && info->types.builtins[indx] != DEBUG_TYPE_NULL) 59533965Sjdp return info->types.builtins[indx]; 59633965Sjdp 59733965Sjdp dhandle = info->dhandle; 59833965Sjdp 59933965Sjdp if (indx >= 32 && indx < 64) 60033965Sjdp { 60133965Sjdp type = debug_make_pointer_type (dhandle, 60233965Sjdp ieee_builtin_type (info, p, indx - 32)); 60333965Sjdp assert (indx < BUILTIN_TYPE_COUNT); 60433965Sjdp info->types.builtins[indx] = type; 60533965Sjdp return type; 60633965Sjdp } 60733965Sjdp 60833965Sjdp switch ((enum builtin_types) indx) 60933965Sjdp { 61033965Sjdp default: 61160484Sobrien ieee_error (info, p, _("unknown builtin type")); 61233965Sjdp return NULL; 61333965Sjdp 61433965Sjdp case builtin_unknown: 61533965Sjdp type = debug_make_void_type (dhandle); 61633965Sjdp name = NULL; 61733965Sjdp break; 61833965Sjdp 61933965Sjdp case builtin_void: 62033965Sjdp type = debug_make_void_type (dhandle); 62133965Sjdp name = "void"; 62233965Sjdp break; 62333965Sjdp 62433965Sjdp case builtin_signed_char: 625130561Sobrien type = debug_make_int_type (dhandle, 1, FALSE); 62633965Sjdp name = "signed char"; 62733965Sjdp break; 62833965Sjdp 62933965Sjdp case builtin_unsigned_char: 630130561Sobrien type = debug_make_int_type (dhandle, 1, TRUE); 63133965Sjdp name = "unsigned char"; 63233965Sjdp break; 63333965Sjdp 63433965Sjdp case builtin_signed_short_int: 635130561Sobrien type = debug_make_int_type (dhandle, 2, FALSE); 63633965Sjdp name = "signed short int"; 63733965Sjdp break; 63833965Sjdp 63933965Sjdp case builtin_unsigned_short_int: 640130561Sobrien type = debug_make_int_type (dhandle, 2, TRUE); 64133965Sjdp name = "unsigned short int"; 64233965Sjdp break; 64333965Sjdp 64433965Sjdp case builtin_signed_long: 645130561Sobrien type = debug_make_int_type (dhandle, 4, FALSE); 64633965Sjdp name = "signed long"; 64733965Sjdp break; 64833965Sjdp 64933965Sjdp case builtin_unsigned_long: 650130561Sobrien type = debug_make_int_type (dhandle, 4, TRUE); 65133965Sjdp name = "unsigned long"; 65233965Sjdp break; 65333965Sjdp 65433965Sjdp case builtin_signed_long_long: 655130561Sobrien type = debug_make_int_type (dhandle, 8, FALSE); 65633965Sjdp name = "signed long long"; 65733965Sjdp break; 65833965Sjdp 65933965Sjdp case builtin_unsigned_long_long: 660130561Sobrien type = debug_make_int_type (dhandle, 8, TRUE); 66133965Sjdp name = "unsigned long long"; 66233965Sjdp break; 66333965Sjdp 66433965Sjdp case builtin_float: 66533965Sjdp type = debug_make_float_type (dhandle, 4); 66633965Sjdp name = "float"; 66733965Sjdp break; 66833965Sjdp 66933965Sjdp case builtin_double: 67033965Sjdp type = debug_make_float_type (dhandle, 8); 67133965Sjdp name = "double"; 67233965Sjdp break; 67333965Sjdp 67433965Sjdp case builtin_long_double: 67533965Sjdp /* FIXME: The size for this type should depend upon the 67633965Sjdp processor. */ 67733965Sjdp type = debug_make_float_type (dhandle, 12); 67833965Sjdp name = "long double"; 67933965Sjdp break; 68033965Sjdp 68133965Sjdp case builtin_long_long_double: 68233965Sjdp type = debug_make_float_type (dhandle, 16); 68333965Sjdp name = "long long double"; 68433965Sjdp break; 68533965Sjdp 68633965Sjdp case builtin_quoted_string: 68733965Sjdp type = debug_make_array_type (dhandle, 68833965Sjdp ieee_builtin_type (info, p, 68933965Sjdp ((unsigned int) 69033965Sjdp builtin_char)), 69133965Sjdp ieee_builtin_type (info, p, 69233965Sjdp ((unsigned int) 69333965Sjdp builtin_int)), 694130561Sobrien 0, -1, TRUE); 69533965Sjdp name = "QUOTED STRING"; 69633965Sjdp break; 69733965Sjdp 69833965Sjdp case builtin_instruction_address: 69933965Sjdp /* FIXME: This should be a code address. */ 700130561Sobrien type = debug_make_int_type (dhandle, 4, TRUE); 70133965Sjdp name = "instruction address"; 70233965Sjdp break; 70333965Sjdp 70433965Sjdp case builtin_int: 70533965Sjdp /* FIXME: The size for this type should depend upon the 70633965Sjdp processor. */ 707130561Sobrien type = debug_make_int_type (dhandle, 4, FALSE); 70833965Sjdp name = "int"; 70933965Sjdp break; 71033965Sjdp 71133965Sjdp case builtin_unsigned: 71233965Sjdp /* FIXME: The size for this type should depend upon the 71333965Sjdp processor. */ 714130561Sobrien type = debug_make_int_type (dhandle, 4, TRUE); 71533965Sjdp name = "unsigned"; 71633965Sjdp break; 71733965Sjdp 71833965Sjdp case builtin_unsigned_int: 71933965Sjdp /* FIXME: The size for this type should depend upon the 72033965Sjdp processor. */ 721130561Sobrien type = debug_make_int_type (dhandle, 4, TRUE); 72233965Sjdp name = "unsigned int"; 72333965Sjdp break; 72433965Sjdp 72533965Sjdp case builtin_char: 726130561Sobrien type = debug_make_int_type (dhandle, 1, FALSE); 72733965Sjdp name = "char"; 72833965Sjdp break; 72933965Sjdp 73033965Sjdp case builtin_long: 731130561Sobrien type = debug_make_int_type (dhandle, 4, FALSE); 73233965Sjdp name = "long"; 73333965Sjdp break; 73433965Sjdp 73533965Sjdp case builtin_short: 736130561Sobrien type = debug_make_int_type (dhandle, 2, FALSE); 73733965Sjdp name = "short"; 73833965Sjdp break; 73933965Sjdp 74033965Sjdp case builtin_unsigned_short: 741130561Sobrien type = debug_make_int_type (dhandle, 2, TRUE); 74233965Sjdp name = "unsigned short"; 74333965Sjdp break; 74433965Sjdp 74533965Sjdp case builtin_short_int: 746130561Sobrien type = debug_make_int_type (dhandle, 2, FALSE); 74733965Sjdp name = "short int"; 74833965Sjdp break; 74933965Sjdp 75033965Sjdp case builtin_signed_short: 751130561Sobrien type = debug_make_int_type (dhandle, 2, FALSE); 75233965Sjdp name = "signed short"; 75333965Sjdp break; 75433965Sjdp 75533965Sjdp case builtin_bcd_float: 75660484Sobrien ieee_error (info, p, _("BCD float type not supported")); 75760484Sobrien return DEBUG_TYPE_NULL; 75833965Sjdp } 75933965Sjdp 76033965Sjdp if (name != NULL) 76133965Sjdp type = debug_name_type (dhandle, name, type); 76233965Sjdp 76333965Sjdp assert (indx < BUILTIN_TYPE_COUNT); 76433965Sjdp 76533965Sjdp info->types.builtins[indx] = type; 76633965Sjdp 76733965Sjdp return type; 76833965Sjdp} 76933965Sjdp 770130561Sobrien/* Allocate more space in the type table. If ref is TRUE, this is a 77133965Sjdp reference to the type; if it is not already defined, we should set 77233965Sjdp up an indirect type. */ 77333965Sjdp 774130561Sobrienstatic bfd_boolean 775130561Sobrienieee_alloc_type (struct ieee_info *info, unsigned int indx, bfd_boolean ref) 77633965Sjdp{ 77733965Sjdp unsigned int nalloc; 77833965Sjdp register struct ieee_type *t; 77933965Sjdp struct ieee_type *tend; 78033965Sjdp 78133965Sjdp if (indx >= info->types.alloc) 78233965Sjdp { 78333965Sjdp nalloc = info->types.alloc; 78433965Sjdp if (nalloc == 0) 78533965Sjdp nalloc = 4; 78633965Sjdp while (indx >= nalloc) 78733965Sjdp nalloc *= 2; 78833965Sjdp 78933965Sjdp info->types.types = ((struct ieee_type *) 79033965Sjdp xrealloc (info->types.types, 79133965Sjdp nalloc * sizeof *info->types.types)); 79233965Sjdp 79333965Sjdp memset (info->types.types + info->types.alloc, 0, 79433965Sjdp (nalloc - info->types.alloc) * sizeof *info->types.types); 79533965Sjdp 79633965Sjdp tend = info->types.types + nalloc; 79733965Sjdp for (t = info->types.types + info->types.alloc; t < tend; t++) 79833965Sjdp t->type = DEBUG_TYPE_NULL; 79933965Sjdp 80033965Sjdp info->types.alloc = nalloc; 80133965Sjdp } 80233965Sjdp 80333965Sjdp if (ref) 80433965Sjdp { 80533965Sjdp t = info->types.types + indx; 80633965Sjdp if (t->type == NULL) 80733965Sjdp { 80833965Sjdp t->pslot = (debug_type *) xmalloc (sizeof *t->pslot); 80933965Sjdp *t->pslot = DEBUG_TYPE_NULL; 81033965Sjdp t->type = debug_make_indirect_type (info->dhandle, t->pslot, 81133965Sjdp (const char *) NULL); 81233965Sjdp if (t->type == NULL) 813130561Sobrien return FALSE; 81433965Sjdp } 81533965Sjdp } 81633965Sjdp 817130561Sobrien return TRUE; 81833965Sjdp} 81933965Sjdp 82033965Sjdp/* Read a type index and return the corresponding type. */ 82133965Sjdp 822130561Sobrienstatic bfd_boolean 823130561Sobrienieee_read_type_index (struct ieee_info *info, const bfd_byte **pp, 824130561Sobrien debug_type *ptype) 82533965Sjdp{ 82633965Sjdp const bfd_byte *start; 82733965Sjdp bfd_vma indx; 82833965Sjdp 82933965Sjdp start = *pp; 83033965Sjdp 83133965Sjdp if (! ieee_read_number (info, pp, &indx)) 832130561Sobrien return FALSE; 83333965Sjdp 83433965Sjdp if (indx < 256) 83533965Sjdp { 83633965Sjdp *ptype = ieee_builtin_type (info, start, indx); 83733965Sjdp if (*ptype == NULL) 838130561Sobrien return FALSE; 839130561Sobrien return TRUE; 84033965Sjdp } 84133965Sjdp 84233965Sjdp indx -= 256; 843130561Sobrien if (! ieee_alloc_type (info, indx, TRUE)) 844130561Sobrien return FALSE; 84533965Sjdp 84633965Sjdp *ptype = info->types.types[indx].type; 84733965Sjdp 848130561Sobrien return TRUE; 84933965Sjdp} 85033965Sjdp 85133965Sjdp/* Parse IEEE debugging information for a file. This is passed the 85233965Sjdp bytes which compose the Debug Information Part of an IEEE file. */ 85333965Sjdp 854130561Sobrienbfd_boolean 855130561Sobrienparse_ieee (void *dhandle, bfd *abfd, const bfd_byte *bytes, bfd_size_type len) 85633965Sjdp{ 85733965Sjdp struct ieee_info info; 85833965Sjdp unsigned int i; 85933965Sjdp const bfd_byte *p, *pend; 86033965Sjdp 86133965Sjdp info.dhandle = dhandle; 86233965Sjdp info.abfd = abfd; 86333965Sjdp info.bytes = bytes; 86433965Sjdp info.pend = bytes + len; 86533965Sjdp info.blockstack.bsp = info.blockstack.stack; 866130561Sobrien info.saw_filename = FALSE; 86733965Sjdp info.vars.alloc = 0; 86833965Sjdp info.vars.vars = NULL; 86960484Sobrien info.global_vars = NULL; 87033965Sjdp info.types.alloc = 0; 87133965Sjdp info.types.types = NULL; 87260484Sobrien info.global_types = NULL; 87333965Sjdp info.tags = NULL; 87433965Sjdp for (i = 0; i < BUILTIN_TYPE_COUNT; i++) 87533965Sjdp info.types.builtins[i] = DEBUG_TYPE_NULL; 87633965Sjdp 87733965Sjdp p = bytes; 87833965Sjdp pend = info.pend; 87933965Sjdp while (p < pend) 88033965Sjdp { 88133965Sjdp const bfd_byte *record_start; 88233965Sjdp ieee_record_enum_type c; 88333965Sjdp 88433965Sjdp record_start = p; 88533965Sjdp 88633965Sjdp c = (ieee_record_enum_type) *p++; 88733965Sjdp 88833965Sjdp if (c == ieee_at_record_enum) 88933965Sjdp c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++); 89033965Sjdp 89133965Sjdp if (c <= ieee_number_repeat_end_enum) 89233965Sjdp { 89360484Sobrien ieee_error (&info, record_start, _("unexpected number")); 894130561Sobrien return FALSE; 89533965Sjdp } 89633965Sjdp 89733965Sjdp switch (c) 89833965Sjdp { 89933965Sjdp default: 90060484Sobrien ieee_error (&info, record_start, _("unexpected record type")); 901130561Sobrien return FALSE; 90233965Sjdp 90333965Sjdp case ieee_bb_record_enum: 90433965Sjdp if (! parse_ieee_bb (&info, &p)) 905130561Sobrien return FALSE; 90633965Sjdp break; 90733965Sjdp 90833965Sjdp case ieee_be_record_enum: 90933965Sjdp if (! parse_ieee_be (&info, &p)) 910130561Sobrien return FALSE; 91133965Sjdp break; 91233965Sjdp 91333965Sjdp case ieee_nn_record: 91433965Sjdp if (! parse_ieee_nn (&info, &p)) 915130561Sobrien return FALSE; 91633965Sjdp break; 91733965Sjdp 91833965Sjdp case ieee_ty_record_enum: 91933965Sjdp if (! parse_ieee_ty (&info, &p)) 920130561Sobrien return FALSE; 92133965Sjdp break; 92233965Sjdp 92333965Sjdp case ieee_atn_record_enum: 92433965Sjdp if (! parse_ieee_atn (&info, &p)) 925130561Sobrien return FALSE; 92633965Sjdp break; 92733965Sjdp } 92833965Sjdp } 92933965Sjdp 93033965Sjdp if (info.blockstack.bsp != info.blockstack.stack) 93133965Sjdp { 93233965Sjdp ieee_error (&info, (const bfd_byte *) NULL, 93360484Sobrien _("blocks left on stack at end")); 934130561Sobrien return FALSE; 93533965Sjdp } 93633965Sjdp 937130561Sobrien return TRUE; 93833965Sjdp} 93933965Sjdp 94033965Sjdp/* Handle an IEEE BB record. */ 94133965Sjdp 942130561Sobrienstatic bfd_boolean 943130561Sobrienparse_ieee_bb (struct ieee_info *info, const bfd_byte **pp) 94433965Sjdp{ 94533965Sjdp const bfd_byte *block_start; 94633965Sjdp bfd_byte b; 94733965Sjdp bfd_vma size; 94833965Sjdp const char *name; 94933965Sjdp unsigned long namlen; 95033965Sjdp char *namcopy = NULL; 95133965Sjdp unsigned int fnindx; 952130561Sobrien bfd_boolean skip; 95333965Sjdp 95433965Sjdp block_start = *pp; 95533965Sjdp 95633965Sjdp b = **pp; 95733965Sjdp ++*pp; 95833965Sjdp 95933965Sjdp if (! ieee_read_number (info, pp, &size) 96033965Sjdp || ! ieee_read_id (info, pp, &name, &namlen)) 961130561Sobrien return FALSE; 96233965Sjdp 96333965Sjdp fnindx = (unsigned int) -1; 964130561Sobrien skip = FALSE; 96533965Sjdp 96633965Sjdp switch (b) 96733965Sjdp { 96833965Sjdp case 1: 96933965Sjdp /* BB1: Type definitions local to a module. */ 97033965Sjdp namcopy = savestring (name, namlen); 97133965Sjdp if (namcopy == NULL) 972130561Sobrien return FALSE; 97333965Sjdp if (! debug_set_filename (info->dhandle, namcopy)) 974130561Sobrien return FALSE; 975130561Sobrien info->saw_filename = TRUE; 97633965Sjdp 97733965Sjdp /* Discard any variables or types we may have seen before. */ 97833965Sjdp if (info->vars.vars != NULL) 97933965Sjdp free (info->vars.vars); 98033965Sjdp info->vars.vars = NULL; 98133965Sjdp info->vars.alloc = 0; 98233965Sjdp if (info->types.types != NULL) 98333965Sjdp free (info->types.types); 98433965Sjdp info->types.types = NULL; 98533965Sjdp info->types.alloc = 0; 98633965Sjdp 98733965Sjdp /* Initialize the types to the global types. */ 98833965Sjdp if (info->global_types != NULL) 98933965Sjdp { 99033965Sjdp info->types.alloc = info->global_types->alloc; 99133965Sjdp info->types.types = ((struct ieee_type *) 99233965Sjdp xmalloc (info->types.alloc 99333965Sjdp * sizeof (*info->types.types))); 99433965Sjdp memcpy (info->types.types, info->global_types->types, 99533965Sjdp info->types.alloc * sizeof (*info->types.types)); 99633965Sjdp } 99733965Sjdp 99833965Sjdp break; 99933965Sjdp 100033965Sjdp case 2: 100133965Sjdp /* BB2: Global type definitions. The name is supposed to be 1002104834Sobrien empty, but we don't check. */ 100333965Sjdp if (! debug_set_filename (info->dhandle, "*global*")) 1004130561Sobrien return FALSE; 1005130561Sobrien info->saw_filename = TRUE; 100633965Sjdp break; 100733965Sjdp 100833965Sjdp case 3: 100933965Sjdp /* BB3: High level module block begin. We don't have to do 101033965Sjdp anything here. The name is supposed to be the same as for 101133965Sjdp the BB1, but we don't check. */ 101233965Sjdp break; 101333965Sjdp 101433965Sjdp case 4: 101533965Sjdp /* BB4: Global function. */ 101633965Sjdp { 101733965Sjdp bfd_vma stackspace, typindx, offset; 101833965Sjdp debug_type return_type; 101933965Sjdp 102033965Sjdp if (! ieee_read_number (info, pp, &stackspace) 102133965Sjdp || ! ieee_read_number (info, pp, &typindx) 102233965Sjdp || ! ieee_read_expression (info, pp, &offset)) 1023130561Sobrien return FALSE; 102433965Sjdp 102533965Sjdp /* We have no way to record the stack space. FIXME. */ 102633965Sjdp 102733965Sjdp if (typindx < 256) 102833965Sjdp { 102933965Sjdp return_type = ieee_builtin_type (info, block_start, typindx); 103033965Sjdp if (return_type == DEBUG_TYPE_NULL) 1031130561Sobrien return FALSE; 103233965Sjdp } 103333965Sjdp else 103433965Sjdp { 103533965Sjdp typindx -= 256; 1036130561Sobrien if (! ieee_alloc_type (info, typindx, TRUE)) 1037130561Sobrien return FALSE; 103833965Sjdp fnindx = typindx; 103933965Sjdp return_type = info->types.types[typindx].type; 104033965Sjdp if (debug_get_type_kind (info->dhandle, return_type) 104133965Sjdp == DEBUG_KIND_FUNCTION) 104233965Sjdp return_type = debug_get_return_type (info->dhandle, 104333965Sjdp return_type); 104433965Sjdp } 104533965Sjdp 104633965Sjdp namcopy = savestring (name, namlen); 104733965Sjdp if (namcopy == NULL) 1048130561Sobrien return FALSE; 104933965Sjdp if (! debug_record_function (info->dhandle, namcopy, return_type, 1050130561Sobrien TRUE, offset)) 1051130561Sobrien return FALSE; 105233965Sjdp } 105333965Sjdp break; 105433965Sjdp 105533965Sjdp case 5: 105633965Sjdp /* BB5: File name for source line numbers. */ 105733965Sjdp { 105833965Sjdp unsigned int i; 105933965Sjdp 106033965Sjdp /* We ignore the date and time. FIXME. */ 106133965Sjdp for (i = 0; i < 6; i++) 106233965Sjdp { 106333965Sjdp bfd_vma ignore; 1064130561Sobrien bfd_boolean present; 106533965Sjdp 106633965Sjdp if (! ieee_read_optional_number (info, pp, &ignore, &present)) 1067130561Sobrien return FALSE; 106833965Sjdp if (! present) 106933965Sjdp break; 107033965Sjdp } 107133965Sjdp 107233965Sjdp namcopy = savestring (name, namlen); 107333965Sjdp if (namcopy == NULL) 1074130561Sobrien return FALSE; 107533965Sjdp if (! debug_start_source (info->dhandle, namcopy)) 1076130561Sobrien return FALSE; 107733965Sjdp } 107833965Sjdp break; 107933965Sjdp 108033965Sjdp case 6: 108133965Sjdp /* BB6: Local function or block. */ 108233965Sjdp { 108333965Sjdp bfd_vma stackspace, typindx, offset; 108433965Sjdp 108533965Sjdp if (! ieee_read_number (info, pp, &stackspace) 108633965Sjdp || ! ieee_read_number (info, pp, &typindx) 108733965Sjdp || ! ieee_read_expression (info, pp, &offset)) 1088130561Sobrien return FALSE; 108933965Sjdp 109033965Sjdp /* We have no way to record the stack space. FIXME. */ 109133965Sjdp 109233965Sjdp if (namlen == 0) 109333965Sjdp { 109433965Sjdp if (! debug_start_block (info->dhandle, offset)) 1095130561Sobrien return FALSE; 109633965Sjdp /* Change b to indicate that this is a block 109733965Sjdp rather than a function. */ 109833965Sjdp b = 0x86; 109933965Sjdp } 110033965Sjdp else 110133965Sjdp { 110233965Sjdp /* The MRI C++ compiler will output a fake function named 110333965Sjdp __XRYCPP to hold C++ debugging information. We skip 110433965Sjdp that function. This is not crucial, but it makes 110533965Sjdp converting from IEEE to other debug formats work 110633965Sjdp better. */ 110733965Sjdp if (strncmp (name, "__XRYCPP", namlen) == 0) 1108130561Sobrien skip = TRUE; 110933965Sjdp else 111033965Sjdp { 111133965Sjdp debug_type return_type; 111233965Sjdp 111333965Sjdp if (typindx < 256) 111433965Sjdp { 111533965Sjdp return_type = ieee_builtin_type (info, block_start, 111633965Sjdp typindx); 111733965Sjdp if (return_type == NULL) 1118130561Sobrien return FALSE; 111933965Sjdp } 112033965Sjdp else 112133965Sjdp { 112233965Sjdp typindx -= 256; 1123130561Sobrien if (! ieee_alloc_type (info, typindx, TRUE)) 1124130561Sobrien return FALSE; 112533965Sjdp fnindx = typindx; 112633965Sjdp return_type = info->types.types[typindx].type; 112733965Sjdp if (debug_get_type_kind (info->dhandle, return_type) 112833965Sjdp == DEBUG_KIND_FUNCTION) 112933965Sjdp return_type = debug_get_return_type (info->dhandle, 113033965Sjdp return_type); 113133965Sjdp } 113233965Sjdp 113333965Sjdp namcopy = savestring (name, namlen); 113433965Sjdp if (namcopy == NULL) 1135130561Sobrien return FALSE; 113633965Sjdp if (! debug_record_function (info->dhandle, namcopy, 1137130561Sobrien return_type, FALSE, offset)) 1138130561Sobrien return FALSE; 113933965Sjdp } 114033965Sjdp } 114133965Sjdp } 114233965Sjdp break; 114333965Sjdp 114433965Sjdp case 10: 114533965Sjdp /* BB10: Assembler module scope. In the normal case, we 114633965Sjdp completely ignore all this information. FIXME. */ 114733965Sjdp { 114833965Sjdp const char *inam, *vstr; 114933965Sjdp unsigned long inamlen, vstrlen; 115033965Sjdp bfd_vma tool_type; 1151130561Sobrien bfd_boolean present; 115233965Sjdp unsigned int i; 115333965Sjdp 115433965Sjdp if (! info->saw_filename) 115533965Sjdp { 115633965Sjdp namcopy = savestring (name, namlen); 115733965Sjdp if (namcopy == NULL) 1158130561Sobrien return FALSE; 115933965Sjdp if (! debug_set_filename (info->dhandle, namcopy)) 1160130561Sobrien return FALSE; 1161130561Sobrien info->saw_filename = TRUE; 116233965Sjdp } 116333965Sjdp 116433965Sjdp if (! ieee_read_id (info, pp, &inam, &inamlen) 116533965Sjdp || ! ieee_read_number (info, pp, &tool_type) 116633965Sjdp || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present)) 1167130561Sobrien return FALSE; 116833965Sjdp for (i = 0; i < 6; i++) 116933965Sjdp { 117033965Sjdp bfd_vma ignore; 117133965Sjdp 117233965Sjdp if (! ieee_read_optional_number (info, pp, &ignore, &present)) 1173130561Sobrien return FALSE; 117433965Sjdp if (! present) 117533965Sjdp break; 117633965Sjdp } 117733965Sjdp } 117833965Sjdp break; 117933965Sjdp 118033965Sjdp case 11: 118133965Sjdp /* BB11: Module section. We completely ignore all this 118233965Sjdp information. FIXME. */ 118333965Sjdp { 118433965Sjdp bfd_vma sectype, secindx, offset, map; 1185130561Sobrien bfd_boolean present; 118633965Sjdp 118733965Sjdp if (! ieee_read_number (info, pp, §ype) 118833965Sjdp || ! ieee_read_number (info, pp, &secindx) 118933965Sjdp || ! ieee_read_expression (info, pp, &offset) 119033965Sjdp || ! ieee_read_optional_number (info, pp, &map, &present)) 1191130561Sobrien return FALSE; 119233965Sjdp } 119333965Sjdp break; 119433965Sjdp 119533965Sjdp default: 119660484Sobrien ieee_error (info, block_start, _("unknown BB type")); 1197130561Sobrien return FALSE; 119833965Sjdp } 119933965Sjdp 120033965Sjdp 120133965Sjdp /* Push this block on the block stack. */ 120233965Sjdp 120333965Sjdp if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE) 120433965Sjdp { 120560484Sobrien ieee_error (info, (const bfd_byte *) NULL, _("stack overflow")); 1206130561Sobrien return FALSE; 120733965Sjdp } 120833965Sjdp 120933965Sjdp info->blockstack.bsp->kind = b; 121033965Sjdp if (b == 5) 121133965Sjdp info->blockstack.bsp->filename = namcopy; 121233965Sjdp info->blockstack.bsp->fnindx = fnindx; 121333965Sjdp info->blockstack.bsp->skip = skip; 121433965Sjdp ++info->blockstack.bsp; 121533965Sjdp 1216130561Sobrien return TRUE; 121733965Sjdp} 121833965Sjdp 121933965Sjdp/* Handle an IEEE BE record. */ 122033965Sjdp 1221130561Sobrienstatic bfd_boolean 1222130561Sobrienparse_ieee_be (struct ieee_info *info, const bfd_byte **pp) 122333965Sjdp{ 122433965Sjdp bfd_vma offset; 122533965Sjdp 122633965Sjdp if (info->blockstack.bsp <= info->blockstack.stack) 122733965Sjdp { 122860484Sobrien ieee_error (info, *pp, _("stack underflow")); 1229130561Sobrien return FALSE; 123033965Sjdp } 123133965Sjdp --info->blockstack.bsp; 123233965Sjdp 123333965Sjdp switch (info->blockstack.bsp->kind) 123433965Sjdp { 123533965Sjdp case 2: 1236130561Sobrien /* When we end the global typedefs block, we copy out the 123733965Sjdp contents of info->vars. This is because the variable indices 123833965Sjdp may be reused in the local blocks. However, we need to 123933965Sjdp preserve them so that we can locate a function returning a 124033965Sjdp reference variable whose type is named in the global typedef 124133965Sjdp block. */ 124233965Sjdp info->global_vars = ((struct ieee_vars *) 124333965Sjdp xmalloc (sizeof *info->global_vars)); 124433965Sjdp info->global_vars->alloc = info->vars.alloc; 124533965Sjdp info->global_vars->vars = ((struct ieee_var *) 124633965Sjdp xmalloc (info->vars.alloc 124733965Sjdp * sizeof (*info->vars.vars))); 124833965Sjdp memcpy (info->global_vars->vars, info->vars.vars, 124933965Sjdp info->vars.alloc * sizeof (*info->vars.vars)); 125033965Sjdp 125133965Sjdp /* We also copy out the non builtin parts of info->types, since 125233965Sjdp the types are discarded when we start a new block. */ 125333965Sjdp info->global_types = ((struct ieee_types *) 125433965Sjdp xmalloc (sizeof *info->global_types)); 125533965Sjdp info->global_types->alloc = info->types.alloc; 125633965Sjdp info->global_types->types = ((struct ieee_type *) 125733965Sjdp xmalloc (info->types.alloc 125833965Sjdp * sizeof (*info->types.types))); 125933965Sjdp memcpy (info->global_types->types, info->types.types, 126033965Sjdp info->types.alloc * sizeof (*info->types.types)); 126133965Sjdp memset (info->global_types->builtins, 0, 126233965Sjdp sizeof (info->global_types->builtins)); 126333965Sjdp 126433965Sjdp break; 126533965Sjdp 126633965Sjdp case 4: 126733965Sjdp case 6: 126833965Sjdp if (! ieee_read_expression (info, pp, &offset)) 1269130561Sobrien return FALSE; 127033965Sjdp if (! info->blockstack.bsp->skip) 127133965Sjdp { 127233965Sjdp if (! debug_end_function (info->dhandle, offset + 1)) 1273130561Sobrien return FALSE; 127433965Sjdp } 127533965Sjdp break; 127633965Sjdp 127733965Sjdp case 0x86: 127833965Sjdp /* This is BE6 when BB6 started a block rather than a local 127933965Sjdp function. */ 128033965Sjdp if (! ieee_read_expression (info, pp, &offset)) 1281130561Sobrien return FALSE; 128233965Sjdp if (! debug_end_block (info->dhandle, offset + 1)) 1283130561Sobrien return FALSE; 128433965Sjdp break; 128533965Sjdp 128633965Sjdp case 5: 128733965Sjdp /* When we end a BB5, we look up the stack for the last BB5, if 128833965Sjdp there is one, so that we can call debug_start_source. */ 128933965Sjdp if (info->blockstack.bsp > info->blockstack.stack) 129033965Sjdp { 129133965Sjdp struct ieee_block *bl; 129233965Sjdp 129333965Sjdp bl = info->blockstack.bsp; 129433965Sjdp do 129533965Sjdp { 129633965Sjdp --bl; 129733965Sjdp if (bl->kind == 5) 129833965Sjdp { 129933965Sjdp if (! debug_start_source (info->dhandle, bl->filename)) 1300130561Sobrien return FALSE; 130133965Sjdp break; 130233965Sjdp } 130333965Sjdp } 130433965Sjdp while (bl != info->blockstack.stack); 130533965Sjdp } 130633965Sjdp break; 130733965Sjdp 130833965Sjdp case 11: 130933965Sjdp if (! ieee_read_expression (info, pp, &offset)) 1310130561Sobrien return FALSE; 131133965Sjdp /* We just ignore the module size. FIXME. */ 131233965Sjdp break; 131333965Sjdp 131433965Sjdp default: 131533965Sjdp /* Other block types do not have any trailing information. */ 131633965Sjdp break; 131733965Sjdp } 131833965Sjdp 1319130561Sobrien return TRUE; 132033965Sjdp} 132133965Sjdp 132233965Sjdp/* Parse an NN record. */ 132333965Sjdp 1324130561Sobrienstatic bfd_boolean 1325130561Sobrienparse_ieee_nn (struct ieee_info *info, const bfd_byte **pp) 132633965Sjdp{ 132733965Sjdp const bfd_byte *nn_start; 132833965Sjdp bfd_vma varindx; 132933965Sjdp const char *name; 133033965Sjdp unsigned long namlen; 133133965Sjdp 133233965Sjdp nn_start = *pp; 133333965Sjdp 133433965Sjdp if (! ieee_read_number (info, pp, &varindx) 133533965Sjdp || ! ieee_read_id (info, pp, &name, &namlen)) 1336130561Sobrien return FALSE; 133733965Sjdp 133833965Sjdp if (varindx < 32) 133933965Sjdp { 134060484Sobrien ieee_error (info, nn_start, _("illegal variable index")); 1341130561Sobrien return FALSE; 134233965Sjdp } 134333965Sjdp varindx -= 32; 134433965Sjdp 134533965Sjdp if (varindx >= info->vars.alloc) 134633965Sjdp { 134733965Sjdp unsigned int alloc; 134833965Sjdp 134933965Sjdp alloc = info->vars.alloc; 135033965Sjdp if (alloc == 0) 135133965Sjdp alloc = 4; 135233965Sjdp while (varindx >= alloc) 135333965Sjdp alloc *= 2; 135433965Sjdp info->vars.vars = ((struct ieee_var *) 135533965Sjdp xrealloc (info->vars.vars, 135633965Sjdp alloc * sizeof *info->vars.vars)); 135733965Sjdp memset (info->vars.vars + info->vars.alloc, 0, 135833965Sjdp (alloc - info->vars.alloc) * sizeof *info->vars.vars); 135933965Sjdp info->vars.alloc = alloc; 136033965Sjdp } 136133965Sjdp 136233965Sjdp info->vars.vars[varindx].name = name; 136333965Sjdp info->vars.vars[varindx].namlen = namlen; 136433965Sjdp 1365130561Sobrien return TRUE; 136633965Sjdp} 136733965Sjdp 136833965Sjdp/* Parse a TY record. */ 136933965Sjdp 1370130561Sobrienstatic bfd_boolean 1371130561Sobrienparse_ieee_ty (struct ieee_info *info, const bfd_byte **pp) 137233965Sjdp{ 137333965Sjdp const bfd_byte *ty_start, *ty_var_start, *ty_code_start; 137433965Sjdp bfd_vma typeindx, varindx, tc; 1375130561Sobrien void *dhandle; 1376130561Sobrien bfd_boolean tag, typdef; 137733965Sjdp debug_type *arg_slots; 137833965Sjdp unsigned long type_bitsize; 137933965Sjdp debug_type type; 138033965Sjdp 138133965Sjdp ty_start = *pp; 138233965Sjdp 138333965Sjdp if (! ieee_read_number (info, pp, &typeindx)) 1384130561Sobrien return FALSE; 138533965Sjdp 138633965Sjdp if (typeindx < 256) 138733965Sjdp { 138860484Sobrien ieee_error (info, ty_start, _("illegal type index")); 1389130561Sobrien return FALSE; 139033965Sjdp } 139133965Sjdp 139233965Sjdp typeindx -= 256; 1393130561Sobrien if (! ieee_alloc_type (info, typeindx, FALSE)) 1394130561Sobrien return FALSE; 139533965Sjdp 139633965Sjdp if (**pp != 0xce) 139733965Sjdp { 139860484Sobrien ieee_error (info, *pp, _("unknown TY code")); 1399130561Sobrien return FALSE; 140033965Sjdp } 140133965Sjdp ++*pp; 140233965Sjdp 140333965Sjdp ty_var_start = *pp; 140433965Sjdp 140533965Sjdp if (! ieee_read_number (info, pp, &varindx)) 1406130561Sobrien return FALSE; 140733965Sjdp 140833965Sjdp if (varindx < 32) 140933965Sjdp { 141060484Sobrien ieee_error (info, ty_var_start, _("illegal variable index")); 1411130561Sobrien return FALSE; 141233965Sjdp } 141333965Sjdp varindx -= 32; 141433965Sjdp 141533965Sjdp if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL) 141633965Sjdp { 141760484Sobrien ieee_error (info, ty_var_start, _("undefined variable in TY")); 1418130561Sobrien return FALSE; 141933965Sjdp } 142033965Sjdp 142133965Sjdp ty_code_start = *pp; 142233965Sjdp 142333965Sjdp if (! ieee_read_number (info, pp, &tc)) 1424130561Sobrien return FALSE; 142533965Sjdp 142633965Sjdp dhandle = info->dhandle; 142733965Sjdp 1428130561Sobrien tag = FALSE; 1429130561Sobrien typdef = FALSE; 143033965Sjdp arg_slots = NULL; 143133965Sjdp type_bitsize = 0; 143233965Sjdp switch (tc) 143333965Sjdp { 143433965Sjdp default: 143560484Sobrien ieee_error (info, ty_code_start, _("unknown TY code")); 1436130561Sobrien return FALSE; 143733965Sjdp 143833965Sjdp case '!': 143933965Sjdp /* Unknown type, with size. We treat it as int. FIXME. */ 144033965Sjdp { 144133965Sjdp bfd_vma size; 144233965Sjdp 144333965Sjdp if (! ieee_read_number (info, pp, &size)) 1444130561Sobrien return FALSE; 1445130561Sobrien type = debug_make_int_type (dhandle, size, FALSE); 144633965Sjdp } 144733965Sjdp break; 144833965Sjdp 144933965Sjdp case 'A': /* Array. */ 145033965Sjdp case 'a': /* FORTRAN array in column/row order. FIXME: Not 145133965Sjdp distinguished from normal array. */ 145233965Sjdp { 145333965Sjdp debug_type ele_type; 145433965Sjdp bfd_vma lower, upper; 145533965Sjdp 145633965Sjdp if (! ieee_read_type_index (info, pp, &ele_type) 145733965Sjdp || ! ieee_read_number (info, pp, &lower) 145833965Sjdp || ! ieee_read_number (info, pp, &upper)) 1459130561Sobrien return FALSE; 146033965Sjdp type = debug_make_array_type (dhandle, ele_type, 146133965Sjdp ieee_builtin_type (info, ty_code_start, 146233965Sjdp ((unsigned int) 146333965Sjdp builtin_int)), 146433965Sjdp (bfd_signed_vma) lower, 146533965Sjdp (bfd_signed_vma) upper, 1466130561Sobrien FALSE); 146733965Sjdp } 146833965Sjdp break; 146933965Sjdp 147033965Sjdp case 'E': 147133965Sjdp /* Simple enumeration. */ 147233965Sjdp { 147333965Sjdp bfd_vma size; 147433965Sjdp unsigned int alloc; 147533965Sjdp const char **names; 147633965Sjdp unsigned int c; 147733965Sjdp bfd_signed_vma *vals; 147833965Sjdp unsigned int i; 147933965Sjdp 148033965Sjdp if (! ieee_read_number (info, pp, &size)) 1481130561Sobrien return FALSE; 148233965Sjdp /* FIXME: we ignore the enumeration size. */ 148333965Sjdp 148433965Sjdp alloc = 10; 148533965Sjdp names = (const char **) xmalloc (alloc * sizeof *names); 148633965Sjdp memset (names, 0, alloc * sizeof *names); 148733965Sjdp c = 0; 148833965Sjdp while (1) 148933965Sjdp { 149033965Sjdp const char *name; 149133965Sjdp unsigned long namlen; 1492130561Sobrien bfd_boolean present; 149333965Sjdp 149433965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 1495130561Sobrien return FALSE; 149633965Sjdp if (! present) 149733965Sjdp break; 149833965Sjdp 149933965Sjdp if (c + 1 >= alloc) 150033965Sjdp { 150133965Sjdp alloc += 10; 150233965Sjdp names = ((const char **) 150333965Sjdp xrealloc (names, alloc * sizeof *names)); 150433965Sjdp } 150533965Sjdp 150633965Sjdp names[c] = savestring (name, namlen); 150733965Sjdp if (names[c] == NULL) 1508130561Sobrien return FALSE; 150933965Sjdp ++c; 151033965Sjdp } 151133965Sjdp 151233965Sjdp names[c] = NULL; 151333965Sjdp 151433965Sjdp vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals); 151533965Sjdp for (i = 0; i < c; i++) 151633965Sjdp vals[i] = i; 151733965Sjdp 151833965Sjdp type = debug_make_enum_type (dhandle, names, vals); 1519130561Sobrien tag = TRUE; 152033965Sjdp } 152133965Sjdp break; 152233965Sjdp 152333965Sjdp case 'G': 152433965Sjdp /* Struct with bit fields. */ 152533965Sjdp { 152633965Sjdp bfd_vma size; 152733965Sjdp unsigned int alloc; 152833965Sjdp debug_field *fields; 152933965Sjdp unsigned int c; 153033965Sjdp 153133965Sjdp if (! ieee_read_number (info, pp, &size)) 1532130561Sobrien return FALSE; 153333965Sjdp 153433965Sjdp alloc = 10; 153533965Sjdp fields = (debug_field *) xmalloc (alloc * sizeof *fields); 153633965Sjdp c = 0; 153733965Sjdp while (1) 153833965Sjdp { 153933965Sjdp const char *name; 154033965Sjdp unsigned long namlen; 1541130561Sobrien bfd_boolean present; 154233965Sjdp debug_type ftype; 154333965Sjdp bfd_vma bitpos, bitsize; 154433965Sjdp 154533965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 1546130561Sobrien return FALSE; 154733965Sjdp if (! present) 154833965Sjdp break; 154933965Sjdp if (! ieee_read_type_index (info, pp, &ftype) 155033965Sjdp || ! ieee_read_number (info, pp, &bitpos) 155133965Sjdp || ! ieee_read_number (info, pp, &bitsize)) 1552130561Sobrien return FALSE; 155333965Sjdp 155433965Sjdp if (c + 1 >= alloc) 155533965Sjdp { 155633965Sjdp alloc += 10; 155733965Sjdp fields = ((debug_field *) 155833965Sjdp xrealloc (fields, alloc * sizeof *fields)); 155933965Sjdp } 156033965Sjdp 156133965Sjdp fields[c] = debug_make_field (dhandle, savestring (name, namlen), 156233965Sjdp ftype, bitpos, bitsize, 156333965Sjdp DEBUG_VISIBILITY_PUBLIC); 156433965Sjdp if (fields[c] == NULL) 1565130561Sobrien return FALSE; 156633965Sjdp ++c; 156733965Sjdp } 156833965Sjdp 156933965Sjdp fields[c] = NULL; 157033965Sjdp 1571130561Sobrien type = debug_make_struct_type (dhandle, TRUE, size, fields); 1572130561Sobrien tag = TRUE; 157333965Sjdp } 157433965Sjdp break; 157533965Sjdp 157633965Sjdp case 'N': 157733965Sjdp /* Enumeration. */ 157833965Sjdp { 157933965Sjdp unsigned int alloc; 158033965Sjdp const char **names; 158133965Sjdp bfd_signed_vma *vals; 158233965Sjdp unsigned int c; 158333965Sjdp 158433965Sjdp alloc = 10; 158533965Sjdp names = (const char **) xmalloc (alloc * sizeof *names); 158633965Sjdp vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names); 158733965Sjdp c = 0; 158833965Sjdp while (1) 158933965Sjdp { 159033965Sjdp const char *name; 159133965Sjdp unsigned long namlen; 1592130561Sobrien bfd_boolean present; 159333965Sjdp bfd_vma val; 159433965Sjdp 159533965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 1596130561Sobrien return FALSE; 159733965Sjdp if (! present) 159833965Sjdp break; 159933965Sjdp if (! ieee_read_number (info, pp, &val)) 1600130561Sobrien return FALSE; 160133965Sjdp 160233965Sjdp /* If the length of the name is zero, then the value is 160333965Sjdp actually the size of the enum. We ignore this 160433965Sjdp information. FIXME. */ 160533965Sjdp if (namlen == 0) 160633965Sjdp continue; 160733965Sjdp 160833965Sjdp if (c + 1 >= alloc) 160933965Sjdp { 161033965Sjdp alloc += 10; 161133965Sjdp names = ((const char **) 161233965Sjdp xrealloc (names, alloc * sizeof *names)); 161333965Sjdp vals = ((bfd_signed_vma *) 161433965Sjdp xrealloc (vals, alloc * sizeof *vals)); 161533965Sjdp } 161633965Sjdp 161733965Sjdp names[c] = savestring (name, namlen); 161833965Sjdp if (names[c] == NULL) 1619130561Sobrien return FALSE; 162033965Sjdp vals[c] = (bfd_signed_vma) val; 162133965Sjdp ++c; 162233965Sjdp } 162333965Sjdp 162433965Sjdp names[c] = NULL; 162533965Sjdp 162633965Sjdp type = debug_make_enum_type (dhandle, names, vals); 1627130561Sobrien tag = TRUE; 162833965Sjdp } 162933965Sjdp break; 163033965Sjdp 163133965Sjdp case 'O': /* Small pointer. We don't distinguish small and large 163233965Sjdp pointers. FIXME. */ 163333965Sjdp case 'P': /* Large pointer. */ 163433965Sjdp { 163533965Sjdp debug_type t; 163633965Sjdp 163733965Sjdp if (! ieee_read_type_index (info, pp, &t)) 1638130561Sobrien return FALSE; 163933965Sjdp type = debug_make_pointer_type (dhandle, t); 164033965Sjdp } 164133965Sjdp break; 164233965Sjdp 164333965Sjdp case 'R': 164433965Sjdp /* Range. */ 164533965Sjdp { 164633965Sjdp bfd_vma low, high, signedp, size; 164733965Sjdp 164833965Sjdp if (! ieee_read_number (info, pp, &low) 164933965Sjdp || ! ieee_read_number (info, pp, &high) 165033965Sjdp || ! ieee_read_number (info, pp, &signedp) 165133965Sjdp || ! ieee_read_number (info, pp, &size)) 1652130561Sobrien return FALSE; 165333965Sjdp 165433965Sjdp type = debug_make_range_type (dhandle, 165533965Sjdp debug_make_int_type (dhandle, size, 165633965Sjdp ! signedp), 165733965Sjdp (bfd_signed_vma) low, 165833965Sjdp (bfd_signed_vma) high); 165933965Sjdp } 166033965Sjdp break; 166133965Sjdp 166233965Sjdp case 'S': /* Struct. */ 166333965Sjdp case 'U': /* Union. */ 166433965Sjdp { 166533965Sjdp bfd_vma size; 166633965Sjdp unsigned int alloc; 166733965Sjdp debug_field *fields; 166833965Sjdp unsigned int c; 166933965Sjdp 167033965Sjdp if (! ieee_read_number (info, pp, &size)) 1671130561Sobrien return FALSE; 167233965Sjdp 167333965Sjdp alloc = 10; 167433965Sjdp fields = (debug_field *) xmalloc (alloc * sizeof *fields); 167533965Sjdp c = 0; 167633965Sjdp while (1) 167733965Sjdp { 167833965Sjdp const char *name; 167933965Sjdp unsigned long namlen; 1680130561Sobrien bfd_boolean present; 168133965Sjdp bfd_vma tindx; 168233965Sjdp bfd_vma offset; 168333965Sjdp debug_type ftype; 168433965Sjdp bfd_vma bitsize; 168533965Sjdp 168633965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 1687130561Sobrien return FALSE; 168833965Sjdp if (! present) 168933965Sjdp break; 169033965Sjdp if (! ieee_read_number (info, pp, &tindx) 169133965Sjdp || ! ieee_read_number (info, pp, &offset)) 1692130561Sobrien return FALSE; 169333965Sjdp 169433965Sjdp if (tindx < 256) 169533965Sjdp { 169633965Sjdp ftype = ieee_builtin_type (info, ty_code_start, tindx); 169733965Sjdp bitsize = 0; 169833965Sjdp offset *= 8; 169933965Sjdp } 170033965Sjdp else 170133965Sjdp { 170233965Sjdp struct ieee_type *t; 170333965Sjdp 170433965Sjdp tindx -= 256; 1705130561Sobrien if (! ieee_alloc_type (info, tindx, TRUE)) 1706130561Sobrien return FALSE; 170733965Sjdp t = info->types.types + tindx; 170833965Sjdp ftype = t->type; 170933965Sjdp bitsize = t->bitsize; 171033965Sjdp if (bitsize == 0) 171133965Sjdp offset *= 8; 171233965Sjdp } 171333965Sjdp 171433965Sjdp if (c + 1 >= alloc) 171533965Sjdp { 171633965Sjdp alloc += 10; 171733965Sjdp fields = ((debug_field *) 171833965Sjdp xrealloc (fields, alloc * sizeof *fields)); 171933965Sjdp } 172033965Sjdp 172133965Sjdp fields[c] = debug_make_field (dhandle, savestring (name, namlen), 172233965Sjdp ftype, offset, bitsize, 172333965Sjdp DEBUG_VISIBILITY_PUBLIC); 172433965Sjdp if (fields[c] == NULL) 1725130561Sobrien return FALSE; 172633965Sjdp ++c; 172733965Sjdp } 172833965Sjdp 172933965Sjdp fields[c] = NULL; 173033965Sjdp 173133965Sjdp type = debug_make_struct_type (dhandle, tc == 'S', size, fields); 1732130561Sobrien tag = TRUE; 173333965Sjdp } 173433965Sjdp break; 173533965Sjdp 173633965Sjdp case 'T': 173733965Sjdp /* Typedef. */ 173833965Sjdp if (! ieee_read_type_index (info, pp, &type)) 1739130561Sobrien return FALSE; 1740130561Sobrien typdef = TRUE; 174133965Sjdp break; 174233965Sjdp 174333965Sjdp case 'X': 174433965Sjdp /* Procedure. FIXME: This is an extern declaration, which we 174533965Sjdp have no way of representing. */ 174633965Sjdp { 174733965Sjdp bfd_vma attr; 174833965Sjdp debug_type rtype; 174933965Sjdp bfd_vma nargs; 1750130561Sobrien bfd_boolean present; 175133965Sjdp struct ieee_var *pv; 175233965Sjdp 175333965Sjdp /* FIXME: We ignore the attribute and the argument names. */ 175433965Sjdp 175533965Sjdp if (! ieee_read_number (info, pp, &attr) 175633965Sjdp || ! ieee_read_type_index (info, pp, &rtype) 175733965Sjdp || ! ieee_read_number (info, pp, &nargs)) 1758130561Sobrien return FALSE; 175933965Sjdp do 176033965Sjdp { 176133965Sjdp const char *name; 176233965Sjdp unsigned long namlen; 176333965Sjdp 176433965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 1765130561Sobrien return FALSE; 176633965Sjdp } 176733965Sjdp while (present); 176833965Sjdp 176933965Sjdp pv = info->vars.vars + varindx; 177033965Sjdp pv->kind = IEEE_EXTERNAL; 177133965Sjdp if (pv->namlen > 0 177233965Sjdp && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) 177333965Sjdp { 177433965Sjdp /* Set up the return type as an indirect type pointing to 177533965Sjdp the variable slot, so that we can change it to a 177633965Sjdp reference later if appropriate. */ 177733965Sjdp pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); 177833965Sjdp *pv->pslot = rtype; 177933965Sjdp rtype = debug_make_indirect_type (dhandle, pv->pslot, 178033965Sjdp (const char *) NULL); 178133965Sjdp } 178233965Sjdp 178333965Sjdp type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL, 1784130561Sobrien FALSE); 178533965Sjdp } 178633965Sjdp break; 178733965Sjdp 178833965Sjdp case 'V': 178933965Sjdp /* Void. This is not documented, but the MRI compiler emits it. */ 179033965Sjdp type = debug_make_void_type (dhandle); 179133965Sjdp break; 179233965Sjdp 179333965Sjdp case 'Z': 179433965Sjdp /* Array with 0 lower bound. */ 179533965Sjdp { 179633965Sjdp debug_type etype; 179733965Sjdp bfd_vma high; 179833965Sjdp 179933965Sjdp if (! ieee_read_type_index (info, pp, &etype) 180033965Sjdp || ! ieee_read_number (info, pp, &high)) 1801130561Sobrien return FALSE; 180233965Sjdp 180333965Sjdp type = debug_make_array_type (dhandle, etype, 180433965Sjdp ieee_builtin_type (info, ty_code_start, 180533965Sjdp ((unsigned int) 180633965Sjdp builtin_int)), 1807130561Sobrien 0, (bfd_signed_vma) high, FALSE); 180833965Sjdp } 180933965Sjdp break; 181033965Sjdp 181133965Sjdp case 'c': /* Complex. */ 181233965Sjdp case 'd': /* Double complex. */ 181333965Sjdp { 181433965Sjdp const char *name; 181533965Sjdp unsigned long namlen; 181633965Sjdp 181733965Sjdp /* FIXME: I don't know what the name means. */ 181833965Sjdp 181933965Sjdp if (! ieee_read_id (info, pp, &name, &namlen)) 1820130561Sobrien return FALSE; 182133965Sjdp 182233965Sjdp type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8); 182333965Sjdp } 182433965Sjdp break; 182533965Sjdp 182633965Sjdp case 'f': 182733965Sjdp /* Pascal file name. FIXME. */ 182860484Sobrien ieee_error (info, ty_code_start, _("Pascal file name not supported")); 1829130561Sobrien return FALSE; 183033965Sjdp 183133965Sjdp case 'g': 183233965Sjdp /* Bitfield type. */ 183333965Sjdp { 183433965Sjdp bfd_vma signedp, bitsize, dummy; 183533965Sjdp const bfd_byte *hold; 1836130561Sobrien bfd_boolean present; 183733965Sjdp 183833965Sjdp if (! ieee_read_number (info, pp, &signedp) 183933965Sjdp || ! ieee_read_number (info, pp, &bitsize)) 1840130561Sobrien return FALSE; 184133965Sjdp 184233965Sjdp /* I think the documentation says that there is a type index, 184333965Sjdp but some actual files do not have one. */ 184433965Sjdp hold = *pp; 184533965Sjdp if (! ieee_read_optional_number (info, pp, &dummy, &present)) 1846130561Sobrien return FALSE; 184733965Sjdp if (! present) 184833965Sjdp { 184933965Sjdp /* FIXME: This is just a guess. */ 185033965Sjdp type = debug_make_int_type (dhandle, 4, 1851130561Sobrien signedp ? FALSE : TRUE); 185233965Sjdp } 185333965Sjdp else 185433965Sjdp { 185533965Sjdp *pp = hold; 185633965Sjdp if (! ieee_read_type_index (info, pp, &type)) 1857130561Sobrien return FALSE; 185833965Sjdp } 185933965Sjdp type_bitsize = bitsize; 186033965Sjdp } 186133965Sjdp break; 186233965Sjdp 186333965Sjdp case 'n': 186433965Sjdp /* Qualifier. */ 186533965Sjdp { 186633965Sjdp bfd_vma kind; 186733965Sjdp debug_type t; 186833965Sjdp 186933965Sjdp if (! ieee_read_number (info, pp, &kind) 187033965Sjdp || ! ieee_read_type_index (info, pp, &t)) 1871130561Sobrien return FALSE; 187233965Sjdp 187333965Sjdp switch (kind) 187433965Sjdp { 187533965Sjdp default: 1876104834Sobrien ieee_error (info, ty_start, _("unsupported qualifier")); 1877130561Sobrien return FALSE; 187833965Sjdp 187933965Sjdp case 1: 188033965Sjdp type = debug_make_const_type (dhandle, t); 188133965Sjdp break; 188233965Sjdp 188333965Sjdp case 2: 188433965Sjdp type = debug_make_volatile_type (dhandle, t); 188533965Sjdp break; 188633965Sjdp } 188733965Sjdp } 188833965Sjdp break; 188933965Sjdp 189033965Sjdp case 's': 189133965Sjdp /* Set. */ 189233965Sjdp { 189333965Sjdp bfd_vma size; 189433965Sjdp debug_type etype; 189533965Sjdp 189633965Sjdp if (! ieee_read_number (info, pp, &size) 189733965Sjdp || ! ieee_read_type_index (info, pp, &etype)) 1898130561Sobrien return FALSE; 189933965Sjdp 190033965Sjdp /* FIXME: We ignore the size. */ 190133965Sjdp 1902130561Sobrien type = debug_make_set_type (dhandle, etype, FALSE); 190333965Sjdp } 190433965Sjdp break; 190533965Sjdp 190633965Sjdp case 'x': 190733965Sjdp /* Procedure with compiler dependencies. */ 190833965Sjdp { 190933965Sjdp struct ieee_var *pv; 191033965Sjdp bfd_vma attr, frame_type, push_mask, nargs, level, father; 191133965Sjdp debug_type rtype; 191233965Sjdp debug_type *arg_types; 1913130561Sobrien bfd_boolean varargs; 1914130561Sobrien bfd_boolean present; 191533965Sjdp 191633965Sjdp /* FIXME: We ignore some of this information. */ 191733965Sjdp 191833965Sjdp pv = info->vars.vars + varindx; 191933965Sjdp 192033965Sjdp if (! ieee_read_number (info, pp, &attr) 192133965Sjdp || ! ieee_read_number (info, pp, &frame_type) 192233965Sjdp || ! ieee_read_number (info, pp, &push_mask) 192333965Sjdp || ! ieee_read_type_index (info, pp, &rtype) 192433965Sjdp || ! ieee_read_number (info, pp, &nargs)) 1925130561Sobrien return FALSE; 192633965Sjdp if (nargs == (bfd_vma) -1) 192733965Sjdp { 192833965Sjdp arg_types = NULL; 1929130561Sobrien varargs = FALSE; 193033965Sjdp } 193133965Sjdp else 193233965Sjdp { 193333965Sjdp unsigned int i; 193433965Sjdp 193533965Sjdp arg_types = ((debug_type *) 193633965Sjdp xmalloc ((nargs + 1) * sizeof *arg_types)); 193733965Sjdp for (i = 0; i < nargs; i++) 193833965Sjdp if (! ieee_read_type_index (info, pp, arg_types + i)) 1939130561Sobrien return FALSE; 194033965Sjdp 194133965Sjdp /* If the last type is pointer to void, this is really a 194233965Sjdp varargs function. */ 1943130561Sobrien varargs = FALSE; 194433965Sjdp if (nargs > 0) 194533965Sjdp { 194633965Sjdp debug_type last; 194733965Sjdp 194833965Sjdp last = arg_types[nargs - 1]; 194933965Sjdp if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER 195033965Sjdp && (debug_get_type_kind (dhandle, 195133965Sjdp debug_get_target_type (dhandle, 195233965Sjdp last)) 195333965Sjdp == DEBUG_KIND_VOID)) 195433965Sjdp { 195533965Sjdp --nargs; 1956130561Sobrien varargs = TRUE; 195733965Sjdp } 195833965Sjdp } 195933965Sjdp 196033965Sjdp /* If there are any pointer arguments, turn them into 196133965Sjdp indirect types in case we later need to convert them to 196233965Sjdp reference types. */ 196333965Sjdp for (i = 0; i < nargs; i++) 196433965Sjdp { 196533965Sjdp if (debug_get_type_kind (dhandle, arg_types[i]) 196633965Sjdp == DEBUG_KIND_POINTER) 196733965Sjdp { 196833965Sjdp if (arg_slots == NULL) 196933965Sjdp { 197033965Sjdp arg_slots = ((debug_type *) 197133965Sjdp xmalloc (nargs * sizeof *arg_slots)); 197233965Sjdp memset (arg_slots, 0, nargs * sizeof *arg_slots); 197333965Sjdp } 197433965Sjdp arg_slots[i] = arg_types[i]; 197533965Sjdp arg_types[i] = 197633965Sjdp debug_make_indirect_type (dhandle, 197733965Sjdp arg_slots + i, 197833965Sjdp (const char *) NULL); 197933965Sjdp } 198033965Sjdp } 198133965Sjdp 198233965Sjdp arg_types[nargs] = DEBUG_TYPE_NULL; 198333965Sjdp } 198433965Sjdp if (! ieee_read_number (info, pp, &level) 198533965Sjdp || ! ieee_read_optional_number (info, pp, &father, &present)) 1986130561Sobrien return FALSE; 198733965Sjdp 198833965Sjdp /* We can't distinguish between a global function and a static 198933965Sjdp function. */ 199033965Sjdp pv->kind = IEEE_FUNCTION; 199133965Sjdp 199233965Sjdp if (pv->namlen > 0 199333965Sjdp && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) 199433965Sjdp { 199533965Sjdp /* Set up the return type as an indirect type pointing to 199633965Sjdp the variable slot, so that we can change it to a 199733965Sjdp reference later if appropriate. */ 199833965Sjdp pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); 199933965Sjdp *pv->pslot = rtype; 200033965Sjdp rtype = debug_make_indirect_type (dhandle, pv->pslot, 200133965Sjdp (const char *) NULL); 200233965Sjdp } 200333965Sjdp 200433965Sjdp type = debug_make_function_type (dhandle, rtype, arg_types, varargs); 200533965Sjdp } 200633965Sjdp break; 200733965Sjdp } 200833965Sjdp 200933965Sjdp /* Record the type in the table. */ 201033965Sjdp 201133965Sjdp if (type == DEBUG_TYPE_NULL) 2012130561Sobrien return FALSE; 201333965Sjdp 201433965Sjdp info->vars.vars[varindx].type = type; 201533965Sjdp 201633965Sjdp if ((tag || typdef) 201733965Sjdp && info->vars.vars[varindx].namlen > 0) 201833965Sjdp { 201933965Sjdp const char *name; 202033965Sjdp 202133965Sjdp name = savestring (info->vars.vars[varindx].name, 202233965Sjdp info->vars.vars[varindx].namlen); 202333965Sjdp if (typdef) 202433965Sjdp type = debug_name_type (dhandle, name, type); 202533965Sjdp else if (tc == 'E' || tc == 'N') 202633965Sjdp type = debug_tag_type (dhandle, name, type); 202733965Sjdp else 202833965Sjdp { 202933965Sjdp struct ieee_tag *it; 203033965Sjdp 203133965Sjdp /* We must allocate all struct tags as indirect types, so 203233965Sjdp that if we later see a definition of the tag as a C++ 203333965Sjdp record we can update the indirect slot and automatically 203433965Sjdp change all the existing references. */ 203533965Sjdp it = (struct ieee_tag *) xmalloc (sizeof *it); 203633965Sjdp memset (it, 0, sizeof *it); 203733965Sjdp it->next = info->tags; 203833965Sjdp info->tags = it; 203933965Sjdp it->name = name; 204033965Sjdp it->slot = type; 204133965Sjdp 204233965Sjdp type = debug_make_indirect_type (dhandle, &it->slot, name); 204333965Sjdp type = debug_tag_type (dhandle, name, type); 204433965Sjdp 204533965Sjdp it->type = type; 204633965Sjdp } 204733965Sjdp if (type == NULL) 2048130561Sobrien return FALSE; 204933965Sjdp } 205033965Sjdp 205133965Sjdp info->types.types[typeindx].type = type; 205233965Sjdp info->types.types[typeindx].arg_slots = arg_slots; 205333965Sjdp info->types.types[typeindx].bitsize = type_bitsize; 205433965Sjdp 205533965Sjdp /* We may have already allocated type as an indirect type pointing 205633965Sjdp to slot. It does no harm to replace the indirect type with the 205733965Sjdp real type. Filling in slot as well handles the indirect types 205833965Sjdp which are already hanging around. */ 205933965Sjdp if (info->types.types[typeindx].pslot != NULL) 206033965Sjdp *info->types.types[typeindx].pslot = type; 206133965Sjdp 2062130561Sobrien return TRUE; 206333965Sjdp} 206433965Sjdp 206533965Sjdp/* Parse an ATN record. */ 206633965Sjdp 2067130561Sobrienstatic bfd_boolean 2068130561Sobrienparse_ieee_atn (struct ieee_info *info, const bfd_byte **pp) 206933965Sjdp{ 207033965Sjdp const bfd_byte *atn_start, *atn_code_start; 207133965Sjdp bfd_vma varindx; 207233965Sjdp struct ieee_var *pvar; 207333965Sjdp debug_type type; 207433965Sjdp bfd_vma atn_code; 2075130561Sobrien void *dhandle; 207633965Sjdp bfd_vma v, v2, v3, v4, v5; 207733965Sjdp const char *name; 207833965Sjdp unsigned long namlen; 207933965Sjdp char *namcopy; 2080130561Sobrien bfd_boolean present; 208133965Sjdp int blocktype; 208233965Sjdp 208333965Sjdp atn_start = *pp; 208433965Sjdp 208533965Sjdp if (! ieee_read_number (info, pp, &varindx) 208633965Sjdp || ! ieee_read_type_index (info, pp, &type)) 2087130561Sobrien return FALSE; 208833965Sjdp 208933965Sjdp atn_code_start = *pp; 209033965Sjdp 209133965Sjdp if (! ieee_read_number (info, pp, &atn_code)) 2092130561Sobrien return FALSE; 209333965Sjdp 209433965Sjdp if (varindx == 0) 209533965Sjdp { 209633965Sjdp pvar = NULL; 209733965Sjdp name = ""; 209833965Sjdp namlen = 0; 209933965Sjdp } 210033965Sjdp else if (varindx < 32) 210133965Sjdp { 210260484Sobrien /* The MRI compiler reportedly sometimes emits variable lifetime 210360484Sobrien information for a register. We just ignore it. */ 210460484Sobrien if (atn_code == 9) 210560484Sobrien return ieee_read_number (info, pp, &v); 210660484Sobrien 210760484Sobrien ieee_error (info, atn_start, _("illegal variable index")); 2108130561Sobrien return FALSE; 210933965Sjdp } 211033965Sjdp else 211133965Sjdp { 211233965Sjdp varindx -= 32; 211333965Sjdp if (varindx >= info->vars.alloc 211433965Sjdp || info->vars.vars[varindx].name == NULL) 211533965Sjdp { 211633965Sjdp /* The MRI compiler or linker sometimes omits the NN record 211733965Sjdp for a pmisc record. */ 211833965Sjdp if (atn_code == 62) 211933965Sjdp { 212033965Sjdp if (varindx >= info->vars.alloc) 212133965Sjdp { 212233965Sjdp unsigned int alloc; 212333965Sjdp 212433965Sjdp alloc = info->vars.alloc; 212533965Sjdp if (alloc == 0) 212633965Sjdp alloc = 4; 212733965Sjdp while (varindx >= alloc) 212833965Sjdp alloc *= 2; 212933965Sjdp info->vars.vars = ((struct ieee_var *) 213033965Sjdp xrealloc (info->vars.vars, 213133965Sjdp (alloc 213233965Sjdp * sizeof *info->vars.vars))); 213333965Sjdp memset (info->vars.vars + info->vars.alloc, 0, 213433965Sjdp ((alloc - info->vars.alloc) 213533965Sjdp * sizeof *info->vars.vars)); 213633965Sjdp info->vars.alloc = alloc; 213733965Sjdp } 213833965Sjdp 213933965Sjdp pvar = info->vars.vars + varindx; 214033965Sjdp pvar->name = ""; 214133965Sjdp pvar->namlen = 0; 214233965Sjdp } 214333965Sjdp else 214433965Sjdp { 214560484Sobrien ieee_error (info, atn_start, _("undefined variable in ATN")); 2146130561Sobrien return FALSE; 214733965Sjdp } 214833965Sjdp } 214933965Sjdp 215033965Sjdp pvar = info->vars.vars + varindx; 215133965Sjdp 215233965Sjdp pvar->type = type; 215333965Sjdp 215433965Sjdp name = pvar->name; 215533965Sjdp namlen = pvar->namlen; 215633965Sjdp } 215733965Sjdp 215833965Sjdp dhandle = info->dhandle; 215933965Sjdp 216033965Sjdp /* If we are going to call debug_record_variable with a pointer 216133965Sjdp type, change the type to an indirect type so that we can later 216233965Sjdp change it to a reference type if we encounter a C++ pmisc 'R' 216333965Sjdp record. */ 216433965Sjdp if (pvar != NULL 216533965Sjdp && type != DEBUG_TYPE_NULL 216633965Sjdp && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER) 216733965Sjdp { 216833965Sjdp switch (atn_code) 216933965Sjdp { 217033965Sjdp case 1: 217133965Sjdp case 2: 217233965Sjdp case 3: 217333965Sjdp case 5: 217433965Sjdp case 8: 217533965Sjdp case 10: 217633965Sjdp pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot); 217733965Sjdp *pvar->pslot = type; 217833965Sjdp type = debug_make_indirect_type (dhandle, pvar->pslot, 217933965Sjdp (const char *) NULL); 218033965Sjdp pvar->type = type; 218133965Sjdp break; 218233965Sjdp } 218333965Sjdp } 218433965Sjdp 218533965Sjdp switch (atn_code) 218633965Sjdp { 218733965Sjdp default: 218860484Sobrien ieee_error (info, atn_code_start, _("unknown ATN type")); 2189130561Sobrien return FALSE; 219033965Sjdp 219133965Sjdp case 1: 219233965Sjdp /* Automatic variable. */ 219333965Sjdp if (! ieee_read_number (info, pp, &v)) 2194130561Sobrien return FALSE; 219533965Sjdp namcopy = savestring (name, namlen); 219633965Sjdp if (type == NULL) 219733965Sjdp type = debug_make_void_type (dhandle); 219833965Sjdp if (pvar != NULL) 219933965Sjdp pvar->kind = IEEE_LOCAL; 220033965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v); 220133965Sjdp 220233965Sjdp case 2: 220333965Sjdp /* Register variable. */ 220433965Sjdp if (! ieee_read_number (info, pp, &v)) 2205130561Sobrien return FALSE; 220633965Sjdp namcopy = savestring (name, namlen); 220733965Sjdp if (type == NULL) 220833965Sjdp type = debug_make_void_type (dhandle); 220933965Sjdp if (pvar != NULL) 221033965Sjdp pvar->kind = IEEE_LOCAL; 221133965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, 221233965Sjdp ieee_regno_to_genreg (info->abfd, v)); 221333965Sjdp 221433965Sjdp case 3: 221533965Sjdp /* Static variable. */ 221633965Sjdp if (! ieee_require_asn (info, pp, &v)) 2217130561Sobrien return FALSE; 221833965Sjdp namcopy = savestring (name, namlen); 221933965Sjdp if (type == NULL) 222033965Sjdp type = debug_make_void_type (dhandle); 222133965Sjdp if (info->blockstack.bsp <= info->blockstack.stack) 222233965Sjdp blocktype = 0; 222333965Sjdp else 222433965Sjdp blocktype = info->blockstack.bsp[-1].kind; 222533965Sjdp if (pvar != NULL) 222633965Sjdp { 222733965Sjdp if (blocktype == 4 || blocktype == 6) 222833965Sjdp pvar->kind = IEEE_LOCAL; 222933965Sjdp else 223033965Sjdp pvar->kind = IEEE_STATIC; 223133965Sjdp } 223233965Sjdp return debug_record_variable (dhandle, namcopy, type, 223333965Sjdp (blocktype == 4 || blocktype == 6 223433965Sjdp ? DEBUG_LOCAL_STATIC 223533965Sjdp : DEBUG_STATIC), 223633965Sjdp v); 223733965Sjdp 223833965Sjdp case 4: 223933965Sjdp /* External function. We don't currently record these. FIXME. */ 224033965Sjdp if (pvar != NULL) 224133965Sjdp pvar->kind = IEEE_EXTERNAL; 2242130561Sobrien return TRUE; 224333965Sjdp 224433965Sjdp case 5: 224533965Sjdp /* External variable. We don't currently record these. FIXME. */ 224633965Sjdp if (pvar != NULL) 224733965Sjdp pvar->kind = IEEE_EXTERNAL; 2248130561Sobrien return TRUE; 224933965Sjdp 225033965Sjdp case 7: 225133965Sjdp if (! ieee_read_number (info, pp, &v) 225233965Sjdp || ! ieee_read_number (info, pp, &v2) 225333965Sjdp || ! ieee_read_optional_number (info, pp, &v3, &present)) 2254130561Sobrien return FALSE; 225533965Sjdp if (present) 225633965Sjdp { 225733965Sjdp if (! ieee_read_optional_number (info, pp, &v4, &present)) 2258130561Sobrien return FALSE; 225933965Sjdp } 226033965Sjdp 226133965Sjdp /* We just ignore the two optional fields in v3 and v4, since 226233965Sjdp they are not defined. */ 226333965Sjdp 226433965Sjdp if (! ieee_require_asn (info, pp, &v3)) 2265130561Sobrien return FALSE; 226633965Sjdp 226733965Sjdp /* We have no way to record the column number. FIXME. */ 226833965Sjdp 226933965Sjdp return debug_record_line (dhandle, v, v3); 227033965Sjdp 227133965Sjdp case 8: 227233965Sjdp /* Global variable. */ 227333965Sjdp if (! ieee_require_asn (info, pp, &v)) 2274130561Sobrien return FALSE; 227533965Sjdp namcopy = savestring (name, namlen); 227633965Sjdp if (type == NULL) 227733965Sjdp type = debug_make_void_type (dhandle); 227833965Sjdp if (pvar != NULL) 227933965Sjdp pvar->kind = IEEE_GLOBAL; 228033965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v); 228133965Sjdp 228233965Sjdp case 9: 228333965Sjdp /* Variable lifetime information. */ 228433965Sjdp if (! ieee_read_number (info, pp, &v)) 2285130561Sobrien return FALSE; 228633965Sjdp 228733965Sjdp /* We have no way to record this information. FIXME. */ 2288130561Sobrien return TRUE; 228933965Sjdp 229033965Sjdp case 10: 229133965Sjdp /* Locked register. The spec says that there are two required 229233965Sjdp fields, but at least on occasion the MRI compiler only emits 229333965Sjdp one. */ 229433965Sjdp if (! ieee_read_number (info, pp, &v) 229533965Sjdp || ! ieee_read_optional_number (info, pp, &v2, &present)) 2296130561Sobrien return FALSE; 229733965Sjdp 229833965Sjdp /* I think this means a variable that is both in a register and 229933965Sjdp a frame slot. We ignore the frame slot. FIXME. */ 230033965Sjdp 230133965Sjdp namcopy = savestring (name, namlen); 230233965Sjdp if (type == NULL) 230333965Sjdp type = debug_make_void_type (dhandle); 230433965Sjdp if (pvar != NULL) 230533965Sjdp pvar->kind = IEEE_LOCAL; 230633965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v); 230733965Sjdp 230833965Sjdp case 11: 230933965Sjdp /* Reserved for FORTRAN common. */ 231060484Sobrien ieee_error (info, atn_code_start, _("unsupported ATN11")); 231133965Sjdp 2312130561Sobrien /* Return TRUE to keep going. */ 2313130561Sobrien return TRUE; 231433965Sjdp 231533965Sjdp case 12: 231633965Sjdp /* Based variable. */ 231733965Sjdp v3 = 0; 231833965Sjdp v4 = 0x80; 231933965Sjdp v5 = 0; 232033965Sjdp if (! ieee_read_number (info, pp, &v) 232133965Sjdp || ! ieee_read_number (info, pp, &v2) 232233965Sjdp || ! ieee_read_optional_number (info, pp, &v3, &present)) 2323130561Sobrien return FALSE; 232433965Sjdp if (present) 232533965Sjdp { 232633965Sjdp if (! ieee_read_optional_number (info, pp, &v4, &present)) 2327130561Sobrien return FALSE; 232833965Sjdp if (present) 232933965Sjdp { 233033965Sjdp if (! ieee_read_optional_number (info, pp, &v5, &present)) 2331130561Sobrien return FALSE; 233233965Sjdp } 233333965Sjdp } 233433965Sjdp 233533965Sjdp /* We have no way to record this information. FIXME. */ 233633965Sjdp 233760484Sobrien ieee_error (info, atn_code_start, _("unsupported ATN12")); 233833965Sjdp 2339130561Sobrien /* Return TRUE to keep going. */ 2340130561Sobrien return TRUE; 234133965Sjdp 234233965Sjdp case 16: 234333965Sjdp /* Constant. The description of this that I have is ambiguous, 234433965Sjdp so I'm not going to try to implement it. */ 234533965Sjdp if (! ieee_read_number (info, pp, &v) 234633965Sjdp || ! ieee_read_optional_number (info, pp, &v2, &present)) 2347130561Sobrien return FALSE; 234833965Sjdp if (present) 234933965Sjdp { 235033965Sjdp if (! ieee_read_optional_number (info, pp, &v2, &present)) 2351130561Sobrien return FALSE; 235233965Sjdp if (present) 235333965Sjdp { 235433965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 2355130561Sobrien return FALSE; 235633965Sjdp } 235733965Sjdp } 235833965Sjdp 235933965Sjdp if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum) 236033965Sjdp { 236133965Sjdp if (! ieee_require_asn (info, pp, &v3)) 2362130561Sobrien return FALSE; 236333965Sjdp } 236433965Sjdp 2365130561Sobrien return TRUE; 236633965Sjdp 236733965Sjdp case 19: 236833965Sjdp /* Static variable from assembler. */ 236933965Sjdp v2 = 0; 237033965Sjdp if (! ieee_read_number (info, pp, &v) 237133965Sjdp || ! ieee_read_optional_number (info, pp, &v2, &present) 237233965Sjdp || ! ieee_require_asn (info, pp, &v3)) 2373130561Sobrien return FALSE; 237433965Sjdp namcopy = savestring (name, namlen); 237533965Sjdp /* We don't really handle this correctly. FIXME. */ 237633965Sjdp return debug_record_variable (dhandle, namcopy, 237733965Sjdp debug_make_void_type (dhandle), 237833965Sjdp v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC, 237933965Sjdp v3); 238033965Sjdp 238133965Sjdp case 62: 238233965Sjdp /* Procedure miscellaneous information. */ 238333965Sjdp case 63: 238433965Sjdp /* Variable miscellaneous information. */ 238533965Sjdp case 64: 238633965Sjdp /* Module miscellaneous information. */ 238733965Sjdp if (! ieee_read_number (info, pp, &v) 238833965Sjdp || ! ieee_read_number (info, pp, &v2) 238933965Sjdp || ! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 2390130561Sobrien return FALSE; 239133965Sjdp 239233965Sjdp if (atn_code == 62 && v == 80) 239333965Sjdp { 239433965Sjdp if (present) 239533965Sjdp { 239633965Sjdp ieee_error (info, atn_code_start, 239760484Sobrien _("unexpected string in C++ misc")); 2398130561Sobrien return FALSE; 239933965Sjdp } 240033965Sjdp return ieee_read_cxx_misc (info, pp, v2); 240133965Sjdp } 240233965Sjdp 240333965Sjdp /* We just ignore all of this stuff. FIXME. */ 240433965Sjdp 240533965Sjdp for (; v2 > 0; --v2) 240633965Sjdp { 240733965Sjdp switch ((ieee_record_enum_type) **pp) 240833965Sjdp { 240933965Sjdp default: 241060484Sobrien ieee_error (info, *pp, _("bad misc record")); 2411130561Sobrien return FALSE; 241233965Sjdp 241333965Sjdp case ieee_at_record_enum: 241433965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen)) 2415130561Sobrien return FALSE; 241633965Sjdp break; 241733965Sjdp 241833965Sjdp case ieee_e2_first_byte_enum: 241933965Sjdp if (! ieee_require_asn (info, pp, &v3)) 2420130561Sobrien return FALSE; 242133965Sjdp break; 242233965Sjdp } 242333965Sjdp } 242433965Sjdp 2425130561Sobrien return TRUE; 242633965Sjdp } 242733965Sjdp 242833965Sjdp /*NOTREACHED*/ 242933965Sjdp} 243033965Sjdp 243133965Sjdp/* Handle C++ debugging miscellaneous records. This is called for 243233965Sjdp procedure miscellaneous records of type 80. */ 243333965Sjdp 2434130561Sobrienstatic bfd_boolean 2435130561Sobrienieee_read_cxx_misc (struct ieee_info *info, const bfd_byte **pp, 2436130561Sobrien unsigned long count) 243733965Sjdp{ 243833965Sjdp const bfd_byte *start; 243933965Sjdp bfd_vma category; 244033965Sjdp 244133965Sjdp start = *pp; 244233965Sjdp 244333965Sjdp /* Get the category of C++ misc record. */ 244433965Sjdp if (! ieee_require_asn (info, pp, &category)) 2445130561Sobrien return FALSE; 244633965Sjdp --count; 244733965Sjdp 244833965Sjdp switch (category) 244933965Sjdp { 245033965Sjdp default: 245160484Sobrien ieee_error (info, start, _("unrecognized C++ misc record")); 2452130561Sobrien return FALSE; 245333965Sjdp 245433965Sjdp case 'T': 245533965Sjdp if (! ieee_read_cxx_class (info, pp, count)) 2456130561Sobrien return FALSE; 245733965Sjdp break; 245833965Sjdp 245933965Sjdp case 'M': 246033965Sjdp { 246133965Sjdp bfd_vma flags; 246233965Sjdp const char *name; 246333965Sjdp unsigned long namlen; 246433965Sjdp 246533965Sjdp /* The IEEE spec indicates that the 'M' record only has a 246633965Sjdp flags field. The MRI compiler also emits the name of the 246733965Sjdp function. */ 246833965Sjdp 246933965Sjdp if (! ieee_require_asn (info, pp, &flags)) 2470130561Sobrien return FALSE; 247133965Sjdp if (*pp < info->pend 247233965Sjdp && (ieee_record_enum_type) **pp == ieee_at_record_enum) 247333965Sjdp { 247433965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen)) 2475130561Sobrien return FALSE; 247633965Sjdp } 247733965Sjdp 247833965Sjdp /* This is emitted for method functions, but I don't think we 247933965Sjdp care very much. It might help if it told us useful 248033965Sjdp information like the class with which this function is 248133965Sjdp associated, but it doesn't, so it isn't helpful. */ 248233965Sjdp } 248333965Sjdp break; 248433965Sjdp 248533965Sjdp case 'B': 248633965Sjdp if (! ieee_read_cxx_defaults (info, pp, count)) 2487130561Sobrien return FALSE; 248833965Sjdp break; 248933965Sjdp 249033965Sjdp case 'z': 249133965Sjdp { 249233965Sjdp const char *name, *mangled, *class; 249333965Sjdp unsigned long namlen, mangledlen, classlen; 249433965Sjdp bfd_vma control; 249533965Sjdp 249633965Sjdp /* Pointer to member. */ 249733965Sjdp 249833965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen) 249933965Sjdp || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen) 250033965Sjdp || ! ieee_require_atn65 (info, pp, &class, &classlen) 250133965Sjdp || ! ieee_require_asn (info, pp, &control)) 2502130561Sobrien return FALSE; 250333965Sjdp 250433965Sjdp /* FIXME: We should now track down name and change its type. */ 250533965Sjdp } 250633965Sjdp break; 250733965Sjdp 250833965Sjdp case 'R': 250933965Sjdp if (! ieee_read_reference (info, pp)) 2510130561Sobrien return FALSE; 251133965Sjdp break; 251233965Sjdp } 251333965Sjdp 2514130561Sobrien return TRUE; 251533965Sjdp} 251633965Sjdp 251733965Sjdp/* Read a C++ class definition. This is a pmisc type 80 record of 251833965Sjdp category 'T'. */ 251933965Sjdp 2520130561Sobrienstatic bfd_boolean 2521130561Sobrienieee_read_cxx_class (struct ieee_info *info, const bfd_byte **pp, 2522130561Sobrien unsigned long count) 252333965Sjdp{ 252433965Sjdp const bfd_byte *start; 252533965Sjdp bfd_vma class; 252633965Sjdp const char *tag; 252733965Sjdp unsigned long taglen; 252833965Sjdp struct ieee_tag *it; 2529130561Sobrien void *dhandle; 253033965Sjdp debug_field *fields; 253133965Sjdp unsigned int field_count, field_alloc; 253233965Sjdp debug_baseclass *baseclasses; 253333965Sjdp unsigned int baseclasses_count, baseclasses_alloc; 253433965Sjdp const debug_field *structfields; 253533965Sjdp struct ieee_method 253633965Sjdp { 253733965Sjdp const char *name; 253833965Sjdp unsigned long namlen; 253933965Sjdp debug_method_variant *variants; 254033965Sjdp unsigned count; 254133965Sjdp unsigned int alloc; 254233965Sjdp } *methods; 254333965Sjdp unsigned int methods_count, methods_alloc; 254433965Sjdp debug_type vptrbase; 2545130561Sobrien bfd_boolean ownvptr; 254633965Sjdp debug_method *dmethods; 254733965Sjdp 254833965Sjdp start = *pp; 254933965Sjdp 255033965Sjdp if (! ieee_require_asn (info, pp, &class)) 2551130561Sobrien return FALSE; 255233965Sjdp --count; 255333965Sjdp 255433965Sjdp if (! ieee_require_atn65 (info, pp, &tag, &taglen)) 2555130561Sobrien return FALSE; 255633965Sjdp --count; 255733965Sjdp 255833965Sjdp /* Find the C struct with this name. */ 255933965Sjdp for (it = info->tags; it != NULL; it = it->next) 256033965Sjdp if (it->name[0] == tag[0] 256133965Sjdp && strncmp (it->name, tag, taglen) == 0 256233965Sjdp && strlen (it->name) == taglen) 256333965Sjdp break; 256433965Sjdp if (it == NULL) 256533965Sjdp { 256660484Sobrien ieee_error (info, start, _("undefined C++ object")); 2567130561Sobrien return FALSE; 256833965Sjdp } 256933965Sjdp 257033965Sjdp dhandle = info->dhandle; 257133965Sjdp 257233965Sjdp fields = NULL; 257333965Sjdp field_count = 0; 257433965Sjdp field_alloc = 0; 257533965Sjdp baseclasses = NULL; 257633965Sjdp baseclasses_count = 0; 257733965Sjdp baseclasses_alloc = 0; 257833965Sjdp methods = NULL; 257933965Sjdp methods_count = 0; 258033965Sjdp methods_alloc = 0; 258133965Sjdp vptrbase = DEBUG_TYPE_NULL; 2582130561Sobrien ownvptr = FALSE; 258333965Sjdp 258433965Sjdp structfields = debug_get_fields (dhandle, it->type); 258533965Sjdp 258633965Sjdp while (count > 0) 258733965Sjdp { 258833965Sjdp bfd_vma id; 258933965Sjdp const bfd_byte *spec_start; 259033965Sjdp 259133965Sjdp spec_start = *pp; 259233965Sjdp 259333965Sjdp if (! ieee_require_asn (info, pp, &id)) 2594130561Sobrien return FALSE; 259533965Sjdp --count; 259633965Sjdp 259733965Sjdp switch (id) 259833965Sjdp { 259933965Sjdp default: 260060484Sobrien ieee_error (info, spec_start, _("unrecognized C++ object spec")); 2601130561Sobrien return FALSE; 260233965Sjdp 260333965Sjdp case 'b': 260433965Sjdp { 260533965Sjdp bfd_vma flags, cinline; 260633965Sjdp const char *basename, *fieldname; 260733965Sjdp unsigned long baselen, fieldlen; 260833965Sjdp char *basecopy; 260933965Sjdp debug_type basetype; 261033965Sjdp bfd_vma bitpos; 2611130561Sobrien bfd_boolean virtualp; 261233965Sjdp enum debug_visibility visibility; 261333965Sjdp debug_baseclass baseclass; 261433965Sjdp 261533965Sjdp /* This represents a base or friend class. */ 261633965Sjdp 261733965Sjdp if (! ieee_require_asn (info, pp, &flags) 261833965Sjdp || ! ieee_require_atn65 (info, pp, &basename, &baselen) 261933965Sjdp || ! ieee_require_asn (info, pp, &cinline) 262033965Sjdp || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)) 2621130561Sobrien return FALSE; 262233965Sjdp count -= 4; 262333965Sjdp 262433965Sjdp /* We have no way of recording friend information, so we 262533965Sjdp just ignore it. */ 262633965Sjdp if ((flags & BASEFLAGS_FRIEND) != 0) 262733965Sjdp break; 262833965Sjdp 262933965Sjdp /* I assume that either all of the members of the 263033965Sjdp baseclass are included in the object, starting at the 263133965Sjdp beginning of the object, or that none of them are 263233965Sjdp included. */ 263333965Sjdp 263433965Sjdp if ((fieldlen == 0) == (cinline == 0)) 263533965Sjdp { 263660484Sobrien ieee_error (info, start, _("unsupported C++ object type")); 2637130561Sobrien return FALSE; 263833965Sjdp } 263933965Sjdp 264033965Sjdp basecopy = savestring (basename, baselen); 264133965Sjdp basetype = debug_find_tagged_type (dhandle, basecopy, 264233965Sjdp DEBUG_KIND_ILLEGAL); 264333965Sjdp free (basecopy); 264433965Sjdp if (basetype == DEBUG_TYPE_NULL) 264533965Sjdp { 264660484Sobrien ieee_error (info, start, _("C++ base class not defined")); 2647130561Sobrien return FALSE; 264833965Sjdp } 264933965Sjdp 265033965Sjdp if (fieldlen == 0) 265133965Sjdp bitpos = 0; 265233965Sjdp else 265333965Sjdp { 265433965Sjdp const debug_field *pf; 265533965Sjdp 265633965Sjdp if (structfields == NULL) 265733965Sjdp { 265860484Sobrien ieee_error (info, start, _("C++ object has no fields")); 2659130561Sobrien return FALSE; 266033965Sjdp } 266133965Sjdp 266233965Sjdp for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++) 266333965Sjdp { 266433965Sjdp const char *fname; 266533965Sjdp 266633965Sjdp fname = debug_get_field_name (dhandle, *pf); 266733965Sjdp if (fname == NULL) 2668130561Sobrien return FALSE; 266933965Sjdp if (fname[0] == fieldname[0] 267033965Sjdp && strncmp (fname, fieldname, fieldlen) == 0 267133965Sjdp && strlen (fname) == fieldlen) 267233965Sjdp break; 267333965Sjdp } 267433965Sjdp if (*pf == DEBUG_FIELD_NULL) 267533965Sjdp { 267633965Sjdp ieee_error (info, start, 267760484Sobrien _("C++ base class not found in container")); 2678130561Sobrien return FALSE; 267933965Sjdp } 268033965Sjdp 268133965Sjdp bitpos = debug_get_field_bitpos (dhandle, *pf); 268233965Sjdp } 268333965Sjdp 268433965Sjdp if ((flags & BASEFLAGS_VIRTUAL) != 0) 2685130561Sobrien virtualp = TRUE; 268633965Sjdp else 2687130561Sobrien virtualp = FALSE; 268833965Sjdp if ((flags & BASEFLAGS_PRIVATE) != 0) 268933965Sjdp visibility = DEBUG_VISIBILITY_PRIVATE; 269033965Sjdp else 269133965Sjdp visibility = DEBUG_VISIBILITY_PUBLIC; 269233965Sjdp 269333965Sjdp baseclass = debug_make_baseclass (dhandle, basetype, bitpos, 269433965Sjdp virtualp, visibility); 269533965Sjdp if (baseclass == DEBUG_BASECLASS_NULL) 2696130561Sobrien return FALSE; 269733965Sjdp 269833965Sjdp if (baseclasses_count + 1 >= baseclasses_alloc) 269933965Sjdp { 270033965Sjdp baseclasses_alloc += 10; 270133965Sjdp baseclasses = ((debug_baseclass *) 270233965Sjdp xrealloc (baseclasses, 270333965Sjdp (baseclasses_alloc 270433965Sjdp * sizeof *baseclasses))); 270533965Sjdp } 270633965Sjdp 270733965Sjdp baseclasses[baseclasses_count] = baseclass; 270833965Sjdp ++baseclasses_count; 270933965Sjdp baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL; 271033965Sjdp } 271133965Sjdp break; 271233965Sjdp 271333965Sjdp case 'd': 271433965Sjdp { 271533965Sjdp bfd_vma flags; 271633965Sjdp const char *fieldname, *mangledname; 271733965Sjdp unsigned long fieldlen, mangledlen; 271833965Sjdp char *fieldcopy; 2719130561Sobrien bfd_boolean staticp; 272033965Sjdp debug_type ftype; 272133965Sjdp const debug_field *pf = NULL; 272233965Sjdp enum debug_visibility visibility; 272333965Sjdp debug_field field; 272433965Sjdp 272533965Sjdp /* This represents a data member. */ 272633965Sjdp 272733965Sjdp if (! ieee_require_asn (info, pp, &flags) 272833965Sjdp || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen) 272933965Sjdp || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen)) 2730130561Sobrien return FALSE; 273133965Sjdp count -= 3; 273233965Sjdp 273333965Sjdp fieldcopy = savestring (fieldname, fieldlen); 273433965Sjdp 2735130561Sobrien staticp = (flags & CXXFLAGS_STATIC) != 0 ? TRUE : FALSE; 273633965Sjdp 273733965Sjdp if (staticp) 273833965Sjdp { 273933965Sjdp struct ieee_var *pv, *pvend; 274033965Sjdp 274133965Sjdp /* See if we can find a definition for this variable. */ 274233965Sjdp pv = info->vars.vars; 274333965Sjdp pvend = pv + info->vars.alloc; 274433965Sjdp for (; pv < pvend; pv++) 274533965Sjdp if (pv->namlen == mangledlen 274633965Sjdp && strncmp (pv->name, mangledname, mangledlen) == 0) 274733965Sjdp break; 274833965Sjdp if (pv < pvend) 274933965Sjdp ftype = pv->type; 275033965Sjdp else 275133965Sjdp { 275233965Sjdp /* This can happen if the variable is never used. */ 275333965Sjdp ftype = ieee_builtin_type (info, start, 275433965Sjdp (unsigned int) builtin_void); 275533965Sjdp } 275633965Sjdp } 275733965Sjdp else 275833965Sjdp { 275933965Sjdp unsigned int findx; 276033965Sjdp 276133965Sjdp if (structfields == NULL) 276233965Sjdp { 276360484Sobrien ieee_error (info, start, _("C++ object has no fields")); 2764130561Sobrien return FALSE; 276533965Sjdp } 276633965Sjdp 276733965Sjdp for (pf = structfields, findx = 0; 276833965Sjdp *pf != DEBUG_FIELD_NULL; 276933965Sjdp pf++, findx++) 277033965Sjdp { 277133965Sjdp const char *fname; 277233965Sjdp 277333965Sjdp fname = debug_get_field_name (dhandle, *pf); 277433965Sjdp if (fname == NULL) 2775130561Sobrien return FALSE; 277633965Sjdp if (fname[0] == mangledname[0] 277733965Sjdp && strncmp (fname, mangledname, mangledlen) == 0 277833965Sjdp && strlen (fname) == mangledlen) 277933965Sjdp break; 278033965Sjdp } 278133965Sjdp if (*pf == DEBUG_FIELD_NULL) 278233965Sjdp { 278333965Sjdp ieee_error (info, start, 278460484Sobrien _("C++ data member not found in container")); 2785130561Sobrien return FALSE; 278633965Sjdp } 278733965Sjdp 278833965Sjdp ftype = debug_get_field_type (dhandle, *pf); 278933965Sjdp 279033965Sjdp if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER) 279133965Sjdp { 279233965Sjdp /* We might need to convert this field into a 279333965Sjdp reference type later on, so make it an indirect 279433965Sjdp type. */ 279533965Sjdp if (it->fslots == NULL) 279633965Sjdp { 279733965Sjdp unsigned int fcnt; 279833965Sjdp const debug_field *pfcnt; 279933965Sjdp 280033965Sjdp fcnt = 0; 280133965Sjdp for (pfcnt = structfields; 280233965Sjdp *pfcnt != DEBUG_FIELD_NULL; 280333965Sjdp pfcnt++) 280433965Sjdp ++fcnt; 280533965Sjdp it->fslots = ((debug_type *) 280633965Sjdp xmalloc (fcnt * sizeof *it->fslots)); 280733965Sjdp memset (it->fslots, 0, 280833965Sjdp fcnt * sizeof *it->fslots); 280933965Sjdp } 281033965Sjdp 281133965Sjdp if (ftype == DEBUG_TYPE_NULL) 2812130561Sobrien return FALSE; 281333965Sjdp it->fslots[findx] = ftype; 281433965Sjdp ftype = debug_make_indirect_type (dhandle, 281533965Sjdp it->fslots + findx, 281633965Sjdp (const char *) NULL); 281733965Sjdp } 281833965Sjdp } 281933965Sjdp if (ftype == DEBUG_TYPE_NULL) 2820130561Sobrien return FALSE; 282133965Sjdp 282233965Sjdp switch (flags & CXXFLAGS_VISIBILITY) 282333965Sjdp { 282433965Sjdp default: 282560484Sobrien ieee_error (info, start, _("unknown C++ visibility")); 2826130561Sobrien return FALSE; 282733965Sjdp 282833965Sjdp case CXXFLAGS_VISIBILITY_PUBLIC: 282933965Sjdp visibility = DEBUG_VISIBILITY_PUBLIC; 283033965Sjdp break; 283133965Sjdp 283233965Sjdp case CXXFLAGS_VISIBILITY_PRIVATE: 283333965Sjdp visibility = DEBUG_VISIBILITY_PRIVATE; 283433965Sjdp break; 283533965Sjdp 283633965Sjdp case CXXFLAGS_VISIBILITY_PROTECTED: 283733965Sjdp visibility = DEBUG_VISIBILITY_PROTECTED; 283833965Sjdp break; 283933965Sjdp } 284033965Sjdp 284133965Sjdp if (staticp) 284233965Sjdp { 284333965Sjdp char *mangledcopy; 284433965Sjdp 284533965Sjdp mangledcopy = savestring (mangledname, mangledlen); 284633965Sjdp 284733965Sjdp field = debug_make_static_member (dhandle, fieldcopy, 284833965Sjdp ftype, mangledcopy, 284933965Sjdp visibility); 285033965Sjdp } 285133965Sjdp else 285233965Sjdp { 285333965Sjdp bfd_vma bitpos, bitsize; 285433965Sjdp 285533965Sjdp bitpos = debug_get_field_bitpos (dhandle, *pf); 285633965Sjdp bitsize = debug_get_field_bitsize (dhandle, *pf); 285733965Sjdp if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1) 285833965Sjdp { 285960484Sobrien ieee_error (info, start, _("bad C++ field bit pos or size")); 2860130561Sobrien return FALSE; 286133965Sjdp } 286233965Sjdp field = debug_make_field (dhandle, fieldcopy, ftype, bitpos, 286333965Sjdp bitsize, visibility); 286433965Sjdp } 286533965Sjdp 286633965Sjdp if (field == DEBUG_FIELD_NULL) 2867130561Sobrien return FALSE; 286833965Sjdp 286933965Sjdp if (field_count + 1 >= field_alloc) 287033965Sjdp { 287133965Sjdp field_alloc += 10; 287233965Sjdp fields = ((debug_field *) 287333965Sjdp xrealloc (fields, field_alloc * sizeof *fields)); 287433965Sjdp } 287533965Sjdp 287633965Sjdp fields[field_count] = field; 287733965Sjdp ++field_count; 287833965Sjdp fields[field_count] = DEBUG_FIELD_NULL; 287933965Sjdp } 288033965Sjdp break; 288133965Sjdp 288233965Sjdp case 'm': 288333965Sjdp case 'v': 288433965Sjdp { 288533965Sjdp bfd_vma flags, voffset, control; 288633965Sjdp const char *name, *mangled; 288733965Sjdp unsigned long namlen, mangledlen; 288833965Sjdp struct ieee_var *pv, *pvend; 288933965Sjdp debug_type type; 289033965Sjdp enum debug_visibility visibility; 2891130561Sobrien bfd_boolean constp, volatilep; 289233965Sjdp char *mangledcopy; 289333965Sjdp debug_method_variant mv; 289433965Sjdp struct ieee_method *meth; 289533965Sjdp unsigned int im; 289633965Sjdp 289733965Sjdp if (! ieee_require_asn (info, pp, &flags) 289833965Sjdp || ! ieee_require_atn65 (info, pp, &name, &namlen) 289933965Sjdp || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) 2900130561Sobrien return FALSE; 290133965Sjdp count -= 3; 290233965Sjdp if (id != 'v') 290333965Sjdp voffset = 0; 290433965Sjdp else 290533965Sjdp { 290633965Sjdp if (! ieee_require_asn (info, pp, &voffset)) 2907130561Sobrien return FALSE; 290833965Sjdp --count; 290933965Sjdp } 291033965Sjdp if (! ieee_require_asn (info, pp, &control)) 2911130561Sobrien return FALSE; 291233965Sjdp --count; 291333965Sjdp 291433965Sjdp /* We just ignore the control information. */ 291533965Sjdp 291633965Sjdp /* We have no way to represent friend information, so we 291733965Sjdp just ignore it. */ 291833965Sjdp if ((flags & CXXFLAGS_FRIEND) != 0) 291933965Sjdp break; 292033965Sjdp 292133965Sjdp /* We should already have seen a type for the function. */ 292233965Sjdp pv = info->vars.vars; 292333965Sjdp pvend = pv + info->vars.alloc; 292433965Sjdp for (; pv < pvend; pv++) 292533965Sjdp if (pv->namlen == mangledlen 292633965Sjdp && strncmp (pv->name, mangled, mangledlen) == 0) 292733965Sjdp break; 292833965Sjdp 292933965Sjdp if (pv >= pvend) 293033965Sjdp { 293133965Sjdp /* We won't have type information for this function if 293233965Sjdp it is not included in this file. We don't try to 293333965Sjdp handle this case. FIXME. */ 293433965Sjdp type = (debug_make_function_type 293533965Sjdp (dhandle, 293633965Sjdp ieee_builtin_type (info, start, 293733965Sjdp (unsigned int) builtin_void), 293833965Sjdp (debug_type *) NULL, 2939130561Sobrien FALSE)); 294033965Sjdp } 294133965Sjdp else 294233965Sjdp { 294333965Sjdp debug_type return_type; 294433965Sjdp const debug_type *arg_types; 2945130561Sobrien bfd_boolean varargs; 294633965Sjdp 294733965Sjdp if (debug_get_type_kind (dhandle, pv->type) 294833965Sjdp != DEBUG_KIND_FUNCTION) 294933965Sjdp { 295033965Sjdp ieee_error (info, start, 295160484Sobrien _("bad type for C++ method function")); 2952130561Sobrien return FALSE; 295333965Sjdp } 295433965Sjdp 295533965Sjdp return_type = debug_get_return_type (dhandle, pv->type); 295633965Sjdp arg_types = debug_get_parameter_types (dhandle, pv->type, 295733965Sjdp &varargs); 295833965Sjdp if (return_type == DEBUG_TYPE_NULL || arg_types == NULL) 295933965Sjdp { 296033965Sjdp ieee_error (info, start, 296160484Sobrien _("no type information for C++ method function")); 2962130561Sobrien return FALSE; 296333965Sjdp } 296433965Sjdp 296533965Sjdp type = debug_make_method_type (dhandle, return_type, it->type, 296633965Sjdp (debug_type *) arg_types, 296733965Sjdp varargs); 296833965Sjdp } 296933965Sjdp if (type == DEBUG_TYPE_NULL) 2970130561Sobrien return FALSE; 297133965Sjdp 297233965Sjdp switch (flags & CXXFLAGS_VISIBILITY) 297333965Sjdp { 297433965Sjdp default: 297560484Sobrien ieee_error (info, start, _("unknown C++ visibility")); 2976130561Sobrien return FALSE; 297733965Sjdp 297833965Sjdp case CXXFLAGS_VISIBILITY_PUBLIC: 297933965Sjdp visibility = DEBUG_VISIBILITY_PUBLIC; 298033965Sjdp break; 298133965Sjdp 298233965Sjdp case CXXFLAGS_VISIBILITY_PRIVATE: 298333965Sjdp visibility = DEBUG_VISIBILITY_PRIVATE; 298433965Sjdp break; 298533965Sjdp 298633965Sjdp case CXXFLAGS_VISIBILITY_PROTECTED: 298733965Sjdp visibility = DEBUG_VISIBILITY_PROTECTED; 298833965Sjdp break; 298933965Sjdp } 299033965Sjdp 2991130561Sobrien constp = (flags & CXXFLAGS_CONST) != 0 ? TRUE : FALSE; 2992130561Sobrien volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? TRUE : FALSE; 299333965Sjdp 299433965Sjdp mangledcopy = savestring (mangled, mangledlen); 299533965Sjdp 299633965Sjdp if ((flags & CXXFLAGS_STATIC) != 0) 299733965Sjdp { 299833965Sjdp if (id == 'v') 299933965Sjdp { 300060484Sobrien ieee_error (info, start, _("C++ static virtual method")); 3001130561Sobrien return FALSE; 300233965Sjdp } 300333965Sjdp mv = debug_make_static_method_variant (dhandle, mangledcopy, 300433965Sjdp type, visibility, 300533965Sjdp constp, volatilep); 300633965Sjdp } 300733965Sjdp else 300833965Sjdp { 300933965Sjdp debug_type vcontext; 301033965Sjdp 301133965Sjdp if (id != 'v') 301233965Sjdp vcontext = DEBUG_TYPE_NULL; 301333965Sjdp else 301433965Sjdp { 301533965Sjdp /* FIXME: How can we calculate this correctly? */ 301633965Sjdp vcontext = it->type; 301733965Sjdp } 301833965Sjdp mv = debug_make_method_variant (dhandle, mangledcopy, type, 301933965Sjdp visibility, constp, 302033965Sjdp volatilep, voffset, 302133965Sjdp vcontext); 302233965Sjdp } 302333965Sjdp if (mv == DEBUG_METHOD_VARIANT_NULL) 3024130561Sobrien return FALSE; 302533965Sjdp 302633965Sjdp for (meth = methods, im = 0; im < methods_count; meth++, im++) 302733965Sjdp if (meth->namlen == namlen 302833965Sjdp && strncmp (meth->name, name, namlen) == 0) 302933965Sjdp break; 303033965Sjdp if (im >= methods_count) 303133965Sjdp { 303233965Sjdp if (methods_count >= methods_alloc) 303333965Sjdp { 303433965Sjdp methods_alloc += 10; 303533965Sjdp methods = ((struct ieee_method *) 303633965Sjdp xrealloc (methods, 303733965Sjdp methods_alloc * sizeof *methods)); 303833965Sjdp } 303933965Sjdp methods[methods_count].name = name; 304033965Sjdp methods[methods_count].namlen = namlen; 304133965Sjdp methods[methods_count].variants = NULL; 304233965Sjdp methods[methods_count].count = 0; 304333965Sjdp methods[methods_count].alloc = 0; 304433965Sjdp meth = methods + methods_count; 304533965Sjdp ++methods_count; 304633965Sjdp } 304733965Sjdp 304833965Sjdp if (meth->count + 1 >= meth->alloc) 304933965Sjdp { 305033965Sjdp meth->alloc += 10; 305133965Sjdp meth->variants = ((debug_method_variant *) 305233965Sjdp xrealloc (meth->variants, 305333965Sjdp (meth->alloc 305433965Sjdp * sizeof *meth->variants))); 305533965Sjdp } 305633965Sjdp 305733965Sjdp meth->variants[meth->count] = mv; 305833965Sjdp ++meth->count; 305933965Sjdp meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL; 306033965Sjdp } 306133965Sjdp break; 306233965Sjdp 306333965Sjdp case 'o': 306433965Sjdp { 306533965Sjdp bfd_vma spec; 306633965Sjdp 306733965Sjdp /* We have no way to store this information, so we just 306833965Sjdp ignore it. */ 306933965Sjdp if (! ieee_require_asn (info, pp, &spec)) 3070130561Sobrien return FALSE; 307133965Sjdp --count; 307233965Sjdp if ((spec & 4) != 0) 307333965Sjdp { 307433965Sjdp const char *filename; 307533965Sjdp unsigned long filenamlen; 307633965Sjdp bfd_vma lineno; 307733965Sjdp 307833965Sjdp if (! ieee_require_atn65 (info, pp, &filename, &filenamlen) 307933965Sjdp || ! ieee_require_asn (info, pp, &lineno)) 3080130561Sobrien return FALSE; 308133965Sjdp count -= 2; 308233965Sjdp } 308333965Sjdp else if ((spec & 8) != 0) 308433965Sjdp { 308533965Sjdp const char *mangled; 308633965Sjdp unsigned long mangledlen; 308733965Sjdp 308833965Sjdp if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) 3089130561Sobrien return FALSE; 309033965Sjdp --count; 309133965Sjdp } 309233965Sjdp else 309333965Sjdp { 309433965Sjdp ieee_error (info, start, 309560484Sobrien _("unrecognized C++ object overhead spec")); 3096130561Sobrien return FALSE; 309733965Sjdp } 309833965Sjdp } 309933965Sjdp break; 310033965Sjdp 310133965Sjdp case 'z': 310233965Sjdp { 310333965Sjdp const char *vname, *basename; 310433965Sjdp unsigned long vnamelen, baselen; 310533965Sjdp bfd_vma vsize, control; 310633965Sjdp 310733965Sjdp /* A virtual table pointer. */ 310833965Sjdp 310933965Sjdp if (! ieee_require_atn65 (info, pp, &vname, &vnamelen) 311033965Sjdp || ! ieee_require_asn (info, pp, &vsize) 311133965Sjdp || ! ieee_require_atn65 (info, pp, &basename, &baselen) 311233965Sjdp || ! ieee_require_asn (info, pp, &control)) 3113130561Sobrien return FALSE; 311433965Sjdp count -= 4; 311533965Sjdp 311633965Sjdp /* We just ignore the control number. We don't care what 311733965Sjdp the virtual table name is. We have no way to store the 311833965Sjdp virtual table size, and I don't think we care anyhow. */ 311933965Sjdp 312033965Sjdp /* FIXME: We can't handle multiple virtual table pointers. */ 312133965Sjdp 312233965Sjdp if (baselen == 0) 3123130561Sobrien ownvptr = TRUE; 312433965Sjdp else 312533965Sjdp { 312633965Sjdp char *basecopy; 312733965Sjdp 312833965Sjdp basecopy = savestring (basename, baselen); 312933965Sjdp vptrbase = debug_find_tagged_type (dhandle, basecopy, 313033965Sjdp DEBUG_KIND_ILLEGAL); 313133965Sjdp free (basecopy); 313233965Sjdp if (vptrbase == DEBUG_TYPE_NULL) 313333965Sjdp { 313460484Sobrien ieee_error (info, start, _("undefined C++ vtable")); 3135130561Sobrien return FALSE; 313633965Sjdp } 313733965Sjdp } 313833965Sjdp } 313933965Sjdp break; 314033965Sjdp } 314133965Sjdp } 314233965Sjdp 314333965Sjdp /* Now that we have seen all the method variants, we can call 314433965Sjdp debug_make_method for each one. */ 314533965Sjdp 314633965Sjdp if (methods_count == 0) 314733965Sjdp dmethods = NULL; 314833965Sjdp else 314933965Sjdp { 315033965Sjdp unsigned int i; 315133965Sjdp 315233965Sjdp dmethods = ((debug_method *) 315333965Sjdp xmalloc ((methods_count + 1) * sizeof *dmethods)); 315433965Sjdp for (i = 0; i < methods_count; i++) 315533965Sjdp { 315633965Sjdp char *namcopy; 315733965Sjdp 315833965Sjdp namcopy = savestring (methods[i].name, methods[i].namlen); 315933965Sjdp dmethods[i] = debug_make_method (dhandle, namcopy, 316033965Sjdp methods[i].variants); 316133965Sjdp if (dmethods[i] == DEBUG_METHOD_NULL) 3162130561Sobrien return FALSE; 316333965Sjdp } 316433965Sjdp dmethods[i] = DEBUG_METHOD_NULL; 316533965Sjdp free (methods); 316633965Sjdp } 316733965Sjdp 316833965Sjdp /* The struct type was created as an indirect type pointing at 316933965Sjdp it->slot. We update it->slot to automatically update all 317033965Sjdp references to this struct. */ 317133965Sjdp it->slot = debug_make_object_type (dhandle, 317233965Sjdp class != 'u', 317333965Sjdp debug_get_type_size (dhandle, 317433965Sjdp it->slot), 317533965Sjdp fields, baseclasses, dmethods, 317633965Sjdp vptrbase, ownvptr); 317733965Sjdp if (it->slot == DEBUG_TYPE_NULL) 3178130561Sobrien return FALSE; 317933965Sjdp 3180130561Sobrien return TRUE; 318133965Sjdp} 318233965Sjdp 318333965Sjdp/* Read C++ default argument value and reference type information. */ 318433965Sjdp 3185130561Sobrienstatic bfd_boolean 3186130561Sobrienieee_read_cxx_defaults (struct ieee_info *info, const bfd_byte **pp, 3187130561Sobrien unsigned long count) 318833965Sjdp{ 318933965Sjdp const bfd_byte *start; 319033965Sjdp const char *fnname; 319133965Sjdp unsigned long fnlen; 319233965Sjdp bfd_vma defcount; 319333965Sjdp 319433965Sjdp start = *pp; 319533965Sjdp 319633965Sjdp /* Giving the function name before the argument count is an addendum 319733965Sjdp to the spec. The function name is demangled, though, so this 319833965Sjdp record must always refer to the current function. */ 319933965Sjdp 320033965Sjdp if (info->blockstack.bsp <= info->blockstack.stack 320133965Sjdp || info->blockstack.bsp[-1].fnindx == (unsigned int) -1) 320233965Sjdp { 320360484Sobrien ieee_error (info, start, _("C++ default values not in a function")); 3204130561Sobrien return FALSE; 320533965Sjdp } 320633965Sjdp 320733965Sjdp if (! ieee_require_atn65 (info, pp, &fnname, &fnlen) 320833965Sjdp || ! ieee_require_asn (info, pp, &defcount)) 3209130561Sobrien return FALSE; 321033965Sjdp count -= 2; 321133965Sjdp 321233965Sjdp while (defcount-- > 0) 321333965Sjdp { 321433965Sjdp bfd_vma type, val; 321533965Sjdp const char *strval; 321633965Sjdp unsigned long strvallen; 321733965Sjdp 321833965Sjdp if (! ieee_require_asn (info, pp, &type)) 3219130561Sobrien return FALSE; 322033965Sjdp --count; 322133965Sjdp 322233965Sjdp switch (type) 322333965Sjdp { 322433965Sjdp case 0: 322533965Sjdp case 4: 322633965Sjdp break; 322733965Sjdp 322833965Sjdp case 1: 322933965Sjdp case 2: 323033965Sjdp if (! ieee_require_asn (info, pp, &val)) 3231130561Sobrien return FALSE; 323233965Sjdp --count; 323333965Sjdp break; 323433965Sjdp 323533965Sjdp case 3: 323633965Sjdp case 7: 323733965Sjdp if (! ieee_require_atn65 (info, pp, &strval, &strvallen)) 3238130561Sobrien return FALSE; 323933965Sjdp --count; 324033965Sjdp break; 324133965Sjdp 324233965Sjdp default: 324360484Sobrien ieee_error (info, start, _("unrecognized C++ default type")); 3244130561Sobrien return FALSE; 324533965Sjdp } 324633965Sjdp 324733965Sjdp /* We have no way to record the default argument values, so we 324833965Sjdp just ignore them. FIXME. */ 324933965Sjdp } 325033965Sjdp 325133965Sjdp /* Any remaining arguments are indices of parameters that are really 325233965Sjdp reference type. */ 325333965Sjdp if (count > 0) 325433965Sjdp { 3255130561Sobrien void *dhandle; 325633965Sjdp debug_type *arg_slots; 325733965Sjdp 325833965Sjdp dhandle = info->dhandle; 325933965Sjdp arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots; 326033965Sjdp while (count-- > 0) 326133965Sjdp { 326233965Sjdp bfd_vma indx; 326333965Sjdp debug_type target; 326433965Sjdp 326533965Sjdp if (! ieee_require_asn (info, pp, &indx)) 3266130561Sobrien return FALSE; 326733965Sjdp /* The index is 1 based. */ 326833965Sjdp --indx; 326933965Sjdp if (arg_slots == NULL 327033965Sjdp || arg_slots[indx] == DEBUG_TYPE_NULL 327133965Sjdp || (debug_get_type_kind (dhandle, arg_slots[indx]) 327233965Sjdp != DEBUG_KIND_POINTER)) 327333965Sjdp { 327460484Sobrien ieee_error (info, start, _("reference parameter is not a pointer")); 3275130561Sobrien return FALSE; 327633965Sjdp } 327733965Sjdp 327833965Sjdp target = debug_get_target_type (dhandle, arg_slots[indx]); 327933965Sjdp arg_slots[indx] = debug_make_reference_type (dhandle, target); 328033965Sjdp if (arg_slots[indx] == DEBUG_TYPE_NULL) 3281130561Sobrien return FALSE; 328233965Sjdp } 328333965Sjdp } 328433965Sjdp 3285130561Sobrien return TRUE; 328633965Sjdp} 328733965Sjdp 328833965Sjdp/* Read a C++ reference definition. */ 328933965Sjdp 3290130561Sobrienstatic bfd_boolean 3291130561Sobrienieee_read_reference (struct ieee_info *info, const bfd_byte **pp) 329233965Sjdp{ 329333965Sjdp const bfd_byte *start; 329433965Sjdp bfd_vma flags; 329533965Sjdp const char *class, *name; 329633965Sjdp unsigned long classlen, namlen; 329733965Sjdp debug_type *pslot; 329833965Sjdp debug_type target; 329933965Sjdp 330033965Sjdp start = *pp; 330133965Sjdp 330233965Sjdp if (! ieee_require_asn (info, pp, &flags)) 3303130561Sobrien return FALSE; 330433965Sjdp 330533965Sjdp /* Giving the class name before the member name is in an addendum to 330633965Sjdp the spec. */ 330733965Sjdp if (flags == 3) 330833965Sjdp { 330933965Sjdp if (! ieee_require_atn65 (info, pp, &class, &classlen)) 3310130561Sobrien return FALSE; 331133965Sjdp } 331233965Sjdp 331333965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen)) 3314130561Sobrien return FALSE; 331533965Sjdp 331633965Sjdp pslot = NULL; 331733965Sjdp if (flags != 3) 331833965Sjdp { 331933965Sjdp int pass; 332033965Sjdp 332133965Sjdp /* We search from the last variable indices to the first in 332233965Sjdp hopes of finding local variables correctly. We search the 332333965Sjdp local variables on the first pass, and the global variables 332433965Sjdp on the second. FIXME: This probably won't work in all cases. 332533965Sjdp On the other hand, I don't know what will. */ 332633965Sjdp for (pass = 0; pass < 2; pass++) 332733965Sjdp { 332833965Sjdp struct ieee_vars *vars; 332933965Sjdp int i; 333033965Sjdp struct ieee_var *pv = NULL; 333133965Sjdp 333233965Sjdp if (pass == 0) 333333965Sjdp vars = &info->vars; 333433965Sjdp else 333533965Sjdp { 333633965Sjdp vars = info->global_vars; 333733965Sjdp if (vars == NULL) 333833965Sjdp break; 333933965Sjdp } 334033965Sjdp 334133965Sjdp for (i = (int) vars->alloc - 1; i >= 0; i--) 334233965Sjdp { 3343130561Sobrien bfd_boolean found; 334433965Sjdp 334533965Sjdp pv = vars->vars + i; 334633965Sjdp 334733965Sjdp if (pv->pslot == NULL 334833965Sjdp || pv->namlen != namlen 334933965Sjdp || strncmp (pv->name, name, namlen) != 0) 335033965Sjdp continue; 335133965Sjdp 3352130561Sobrien found = FALSE; 335333965Sjdp switch (flags) 335433965Sjdp { 335533965Sjdp default: 335633965Sjdp ieee_error (info, start, 335760484Sobrien _("unrecognized C++ reference type")); 3358130561Sobrien return FALSE; 335933965Sjdp 336033965Sjdp case 0: 336133965Sjdp /* Global variable or function. */ 336233965Sjdp if (pv->kind == IEEE_GLOBAL 336333965Sjdp || pv->kind == IEEE_EXTERNAL 336433965Sjdp || pv->kind == IEEE_FUNCTION) 3365130561Sobrien found = TRUE; 336633965Sjdp break; 336733965Sjdp 336833965Sjdp case 1: 336933965Sjdp /* Global static variable or function. */ 337033965Sjdp if (pv->kind == IEEE_STATIC 337133965Sjdp || pv->kind == IEEE_FUNCTION) 3372130561Sobrien found = TRUE; 337333965Sjdp break; 337433965Sjdp 337533965Sjdp case 2: 337633965Sjdp /* Local variable. */ 337733965Sjdp if (pv->kind == IEEE_LOCAL) 3378130561Sobrien found = TRUE; 337933965Sjdp break; 338033965Sjdp } 338133965Sjdp 338233965Sjdp if (found) 338333965Sjdp break; 338433965Sjdp } 338533965Sjdp 338633965Sjdp if (i >= 0) 338733965Sjdp { 338833965Sjdp pslot = pv->pslot; 338933965Sjdp break; 339033965Sjdp } 339133965Sjdp } 339233965Sjdp } 339333965Sjdp else 339433965Sjdp { 339533965Sjdp struct ieee_tag *it; 339633965Sjdp 339733965Sjdp for (it = info->tags; it != NULL; it = it->next) 339833965Sjdp { 339933965Sjdp if (it->name[0] == class[0] 340033965Sjdp && strncmp (it->name, class, classlen) == 0 340133965Sjdp && strlen (it->name) == classlen) 340233965Sjdp { 340333965Sjdp if (it->fslots != NULL) 340433965Sjdp { 340533965Sjdp const debug_field *pf; 340633965Sjdp unsigned int findx; 340733965Sjdp 340833965Sjdp pf = debug_get_fields (info->dhandle, it->type); 340933965Sjdp if (pf == NULL) 341033965Sjdp { 341133965Sjdp ieee_error (info, start, 341233965Sjdp "C++ reference in class with no fields"); 3413130561Sobrien return FALSE; 341433965Sjdp } 341533965Sjdp 341633965Sjdp for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++) 341733965Sjdp { 341833965Sjdp const char *fname; 341933965Sjdp 342033965Sjdp fname = debug_get_field_name (info->dhandle, *pf); 342133965Sjdp if (fname == NULL) 3422130561Sobrien return FALSE; 342333965Sjdp if (strncmp (fname, name, namlen) == 0 342433965Sjdp && strlen (fname) == namlen) 342533965Sjdp { 342633965Sjdp pslot = it->fslots + findx; 342733965Sjdp break; 342833965Sjdp } 342933965Sjdp } 343033965Sjdp } 343133965Sjdp 343233965Sjdp break; 343333965Sjdp } 343433965Sjdp } 343533965Sjdp } 343633965Sjdp 343733965Sjdp if (pslot == NULL) 343833965Sjdp { 343960484Sobrien ieee_error (info, start, _("C++ reference not found")); 3440130561Sobrien return FALSE; 344133965Sjdp } 344233965Sjdp 344333965Sjdp /* We allocated the type of the object as an indirect type pointing 344433965Sjdp to *pslot, which we can now update to be a reference type. */ 344533965Sjdp if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER) 344633965Sjdp { 344760484Sobrien ieee_error (info, start, _("C++ reference is not pointer")); 3448130561Sobrien return FALSE; 344933965Sjdp } 345033965Sjdp 345133965Sjdp target = debug_get_target_type (info->dhandle, *pslot); 345233965Sjdp *pslot = debug_make_reference_type (info->dhandle, target); 345333965Sjdp if (*pslot == DEBUG_TYPE_NULL) 3454130561Sobrien return FALSE; 345533965Sjdp 3456130561Sobrien return TRUE; 345733965Sjdp} 345833965Sjdp 345933965Sjdp/* Require an ASN record. */ 346033965Sjdp 3461130561Sobrienstatic bfd_boolean 3462130561Sobrienieee_require_asn (struct ieee_info *info, const bfd_byte **pp, bfd_vma *pv) 346333965Sjdp{ 346433965Sjdp const bfd_byte *start; 346533965Sjdp ieee_record_enum_type c; 346633965Sjdp bfd_vma varindx; 346733965Sjdp 346833965Sjdp start = *pp; 346933965Sjdp 347033965Sjdp c = (ieee_record_enum_type) **pp; 347133965Sjdp if (c != ieee_e2_first_byte_enum) 347233965Sjdp { 347360484Sobrien ieee_error (info, start, _("missing required ASN")); 3474130561Sobrien return FALSE; 347533965Sjdp } 347633965Sjdp ++*pp; 347733965Sjdp 347833965Sjdp c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); 347933965Sjdp if (c != ieee_asn_record_enum) 348033965Sjdp { 348160484Sobrien ieee_error (info, start, _("missing required ASN")); 3482130561Sobrien return FALSE; 348333965Sjdp } 348433965Sjdp ++*pp; 348533965Sjdp 348633965Sjdp /* Just ignore the variable index. */ 348733965Sjdp if (! ieee_read_number (info, pp, &varindx)) 3488130561Sobrien return FALSE; 348933965Sjdp 349033965Sjdp return ieee_read_expression (info, pp, pv); 349133965Sjdp} 349233965Sjdp 349333965Sjdp/* Require an ATN65 record. */ 349433965Sjdp 3495130561Sobrienstatic bfd_boolean 3496130561Sobrienieee_require_atn65 (struct ieee_info *info, const bfd_byte **pp, 3497130561Sobrien const char **pname, unsigned long *pnamlen) 349833965Sjdp{ 349933965Sjdp const bfd_byte *start; 350033965Sjdp ieee_record_enum_type c; 350133965Sjdp bfd_vma name_indx, type_indx, atn_code; 350233965Sjdp 350333965Sjdp start = *pp; 350433965Sjdp 350533965Sjdp c = (ieee_record_enum_type) **pp; 350633965Sjdp if (c != ieee_at_record_enum) 350733965Sjdp { 350860484Sobrien ieee_error (info, start, _("missing required ATN65")); 3509130561Sobrien return FALSE; 351033965Sjdp } 351133965Sjdp ++*pp; 351233965Sjdp 351333965Sjdp c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); 351433965Sjdp if (c != ieee_atn_record_enum) 351533965Sjdp { 351660484Sobrien ieee_error (info, start, _("missing required ATN65")); 3517130561Sobrien return FALSE; 351833965Sjdp } 351933965Sjdp ++*pp; 352033965Sjdp 352133965Sjdp if (! ieee_read_number (info, pp, &name_indx) 352233965Sjdp || ! ieee_read_number (info, pp, &type_indx) 352333965Sjdp || ! ieee_read_number (info, pp, &atn_code)) 3524130561Sobrien return FALSE; 352533965Sjdp 352633965Sjdp /* Just ignore name_indx. */ 352733965Sjdp 352833965Sjdp if (type_indx != 0 || atn_code != 65) 352933965Sjdp { 353060484Sobrien ieee_error (info, start, _("bad ATN65 record")); 3531130561Sobrien return FALSE; 353233965Sjdp } 353333965Sjdp 353433965Sjdp return ieee_read_id (info, pp, pname, pnamlen); 353533965Sjdp} 353633965Sjdp 353733965Sjdp/* Convert a register number in IEEE debugging information into a 353833965Sjdp generic register number. */ 353933965Sjdp 354033965Sjdpstatic int 3541130561Sobrienieee_regno_to_genreg (bfd *abfd, int r) 354233965Sjdp{ 354333965Sjdp switch (bfd_get_arch (abfd)) 354433965Sjdp { 354533965Sjdp case bfd_arch_m68k: 354633965Sjdp /* For some reasons stabs adds 2 to the floating point register 354733965Sjdp numbers. */ 354833965Sjdp if (r >= 16) 354933965Sjdp r += 2; 355033965Sjdp break; 355133965Sjdp 355233965Sjdp case bfd_arch_i960: 355333965Sjdp /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and 355433965Sjdp 32 to 35 for fp0 to fp3. */ 355533965Sjdp --r; 355633965Sjdp break; 355733965Sjdp 355833965Sjdp default: 355933965Sjdp break; 356033965Sjdp } 356133965Sjdp 356233965Sjdp return r; 356333965Sjdp} 356433965Sjdp 356533965Sjdp/* Convert a generic register number to an IEEE specific one. */ 356633965Sjdp 356733965Sjdpstatic int 3568130561Sobrienieee_genreg_to_regno (bfd *abfd, int r) 356933965Sjdp{ 357033965Sjdp switch (bfd_get_arch (abfd)) 357133965Sjdp { 357233965Sjdp case bfd_arch_m68k: 357333965Sjdp /* For some reason stabs add 2 to the floating point register 357433965Sjdp numbers. */ 357533965Sjdp if (r >= 18) 357633965Sjdp r -= 2; 357733965Sjdp break; 357833965Sjdp 357933965Sjdp case bfd_arch_i960: 358033965Sjdp /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and 358133965Sjdp 32 to 35 for fp0 to fp3. */ 358233965Sjdp ++r; 358333965Sjdp break; 358433965Sjdp 358533965Sjdp default: 358633965Sjdp break; 358733965Sjdp } 358833965Sjdp 358933965Sjdp return r; 359033965Sjdp} 359133965Sjdp 359233965Sjdp/* These routines build IEEE debugging information out of the generic 359333965Sjdp debugging information. */ 359433965Sjdp 359533965Sjdp/* We build the IEEE debugging information byte by byte. Rather than 359633965Sjdp waste time copying data around, we use a linked list of buffers to 359733965Sjdp hold the data. */ 359833965Sjdp 359933965Sjdp#define IEEE_BUFSIZE (490) 360033965Sjdp 360133965Sjdpstruct ieee_buf 360233965Sjdp{ 360333965Sjdp /* Next buffer. */ 360433965Sjdp struct ieee_buf *next; 360533965Sjdp /* Number of data bytes in this buffer. */ 360633965Sjdp unsigned int c; 360733965Sjdp /* Bytes. */ 360833965Sjdp bfd_byte buf[IEEE_BUFSIZE]; 360933965Sjdp}; 361033965Sjdp 361133965Sjdp/* A list of buffers. */ 361233965Sjdp 361333965Sjdpstruct ieee_buflist 361433965Sjdp{ 361533965Sjdp /* Head of list. */ 361633965Sjdp struct ieee_buf *head; 361733965Sjdp /* Tail--last buffer on list. */ 361833965Sjdp struct ieee_buf *tail; 361933965Sjdp}; 362033965Sjdp 362133965Sjdp/* In order to generate the BB11 blocks required by the HP emulator, 362233965Sjdp we keep track of ranges of addresses which correspond to a given 362333965Sjdp compilation unit. */ 362433965Sjdp 362533965Sjdpstruct ieee_range 362633965Sjdp{ 362733965Sjdp /* Next range. */ 362833965Sjdp struct ieee_range *next; 362933965Sjdp /* Low address. */ 363033965Sjdp bfd_vma low; 363133965Sjdp /* High address. */ 363233965Sjdp bfd_vma high; 363333965Sjdp}; 363433965Sjdp 363533965Sjdp/* This structure holds information for a class on the type stack. */ 363633965Sjdp 363733965Sjdpstruct ieee_type_class 363833965Sjdp{ 363933965Sjdp /* The name index in the debugging information. */ 364033965Sjdp unsigned int indx; 364133965Sjdp /* The pmisc records for the class. */ 364233965Sjdp struct ieee_buflist pmiscbuf; 364333965Sjdp /* The number of pmisc records. */ 364433965Sjdp unsigned int pmisccount; 364533965Sjdp /* The name of the class holding the virtual table, if not this 364633965Sjdp class. */ 364733965Sjdp const char *vclass; 364833965Sjdp /* Whether this class holds its own virtual table. */ 3649130561Sobrien bfd_boolean ownvptr; 365033965Sjdp /* The largest virtual table offset seen so far. */ 365133965Sjdp bfd_vma voffset; 365233965Sjdp /* The current method. */ 365333965Sjdp const char *method; 365433965Sjdp /* Additional pmisc records used to record fields of reference type. */ 365533965Sjdp struct ieee_buflist refs; 365633965Sjdp}; 365733965Sjdp 365833965Sjdp/* This is how we store types for the writing routines. Most types 365933965Sjdp are simply represented by a type index. */ 366033965Sjdp 366133965Sjdpstruct ieee_write_type 366233965Sjdp{ 366333965Sjdp /* Type index. */ 366433965Sjdp unsigned int indx; 366533965Sjdp /* The size of the type, if known. */ 366633965Sjdp unsigned int size; 366733965Sjdp /* The name of the type, if any. */ 366833965Sjdp const char *name; 366933965Sjdp /* If this is a function or method type, we build the type here, and 367033965Sjdp only add it to the output buffers if we need it. */ 367133965Sjdp struct ieee_buflist fndef; 367233965Sjdp /* If this is a struct, this is where the struct definition is 367333965Sjdp built. */ 367433965Sjdp struct ieee_buflist strdef; 367533965Sjdp /* If this is a class, this is where the class information is built. */ 367633965Sjdp struct ieee_type_class *classdef; 367733965Sjdp /* Whether the type is unsigned. */ 367833965Sjdp unsigned int unsignedp : 1; 367933965Sjdp /* Whether this is a reference type. */ 368033965Sjdp unsigned int referencep : 1; 368133965Sjdp /* Whether this is in the local type block. */ 368233965Sjdp unsigned int localp : 1; 368333965Sjdp /* Whether this is a duplicate struct definition which we are 368433965Sjdp ignoring. */ 368533965Sjdp unsigned int ignorep : 1; 368633965Sjdp}; 368733965Sjdp 368833965Sjdp/* This is the type stack used by the debug writing routines. FIXME: 368933965Sjdp We could generate more efficient output if we remembered when we 369033965Sjdp have output a particular type before. */ 369133965Sjdp 369233965Sjdpstruct ieee_type_stack 369333965Sjdp{ 369433965Sjdp /* Next entry on stack. */ 369533965Sjdp struct ieee_type_stack *next; 369633965Sjdp /* Type information. */ 369733965Sjdp struct ieee_write_type type; 369833965Sjdp}; 369933965Sjdp 370033965Sjdp/* This is a list of associations between a name and some types. 370133965Sjdp These are used for typedefs and tags. */ 370233965Sjdp 370333965Sjdpstruct ieee_name_type 370433965Sjdp{ 370533965Sjdp /* Next type for this name. */ 370633965Sjdp struct ieee_name_type *next; 370733965Sjdp /* ID number. For a typedef, this is the index of the type to which 370833965Sjdp this name is typedefed. */ 370933965Sjdp unsigned int id; 371033965Sjdp /* Type. */ 371133965Sjdp struct ieee_write_type type; 371233965Sjdp /* If this is a tag which has not yet been defined, this is the 371333965Sjdp kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */ 371433965Sjdp enum debug_type_kind kind; 371533965Sjdp}; 371633965Sjdp 371733965Sjdp/* We use a hash table to associate names and types. */ 371833965Sjdp 371933965Sjdpstruct ieee_name_type_hash_table 372033965Sjdp{ 372133965Sjdp struct bfd_hash_table root; 372233965Sjdp}; 372333965Sjdp 372433965Sjdpstruct ieee_name_type_hash_entry 372533965Sjdp{ 372633965Sjdp struct bfd_hash_entry root; 372733965Sjdp /* Information for this name. */ 372833965Sjdp struct ieee_name_type *types; 372933965Sjdp}; 373033965Sjdp 373133965Sjdp/* This is a list of enums. */ 373233965Sjdp 373333965Sjdpstruct ieee_defined_enum 373433965Sjdp{ 373533965Sjdp /* Next enum. */ 373633965Sjdp struct ieee_defined_enum *next; 373733965Sjdp /* Type index. */ 373833965Sjdp unsigned int indx; 373933965Sjdp /* Whether this enum has been defined. */ 3740130561Sobrien bfd_boolean defined; 374133965Sjdp /* Tag. */ 374233965Sjdp const char *tag; 374333965Sjdp /* Names. */ 374433965Sjdp const char **names; 374533965Sjdp /* Values. */ 374633965Sjdp bfd_signed_vma *vals; 374733965Sjdp}; 374833965Sjdp 374933965Sjdp/* We keep a list of modified versions of types, so that we don't 375033965Sjdp output them more than once. */ 375133965Sjdp 375233965Sjdpstruct ieee_modified_type 375333965Sjdp{ 375433965Sjdp /* Pointer to this type. */ 375533965Sjdp unsigned int pointer; 375633965Sjdp /* Function with unknown arguments returning this type. */ 375733965Sjdp unsigned int function; 375833965Sjdp /* Const version of this type. */ 375933965Sjdp unsigned int const_qualified; 376033965Sjdp /* Volatile version of this type. */ 376133965Sjdp unsigned int volatile_qualified; 376233965Sjdp /* List of arrays of this type of various bounds. */ 376333965Sjdp struct ieee_modified_array_type *arrays; 376433965Sjdp}; 376533965Sjdp 376633965Sjdp/* A list of arrays bounds. */ 376733965Sjdp 376833965Sjdpstruct ieee_modified_array_type 376933965Sjdp{ 377033965Sjdp /* Next array bounds. */ 377133965Sjdp struct ieee_modified_array_type *next; 377233965Sjdp /* Type index with these bounds. */ 377333965Sjdp unsigned int indx; 377433965Sjdp /* Low bound. */ 377533965Sjdp bfd_signed_vma low; 377633965Sjdp /* High bound. */ 377733965Sjdp bfd_signed_vma high; 377833965Sjdp}; 377933965Sjdp 378033965Sjdp/* This is a list of pending function parameter information. We don't 378133965Sjdp output them until we see the first block. */ 378233965Sjdp 378333965Sjdpstruct ieee_pending_parm 378433965Sjdp{ 378533965Sjdp /* Next pending parameter. */ 378633965Sjdp struct ieee_pending_parm *next; 378733965Sjdp /* Name. */ 378833965Sjdp const char *name; 378933965Sjdp /* Type index. */ 379033965Sjdp unsigned int type; 379133965Sjdp /* Whether the type is a reference. */ 3792130561Sobrien bfd_boolean referencep; 379333965Sjdp /* Kind. */ 379433965Sjdp enum debug_parm_kind kind; 379533965Sjdp /* Value. */ 379633965Sjdp bfd_vma val; 379733965Sjdp}; 379833965Sjdp 379933965Sjdp/* This is the handle passed down by debug_write. */ 380033965Sjdp 380133965Sjdpstruct ieee_handle 380233965Sjdp{ 380333965Sjdp /* BFD we are writing to. */ 380433965Sjdp bfd *abfd; 380533965Sjdp /* Whether we got an error in a subroutine called via traverse or 380633965Sjdp map_over_sections. */ 3807130561Sobrien bfd_boolean error; 380833965Sjdp /* Current data buffer list. */ 380933965Sjdp struct ieee_buflist *current; 381033965Sjdp /* Current data buffer. */ 381133965Sjdp struct ieee_buf *curbuf; 381233965Sjdp /* Filename of current compilation unit. */ 381333965Sjdp const char *filename; 381433965Sjdp /* Module name of current compilation unit. */ 381533965Sjdp const char *modname; 381633965Sjdp /* List of buffer for global types. */ 381733965Sjdp struct ieee_buflist global_types; 381833965Sjdp /* List of finished data buffers. */ 381933965Sjdp struct ieee_buflist data; 382033965Sjdp /* List of buffers for typedefs in the current compilation unit. */ 382133965Sjdp struct ieee_buflist types; 382233965Sjdp /* List of buffers for variables and functions in the current 382333965Sjdp compilation unit. */ 382433965Sjdp struct ieee_buflist vars; 382533965Sjdp /* List of buffers for C++ class definitions in the current 382633965Sjdp compilation unit. */ 382733965Sjdp struct ieee_buflist cxx; 382833965Sjdp /* List of buffers for line numbers in the current compilation unit. */ 382933965Sjdp struct ieee_buflist linenos; 383033965Sjdp /* Ranges for the current compilation unit. */ 383133965Sjdp struct ieee_range *ranges; 383233965Sjdp /* Ranges for all debugging information. */ 383333965Sjdp struct ieee_range *global_ranges; 383433965Sjdp /* Nested pending ranges. */ 383533965Sjdp struct ieee_range *pending_ranges; 383633965Sjdp /* Type stack. */ 383733965Sjdp struct ieee_type_stack *type_stack; 383833965Sjdp /* Next unallocated type index. */ 383933965Sjdp unsigned int type_indx; 384033965Sjdp /* Next unallocated name index. */ 384133965Sjdp unsigned int name_indx; 384233965Sjdp /* Typedefs. */ 384333965Sjdp struct ieee_name_type_hash_table typedefs; 384433965Sjdp /* Tags. */ 384533965Sjdp struct ieee_name_type_hash_table tags; 384633965Sjdp /* Enums. */ 384733965Sjdp struct ieee_defined_enum *enums; 384833965Sjdp /* Modified versions of types. */ 384933965Sjdp struct ieee_modified_type *modified; 385033965Sjdp /* Number of entries allocated in modified. */ 385133965Sjdp unsigned int modified_alloc; 385233965Sjdp /* 4 byte complex type. */ 385333965Sjdp unsigned int complex_float_index; 385433965Sjdp /* 8 byte complex type. */ 385533965Sjdp unsigned int complex_double_index; 385633965Sjdp /* The depth of block nesting. This is 0 outside a function, and 1 385733965Sjdp just after start_function is called. */ 385833965Sjdp unsigned int block_depth; 385933965Sjdp /* The name of the current function. */ 386033965Sjdp const char *fnname; 386133965Sjdp /* List of buffers for the type of the function we are currently 386233965Sjdp writing out. */ 386333965Sjdp struct ieee_buflist fntype; 386433965Sjdp /* List of buffers for the parameters of the function we are 386533965Sjdp currently writing out. */ 386633965Sjdp struct ieee_buflist fnargs; 386733965Sjdp /* Number of arguments written to fnargs. */ 386833965Sjdp unsigned int fnargcount; 386933965Sjdp /* Pending function parameters. */ 387033965Sjdp struct ieee_pending_parm *pending_parms; 387133965Sjdp /* Current line number filename. */ 387233965Sjdp const char *lineno_filename; 387333965Sjdp /* Line number name index. */ 387433965Sjdp unsigned int lineno_name_indx; 387533965Sjdp /* Filename of pending line number. */ 387633965Sjdp const char *pending_lineno_filename; 387733965Sjdp /* Pending line number. */ 387833965Sjdp unsigned long pending_lineno; 387933965Sjdp /* Address of pending line number. */ 388033965Sjdp bfd_vma pending_lineno_addr; 388133965Sjdp /* Highest address seen at end of procedure. */ 388233965Sjdp bfd_vma highaddr; 388333965Sjdp}; 388433965Sjdp 3885130561Sobrienstatic bfd_boolean ieee_init_buffer 3886130561Sobrien (struct ieee_handle *, struct ieee_buflist *); 3887130561Sobrienstatic bfd_boolean ieee_change_buffer 3888130561Sobrien (struct ieee_handle *, struct ieee_buflist *); 3889130561Sobrienstatic bfd_boolean ieee_append_buffer 3890130561Sobrien (struct ieee_handle *, struct ieee_buflist *, struct ieee_buflist *); 3891130561Sobrienstatic bfd_boolean ieee_real_write_byte (struct ieee_handle *, int); 3892130561Sobrienstatic bfd_boolean ieee_write_2bytes (struct ieee_handle *, int); 3893130561Sobrienstatic bfd_boolean ieee_write_number (struct ieee_handle *, bfd_vma); 3894130561Sobrienstatic bfd_boolean ieee_write_id (struct ieee_handle *, const char *); 3895130561Sobrienstatic bfd_boolean ieee_write_asn 3896130561Sobrien (struct ieee_handle *, unsigned int, bfd_vma); 3897130561Sobrienstatic bfd_boolean ieee_write_atn65 3898130561Sobrien (struct ieee_handle *, unsigned int, const char *); 3899130561Sobrienstatic bfd_boolean ieee_push_type 3900130561Sobrien (struct ieee_handle *, unsigned int, unsigned int, bfd_boolean, 3901130561Sobrien bfd_boolean); 3902130561Sobrienstatic unsigned int ieee_pop_type (struct ieee_handle *); 3903130561Sobrienstatic void ieee_pop_unused_type (struct ieee_handle *); 3904130561Sobrienstatic unsigned int ieee_pop_type_used (struct ieee_handle *, bfd_boolean); 3905130561Sobrienstatic bfd_boolean ieee_add_range 3906130561Sobrien (struct ieee_handle *, bfd_boolean, bfd_vma, bfd_vma); 3907130561Sobrienstatic bfd_boolean ieee_start_range (struct ieee_handle *, bfd_vma); 3908130561Sobrienstatic bfd_boolean ieee_end_range (struct ieee_handle *, bfd_vma); 3909130561Sobrienstatic bfd_boolean ieee_define_type 3910130561Sobrien (struct ieee_handle *, unsigned int, bfd_boolean, bfd_boolean); 3911130561Sobrienstatic bfd_boolean ieee_define_named_type 3912130561Sobrien (struct ieee_handle *, const char *, unsigned int, unsigned int, 3913130561Sobrien bfd_boolean, bfd_boolean, struct ieee_buflist *); 391433965Sjdpstatic struct ieee_modified_type *ieee_get_modified_info 3915130561Sobrien (struct ieee_handle *, unsigned int); 391633965Sjdpstatic struct bfd_hash_entry *ieee_name_type_newfunc 3917130561Sobrien (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); 3918130561Sobrienstatic bfd_boolean ieee_write_undefined_tag 3919130561Sobrien (struct ieee_name_type_hash_entry *, void *); 3920130561Sobrienstatic bfd_boolean ieee_finish_compilation_unit (struct ieee_handle *); 3921130561Sobrienstatic void ieee_add_bb11_blocks (bfd *, asection *, void *); 3922130561Sobrienstatic bfd_boolean ieee_add_bb11 3923130561Sobrien (struct ieee_handle *, asection *, bfd_vma, bfd_vma); 3924130561Sobrienstatic bfd_boolean ieee_output_pending_parms (struct ieee_handle *); 3925130561Sobrienstatic unsigned int ieee_vis_to_flags (enum debug_visibility); 3926130561Sobrienstatic bfd_boolean ieee_class_method_var 3927130561Sobrien (struct ieee_handle *, const char *, enum debug_visibility, bfd_boolean, 3928130561Sobrien bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean); 392933965Sjdp 3930130561Sobrienstatic bfd_boolean ieee_start_compilation_unit (void *, const char *); 3931130561Sobrienstatic bfd_boolean ieee_start_source (void *, const char *); 3932130561Sobrienstatic bfd_boolean ieee_empty_type (void *); 3933130561Sobrienstatic bfd_boolean ieee_void_type (void *); 3934130561Sobrienstatic bfd_boolean ieee_int_type (void *, unsigned int, bfd_boolean); 3935130561Sobrienstatic bfd_boolean ieee_float_type (void *, unsigned int); 3936130561Sobrienstatic bfd_boolean ieee_complex_type (void *, unsigned int); 3937130561Sobrienstatic bfd_boolean ieee_bool_type (void *, unsigned int); 3938130561Sobrienstatic bfd_boolean ieee_enum_type 3939130561Sobrien (void *, const char *, const char **, bfd_signed_vma *); 3940130561Sobrienstatic bfd_boolean ieee_pointer_type (void *); 3941130561Sobrienstatic bfd_boolean ieee_function_type (void *, int, bfd_boolean); 3942130561Sobrienstatic bfd_boolean ieee_reference_type (void *); 3943130561Sobrienstatic bfd_boolean ieee_range_type (void *, bfd_signed_vma, bfd_signed_vma); 3944130561Sobrienstatic bfd_boolean ieee_array_type 3945130561Sobrien (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean); 3946130561Sobrienstatic bfd_boolean ieee_set_type (void *, bfd_boolean); 3947130561Sobrienstatic bfd_boolean ieee_offset_type (void *); 3948130561Sobrienstatic bfd_boolean ieee_method_type (void *, bfd_boolean, int, bfd_boolean); 3949130561Sobrienstatic bfd_boolean ieee_const_type (void *); 3950130561Sobrienstatic bfd_boolean ieee_volatile_type (void *); 3951130561Sobrienstatic bfd_boolean ieee_start_struct_type 3952130561Sobrien (void *, const char *, unsigned int, bfd_boolean, unsigned int); 3953130561Sobrienstatic bfd_boolean ieee_struct_field 3954130561Sobrien (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility); 3955130561Sobrienstatic bfd_boolean ieee_end_struct_type (void *); 3956130561Sobrienstatic bfd_boolean ieee_start_class_type 3957130561Sobrien (void *, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, 3958130561Sobrien bfd_boolean); 3959130561Sobrienstatic bfd_boolean ieee_class_static_member 3960130561Sobrien (void *, const char *, const char *, enum debug_visibility); 3961130561Sobrienstatic bfd_boolean ieee_class_baseclass 3962130561Sobrien (void *, bfd_vma, bfd_boolean, enum debug_visibility); 3963130561Sobrienstatic bfd_boolean ieee_class_start_method (void *, const char *); 3964130561Sobrienstatic bfd_boolean ieee_class_method_variant 3965130561Sobrien (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, 3966130561Sobrien bfd_vma, bfd_boolean); 3967130561Sobrienstatic bfd_boolean ieee_class_static_method_variant 3968130561Sobrien (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean); 3969130561Sobrienstatic bfd_boolean ieee_class_end_method (void *); 3970130561Sobrienstatic bfd_boolean ieee_end_class_type (void *); 3971130561Sobrienstatic bfd_boolean ieee_typedef_type (void *, const char *); 3972130561Sobrienstatic bfd_boolean ieee_tag_type 3973130561Sobrien (void *, const char *, unsigned int, enum debug_type_kind); 3974130561Sobrienstatic bfd_boolean ieee_typdef (void *, const char *); 3975130561Sobrienstatic bfd_boolean ieee_tag (void *, const char *); 3976130561Sobrienstatic bfd_boolean ieee_int_constant (void *, const char *, bfd_vma); 3977130561Sobrienstatic bfd_boolean ieee_float_constant (void *, const char *, double); 3978130561Sobrienstatic bfd_boolean ieee_typed_constant (void *, const char *, bfd_vma); 3979130561Sobrienstatic bfd_boolean ieee_variable 3980130561Sobrien (void *, const char *, enum debug_var_kind, bfd_vma); 3981130561Sobrienstatic bfd_boolean ieee_start_function (void *, const char *, bfd_boolean); 3982130561Sobrienstatic bfd_boolean ieee_function_parameter 3983130561Sobrien (void *, const char *, enum debug_parm_kind, bfd_vma); 3984130561Sobrienstatic bfd_boolean ieee_start_block (void *, bfd_vma); 3985130561Sobrienstatic bfd_boolean ieee_end_block (void *, bfd_vma); 3986130561Sobrienstatic bfd_boolean ieee_end_function (void *); 3987130561Sobrienstatic bfd_boolean ieee_lineno (void *, const char *, unsigned long, bfd_vma); 398833965Sjdp 398933965Sjdpstatic const struct debug_write_fns ieee_fns = 399033965Sjdp{ 399133965Sjdp ieee_start_compilation_unit, 399233965Sjdp ieee_start_source, 399333965Sjdp ieee_empty_type, 399433965Sjdp ieee_void_type, 399533965Sjdp ieee_int_type, 399633965Sjdp ieee_float_type, 399733965Sjdp ieee_complex_type, 399833965Sjdp ieee_bool_type, 399933965Sjdp ieee_enum_type, 400033965Sjdp ieee_pointer_type, 400133965Sjdp ieee_function_type, 400233965Sjdp ieee_reference_type, 400333965Sjdp ieee_range_type, 400433965Sjdp ieee_array_type, 400533965Sjdp ieee_set_type, 400633965Sjdp ieee_offset_type, 400733965Sjdp ieee_method_type, 400833965Sjdp ieee_const_type, 400933965Sjdp ieee_volatile_type, 401033965Sjdp ieee_start_struct_type, 401133965Sjdp ieee_struct_field, 401233965Sjdp ieee_end_struct_type, 401333965Sjdp ieee_start_class_type, 401433965Sjdp ieee_class_static_member, 401533965Sjdp ieee_class_baseclass, 401633965Sjdp ieee_class_start_method, 401733965Sjdp ieee_class_method_variant, 401833965Sjdp ieee_class_static_method_variant, 401933965Sjdp ieee_class_end_method, 402033965Sjdp ieee_end_class_type, 402133965Sjdp ieee_typedef_type, 402233965Sjdp ieee_tag_type, 402333965Sjdp ieee_typdef, 402433965Sjdp ieee_tag, 402533965Sjdp ieee_int_constant, 402633965Sjdp ieee_float_constant, 402733965Sjdp ieee_typed_constant, 402833965Sjdp ieee_variable, 402933965Sjdp ieee_start_function, 403033965Sjdp ieee_function_parameter, 403133965Sjdp ieee_start_block, 403233965Sjdp ieee_end_block, 403333965Sjdp ieee_end_function, 403433965Sjdp ieee_lineno 403533965Sjdp}; 403633965Sjdp 403733965Sjdp/* Initialize a buffer to be empty. */ 403833965Sjdp 4039130561Sobrienstatic bfd_boolean 4040130561Sobrienieee_init_buffer (struct ieee_handle *info ATTRIBUTE_UNUSED, 4041130561Sobrien struct ieee_buflist *buflist) 404233965Sjdp{ 404333965Sjdp buflist->head = NULL; 404433965Sjdp buflist->tail = NULL; 4045130561Sobrien return TRUE; 404633965Sjdp} 404733965Sjdp 404833965Sjdp/* See whether a buffer list has any data. */ 404933965Sjdp 405033965Sjdp#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL) 405133965Sjdp 405233965Sjdp/* Change the current buffer to a specified buffer chain. */ 405333965Sjdp 4054130561Sobrienstatic bfd_boolean 4055130561Sobrienieee_change_buffer (struct ieee_handle *info, struct ieee_buflist *buflist) 405633965Sjdp{ 405733965Sjdp if (buflist->head == NULL) 405833965Sjdp { 405933965Sjdp struct ieee_buf *buf; 406033965Sjdp 406133965Sjdp buf = (struct ieee_buf *) xmalloc (sizeof *buf); 406233965Sjdp buf->next = NULL; 406333965Sjdp buf->c = 0; 406433965Sjdp buflist->head = buf; 406533965Sjdp buflist->tail = buf; 406633965Sjdp } 406733965Sjdp 406833965Sjdp info->current = buflist; 406933965Sjdp info->curbuf = buflist->tail; 407033965Sjdp 4071130561Sobrien return TRUE; 407233965Sjdp} 407333965Sjdp 407433965Sjdp/* Append a buffer chain. */ 407533965Sjdp 4076130561Sobrienstatic bfd_boolean 4077130561Sobrienieee_append_buffer (struct ieee_handle *info ATTRIBUTE_UNUSED, 4078130561Sobrien struct ieee_buflist *mainbuf, 4079130561Sobrien struct ieee_buflist *newbuf) 408033965Sjdp{ 408133965Sjdp if (newbuf->head != NULL) 408233965Sjdp { 408333965Sjdp if (mainbuf->head == NULL) 408433965Sjdp mainbuf->head = newbuf->head; 408533965Sjdp else 408633965Sjdp mainbuf->tail->next = newbuf->head; 408733965Sjdp mainbuf->tail = newbuf->tail; 408833965Sjdp } 4089130561Sobrien return TRUE; 409033965Sjdp} 409133965Sjdp 409233965Sjdp/* Write a byte into the buffer. We use a macro for speed and a 409333965Sjdp function for the complex cases. */ 409433965Sjdp 409533965Sjdp#define ieee_write_byte(info, b) \ 409633965Sjdp ((info)->curbuf->c < IEEE_BUFSIZE \ 4097130561Sobrien ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), TRUE) \ 409833965Sjdp : ieee_real_write_byte ((info), (b))) 409933965Sjdp 4100130561Sobrienstatic bfd_boolean 4101130561Sobrienieee_real_write_byte (struct ieee_handle *info, int b) 410233965Sjdp{ 410333965Sjdp if (info->curbuf->c >= IEEE_BUFSIZE) 410433965Sjdp { 410533965Sjdp struct ieee_buf *n; 410633965Sjdp 410733965Sjdp n = (struct ieee_buf *) xmalloc (sizeof *n); 410833965Sjdp n->next = NULL; 410933965Sjdp n->c = 0; 411033965Sjdp if (info->current->head == NULL) 411133965Sjdp info->current->head = n; 411233965Sjdp else 411333965Sjdp info->current->tail->next = n; 411433965Sjdp info->current->tail = n; 411533965Sjdp info->curbuf = n; 411633965Sjdp } 411733965Sjdp 411833965Sjdp info->curbuf->buf[info->curbuf->c] = b; 411933965Sjdp ++info->curbuf->c; 412033965Sjdp 4121130561Sobrien return TRUE; 412233965Sjdp} 412333965Sjdp 412433965Sjdp/* Write out two bytes. */ 412533965Sjdp 4126130561Sobrienstatic bfd_boolean 4127130561Sobrienieee_write_2bytes (struct ieee_handle *info, int i) 412833965Sjdp{ 412933965Sjdp return (ieee_write_byte (info, i >> 8) 413033965Sjdp && ieee_write_byte (info, i & 0xff)); 413133965Sjdp} 413233965Sjdp 413333965Sjdp/* Write out an integer. */ 413433965Sjdp 4135130561Sobrienstatic bfd_boolean 4136130561Sobrienieee_write_number (struct ieee_handle *info, bfd_vma v) 413733965Sjdp{ 413833965Sjdp bfd_vma t; 413933965Sjdp bfd_byte ab[20]; 414033965Sjdp bfd_byte *p; 414133965Sjdp unsigned int c; 414233965Sjdp 414333965Sjdp if (v <= (bfd_vma) ieee_number_end_enum) 414433965Sjdp return ieee_write_byte (info, (int) v); 414533965Sjdp 414633965Sjdp t = v; 414733965Sjdp p = ab + sizeof ab; 414833965Sjdp while (t != 0) 414933965Sjdp { 415033965Sjdp *--p = t & 0xff; 415133965Sjdp t >>= 8; 415233965Sjdp } 415333965Sjdp c = (ab + 20) - p; 415433965Sjdp 415533965Sjdp if (c > (unsigned int) (ieee_number_repeat_end_enum 415633965Sjdp - ieee_number_repeat_start_enum)) 415733965Sjdp { 415860484Sobrien fprintf (stderr, _("IEEE numeric overflow: 0x")); 415933965Sjdp fprintf_vma (stderr, v); 416033965Sjdp fprintf (stderr, "\n"); 4161130561Sobrien return FALSE; 416233965Sjdp } 416333965Sjdp 416433965Sjdp if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c)) 4165130561Sobrien return FALSE; 416633965Sjdp for (; c > 0; --c, ++p) 416733965Sjdp { 416833965Sjdp if (! ieee_write_byte (info, *p)) 4169130561Sobrien return FALSE; 417033965Sjdp } 417133965Sjdp 4172130561Sobrien return TRUE; 417333965Sjdp} 417433965Sjdp 417533965Sjdp/* Write out a string. */ 417633965Sjdp 4177130561Sobrienstatic bfd_boolean 4178130561Sobrienieee_write_id (struct ieee_handle *info, const char *s) 417933965Sjdp{ 418033965Sjdp unsigned int len; 418133965Sjdp 418233965Sjdp len = strlen (s); 418333965Sjdp if (len <= 0x7f) 418433965Sjdp { 418533965Sjdp if (! ieee_write_byte (info, len)) 4186130561Sobrien return FALSE; 418733965Sjdp } 418833965Sjdp else if (len <= 0xff) 418933965Sjdp { 419033965Sjdp if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum) 419133965Sjdp || ! ieee_write_byte (info, len)) 4192130561Sobrien return FALSE; 419333965Sjdp } 419433965Sjdp else if (len <= 0xffff) 419533965Sjdp { 419633965Sjdp if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum) 419733965Sjdp || ! ieee_write_2bytes (info, len)) 4198130561Sobrien return FALSE; 419933965Sjdp } 420033965Sjdp else 420133965Sjdp { 420260484Sobrien fprintf (stderr, _("IEEE string length overflow: %u\n"), len); 4203130561Sobrien return FALSE; 420433965Sjdp } 420533965Sjdp 420633965Sjdp for (; *s != '\0'; s++) 420733965Sjdp if (! ieee_write_byte (info, *s)) 4208130561Sobrien return FALSE; 420933965Sjdp 4210130561Sobrien return TRUE; 421133965Sjdp} 421233965Sjdp 421333965Sjdp/* Write out an ASN record. */ 421433965Sjdp 4215130561Sobrienstatic bfd_boolean 4216130561Sobrienieee_write_asn (struct ieee_handle *info, unsigned int indx, bfd_vma val) 421733965Sjdp{ 421833965Sjdp return (ieee_write_2bytes (info, (int) ieee_asn_record_enum) 421933965Sjdp && ieee_write_number (info, indx) 422033965Sjdp && ieee_write_number (info, val)); 422133965Sjdp} 422233965Sjdp 422333965Sjdp/* Write out an ATN65 record. */ 422433965Sjdp 4225130561Sobrienstatic bfd_boolean 4226130561Sobrienieee_write_atn65 (struct ieee_handle *info, unsigned int indx, const char *s) 422733965Sjdp{ 422833965Sjdp return (ieee_write_2bytes (info, (int) ieee_atn_record_enum) 422933965Sjdp && ieee_write_number (info, indx) 423033965Sjdp && ieee_write_number (info, 0) 423133965Sjdp && ieee_write_number (info, 65) 423233965Sjdp && ieee_write_id (info, s)); 423333965Sjdp} 423433965Sjdp 423533965Sjdp/* Push a type index onto the type stack. */ 423633965Sjdp 4237130561Sobrienstatic bfd_boolean 4238130561Sobrienieee_push_type (struct ieee_handle *info, unsigned int indx, 4239130561Sobrien unsigned int size, bfd_boolean unsignedp, bfd_boolean localp) 424033965Sjdp{ 424133965Sjdp struct ieee_type_stack *ts; 424233965Sjdp 424333965Sjdp ts = (struct ieee_type_stack *) xmalloc (sizeof *ts); 424433965Sjdp memset (ts, 0, sizeof *ts); 424533965Sjdp 424633965Sjdp ts->type.indx = indx; 424733965Sjdp ts->type.size = size; 424833965Sjdp ts->type.unsignedp = unsignedp; 424933965Sjdp ts->type.localp = localp; 425033965Sjdp 425133965Sjdp ts->next = info->type_stack; 425233965Sjdp info->type_stack = ts; 425333965Sjdp 4254130561Sobrien return TRUE; 425533965Sjdp} 425633965Sjdp 425733965Sjdp/* Pop a type index off the type stack. */ 425833965Sjdp 425933965Sjdpstatic unsigned int 4260130561Sobrienieee_pop_type (struct ieee_handle *info) 426133965Sjdp{ 4262130561Sobrien return ieee_pop_type_used (info, TRUE); 426333965Sjdp} 426433965Sjdp 426533965Sjdp/* Pop an unused type index off the type stack. */ 426633965Sjdp 426733965Sjdpstatic void 4268130561Sobrienieee_pop_unused_type (struct ieee_handle *info) 426933965Sjdp{ 4270130561Sobrien (void) ieee_pop_type_used (info, FALSE); 427133965Sjdp} 427233965Sjdp 427333965Sjdp/* Pop a used or unused type index off the type stack. */ 427433965Sjdp 427533965Sjdpstatic unsigned int 4276130561Sobrienieee_pop_type_used (struct ieee_handle *info, bfd_boolean used) 427733965Sjdp{ 427833965Sjdp struct ieee_type_stack *ts; 427933965Sjdp unsigned int ret; 428033965Sjdp 428133965Sjdp ts = info->type_stack; 428233965Sjdp assert (ts != NULL); 428333965Sjdp 428433965Sjdp /* If this is a function type, and we need it, we need to append the 428533965Sjdp actual definition to the typedef block now. */ 428633965Sjdp if (used && ! ieee_buffer_emptyp (&ts->type.fndef)) 428733965Sjdp { 428833965Sjdp struct ieee_buflist *buflist; 428933965Sjdp 429033965Sjdp if (ts->type.localp) 429133965Sjdp { 429233965Sjdp /* Make sure we have started the types block. */ 429333965Sjdp if (ieee_buffer_emptyp (&info->types)) 429433965Sjdp { 429533965Sjdp if (! ieee_change_buffer (info, &info->types) 429633965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 429733965Sjdp || ! ieee_write_byte (info, 1) 429833965Sjdp || ! ieee_write_number (info, 0) 429933965Sjdp || ! ieee_write_id (info, info->modname)) 4300130561Sobrien return FALSE; 430133965Sjdp } 430233965Sjdp buflist = &info->types; 430333965Sjdp } 430433965Sjdp else 430533965Sjdp { 430633965Sjdp /* Make sure we started the global type block. */ 430733965Sjdp if (ieee_buffer_emptyp (&info->global_types)) 430833965Sjdp { 430933965Sjdp if (! ieee_change_buffer (info, &info->global_types) 431033965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 431133965Sjdp || ! ieee_write_byte (info, 2) 431233965Sjdp || ! ieee_write_number (info, 0) 431333965Sjdp || ! ieee_write_id (info, "")) 4314130561Sobrien return FALSE; 431533965Sjdp } 431633965Sjdp buflist = &info->global_types; 431733965Sjdp } 431833965Sjdp 431933965Sjdp if (! ieee_append_buffer (info, buflist, &ts->type.fndef)) 4320130561Sobrien return FALSE; 432133965Sjdp } 432233965Sjdp 432333965Sjdp ret = ts->type.indx; 432433965Sjdp info->type_stack = ts->next; 432533965Sjdp free (ts); 432633965Sjdp return ret; 432733965Sjdp} 432833965Sjdp 432933965Sjdp/* Add a range of bytes included in the current compilation unit. */ 433033965Sjdp 4331130561Sobrienstatic bfd_boolean 4332130561Sobrienieee_add_range (struct ieee_handle *info, bfd_boolean global, bfd_vma low, 4333130561Sobrien bfd_vma high) 433433965Sjdp{ 433533965Sjdp struct ieee_range **plist, *r, **pr; 433633965Sjdp 433733965Sjdp if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high) 4338130561Sobrien return TRUE; 433933965Sjdp 434033965Sjdp if (global) 434133965Sjdp plist = &info->global_ranges; 434233965Sjdp else 434333965Sjdp plist = &info->ranges; 434433965Sjdp 434533965Sjdp for (r = *plist; r != NULL; r = r->next) 434633965Sjdp { 434733965Sjdp if (high >= r->low && low <= r->high) 434833965Sjdp { 434933965Sjdp /* The new range overlaps r. */ 435033965Sjdp if (low < r->low) 435133965Sjdp r->low = low; 435233965Sjdp if (high > r->high) 435333965Sjdp r->high = high; 435433965Sjdp pr = &r->next; 435533965Sjdp while (*pr != NULL && (*pr)->low <= r->high) 435633965Sjdp { 435733965Sjdp struct ieee_range *n; 435833965Sjdp 435933965Sjdp if ((*pr)->high > r->high) 436033965Sjdp r->high = (*pr)->high; 436133965Sjdp n = (*pr)->next; 436233965Sjdp free (*pr); 436333965Sjdp *pr = n; 436433965Sjdp } 4365130561Sobrien return TRUE; 436633965Sjdp } 436733965Sjdp } 436833965Sjdp 436933965Sjdp r = (struct ieee_range *) xmalloc (sizeof *r); 437033965Sjdp memset (r, 0, sizeof *r); 437133965Sjdp 437233965Sjdp r->low = low; 437333965Sjdp r->high = high; 437433965Sjdp 437533965Sjdp /* Store the ranges sorted by address. */ 437633965Sjdp for (pr = plist; *pr != NULL; pr = &(*pr)->next) 437733965Sjdp if ((*pr)->low > high) 437833965Sjdp break; 437933965Sjdp r->next = *pr; 438033965Sjdp *pr = r; 438133965Sjdp 4382130561Sobrien return TRUE; 438333965Sjdp} 438433965Sjdp 438533965Sjdp/* Start a new range for which we only have the low address. */ 438633965Sjdp 4387130561Sobrienstatic bfd_boolean 4388130561Sobrienieee_start_range (struct ieee_handle *info, bfd_vma low) 438933965Sjdp{ 439033965Sjdp struct ieee_range *r; 439133965Sjdp 439233965Sjdp r = (struct ieee_range *) xmalloc (sizeof *r); 439333965Sjdp memset (r, 0, sizeof *r); 439433965Sjdp r->low = low; 439533965Sjdp r->next = info->pending_ranges; 439633965Sjdp info->pending_ranges = r; 4397130561Sobrien return TRUE; 439877298Sobrien} 439933965Sjdp 440033965Sjdp/* Finish a range started by ieee_start_range. */ 440133965Sjdp 4402130561Sobrienstatic bfd_boolean 4403130561Sobrienieee_end_range (struct ieee_handle *info, bfd_vma high) 440433965Sjdp{ 440533965Sjdp struct ieee_range *r; 440633965Sjdp bfd_vma low; 440733965Sjdp 440833965Sjdp assert (info->pending_ranges != NULL); 440933965Sjdp r = info->pending_ranges; 441033965Sjdp low = r->low; 441133965Sjdp info->pending_ranges = r->next; 441233965Sjdp free (r); 4413130561Sobrien return ieee_add_range (info, FALSE, low, high); 441433965Sjdp} 441533965Sjdp 441633965Sjdp/* Start defining a type. */ 441733965Sjdp 4418130561Sobrienstatic bfd_boolean 4419130561Sobrienieee_define_type (struct ieee_handle *info, unsigned int size, 4420130561Sobrien bfd_boolean unsignedp, bfd_boolean localp) 442133965Sjdp{ 442233965Sjdp return ieee_define_named_type (info, (const char *) NULL, 442333965Sjdp (unsigned int) -1, size, unsignedp, 442433965Sjdp localp, (struct ieee_buflist *) NULL); 442533965Sjdp} 442633965Sjdp 442733965Sjdp/* Start defining a named type. */ 442833965Sjdp 4429130561Sobrienstatic bfd_boolean 4430130561Sobrienieee_define_named_type (struct ieee_handle *info, const char *name, 4431130561Sobrien unsigned int indx, unsigned int size, 4432130561Sobrien bfd_boolean unsignedp, bfd_boolean localp, 4433130561Sobrien struct ieee_buflist *buflist) 443433965Sjdp{ 443533965Sjdp unsigned int type_indx; 443633965Sjdp unsigned int name_indx; 443733965Sjdp 443833965Sjdp if (indx != (unsigned int) -1) 443933965Sjdp type_indx = indx; 444033965Sjdp else 444133965Sjdp { 444233965Sjdp type_indx = info->type_indx; 444333965Sjdp ++info->type_indx; 444433965Sjdp } 444533965Sjdp 444633965Sjdp name_indx = info->name_indx; 444733965Sjdp ++info->name_indx; 444833965Sjdp 444933965Sjdp if (name == NULL) 445033965Sjdp name = ""; 445133965Sjdp 445233965Sjdp /* If we were given a buffer, use it; otherwise, use either the 445333965Sjdp local or the global type information, and make sure that the type 445433965Sjdp block is started. */ 445533965Sjdp if (buflist != NULL) 445633965Sjdp { 445733965Sjdp if (! ieee_change_buffer (info, buflist)) 4458130561Sobrien return FALSE; 445933965Sjdp } 446033965Sjdp else if (localp) 446133965Sjdp { 446233965Sjdp if (! ieee_buffer_emptyp (&info->types)) 446333965Sjdp { 446433965Sjdp if (! ieee_change_buffer (info, &info->types)) 4465130561Sobrien return FALSE; 446633965Sjdp } 446733965Sjdp else 446833965Sjdp { 446933965Sjdp if (! ieee_change_buffer (info, &info->types) 447033965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 447133965Sjdp || ! ieee_write_byte (info, 1) 447233965Sjdp || ! ieee_write_number (info, 0) 447333965Sjdp || ! ieee_write_id (info, info->modname)) 4474130561Sobrien return FALSE; 447533965Sjdp } 447633965Sjdp } 447733965Sjdp else 447833965Sjdp { 447933965Sjdp if (! ieee_buffer_emptyp (&info->global_types)) 448033965Sjdp { 448133965Sjdp if (! ieee_change_buffer (info, &info->global_types)) 4482130561Sobrien return FALSE; 448333965Sjdp } 448433965Sjdp else 448533965Sjdp { 448633965Sjdp if (! ieee_change_buffer (info, &info->global_types) 448733965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 448833965Sjdp || ! ieee_write_byte (info, 2) 448933965Sjdp || ! ieee_write_number (info, 0) 449033965Sjdp || ! ieee_write_id (info, "")) 4491130561Sobrien return FALSE; 449233965Sjdp } 449333965Sjdp } 449433965Sjdp 449533965Sjdp /* Push the new type on the type stack, write out an NN record, and 449633965Sjdp write out the start of a TY record. The caller will then finish 449733965Sjdp the TY record. */ 449833965Sjdp if (! ieee_push_type (info, type_indx, size, unsignedp, localp)) 4499130561Sobrien return FALSE; 450033965Sjdp 450133965Sjdp return (ieee_write_byte (info, (int) ieee_nn_record) 450233965Sjdp && ieee_write_number (info, name_indx) 450333965Sjdp && ieee_write_id (info, name) 450433965Sjdp && ieee_write_byte (info, (int) ieee_ty_record_enum) 450533965Sjdp && ieee_write_number (info, type_indx) 450633965Sjdp && ieee_write_byte (info, 0xce) 450733965Sjdp && ieee_write_number (info, name_indx)); 450833965Sjdp} 450933965Sjdp 451033965Sjdp/* Get an entry to the list of modified versions of a type. */ 451133965Sjdp 451233965Sjdpstatic struct ieee_modified_type * 4513130561Sobrienieee_get_modified_info (struct ieee_handle *info, unsigned int indx) 451433965Sjdp{ 451533965Sjdp if (indx >= info->modified_alloc) 451633965Sjdp { 451733965Sjdp unsigned int nalloc; 451833965Sjdp 451933965Sjdp nalloc = info->modified_alloc; 452033965Sjdp if (nalloc == 0) 452133965Sjdp nalloc = 16; 452233965Sjdp while (indx >= nalloc) 452333965Sjdp nalloc *= 2; 452433965Sjdp info->modified = ((struct ieee_modified_type *) 452533965Sjdp xrealloc (info->modified, 452633965Sjdp nalloc * sizeof *info->modified)); 452733965Sjdp memset (info->modified + info->modified_alloc, 0, 452833965Sjdp (nalloc - info->modified_alloc) * sizeof *info->modified); 452933965Sjdp info->modified_alloc = nalloc; 453033965Sjdp } 453133965Sjdp 453233965Sjdp return info->modified + indx; 453333965Sjdp} 453433965Sjdp 453533965Sjdp/* Routines for the hash table mapping names to types. */ 453633965Sjdp 453733965Sjdp/* Initialize an entry in the hash table. */ 453833965Sjdp 453933965Sjdpstatic struct bfd_hash_entry * 4540130561Sobrienieee_name_type_newfunc (struct bfd_hash_entry *entry, 4541130561Sobrien struct bfd_hash_table *table, const char *string) 454233965Sjdp{ 454333965Sjdp struct ieee_name_type_hash_entry *ret = 454433965Sjdp (struct ieee_name_type_hash_entry *) entry; 454533965Sjdp 454633965Sjdp /* Allocate the structure if it has not already been allocated by a 454733965Sjdp subclass. */ 454833965Sjdp if (ret == NULL) 454933965Sjdp ret = ((struct ieee_name_type_hash_entry *) 455033965Sjdp bfd_hash_allocate (table, sizeof *ret)); 455133965Sjdp if (ret == NULL) 455233965Sjdp return NULL; 455333965Sjdp 455433965Sjdp /* Call the allocation method of the superclass. */ 455533965Sjdp ret = ((struct ieee_name_type_hash_entry *) 455633965Sjdp bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 455733965Sjdp if (ret) 455833965Sjdp { 455933965Sjdp /* Set local fields. */ 456033965Sjdp ret->types = NULL; 456133965Sjdp } 456233965Sjdp 456333965Sjdp return (struct bfd_hash_entry *) ret; 456433965Sjdp} 456533965Sjdp 456633965Sjdp/* Look up an entry in the hash table. */ 456733965Sjdp 456833965Sjdp#define ieee_name_type_hash_lookup(table, string, create, copy) \ 456933965Sjdp ((struct ieee_name_type_hash_entry *) \ 457033965Sjdp bfd_hash_lookup (&(table)->root, (string), (create), (copy))) 457133965Sjdp 457233965Sjdp/* Traverse the hash table. */ 457333965Sjdp 457433965Sjdp#define ieee_name_type_hash_traverse(table, func, info) \ 457533965Sjdp (bfd_hash_traverse \ 457633965Sjdp (&(table)->root, \ 4577130561Sobrien (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func), \ 457833965Sjdp (info))) 457933965Sjdp 458033965Sjdp/* The general routine to write out IEEE debugging information. */ 458133965Sjdp 4582130561Sobrienbfd_boolean 4583130561Sobrienwrite_ieee_debugging_info (bfd *abfd, void *dhandle) 458433965Sjdp{ 458533965Sjdp struct ieee_handle info; 458633965Sjdp asection *s; 458733965Sjdp const char *err; 458833965Sjdp struct ieee_buf *b; 458933965Sjdp 459033965Sjdp memset (&info, 0, sizeof info); 459133965Sjdp info.abfd = abfd; 459233965Sjdp info.type_indx = 256; 459333965Sjdp info.name_indx = 32; 459433965Sjdp 4595218822Sdim if (!bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc, 4596218822Sdim sizeof (struct ieee_name_type_hash_entry)) 4597218822Sdim || !bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc, 4598218822Sdim sizeof (struct ieee_name_type_hash_entry))) 4599130561Sobrien return FALSE; 460033965Sjdp 460133965Sjdp if (! ieee_init_buffer (&info, &info.global_types) 460233965Sjdp || ! ieee_init_buffer (&info, &info.data) 460333965Sjdp || ! ieee_init_buffer (&info, &info.types) 460433965Sjdp || ! ieee_init_buffer (&info, &info.vars) 460533965Sjdp || ! ieee_init_buffer (&info, &info.cxx) 460633965Sjdp || ! ieee_init_buffer (&info, &info.linenos) 460733965Sjdp || ! ieee_init_buffer (&info, &info.fntype) 460833965Sjdp || ! ieee_init_buffer (&info, &info.fnargs)) 4609130561Sobrien return FALSE; 461033965Sjdp 4611130561Sobrien if (! debug_write (dhandle, &ieee_fns, (void *) &info)) 4612130561Sobrien return FALSE; 461333965Sjdp 461433965Sjdp if (info.filename != NULL) 461533965Sjdp { 461633965Sjdp if (! ieee_finish_compilation_unit (&info)) 4617130561Sobrien return FALSE; 461833965Sjdp } 461933965Sjdp 462033965Sjdp /* Put any undefined tags in the global typedef information. */ 4621130561Sobrien info.error = FALSE; 462233965Sjdp ieee_name_type_hash_traverse (&info.tags, 462333965Sjdp ieee_write_undefined_tag, 4624130561Sobrien (void *) &info); 462533965Sjdp if (info.error) 4626130561Sobrien return FALSE; 462733965Sjdp 462833965Sjdp /* Prepend the global typedef information to the other data. */ 462933965Sjdp if (! ieee_buffer_emptyp (&info.global_types)) 463033965Sjdp { 463133965Sjdp /* The HP debugger seems to have a bug in which it ignores the 463233965Sjdp last entry in the global types, so we add a dummy entry. */ 463333965Sjdp if (! ieee_change_buffer (&info, &info.global_types) 463433965Sjdp || ! ieee_write_byte (&info, (int) ieee_nn_record) 463533965Sjdp || ! ieee_write_number (&info, info.name_indx) 463633965Sjdp || ! ieee_write_id (&info, "") 463733965Sjdp || ! ieee_write_byte (&info, (int) ieee_ty_record_enum) 463833965Sjdp || ! ieee_write_number (&info, info.type_indx) 463933965Sjdp || ! ieee_write_byte (&info, 0xce) 464033965Sjdp || ! ieee_write_number (&info, info.name_indx) 464133965Sjdp || ! ieee_write_number (&info, 'P') 464233965Sjdp || ! ieee_write_number (&info, (int) builtin_void + 32) 464333965Sjdp || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) 4644130561Sobrien return FALSE; 464533965Sjdp 464633965Sjdp if (! ieee_append_buffer (&info, &info.global_types, &info.data)) 4647130561Sobrien return FALSE; 464833965Sjdp info.data = info.global_types; 464933965Sjdp } 465033965Sjdp 465133965Sjdp /* Make sure that we have declare BB11 blocks for each range in the 465233965Sjdp file. They are added to info->vars. */ 4653130561Sobrien info.error = FALSE; 465433965Sjdp if (! ieee_init_buffer (&info, &info.vars)) 4655130561Sobrien return FALSE; 4656130561Sobrien bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (void *) &info); 465733965Sjdp if (info.error) 4658130561Sobrien return FALSE; 465933965Sjdp if (! ieee_buffer_emptyp (&info.vars)) 466033965Sjdp { 466133965Sjdp if (! ieee_change_buffer (&info, &info.vars) 466233965Sjdp || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) 4663130561Sobrien return FALSE; 466433965Sjdp 466533965Sjdp if (! ieee_append_buffer (&info, &info.data, &info.vars)) 4666130561Sobrien return FALSE; 466733965Sjdp } 466833965Sjdp 466933965Sjdp /* Now all the data is in info.data. Write it out to the BFD. We 467033965Sjdp normally would need to worry about whether all the other sections 467133965Sjdp are set up yet, but the IEEE backend will handle this particular 467233965Sjdp case correctly regardless. */ 467333965Sjdp if (ieee_buffer_emptyp (&info.data)) 467433965Sjdp { 467533965Sjdp /* There is no debugging information. */ 4676130561Sobrien return TRUE; 467733965Sjdp } 467833965Sjdp err = NULL; 467933965Sjdp s = bfd_make_section (abfd, ".debug"); 468033965Sjdp if (s == NULL) 468133965Sjdp err = "bfd_make_section"; 468233965Sjdp if (err == NULL) 468333965Sjdp { 468433965Sjdp if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS)) 468533965Sjdp err = "bfd_set_section_flags"; 468633965Sjdp } 468733965Sjdp if (err == NULL) 468833965Sjdp { 468933965Sjdp bfd_size_type size; 469033965Sjdp 469133965Sjdp size = 0; 469233965Sjdp for (b = info.data.head; b != NULL; b = b->next) 469333965Sjdp size += b->c; 469433965Sjdp if (! bfd_set_section_size (abfd, s, size)) 469533965Sjdp err = "bfd_set_section_size"; 469633965Sjdp } 469733965Sjdp if (err == NULL) 469833965Sjdp { 469933965Sjdp file_ptr offset; 470033965Sjdp 470133965Sjdp offset = 0; 470233965Sjdp for (b = info.data.head; b != NULL; b = b->next) 470333965Sjdp { 470433965Sjdp if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c)) 470533965Sjdp { 470633965Sjdp err = "bfd_set_section_contents"; 470733965Sjdp break; 470833965Sjdp } 470933965Sjdp offset += b->c; 471033965Sjdp } 471133965Sjdp } 471233965Sjdp 471333965Sjdp if (err != NULL) 471433965Sjdp { 471533965Sjdp fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err, 471633965Sjdp bfd_errmsg (bfd_get_error ())); 4717130561Sobrien return FALSE; 471833965Sjdp } 471933965Sjdp 472033965Sjdp bfd_hash_table_free (&info.typedefs.root); 472133965Sjdp bfd_hash_table_free (&info.tags.root); 472233965Sjdp 4723130561Sobrien return TRUE; 472433965Sjdp} 472533965Sjdp 472633965Sjdp/* Write out information for an undefined tag. This is called via 472733965Sjdp ieee_name_type_hash_traverse. */ 472833965Sjdp 4729130561Sobrienstatic bfd_boolean 4730130561Sobrienieee_write_undefined_tag (struct ieee_name_type_hash_entry *h, void *p) 473133965Sjdp{ 473233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 473333965Sjdp struct ieee_name_type *nt; 473433965Sjdp 473533965Sjdp for (nt = h->types; nt != NULL; nt = nt->next) 473633965Sjdp { 473733965Sjdp unsigned int name_indx; 473833965Sjdp char code; 473933965Sjdp 474033965Sjdp if (nt->kind == DEBUG_KIND_ILLEGAL) 474133965Sjdp continue; 474233965Sjdp 474333965Sjdp if (ieee_buffer_emptyp (&info->global_types)) 474433965Sjdp { 474533965Sjdp if (! ieee_change_buffer (info, &info->global_types) 474633965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 474733965Sjdp || ! ieee_write_byte (info, 2) 474833965Sjdp || ! ieee_write_number (info, 0) 474933965Sjdp || ! ieee_write_id (info, "")) 475033965Sjdp { 4751130561Sobrien info->error = TRUE; 4752130561Sobrien return FALSE; 475333965Sjdp } 475433965Sjdp } 475533965Sjdp else 475633965Sjdp { 475733965Sjdp if (! ieee_change_buffer (info, &info->global_types)) 475833965Sjdp { 4759130561Sobrien info->error = TRUE; 4760130561Sobrien return FALSE; 476133965Sjdp } 476233965Sjdp } 476333965Sjdp 476433965Sjdp name_indx = info->name_indx; 476533965Sjdp ++info->name_indx; 476633965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 476733965Sjdp || ! ieee_write_number (info, name_indx) 476833965Sjdp || ! ieee_write_id (info, nt->type.name) 476933965Sjdp || ! ieee_write_byte (info, (int) ieee_ty_record_enum) 477033965Sjdp || ! ieee_write_number (info, nt->type.indx) 477133965Sjdp || ! ieee_write_byte (info, 0xce) 477233965Sjdp || ! ieee_write_number (info, name_indx)) 477333965Sjdp { 4774130561Sobrien info->error = TRUE; 4775130561Sobrien return FALSE; 477633965Sjdp } 477733965Sjdp 477833965Sjdp switch (nt->kind) 477933965Sjdp { 478033965Sjdp default: 478133965Sjdp abort (); 4782130561Sobrien info->error = TRUE; 4783130561Sobrien return FALSE; 478433965Sjdp case DEBUG_KIND_STRUCT: 478533965Sjdp case DEBUG_KIND_CLASS: 478633965Sjdp code = 'S'; 478733965Sjdp break; 478833965Sjdp case DEBUG_KIND_UNION: 478933965Sjdp case DEBUG_KIND_UNION_CLASS: 479033965Sjdp code = 'U'; 479133965Sjdp break; 479233965Sjdp case DEBUG_KIND_ENUM: 479333965Sjdp code = 'E'; 479433965Sjdp break; 479533965Sjdp } 479633965Sjdp if (! ieee_write_number (info, code) 479733965Sjdp || ! ieee_write_number (info, 0)) 479833965Sjdp { 4799130561Sobrien info->error = TRUE; 4800130561Sobrien return FALSE; 480133965Sjdp } 480233965Sjdp } 480333965Sjdp 4804130561Sobrien return TRUE; 480533965Sjdp} 480633965Sjdp 480733965Sjdp/* Start writing out information for a compilation unit. */ 480833965Sjdp 4809130561Sobrienstatic bfd_boolean 4810130561Sobrienieee_start_compilation_unit (void *p, const char *filename) 481133965Sjdp{ 481233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 481333965Sjdp const char *modname; 481477298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 481561843Sobrien const char *backslash; 481677298Sobrien#endif 481733965Sjdp char *c, *s; 481833965Sjdp unsigned int nindx; 481933965Sjdp 482033965Sjdp if (info->filename != NULL) 482133965Sjdp { 482233965Sjdp if (! ieee_finish_compilation_unit (info)) 4823130561Sobrien return FALSE; 482433965Sjdp } 482533965Sjdp 482633965Sjdp info->filename = filename; 482733965Sjdp modname = strrchr (filename, '/'); 482877298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 482961843Sobrien /* We could have a mixed forward/back slash case. */ 483077298Sobrien backslash = strrchr (filename, '\\'); 483177298Sobrien if (modname == NULL || (backslash != NULL && backslash > modname)) 483261843Sobrien modname = backslash; 483377298Sobrien#endif 483461843Sobrien 483533965Sjdp if (modname != NULL) 483633965Sjdp ++modname; 483761843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 483861843Sobrien else if (filename[0] && filename[1] == ':') 483961843Sobrien modname = filename + 2; 484061843Sobrien#endif 484133965Sjdp else 484261843Sobrien modname = filename; 484361843Sobrien 484433965Sjdp c = xstrdup (modname); 484533965Sjdp s = strrchr (c, '.'); 484633965Sjdp if (s != NULL) 484733965Sjdp *s = '\0'; 484833965Sjdp info->modname = c; 484933965Sjdp 485033965Sjdp if (! ieee_init_buffer (info, &info->types) 485133965Sjdp || ! ieee_init_buffer (info, &info->vars) 485233965Sjdp || ! ieee_init_buffer (info, &info->cxx) 485333965Sjdp || ! ieee_init_buffer (info, &info->linenos)) 4854130561Sobrien return FALSE; 485533965Sjdp info->ranges = NULL; 485633965Sjdp 485733965Sjdp /* Always include a BB1 and a BB3 block. That is what the output of 485833965Sjdp the MRI linker seems to look like. */ 485933965Sjdp if (! ieee_change_buffer (info, &info->types) 486033965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 486133965Sjdp || ! ieee_write_byte (info, 1) 486233965Sjdp || ! ieee_write_number (info, 0) 486333965Sjdp || ! ieee_write_id (info, info->modname)) 4864130561Sobrien return FALSE; 486533965Sjdp 486633965Sjdp nindx = info->name_indx; 486733965Sjdp ++info->name_indx; 486833965Sjdp if (! ieee_change_buffer (info, &info->vars) 486933965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 487033965Sjdp || ! ieee_write_byte (info, 3) 487133965Sjdp || ! ieee_write_number (info, 0) 487233965Sjdp || ! ieee_write_id (info, info->modname)) 4873130561Sobrien return FALSE; 487433965Sjdp 4875130561Sobrien return TRUE; 487633965Sjdp} 487733965Sjdp 487833965Sjdp/* Finish up a compilation unit. */ 487933965Sjdp 4880130561Sobrienstatic bfd_boolean 4881130561Sobrienieee_finish_compilation_unit (struct ieee_handle *info) 488233965Sjdp{ 488333965Sjdp struct ieee_range *r; 488433965Sjdp 488533965Sjdp if (! ieee_buffer_emptyp (&info->types)) 488633965Sjdp { 488733965Sjdp if (! ieee_change_buffer (info, &info->types) 488833965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum)) 4889130561Sobrien return FALSE; 489033965Sjdp } 489133965Sjdp 489233965Sjdp if (! ieee_buffer_emptyp (&info->cxx)) 489333965Sjdp { 489433965Sjdp /* Append any C++ information to the global function and 489533965Sjdp variable information. */ 489633965Sjdp assert (! ieee_buffer_emptyp (&info->vars)); 489733965Sjdp if (! ieee_change_buffer (info, &info->vars)) 4898130561Sobrien return FALSE; 489933965Sjdp 490033965Sjdp /* We put the pmisc records in a dummy procedure, just as the 490133965Sjdp MRI compiler does. */ 490233965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 490333965Sjdp || ! ieee_write_byte (info, 6) 490433965Sjdp || ! ieee_write_number (info, 0) 490533965Sjdp || ! ieee_write_id (info, "__XRYCPP") 490633965Sjdp || ! ieee_write_number (info, 0) 490733965Sjdp || ! ieee_write_number (info, 0) 490833965Sjdp || ! ieee_write_number (info, info->highaddr - 1) 490933965Sjdp || ! ieee_append_buffer (info, &info->vars, &info->cxx) 491033965Sjdp || ! ieee_change_buffer (info, &info->vars) 491133965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 491233965Sjdp || ! ieee_write_number (info, info->highaddr - 1)) 4913130561Sobrien return FALSE; 491433965Sjdp } 491533965Sjdp 491633965Sjdp if (! ieee_buffer_emptyp (&info->vars)) 491733965Sjdp { 491833965Sjdp if (! ieee_change_buffer (info, &info->vars) 491933965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum)) 4920130561Sobrien return FALSE; 492133965Sjdp } 492233965Sjdp 492333965Sjdp if (info->pending_lineno_filename != NULL) 492433965Sjdp { 492533965Sjdp /* Force out the pending line number. */ 4926130561Sobrien if (! ieee_lineno ((void *) info, (const char *) NULL, 0, (bfd_vma) -1)) 4927130561Sobrien return FALSE; 492833965Sjdp } 492933965Sjdp if (! ieee_buffer_emptyp (&info->linenos)) 493033965Sjdp { 493133965Sjdp if (! ieee_change_buffer (info, &info->linenos) 493233965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum)) 4933130561Sobrien return FALSE; 493433965Sjdp if (strcmp (info->filename, info->lineno_filename) != 0) 493533965Sjdp { 493633965Sjdp /* We were not in the main file. We just closed the 493733965Sjdp included line number block, and now we must close the 493833965Sjdp main line number block. */ 493933965Sjdp if (! ieee_write_byte (info, (int) ieee_be_record_enum)) 4940130561Sobrien return FALSE; 494133965Sjdp } 494233965Sjdp } 494333965Sjdp 494433965Sjdp if (! ieee_append_buffer (info, &info->data, &info->types) 494533965Sjdp || ! ieee_append_buffer (info, &info->data, &info->vars) 494633965Sjdp || ! ieee_append_buffer (info, &info->data, &info->linenos)) 4947130561Sobrien return FALSE; 494833965Sjdp 494933965Sjdp /* Build BB10/BB11 blocks based on the ranges we recorded. */ 495033965Sjdp if (! ieee_change_buffer (info, &info->data)) 4951130561Sobrien return FALSE; 495233965Sjdp 495333965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 495433965Sjdp || ! ieee_write_byte (info, 10) 495533965Sjdp || ! ieee_write_number (info, 0) 495633965Sjdp || ! ieee_write_id (info, info->modname) 495733965Sjdp || ! ieee_write_id (info, "") 495833965Sjdp || ! ieee_write_number (info, 0) 495933965Sjdp || ! ieee_write_id (info, "GNU objcopy")) 4960130561Sobrien return FALSE; 496133965Sjdp 496233965Sjdp for (r = info->ranges; r != NULL; r = r->next) 496333965Sjdp { 496433965Sjdp bfd_vma low, high; 496533965Sjdp asection *s; 496633965Sjdp int kind; 496733965Sjdp 496833965Sjdp low = r->low; 496933965Sjdp high = r->high; 497033965Sjdp 497133965Sjdp /* Find the section corresponding to this range. */ 497233965Sjdp for (s = info->abfd->sections; s != NULL; s = s->next) 497333965Sjdp { 497433965Sjdp if (bfd_get_section_vma (info->abfd, s) <= low 497533965Sjdp && high <= (bfd_get_section_vma (info->abfd, s) 497633965Sjdp + bfd_section_size (info->abfd, s))) 497733965Sjdp break; 497833965Sjdp } 497933965Sjdp 498033965Sjdp if (s == NULL) 498133965Sjdp { 498233965Sjdp /* Just ignore this range. */ 498333965Sjdp continue; 498433965Sjdp } 498533965Sjdp 498633965Sjdp /* Coalesce ranges if it seems reasonable. */ 498733965Sjdp while (r->next != NULL 498833965Sjdp && high + 0x1000 >= r->next->low 498933965Sjdp && (r->next->high 499033965Sjdp <= (bfd_get_section_vma (info->abfd, s) 499133965Sjdp + bfd_section_size (info->abfd, s)))) 499233965Sjdp { 499333965Sjdp r = r->next; 499433965Sjdp high = r->high; 499533965Sjdp } 499633965Sjdp 499733965Sjdp if ((s->flags & SEC_CODE) != 0) 499833965Sjdp kind = 1; 499933965Sjdp else if ((s->flags & SEC_READONLY) != 0) 500033965Sjdp kind = 3; 500133965Sjdp else 500233965Sjdp kind = 2; 500333965Sjdp 500433965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 500533965Sjdp || ! ieee_write_byte (info, 11) 500633965Sjdp || ! ieee_write_number (info, 0) 500733965Sjdp || ! ieee_write_id (info, "") 500833965Sjdp || ! ieee_write_number (info, kind) 500933965Sjdp || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE) 501033965Sjdp || ! ieee_write_number (info, low) 501133965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 501233965Sjdp || ! ieee_write_number (info, high - low)) 5013130561Sobrien return FALSE; 501433965Sjdp 501533965Sjdp /* Add this range to the list of global ranges. */ 5016130561Sobrien if (! ieee_add_range (info, TRUE, low, high)) 5017130561Sobrien return FALSE; 501833965Sjdp } 501933965Sjdp 502033965Sjdp if (! ieee_write_byte (info, (int) ieee_be_record_enum)) 5021130561Sobrien return FALSE; 502233965Sjdp 5023130561Sobrien return TRUE; 502433965Sjdp} 502533965Sjdp 502633965Sjdp/* Add BB11 blocks describing each range that we have not already 502733965Sjdp described. */ 502833965Sjdp 502933965Sjdpstatic void 5030130561Sobrienieee_add_bb11_blocks (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *data) 503133965Sjdp{ 503233965Sjdp struct ieee_handle *info = (struct ieee_handle *) data; 503333965Sjdp bfd_vma low, high; 503433965Sjdp struct ieee_range *r; 503533965Sjdp 503633965Sjdp low = bfd_get_section_vma (abfd, sec); 503733965Sjdp high = low + bfd_section_size (abfd, sec); 503833965Sjdp 503933965Sjdp /* Find the first range at or after this section. The ranges are 504033965Sjdp sorted by address. */ 504133965Sjdp for (r = info->global_ranges; r != NULL; r = r->next) 504233965Sjdp if (r->high > low) 504333965Sjdp break; 504433965Sjdp 504533965Sjdp while (low < high) 504633965Sjdp { 504733965Sjdp if (r == NULL || r->low >= high) 504833965Sjdp { 504933965Sjdp if (! ieee_add_bb11 (info, sec, low, high)) 5050130561Sobrien info->error = TRUE; 505133965Sjdp return; 505233965Sjdp } 505333965Sjdp 505433965Sjdp if (low < r->low 505533965Sjdp && r->low - low > 0x100) 505633965Sjdp { 505733965Sjdp if (! ieee_add_bb11 (info, sec, low, r->low)) 505833965Sjdp { 5059130561Sobrien info->error = TRUE; 506033965Sjdp return; 506133965Sjdp } 506233965Sjdp } 506333965Sjdp low = r->high; 506433965Sjdp 506533965Sjdp r = r->next; 506633965Sjdp } 506733965Sjdp} 506833965Sjdp 506933965Sjdp/* Add a single BB11 block for a range. We add it to info->vars. */ 507033965Sjdp 5071130561Sobrienstatic bfd_boolean 5072130561Sobrienieee_add_bb11 (struct ieee_handle *info, asection *sec, bfd_vma low, 5073130561Sobrien bfd_vma high) 507433965Sjdp{ 507533965Sjdp int kind; 507633965Sjdp 507733965Sjdp if (! ieee_buffer_emptyp (&info->vars)) 507833965Sjdp { 507933965Sjdp if (! ieee_change_buffer (info, &info->vars)) 5080130561Sobrien return FALSE; 508133965Sjdp } 508233965Sjdp else 508333965Sjdp { 508477298Sobrien const char *filename, *modname; 508577298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 508677298Sobrien const char *backslash; 508777298Sobrien#endif 508833965Sjdp char *c, *s; 508933965Sjdp 509033965Sjdp /* Start the enclosing BB10 block. */ 509133965Sjdp filename = bfd_get_filename (info->abfd); 509233965Sjdp modname = strrchr (filename, '/'); 509377298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 509477298Sobrien backslash = strrchr (filename, '\\'); 509577298Sobrien if (modname == NULL || (backslash != NULL && backslash > modname)) 509661843Sobrien modname = backslash; 509777298Sobrien#endif 509861843Sobrien 509933965Sjdp if (modname != NULL) 510033965Sjdp ++modname; 510161843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 510261843Sobrien else if (filename[0] && filename[1] == ':') 510361843Sobrien modname = filename + 2; 510461843Sobrien#endif 510533965Sjdp else 510661843Sobrien modname = filename; 510761843Sobrien 510833965Sjdp c = xstrdup (modname); 510933965Sjdp s = strrchr (c, '.'); 511033965Sjdp if (s != NULL) 511133965Sjdp *s = '\0'; 511233965Sjdp 511333965Sjdp if (! ieee_change_buffer (info, &info->vars) 511433965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 511533965Sjdp || ! ieee_write_byte (info, 10) 511633965Sjdp || ! ieee_write_number (info, 0) 511733965Sjdp || ! ieee_write_id (info, c) 511833965Sjdp || ! ieee_write_id (info, "") 511933965Sjdp || ! ieee_write_number (info, 0) 512033965Sjdp || ! ieee_write_id (info, "GNU objcopy")) 5121130561Sobrien return FALSE; 512233965Sjdp 512333965Sjdp free (c); 512433965Sjdp } 512533965Sjdp 512633965Sjdp if ((sec->flags & SEC_CODE) != 0) 512733965Sjdp kind = 1; 512833965Sjdp else if ((sec->flags & SEC_READONLY) != 0) 512933965Sjdp kind = 3; 513033965Sjdp else 513133965Sjdp kind = 2; 513233965Sjdp 513333965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 513433965Sjdp || ! ieee_write_byte (info, 11) 513533965Sjdp || ! ieee_write_number (info, 0) 513633965Sjdp || ! ieee_write_id (info, "") 513733965Sjdp || ! ieee_write_number (info, kind) 513833965Sjdp || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE) 513933965Sjdp || ! ieee_write_number (info, low) 514033965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 514133965Sjdp || ! ieee_write_number (info, high - low)) 5142130561Sobrien return FALSE; 514333965Sjdp 5144130561Sobrien return TRUE; 514533965Sjdp} 514633965Sjdp 514733965Sjdp/* Start recording information from a particular source file. This is 514833965Sjdp used to record which file defined which types, variables, etc. It 514933965Sjdp is not used for line numbers, since the lineno entry point passes 515033965Sjdp down the file name anyhow. IEEE debugging information doesn't seem 515133965Sjdp to store this information anywhere. */ 515233965Sjdp 5153130561Sobrienstatic bfd_boolean 5154130561Sobrienieee_start_source (void *p ATTRIBUTE_UNUSED, 5155130561Sobrien const char *filename ATTRIBUTE_UNUSED) 515633965Sjdp{ 5157130561Sobrien return TRUE; 515833965Sjdp} 515933965Sjdp 516033965Sjdp/* Make an empty type. */ 516133965Sjdp 5162130561Sobrienstatic bfd_boolean 5163130561Sobrienieee_empty_type (void *p) 516433965Sjdp{ 516533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 516633965Sjdp 5167130561Sobrien return ieee_push_type (info, (int) builtin_unknown, 0, FALSE, FALSE); 516833965Sjdp} 516933965Sjdp 517033965Sjdp/* Make a void type. */ 517133965Sjdp 5172130561Sobrienstatic bfd_boolean 5173130561Sobrienieee_void_type (void *p) 517433965Sjdp{ 517533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 517633965Sjdp 5177130561Sobrien return ieee_push_type (info, (int) builtin_void, 0, FALSE, FALSE); 517833965Sjdp} 517933965Sjdp 518033965Sjdp/* Make an integer type. */ 518133965Sjdp 5182130561Sobrienstatic bfd_boolean 5183130561Sobrienieee_int_type (void *p, unsigned int size, bfd_boolean unsignedp) 518433965Sjdp{ 518533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 518633965Sjdp unsigned int indx; 518733965Sjdp 518833965Sjdp switch (size) 518933965Sjdp { 519033965Sjdp case 1: 519133965Sjdp indx = (int) builtin_signed_char; 519233965Sjdp break; 519333965Sjdp case 2: 519433965Sjdp indx = (int) builtin_signed_short_int; 519533965Sjdp break; 519633965Sjdp case 4: 519733965Sjdp indx = (int) builtin_signed_long; 519833965Sjdp break; 519933965Sjdp case 8: 520033965Sjdp indx = (int) builtin_signed_long_long; 520133965Sjdp break; 520233965Sjdp default: 520360484Sobrien fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size); 5204130561Sobrien return FALSE; 520533965Sjdp } 520633965Sjdp 520733965Sjdp if (unsignedp) 520833965Sjdp ++indx; 520933965Sjdp 5210130561Sobrien return ieee_push_type (info, indx, size, unsignedp, FALSE); 521133965Sjdp} 521233965Sjdp 521333965Sjdp/* Make a floating point type. */ 521433965Sjdp 5215130561Sobrienstatic bfd_boolean 5216130561Sobrienieee_float_type (void *p, unsigned int size) 521733965Sjdp{ 521833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 521933965Sjdp unsigned int indx; 522033965Sjdp 522133965Sjdp switch (size) 522233965Sjdp { 522333965Sjdp case 4: 522433965Sjdp indx = (int) builtin_float; 522533965Sjdp break; 522633965Sjdp case 8: 522733965Sjdp indx = (int) builtin_double; 522833965Sjdp break; 522933965Sjdp case 12: 523033965Sjdp /* FIXME: This size really depends upon the processor. */ 523133965Sjdp indx = (int) builtin_long_double; 523233965Sjdp break; 523333965Sjdp case 16: 523433965Sjdp indx = (int) builtin_long_long_double; 523533965Sjdp break; 523633965Sjdp default: 523760484Sobrien fprintf (stderr, _("IEEE unsupported float type size %u\n"), size); 5238130561Sobrien return FALSE; 523933965Sjdp } 524033965Sjdp 5241130561Sobrien return ieee_push_type (info, indx, size, FALSE, FALSE); 524233965Sjdp} 524333965Sjdp 524433965Sjdp/* Make a complex type. */ 524533965Sjdp 5246130561Sobrienstatic bfd_boolean 5247130561Sobrienieee_complex_type (void *p, unsigned int size) 524833965Sjdp{ 524933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 525033965Sjdp char code; 525133965Sjdp 525233965Sjdp switch (size) 525333965Sjdp { 525433965Sjdp case 4: 525533965Sjdp if (info->complex_float_index != 0) 525633965Sjdp return ieee_push_type (info, info->complex_float_index, size * 2, 5257130561Sobrien FALSE, FALSE); 525833965Sjdp code = 'c'; 525933965Sjdp break; 526033965Sjdp case 12: 526133965Sjdp case 16: 526233965Sjdp /* These cases can be output by gcc -gstabs. Outputting the 526333965Sjdp wrong type is better than crashing. */ 526433965Sjdp case 8: 526533965Sjdp if (info->complex_double_index != 0) 526633965Sjdp return ieee_push_type (info, info->complex_double_index, size * 2, 5267130561Sobrien FALSE, FALSE); 526833965Sjdp code = 'd'; 526933965Sjdp break; 527033965Sjdp default: 527160484Sobrien fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size); 5272130561Sobrien return FALSE; 527333965Sjdp } 527433965Sjdp 527533965Sjdp /* FIXME: I don't know what the string is for. */ 5276130561Sobrien if (! ieee_define_type (info, size * 2, FALSE, FALSE) 527733965Sjdp || ! ieee_write_number (info, code) 527833965Sjdp || ! ieee_write_id (info, "")) 5279130561Sobrien return FALSE; 528033965Sjdp 528133965Sjdp if (size == 4) 528233965Sjdp info->complex_float_index = info->type_stack->type.indx; 528333965Sjdp else 528433965Sjdp info->complex_double_index = info->type_stack->type.indx; 528533965Sjdp 5286130561Sobrien return TRUE; 528733965Sjdp} 528833965Sjdp 528933965Sjdp/* Make a boolean type. IEEE doesn't support these, so we just make 529033965Sjdp an integer type instead. */ 529133965Sjdp 5292130561Sobrienstatic bfd_boolean 5293130561Sobrienieee_bool_type (void *p, unsigned int size) 529433965Sjdp{ 5295130561Sobrien return ieee_int_type (p, size, TRUE); 529633965Sjdp} 529733965Sjdp 529833965Sjdp/* Make an enumeration. */ 529933965Sjdp 5300130561Sobrienstatic bfd_boolean 5301130561Sobrienieee_enum_type (void *p, const char *tag, const char **names, 5302130561Sobrien bfd_signed_vma *vals) 530333965Sjdp{ 530433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 530533965Sjdp struct ieee_defined_enum *e; 5306130561Sobrien bfd_boolean localp, simple; 530733965Sjdp unsigned int indx; 530833965Sjdp int i = 0; 530933965Sjdp 5310130561Sobrien localp = FALSE; 531133965Sjdp indx = (unsigned int) -1; 531233965Sjdp for (e = info->enums; e != NULL; e = e->next) 531333965Sjdp { 531433965Sjdp if (tag == NULL) 531533965Sjdp { 531633965Sjdp if (e->tag != NULL) 531733965Sjdp continue; 531833965Sjdp } 531933965Sjdp else 532033965Sjdp { 532133965Sjdp if (e->tag == NULL 532233965Sjdp || tag[0] != e->tag[0] 532333965Sjdp || strcmp (tag, e->tag) != 0) 532433965Sjdp continue; 532533965Sjdp } 532633965Sjdp 532733965Sjdp if (! e->defined) 532833965Sjdp { 532933965Sjdp /* This enum tag has been seen but not defined. */ 533033965Sjdp indx = e->indx; 533133965Sjdp break; 533233965Sjdp } 533333965Sjdp 533433965Sjdp if (names != NULL && e->names != NULL) 533533965Sjdp { 533633965Sjdp for (i = 0; names[i] != NULL && e->names[i] != NULL; i++) 533733965Sjdp { 533833965Sjdp if (names[i][0] != e->names[i][0] 533933965Sjdp || vals[i] != e->vals[i] 534033965Sjdp || strcmp (names[i], e->names[i]) != 0) 534133965Sjdp break; 534233965Sjdp } 534333965Sjdp } 534433965Sjdp 534533965Sjdp if ((names == NULL && e->names == NULL) 534633965Sjdp || (names != NULL 534733965Sjdp && e->names != NULL 534833965Sjdp && names[i] == NULL 534933965Sjdp && e->names[i] == NULL)) 535033965Sjdp { 535133965Sjdp /* We've seen this enum before. */ 5352130561Sobrien return ieee_push_type (info, e->indx, 0, TRUE, FALSE); 535333965Sjdp } 535433965Sjdp 535533965Sjdp if (tag != NULL) 535633965Sjdp { 535733965Sjdp /* We've already seen an enum of the same name, so we must make 535833965Sjdp sure to output this one locally. */ 5359130561Sobrien localp = TRUE; 536033965Sjdp break; 536133965Sjdp } 536233965Sjdp } 536333965Sjdp 536433965Sjdp /* If this is a simple enumeration, in which the values start at 0 536533965Sjdp and always increment by 1, we can use type E. Otherwise we must 536633965Sjdp use type N. */ 536733965Sjdp 5368130561Sobrien simple = TRUE; 536933965Sjdp if (names != NULL) 537033965Sjdp { 537133965Sjdp for (i = 0; names[i] != NULL; i++) 537233965Sjdp { 537333965Sjdp if (vals[i] != i) 537433965Sjdp { 5375130561Sobrien simple = FALSE; 537633965Sjdp break; 537733965Sjdp } 537833965Sjdp } 537933965Sjdp } 538033965Sjdp 5381130561Sobrien if (! ieee_define_named_type (info, tag, indx, 0, TRUE, localp, 538233965Sjdp (struct ieee_buflist *) NULL) 538333965Sjdp || ! ieee_write_number (info, simple ? 'E' : 'N')) 5384130561Sobrien return FALSE; 538533965Sjdp if (simple) 538633965Sjdp { 538733965Sjdp /* FIXME: This is supposed to be the enumeration size, but we 538833965Sjdp don't store that. */ 538933965Sjdp if (! ieee_write_number (info, 4)) 5390130561Sobrien return FALSE; 539133965Sjdp } 539233965Sjdp if (names != NULL) 539333965Sjdp { 539433965Sjdp for (i = 0; names[i] != NULL; i++) 539533965Sjdp { 539633965Sjdp if (! ieee_write_id (info, names[i])) 5397130561Sobrien return FALSE; 539833965Sjdp if (! simple) 539933965Sjdp { 540033965Sjdp if (! ieee_write_number (info, vals[i])) 5401130561Sobrien return FALSE; 540233965Sjdp } 540333965Sjdp } 540433965Sjdp } 540533965Sjdp 540633965Sjdp if (! localp) 540733965Sjdp { 540833965Sjdp if (indx == (unsigned int) -1) 540933965Sjdp { 541033965Sjdp e = (struct ieee_defined_enum *) xmalloc (sizeof *e); 541133965Sjdp memset (e, 0, sizeof *e); 541233965Sjdp e->indx = info->type_stack->type.indx; 541333965Sjdp e->tag = tag; 541433965Sjdp 541533965Sjdp e->next = info->enums; 541633965Sjdp info->enums = e; 541733965Sjdp } 541833965Sjdp 541933965Sjdp e->names = names; 542033965Sjdp e->vals = vals; 5421130561Sobrien e->defined = TRUE; 542233965Sjdp } 542333965Sjdp 5424130561Sobrien return TRUE; 542533965Sjdp} 542633965Sjdp 542733965Sjdp/* Make a pointer type. */ 542833965Sjdp 5429130561Sobrienstatic bfd_boolean 5430130561Sobrienieee_pointer_type (void *p) 543133965Sjdp{ 543233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 5433130561Sobrien bfd_boolean localp; 543433965Sjdp unsigned int indx; 543533965Sjdp struct ieee_modified_type *m = NULL; 543633965Sjdp 543733965Sjdp localp = info->type_stack->type.localp; 543833965Sjdp indx = ieee_pop_type (info); 543933965Sjdp 544033965Sjdp /* A pointer to a simple builtin type can be obtained by adding 32. 544133965Sjdp FIXME: Will this be a short pointer, and will that matter? */ 544233965Sjdp if (indx < 32) 5443130561Sobrien return ieee_push_type (info, indx + 32, 0, TRUE, FALSE); 544433965Sjdp 544533965Sjdp if (! localp) 544633965Sjdp { 544733965Sjdp m = ieee_get_modified_info (p, indx); 544833965Sjdp if (m == NULL) 5449130561Sobrien return FALSE; 545033965Sjdp 545133965Sjdp /* FIXME: The size should depend upon the architecture. */ 545233965Sjdp if (m->pointer > 0) 5453130561Sobrien return ieee_push_type (info, m->pointer, 4, TRUE, FALSE); 545433965Sjdp } 545533965Sjdp 5456130561Sobrien if (! ieee_define_type (info, 4, TRUE, localp) 545733965Sjdp || ! ieee_write_number (info, 'P') 545833965Sjdp || ! ieee_write_number (info, indx)) 5459130561Sobrien return FALSE; 546033965Sjdp 546133965Sjdp if (! localp) 546233965Sjdp m->pointer = info->type_stack->type.indx; 546333965Sjdp 5464130561Sobrien return TRUE; 546533965Sjdp} 546633965Sjdp 546733965Sjdp/* Make a function type. This will be called for a method, but we 546833965Sjdp don't want to actually add it to the type table in that case. We 546933965Sjdp handle this by defining the type in a private buffer, and only 547033965Sjdp adding that buffer to the typedef block if we are going to use it. */ 547133965Sjdp 5472130561Sobrienstatic bfd_boolean 5473130561Sobrienieee_function_type (void *p, int argcount, bfd_boolean varargs) 547433965Sjdp{ 547533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 5476130561Sobrien bfd_boolean localp; 547733965Sjdp unsigned int *args = NULL; 547833965Sjdp int i; 547933965Sjdp unsigned int retindx; 548033965Sjdp struct ieee_buflist fndef; 548133965Sjdp struct ieee_modified_type *m; 548233965Sjdp 5483130561Sobrien localp = FALSE; 548433965Sjdp 548533965Sjdp if (argcount > 0) 548633965Sjdp { 548733965Sjdp args = (unsigned int *) xmalloc (argcount * sizeof *args); 548833965Sjdp for (i = argcount - 1; i >= 0; i--) 548933965Sjdp { 549033965Sjdp if (info->type_stack->type.localp) 5491130561Sobrien localp = TRUE; 549233965Sjdp args[i] = ieee_pop_type (info); 549333965Sjdp } 549433965Sjdp } 549533965Sjdp else if (argcount < 0) 5496130561Sobrien varargs = FALSE; 549733965Sjdp 549833965Sjdp if (info->type_stack->type.localp) 5499130561Sobrien localp = TRUE; 550033965Sjdp retindx = ieee_pop_type (info); 550133965Sjdp 550233965Sjdp m = NULL; 550333965Sjdp if (argcount < 0 && ! localp) 550433965Sjdp { 550533965Sjdp m = ieee_get_modified_info (p, retindx); 550633965Sjdp if (m == NULL) 5507130561Sobrien return FALSE; 550833965Sjdp 550933965Sjdp if (m->function > 0) 5510130561Sobrien return ieee_push_type (info, m->function, 0, TRUE, FALSE); 551133965Sjdp } 551233965Sjdp 551333965Sjdp /* An attribute of 0x41 means that the frame and push mask are 551433965Sjdp unknown. */ 551533965Sjdp if (! ieee_init_buffer (info, &fndef) 551633965Sjdp || ! ieee_define_named_type (info, (const char *) NULL, 5517130561Sobrien (unsigned int) -1, 0, TRUE, localp, 551833965Sjdp &fndef) 551933965Sjdp || ! ieee_write_number (info, 'x') 552033965Sjdp || ! ieee_write_number (info, 0x41) 552133965Sjdp || ! ieee_write_number (info, 0) 552233965Sjdp || ! ieee_write_number (info, 0) 552333965Sjdp || ! ieee_write_number (info, retindx) 552433965Sjdp || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0))) 5525130561Sobrien return FALSE; 552633965Sjdp if (argcount > 0) 552733965Sjdp { 552833965Sjdp for (i = 0; i < argcount; i++) 552933965Sjdp if (! ieee_write_number (info, args[i])) 5530130561Sobrien return FALSE; 553133965Sjdp free (args); 553233965Sjdp } 553333965Sjdp if (varargs) 553433965Sjdp { 553533965Sjdp /* A varargs function is represented by writing out the last 553633965Sjdp argument as type void *, although this makes little sense. */ 553733965Sjdp if (! ieee_write_number (info, (bfd_vma) builtin_void + 32)) 5538130561Sobrien return FALSE; 553933965Sjdp } 554033965Sjdp 554133965Sjdp if (! ieee_write_number (info, 0)) 5542130561Sobrien return FALSE; 554333965Sjdp 554433965Sjdp /* We wrote the information into fndef, in case we don't need it. 554533965Sjdp It will be appended to info->types by ieee_pop_type. */ 554633965Sjdp info->type_stack->type.fndef = fndef; 554733965Sjdp 554833965Sjdp if (m != NULL) 554933965Sjdp m->function = info->type_stack->type.indx; 555033965Sjdp 5551130561Sobrien return TRUE; 555233965Sjdp} 555333965Sjdp 555433965Sjdp/* Make a reference type. */ 555533965Sjdp 5556130561Sobrienstatic bfd_boolean 5557130561Sobrienieee_reference_type (void *p) 555833965Sjdp{ 555933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 556033965Sjdp 556133965Sjdp /* IEEE appears to record a normal pointer type, and then use a 556233965Sjdp pmisc record to indicate that it is really a reference. */ 556333965Sjdp 556433965Sjdp if (! ieee_pointer_type (p)) 5565130561Sobrien return FALSE; 5566130561Sobrien info->type_stack->type.referencep = TRUE; 5567130561Sobrien return TRUE; 556833965Sjdp} 556933965Sjdp 557033965Sjdp/* Make a range type. */ 557133965Sjdp 5572130561Sobrienstatic bfd_boolean 5573130561Sobrienieee_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high) 557433965Sjdp{ 557533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 557633965Sjdp unsigned int size; 5577130561Sobrien bfd_boolean unsignedp, localp; 557833965Sjdp 557933965Sjdp size = info->type_stack->type.size; 558033965Sjdp unsignedp = info->type_stack->type.unsignedp; 558133965Sjdp localp = info->type_stack->type.localp; 558233965Sjdp ieee_pop_unused_type (info); 558333965Sjdp return (ieee_define_type (info, size, unsignedp, localp) 558433965Sjdp && ieee_write_number (info, 'R') 558533965Sjdp && ieee_write_number (info, (bfd_vma) low) 558633965Sjdp && ieee_write_number (info, (bfd_vma) high) 558733965Sjdp && ieee_write_number (info, unsignedp ? 0 : 1) 558833965Sjdp && ieee_write_number (info, size)); 558933965Sjdp} 559033965Sjdp 559133965Sjdp/* Make an array type. */ 559233965Sjdp 5593130561Sobrienstatic bfd_boolean 5594130561Sobrienieee_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high, 5595130561Sobrien bfd_boolean stringp ATTRIBUTE_UNUSED) 559633965Sjdp{ 559733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 559833965Sjdp unsigned int eleindx; 5599130561Sobrien bfd_boolean localp; 560033965Sjdp unsigned int size; 560133965Sjdp struct ieee_modified_type *m = NULL; 560233965Sjdp struct ieee_modified_array_type *a; 560333965Sjdp 560433965Sjdp /* IEEE does not store the range, so we just ignore it. */ 560533965Sjdp ieee_pop_unused_type (info); 560633965Sjdp localp = info->type_stack->type.localp; 560733965Sjdp size = info->type_stack->type.size; 560833965Sjdp eleindx = ieee_pop_type (info); 560933965Sjdp 561033965Sjdp /* If we don't know the range, treat the size as exactly one 561133965Sjdp element. */ 561233965Sjdp if (low < high) 561333965Sjdp size *= (high - low) + 1; 561433965Sjdp 561533965Sjdp if (! localp) 561633965Sjdp { 561733965Sjdp m = ieee_get_modified_info (info, eleindx); 561833965Sjdp if (m == NULL) 5619130561Sobrien return FALSE; 562033965Sjdp 562133965Sjdp for (a = m->arrays; a != NULL; a = a->next) 562233965Sjdp { 562333965Sjdp if (a->low == low && a->high == high) 5624130561Sobrien return ieee_push_type (info, a->indx, size, FALSE, FALSE); 562533965Sjdp } 562633965Sjdp } 562733965Sjdp 5628130561Sobrien if (! ieee_define_type (info, size, FALSE, localp) 562933965Sjdp || ! ieee_write_number (info, low == 0 ? 'Z' : 'C') 563033965Sjdp || ! ieee_write_number (info, eleindx)) 5631130561Sobrien return FALSE; 563233965Sjdp if (low != 0) 563333965Sjdp { 563433965Sjdp if (! ieee_write_number (info, low)) 5635130561Sobrien return FALSE; 563633965Sjdp } 563733965Sjdp 563833965Sjdp if (! ieee_write_number (info, high + 1)) 5639130561Sobrien return FALSE; 564033965Sjdp 564133965Sjdp if (! localp) 564233965Sjdp { 564333965Sjdp a = (struct ieee_modified_array_type *) xmalloc (sizeof *a); 564433965Sjdp memset (a, 0, sizeof *a); 564533965Sjdp 564633965Sjdp a->indx = info->type_stack->type.indx; 564733965Sjdp a->low = low; 564833965Sjdp a->high = high; 564933965Sjdp 565033965Sjdp a->next = m->arrays; 565133965Sjdp m->arrays = a; 565233965Sjdp } 565333965Sjdp 5654130561Sobrien return TRUE; 565533965Sjdp} 565633965Sjdp 565733965Sjdp/* Make a set type. */ 565833965Sjdp 5659130561Sobrienstatic bfd_boolean 5660130561Sobrienieee_set_type (void *p, bfd_boolean bitstringp ATTRIBUTE_UNUSED) 566133965Sjdp{ 566233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 5663130561Sobrien bfd_boolean localp; 566433965Sjdp unsigned int eleindx; 566533965Sjdp 566633965Sjdp localp = info->type_stack->type.localp; 566733965Sjdp eleindx = ieee_pop_type (info); 566833965Sjdp 566933965Sjdp /* FIXME: We don't know the size, so we just use 4. */ 567033965Sjdp 5671130561Sobrien return (ieee_define_type (info, 0, TRUE, localp) 567233965Sjdp && ieee_write_number (info, 's') 567333965Sjdp && ieee_write_number (info, 4) 567433965Sjdp && ieee_write_number (info, eleindx)); 567533965Sjdp} 567633965Sjdp 567733965Sjdp/* Make an offset type. */ 567833965Sjdp 5679130561Sobrienstatic bfd_boolean 5680130561Sobrienieee_offset_type (void *p) 568133965Sjdp{ 568233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 568333965Sjdp unsigned int targetindx, baseindx; 568433965Sjdp 568533965Sjdp targetindx = ieee_pop_type (info); 568633965Sjdp baseindx = ieee_pop_type (info); 568733965Sjdp 568833965Sjdp /* FIXME: The MRI C++ compiler does not appear to generate any 568933965Sjdp useful type information about an offset type. It just records a 569033965Sjdp pointer to member as an integer. The MRI/HP IEEE spec does 569133965Sjdp describe a pmisc record which can be used for a pointer to 569233965Sjdp member. Unfortunately, it does not describe the target type, 569333965Sjdp which seems pretty important. I'm going to punt this for now. */ 569433965Sjdp 5695130561Sobrien return ieee_int_type (p, 4, TRUE); 569677298Sobrien} 569733965Sjdp 569833965Sjdp/* Make a method type. */ 569933965Sjdp 5700130561Sobrienstatic bfd_boolean 5701130561Sobrienieee_method_type (void *p, bfd_boolean domain, int argcount, 5702130561Sobrien bfd_boolean varargs) 570333965Sjdp{ 570433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 570533965Sjdp 570633965Sjdp /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a 570733965Sjdp method, but the definition is incomplete. We just output an 'x' 570833965Sjdp type. */ 570933965Sjdp 571033965Sjdp if (domain) 571133965Sjdp ieee_pop_unused_type (info); 571233965Sjdp 571333965Sjdp return ieee_function_type (p, argcount, varargs); 571433965Sjdp} 571533965Sjdp 571633965Sjdp/* Make a const qualified type. */ 571733965Sjdp 5718130561Sobrienstatic bfd_boolean 5719130561Sobrienieee_const_type (void *p) 572033965Sjdp{ 572133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 572233965Sjdp unsigned int size; 5723130561Sobrien bfd_boolean unsignedp, localp; 572433965Sjdp unsigned int indx; 572533965Sjdp struct ieee_modified_type *m = NULL; 572633965Sjdp 572733965Sjdp size = info->type_stack->type.size; 572833965Sjdp unsignedp = info->type_stack->type.unsignedp; 572933965Sjdp localp = info->type_stack->type.localp; 573033965Sjdp indx = ieee_pop_type (info); 573133965Sjdp 573233965Sjdp if (! localp) 573333965Sjdp { 573433965Sjdp m = ieee_get_modified_info (info, indx); 573533965Sjdp if (m == NULL) 5736130561Sobrien return FALSE; 573733965Sjdp 573833965Sjdp if (m->const_qualified > 0) 573933965Sjdp return ieee_push_type (info, m->const_qualified, size, unsignedp, 5740130561Sobrien FALSE); 574133965Sjdp } 574233965Sjdp 574333965Sjdp if (! ieee_define_type (info, size, unsignedp, localp) 574433965Sjdp || ! ieee_write_number (info, 'n') 574533965Sjdp || ! ieee_write_number (info, 1) 574633965Sjdp || ! ieee_write_number (info, indx)) 5747130561Sobrien return FALSE; 574833965Sjdp 574933965Sjdp if (! localp) 575033965Sjdp m->const_qualified = info->type_stack->type.indx; 575133965Sjdp 5752130561Sobrien return TRUE; 575333965Sjdp} 575433965Sjdp 575533965Sjdp/* Make a volatile qualified type. */ 575633965Sjdp 5757130561Sobrienstatic bfd_boolean 5758130561Sobrienieee_volatile_type (void *p) 575933965Sjdp{ 576033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 576133965Sjdp unsigned int size; 5762130561Sobrien bfd_boolean unsignedp, localp; 576333965Sjdp unsigned int indx; 576433965Sjdp struct ieee_modified_type *m = NULL; 576533965Sjdp 576633965Sjdp size = info->type_stack->type.size; 576733965Sjdp unsignedp = info->type_stack->type.unsignedp; 576833965Sjdp localp = info->type_stack->type.localp; 576933965Sjdp indx = ieee_pop_type (info); 577033965Sjdp 577133965Sjdp if (! localp) 577233965Sjdp { 577333965Sjdp m = ieee_get_modified_info (info, indx); 577433965Sjdp if (m == NULL) 5775130561Sobrien return FALSE; 577633965Sjdp 577733965Sjdp if (m->volatile_qualified > 0) 577833965Sjdp return ieee_push_type (info, m->volatile_qualified, size, unsignedp, 5779130561Sobrien FALSE); 578033965Sjdp } 578133965Sjdp 578233965Sjdp if (! ieee_define_type (info, size, unsignedp, localp) 578333965Sjdp || ! ieee_write_number (info, 'n') 578433965Sjdp || ! ieee_write_number (info, 2) 578533965Sjdp || ! ieee_write_number (info, indx)) 5786130561Sobrien return FALSE; 578733965Sjdp 578833965Sjdp if (! localp) 578933965Sjdp m->volatile_qualified = info->type_stack->type.indx; 579033965Sjdp 5791130561Sobrien return TRUE; 579233965Sjdp} 579333965Sjdp 579433965Sjdp/* Convert an enum debug_visibility into a CXXFLAGS value. */ 579533965Sjdp 579633965Sjdpstatic unsigned int 5797130561Sobrienieee_vis_to_flags (enum debug_visibility visibility) 579833965Sjdp{ 579933965Sjdp switch (visibility) 580033965Sjdp { 580133965Sjdp default: 580233965Sjdp abort (); 580333965Sjdp case DEBUG_VISIBILITY_PUBLIC: 580433965Sjdp return CXXFLAGS_VISIBILITY_PUBLIC; 580533965Sjdp case DEBUG_VISIBILITY_PRIVATE: 580633965Sjdp return CXXFLAGS_VISIBILITY_PRIVATE; 580733965Sjdp case DEBUG_VISIBILITY_PROTECTED: 580833965Sjdp return CXXFLAGS_VISIBILITY_PROTECTED; 580933965Sjdp } 581033965Sjdp /*NOTREACHED*/ 581133965Sjdp} 581233965Sjdp 581333965Sjdp/* Start defining a struct type. We build it in the strdef field on 581433965Sjdp the stack, to avoid confusing type definitions required by the 581533965Sjdp fields with the struct type itself. */ 581633965Sjdp 5817130561Sobrienstatic bfd_boolean 5818130561Sobrienieee_start_struct_type (void *p, const char *tag, unsigned int id, 5819130561Sobrien bfd_boolean structp, unsigned int size) 582033965Sjdp{ 582133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 5822130561Sobrien bfd_boolean localp, ignorep; 5823130561Sobrien bfd_boolean copy; 582433965Sjdp char ab[20]; 582533965Sjdp const char *look; 582633965Sjdp struct ieee_name_type_hash_entry *h; 582733965Sjdp struct ieee_name_type *nt, *ntlook; 582833965Sjdp struct ieee_buflist strdef; 582933965Sjdp 5830130561Sobrien localp = FALSE; 5831130561Sobrien ignorep = FALSE; 583233965Sjdp 583333965Sjdp /* We need to create a tag for internal use even if we don't want 583433965Sjdp one for external use. This will let us refer to an anonymous 583533965Sjdp struct. */ 583633965Sjdp if (tag != NULL) 583733965Sjdp { 583833965Sjdp look = tag; 5839130561Sobrien copy = FALSE; 584033965Sjdp } 584133965Sjdp else 584233965Sjdp { 584333965Sjdp sprintf (ab, "__anon%u", id); 584433965Sjdp look = ab; 5845130561Sobrien copy = TRUE; 584633965Sjdp } 584733965Sjdp 584833965Sjdp /* If we already have references to the tag, we must use the 584933965Sjdp existing type index. */ 5850130561Sobrien h = ieee_name_type_hash_lookup (&info->tags, look, TRUE, copy); 585133965Sjdp if (h == NULL) 5852130561Sobrien return FALSE; 585333965Sjdp 585433965Sjdp nt = NULL; 585533965Sjdp for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next) 585633965Sjdp { 585733965Sjdp if (ntlook->id == id) 585833965Sjdp nt = ntlook; 585933965Sjdp else if (! ntlook->type.localp) 586033965Sjdp { 586133965Sjdp /* We are creating a duplicate definition of a globally 586233965Sjdp defined tag. Force it to be local to avoid 586333965Sjdp confusion. */ 5864130561Sobrien localp = TRUE; 586533965Sjdp } 586633965Sjdp } 586733965Sjdp 586833965Sjdp if (nt != NULL) 586933965Sjdp { 587033965Sjdp assert (localp == nt->type.localp); 587133965Sjdp if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp) 587233965Sjdp { 587333965Sjdp /* We've already seen a global definition of the type. 587433965Sjdp Ignore this new definition. */ 5875130561Sobrien ignorep = TRUE; 587633965Sjdp } 587733965Sjdp } 587833965Sjdp else 587933965Sjdp { 588033965Sjdp nt = (struct ieee_name_type *) xmalloc (sizeof *nt); 588133965Sjdp memset (nt, 0, sizeof *nt); 588233965Sjdp nt->id = id; 588333965Sjdp nt->type.name = h->root.string; 588433965Sjdp nt->next = h->types; 588533965Sjdp h->types = nt; 588633965Sjdp nt->type.indx = info->type_indx; 588733965Sjdp ++info->type_indx; 588833965Sjdp } 588933965Sjdp 589033965Sjdp nt->kind = DEBUG_KIND_ILLEGAL; 589133965Sjdp 589233965Sjdp if (! ieee_init_buffer (info, &strdef) 5893130561Sobrien || ! ieee_define_named_type (info, tag, nt->type.indx, size, TRUE, 589433965Sjdp localp, &strdef) 589533965Sjdp || ! ieee_write_number (info, structp ? 'S' : 'U') 589633965Sjdp || ! ieee_write_number (info, size)) 5897130561Sobrien return FALSE; 589833965Sjdp 589933965Sjdp if (! ignorep) 590033965Sjdp { 590133965Sjdp const char *hold; 590233965Sjdp 590333965Sjdp /* We never want nt->type.name to be NULL. We want the rest of 590433965Sjdp the type to be the object set up on the type stack; it will 590533965Sjdp have a NULL name if tag is NULL. */ 590633965Sjdp hold = nt->type.name; 590733965Sjdp nt->type = info->type_stack->type; 590833965Sjdp nt->type.name = hold; 590933965Sjdp } 591033965Sjdp 591133965Sjdp info->type_stack->type.name = tag; 591233965Sjdp info->type_stack->type.strdef = strdef; 591333965Sjdp info->type_stack->type.ignorep = ignorep; 591433965Sjdp 5915130561Sobrien return TRUE; 591633965Sjdp} 591733965Sjdp 591833965Sjdp/* Add a field to a struct. */ 591933965Sjdp 5920130561Sobrienstatic bfd_boolean 5921130561Sobrienieee_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize, 5922130561Sobrien enum debug_visibility visibility) 592333965Sjdp{ 592433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 592533965Sjdp unsigned int size; 5926130561Sobrien bfd_boolean unsignedp; 5927130561Sobrien bfd_boolean referencep; 5928130561Sobrien bfd_boolean localp; 592933965Sjdp unsigned int indx; 593033965Sjdp bfd_vma offset; 593133965Sjdp 593233965Sjdp assert (info->type_stack != NULL 593333965Sjdp && info->type_stack->next != NULL 593433965Sjdp && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); 593533965Sjdp 593633965Sjdp /* If we are ignoring this struct definition, just pop and ignore 593733965Sjdp the type. */ 593833965Sjdp if (info->type_stack->next->type.ignorep) 593933965Sjdp { 594033965Sjdp ieee_pop_unused_type (info); 5941130561Sobrien return TRUE; 594233965Sjdp } 594333965Sjdp 594433965Sjdp size = info->type_stack->type.size; 594533965Sjdp unsignedp = info->type_stack->type.unsignedp; 594633965Sjdp referencep = info->type_stack->type.referencep; 594733965Sjdp localp = info->type_stack->type.localp; 594833965Sjdp indx = ieee_pop_type (info); 594933965Sjdp 595033965Sjdp if (localp) 5951130561Sobrien info->type_stack->type.localp = TRUE; 595233965Sjdp 595333965Sjdp if (info->type_stack->type.classdef != NULL) 595433965Sjdp { 595533965Sjdp unsigned int flags; 595633965Sjdp unsigned int nindx; 595733965Sjdp 595833965Sjdp /* This is a class. We must add a description of this field to 595933965Sjdp the class records we are building. */ 596033965Sjdp 596133965Sjdp flags = ieee_vis_to_flags (visibility); 596233965Sjdp nindx = info->type_stack->type.classdef->indx; 596333965Sjdp if (! ieee_change_buffer (info, 596433965Sjdp &info->type_stack->type.classdef->pmiscbuf) 596533965Sjdp || ! ieee_write_asn (info, nindx, 'd') 596633965Sjdp || ! ieee_write_asn (info, nindx, flags) 596733965Sjdp || ! ieee_write_atn65 (info, nindx, name) 596833965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 5969130561Sobrien return FALSE; 597033965Sjdp info->type_stack->type.classdef->pmisccount += 4; 597133965Sjdp 597233965Sjdp if (referencep) 597333965Sjdp { 597433965Sjdp unsigned int nindx; 597533965Sjdp 597633965Sjdp /* We need to output a record recording that this field is 597733965Sjdp really of reference type. We put this on the refs field 597833965Sjdp of classdef, so that it can be appended to the C++ 597933965Sjdp records after the class is defined. */ 598033965Sjdp 598133965Sjdp nindx = info->name_indx; 598233965Sjdp ++info->name_indx; 598333965Sjdp 598433965Sjdp if (! ieee_change_buffer (info, 598533965Sjdp &info->type_stack->type.classdef->refs) 598633965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 598733965Sjdp || ! ieee_write_number (info, nindx) 598833965Sjdp || ! ieee_write_id (info, "") 598933965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 599033965Sjdp || ! ieee_write_number (info, nindx) 599133965Sjdp || ! ieee_write_number (info, 0) 599233965Sjdp || ! ieee_write_number (info, 62) 599333965Sjdp || ! ieee_write_number (info, 80) 599433965Sjdp || ! ieee_write_number (info, 4) 599533965Sjdp || ! ieee_write_asn (info, nindx, 'R') 599633965Sjdp || ! ieee_write_asn (info, nindx, 3) 599733965Sjdp || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name) 599833965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 5999130561Sobrien return FALSE; 600033965Sjdp } 600133965Sjdp } 600233965Sjdp 600333965Sjdp /* If the bitsize doesn't match the expected size, we need to output 600433965Sjdp a bitfield type. */ 600533965Sjdp if (size == 0 || bitsize == 0 || bitsize == size * 8) 600633965Sjdp offset = bitpos / 8; 600733965Sjdp else 600833965Sjdp { 600933965Sjdp if (! ieee_define_type (info, 0, unsignedp, 601033965Sjdp info->type_stack->type.localp) 601133965Sjdp || ! ieee_write_number (info, 'g') 601233965Sjdp || ! ieee_write_number (info, unsignedp ? 0 : 1) 601333965Sjdp || ! ieee_write_number (info, bitsize) 601433965Sjdp || ! ieee_write_number (info, indx)) 6015130561Sobrien return FALSE; 601633965Sjdp indx = ieee_pop_type (info); 601733965Sjdp offset = bitpos; 601833965Sjdp } 601933965Sjdp 602033965Sjdp /* Switch to the struct we are building in order to output this 602133965Sjdp field definition. */ 602233965Sjdp return (ieee_change_buffer (info, &info->type_stack->type.strdef) 602333965Sjdp && ieee_write_id (info, name) 602433965Sjdp && ieee_write_number (info, indx) 602533965Sjdp && ieee_write_number (info, offset)); 602633965Sjdp} 602733965Sjdp 602833965Sjdp/* Finish up a struct type. */ 602933965Sjdp 6030130561Sobrienstatic bfd_boolean 6031130561Sobrienieee_end_struct_type (void *p) 603233965Sjdp{ 603333965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 603433965Sjdp struct ieee_buflist *pb; 603533965Sjdp 603633965Sjdp assert (info->type_stack != NULL 603733965Sjdp && ! ieee_buffer_emptyp (&info->type_stack->type.strdef)); 603833965Sjdp 603933965Sjdp /* If we were ignoring this struct definition because it was a 6040130561Sobrien duplicate definition, just through away whatever bytes we have 6041104834Sobrien accumulated. Leave the type on the stack. */ 604233965Sjdp if (info->type_stack->type.ignorep) 6043130561Sobrien return TRUE; 604433965Sjdp 604533965Sjdp /* If this is not a duplicate definition of this tag, then localp 6046130561Sobrien will be FALSE, and we can put it in the global type block. 604733965Sjdp FIXME: We should avoid outputting duplicate definitions which are 604833965Sjdp the same. */ 604933965Sjdp if (! info->type_stack->type.localp) 605033965Sjdp { 605133965Sjdp /* Make sure we have started the global type block. */ 605233965Sjdp if (ieee_buffer_emptyp (&info->global_types)) 605333965Sjdp { 605433965Sjdp if (! ieee_change_buffer (info, &info->global_types) 605533965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 605633965Sjdp || ! ieee_write_byte (info, 2) 605733965Sjdp || ! ieee_write_number (info, 0) 605833965Sjdp || ! ieee_write_id (info, "")) 6059130561Sobrien return FALSE; 606033965Sjdp } 606133965Sjdp pb = &info->global_types; 606233965Sjdp } 606333965Sjdp else 606433965Sjdp { 606533965Sjdp /* Make sure we have started the types block. */ 606633965Sjdp if (ieee_buffer_emptyp (&info->types)) 606733965Sjdp { 606833965Sjdp if (! ieee_change_buffer (info, &info->types) 606933965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 607033965Sjdp || ! ieee_write_byte (info, 1) 607133965Sjdp || ! ieee_write_number (info, 0) 607233965Sjdp || ! ieee_write_id (info, info->modname)) 6073130561Sobrien return FALSE; 607433965Sjdp } 607533965Sjdp pb = &info->types; 607633965Sjdp } 607733965Sjdp 607833965Sjdp /* Append the struct definition to the types. */ 607933965Sjdp if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef) 608033965Sjdp || ! ieee_init_buffer (info, &info->type_stack->type.strdef)) 6081130561Sobrien return FALSE; 608233965Sjdp 608333965Sjdp /* Leave the struct on the type stack. */ 608433965Sjdp 6085130561Sobrien return TRUE; 608633965Sjdp} 608733965Sjdp 608833965Sjdp/* Start a class type. */ 608933965Sjdp 6090130561Sobrienstatic bfd_boolean 6091130561Sobrienieee_start_class_type (void *p, const char *tag, unsigned int id, 6092130561Sobrien bfd_boolean structp, unsigned int size, 6093130561Sobrien bfd_boolean vptr, bfd_boolean ownvptr) 609433965Sjdp{ 609533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 609633965Sjdp const char *vclass; 609733965Sjdp struct ieee_buflist pmiscbuf; 609833965Sjdp unsigned int indx; 609933965Sjdp struct ieee_type_class *classdef; 610033965Sjdp 610133965Sjdp /* A C++ class is output as a C++ struct along with a set of pmisc 610233965Sjdp records describing the class. */ 610333965Sjdp 610433965Sjdp /* We need to have a name so that we can associate the struct and 610533965Sjdp the class. */ 610633965Sjdp if (tag == NULL) 610733965Sjdp { 610833965Sjdp char *t; 610933965Sjdp 611033965Sjdp t = (char *) xmalloc (20); 611133965Sjdp sprintf (t, "__anon%u", id); 611233965Sjdp tag = t; 611333965Sjdp } 611433965Sjdp 611533965Sjdp /* We can't write out the virtual table information until we have 611633965Sjdp finished the class, because we don't know the virtual table size. 611733965Sjdp We get the size from the largest voffset we see. */ 611833965Sjdp vclass = NULL; 611933965Sjdp if (vptr && ! ownvptr) 612033965Sjdp { 612133965Sjdp vclass = info->type_stack->type.name; 612233965Sjdp assert (vclass != NULL); 612333965Sjdp /* We don't call ieee_pop_unused_type, since the class should 612433965Sjdp get defined. */ 612533965Sjdp (void) ieee_pop_type (info); 612633965Sjdp } 612733965Sjdp 612833965Sjdp if (! ieee_start_struct_type (p, tag, id, structp, size)) 6129130561Sobrien return FALSE; 613033965Sjdp 613133965Sjdp indx = info->name_indx; 613233965Sjdp ++info->name_indx; 613333965Sjdp 613433965Sjdp /* We write out pmisc records into the classdef field. We will 613533965Sjdp write out the pmisc start after we know the number of records we 613633965Sjdp need. */ 613733965Sjdp if (! ieee_init_buffer (info, &pmiscbuf) 613833965Sjdp || ! ieee_change_buffer (info, &pmiscbuf) 613933965Sjdp || ! ieee_write_asn (info, indx, 'T') 614033965Sjdp || ! ieee_write_asn (info, indx, structp ? 'o' : 'u') 614133965Sjdp || ! ieee_write_atn65 (info, indx, tag)) 6142130561Sobrien return FALSE; 614333965Sjdp 614433965Sjdp classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef); 614533965Sjdp memset (classdef, 0, sizeof *classdef); 614633965Sjdp 614733965Sjdp classdef->indx = indx; 614833965Sjdp classdef->pmiscbuf = pmiscbuf; 614933965Sjdp classdef->pmisccount = 3; 615033965Sjdp classdef->vclass = vclass; 615133965Sjdp classdef->ownvptr = ownvptr; 615233965Sjdp 615333965Sjdp info->type_stack->type.classdef = classdef; 615433965Sjdp 6155130561Sobrien return TRUE; 615633965Sjdp} 615733965Sjdp 615833965Sjdp/* Add a static member to a class. */ 615933965Sjdp 6160130561Sobrienstatic bfd_boolean 6161130561Sobrienieee_class_static_member (void *p, const char *name, const char *physname, 6162130561Sobrien enum debug_visibility visibility) 616333965Sjdp{ 616433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 616533965Sjdp unsigned int flags; 616633965Sjdp unsigned int nindx; 616733965Sjdp 616833965Sjdp /* We don't care about the type. Hopefully there will be a call to 616933965Sjdp ieee_variable declaring the physical name and the type, since 617033965Sjdp that is where an IEEE consumer must get the type. */ 617133965Sjdp ieee_pop_unused_type (info); 617233965Sjdp 617333965Sjdp assert (info->type_stack != NULL 617433965Sjdp && info->type_stack->type.classdef != NULL); 617533965Sjdp 617633965Sjdp flags = ieee_vis_to_flags (visibility); 617733965Sjdp flags |= CXXFLAGS_STATIC; 617833965Sjdp 617933965Sjdp nindx = info->type_stack->type.classdef->indx; 618033965Sjdp 618133965Sjdp if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) 618233965Sjdp || ! ieee_write_asn (info, nindx, 'd') 618333965Sjdp || ! ieee_write_asn (info, nindx, flags) 618433965Sjdp || ! ieee_write_atn65 (info, nindx, name) 618533965Sjdp || ! ieee_write_atn65 (info, nindx, physname)) 6186130561Sobrien return FALSE; 618733965Sjdp info->type_stack->type.classdef->pmisccount += 4; 618833965Sjdp 6189130561Sobrien return TRUE; 619033965Sjdp} 619133965Sjdp 619233965Sjdp/* Add a base class to a class. */ 619333965Sjdp 6194130561Sobrienstatic bfd_boolean 6195130561Sobrienieee_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual, 6196130561Sobrien enum debug_visibility visibility) 619733965Sjdp{ 619833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 619933965Sjdp const char *bname; 6200130561Sobrien bfd_boolean localp; 620133965Sjdp unsigned int bindx; 620233965Sjdp char *fname; 620333965Sjdp unsigned int flags; 620433965Sjdp unsigned int nindx; 620533965Sjdp 620633965Sjdp assert (info->type_stack != NULL 620733965Sjdp && info->type_stack->type.name != NULL 620833965Sjdp && info->type_stack->next != NULL 620933965Sjdp && info->type_stack->next->type.classdef != NULL 621033965Sjdp && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); 621133965Sjdp 621233965Sjdp bname = info->type_stack->type.name; 621333965Sjdp localp = info->type_stack->type.localp; 621433965Sjdp bindx = ieee_pop_type (info); 621533965Sjdp 621633965Sjdp /* We are currently defining both a struct and a class. We must 621733965Sjdp write out a field definition in the struct which holds the base 621833965Sjdp class. The stabs debugging reader will create a field named 621933965Sjdp _vb$CLASS for a virtual base class, so we just use that. FIXME: 622033965Sjdp we should not depend upon a detail of stabs debugging. */ 622133965Sjdp if (virtual) 622233965Sjdp { 622333965Sjdp fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$"); 622433965Sjdp sprintf (fname, "_vb$%s", bname); 622533965Sjdp flags = BASEFLAGS_VIRTUAL; 622633965Sjdp } 622733965Sjdp else 622833965Sjdp { 622933965Sjdp if (localp) 6230130561Sobrien info->type_stack->type.localp = TRUE; 623133965Sjdp 623233965Sjdp fname = (char *) xmalloc (strlen (bname) + sizeof "_b$"); 623333965Sjdp sprintf (fname, "_b$%s", bname); 623433965Sjdp 623533965Sjdp if (! ieee_change_buffer (info, &info->type_stack->type.strdef) 623633965Sjdp || ! ieee_write_id (info, fname) 623733965Sjdp || ! ieee_write_number (info, bindx) 623833965Sjdp || ! ieee_write_number (info, bitpos / 8)) 6239130561Sobrien return FALSE; 624033965Sjdp flags = 0; 624133965Sjdp } 624233965Sjdp 624333965Sjdp if (visibility == DEBUG_VISIBILITY_PRIVATE) 624433965Sjdp flags |= BASEFLAGS_PRIVATE; 624533965Sjdp 624633965Sjdp nindx = info->type_stack->type.classdef->indx; 624733965Sjdp 624833965Sjdp if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) 624933965Sjdp || ! ieee_write_asn (info, nindx, 'b') 625033965Sjdp || ! ieee_write_asn (info, nindx, flags) 625133965Sjdp || ! ieee_write_atn65 (info, nindx, bname) 625233965Sjdp || ! ieee_write_asn (info, nindx, 0) 625333965Sjdp || ! ieee_write_atn65 (info, nindx, fname)) 6254130561Sobrien return FALSE; 625533965Sjdp info->type_stack->type.classdef->pmisccount += 5; 625633965Sjdp 625733965Sjdp free (fname); 625833965Sjdp 6259130561Sobrien return TRUE; 626033965Sjdp} 626133965Sjdp 626233965Sjdp/* Start building a method for a class. */ 626333965Sjdp 6264130561Sobrienstatic bfd_boolean 6265130561Sobrienieee_class_start_method (void *p, const char *name) 626633965Sjdp{ 626733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 626833965Sjdp 626933965Sjdp assert (info->type_stack != NULL 627033965Sjdp && info->type_stack->type.classdef != NULL 627133965Sjdp && info->type_stack->type.classdef->method == NULL); 627233965Sjdp 627333965Sjdp info->type_stack->type.classdef->method = name; 627433965Sjdp 6275130561Sobrien return TRUE; 627633965Sjdp} 627733965Sjdp 627833965Sjdp/* Define a new method variant, either static or not. */ 627933965Sjdp 6280130561Sobrienstatic bfd_boolean 6281130561Sobrienieee_class_method_var (struct ieee_handle *info, const char *physname, 6282130561Sobrien enum debug_visibility visibility, 6283130561Sobrien bfd_boolean staticp, bfd_boolean constp, 6284130561Sobrien bfd_boolean volatilep, bfd_vma voffset, 6285130561Sobrien bfd_boolean context) 628633965Sjdp{ 628733965Sjdp unsigned int flags; 628833965Sjdp unsigned int nindx; 6289130561Sobrien bfd_boolean virtual; 629033965Sjdp 629133965Sjdp /* We don't need the type of the method. An IEEE consumer which 629233965Sjdp wants the type must track down the function by the physical name 629333965Sjdp and get the type from that. */ 629433965Sjdp ieee_pop_unused_type (info); 629533965Sjdp 629633965Sjdp /* We don't use the context. FIXME: We probably ought to use it to 629733965Sjdp adjust the voffset somehow, but I don't really know how. */ 629833965Sjdp if (context) 629933965Sjdp ieee_pop_unused_type (info); 630033965Sjdp 630133965Sjdp assert (info->type_stack != NULL 630233965Sjdp && info->type_stack->type.classdef != NULL 630333965Sjdp && info->type_stack->type.classdef->method != NULL); 630433965Sjdp 630533965Sjdp flags = ieee_vis_to_flags (visibility); 630633965Sjdp 630733965Sjdp /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR, 630833965Sjdp CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */ 630933965Sjdp 631033965Sjdp if (staticp) 631133965Sjdp flags |= CXXFLAGS_STATIC; 631233965Sjdp if (constp) 631333965Sjdp flags |= CXXFLAGS_CONST; 631433965Sjdp if (volatilep) 631533965Sjdp flags |= CXXFLAGS_VOLATILE; 631633965Sjdp 631733965Sjdp nindx = info->type_stack->type.classdef->indx; 631833965Sjdp 631933965Sjdp virtual = context || voffset > 0; 632033965Sjdp 632133965Sjdp if (! ieee_change_buffer (info, 632233965Sjdp &info->type_stack->type.classdef->pmiscbuf) 632333965Sjdp || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm') 632433965Sjdp || ! ieee_write_asn (info, nindx, flags) 632533965Sjdp || ! ieee_write_atn65 (info, nindx, 632633965Sjdp info->type_stack->type.classdef->method) 632733965Sjdp || ! ieee_write_atn65 (info, nindx, physname)) 6328130561Sobrien return FALSE; 632933965Sjdp 633033965Sjdp if (virtual) 633133965Sjdp { 633233965Sjdp if (voffset > info->type_stack->type.classdef->voffset) 633333965Sjdp info->type_stack->type.classdef->voffset = voffset; 633433965Sjdp if (! ieee_write_asn (info, nindx, voffset)) 6335130561Sobrien return FALSE; 633633965Sjdp ++info->type_stack->type.classdef->pmisccount; 633733965Sjdp } 633833965Sjdp 633933965Sjdp if (! ieee_write_asn (info, nindx, 0)) 6340130561Sobrien return FALSE; 634133965Sjdp 634233965Sjdp info->type_stack->type.classdef->pmisccount += 5; 634333965Sjdp 6344130561Sobrien return TRUE; 634533965Sjdp} 634633965Sjdp 634733965Sjdp/* Define a new method variant. */ 634833965Sjdp 6349130561Sobrienstatic bfd_boolean 6350130561Sobrienieee_class_method_variant (void *p, const char *physname, 6351130561Sobrien enum debug_visibility visibility, 6352130561Sobrien bfd_boolean constp, bfd_boolean volatilep, 6353130561Sobrien bfd_vma voffset, bfd_boolean context) 635433965Sjdp{ 635533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 635633965Sjdp 6357130561Sobrien return ieee_class_method_var (info, physname, visibility, FALSE, constp, 635833965Sjdp volatilep, voffset, context); 635933965Sjdp} 636033965Sjdp 636133965Sjdp/* Define a new static method variant. */ 636233965Sjdp 6363130561Sobrienstatic bfd_boolean 6364130561Sobrienieee_class_static_method_variant (void *p, const char *physname, 6365130561Sobrien enum debug_visibility visibility, 6366130561Sobrien bfd_boolean constp, bfd_boolean volatilep) 636733965Sjdp{ 636833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 636933965Sjdp 6370130561Sobrien return ieee_class_method_var (info, physname, visibility, TRUE, constp, 6371130561Sobrien volatilep, 0, FALSE); 637233965Sjdp} 637333965Sjdp 637433965Sjdp/* Finish up a method. */ 637533965Sjdp 6376130561Sobrienstatic bfd_boolean 6377130561Sobrienieee_class_end_method (void *p) 637833965Sjdp{ 637933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 638033965Sjdp 638133965Sjdp assert (info->type_stack != NULL 638233965Sjdp && info->type_stack->type.classdef != NULL 638333965Sjdp && info->type_stack->type.classdef->method != NULL); 638433965Sjdp 638533965Sjdp info->type_stack->type.classdef->method = NULL; 638633965Sjdp 6387130561Sobrien return TRUE; 638833965Sjdp} 638933965Sjdp 639033965Sjdp/* Finish up a class. */ 639133965Sjdp 6392130561Sobrienstatic bfd_boolean 6393130561Sobrienieee_end_class_type (void *p) 639433965Sjdp{ 639533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 639633965Sjdp unsigned int nindx; 639733965Sjdp 639833965Sjdp assert (info->type_stack != NULL 639933965Sjdp && info->type_stack->type.classdef != NULL); 640033965Sjdp 640133965Sjdp /* If we were ignoring this class definition because it was a 640233965Sjdp duplicate definition, just through away whatever bytes we have 640333965Sjdp accumulated. Leave the type on the stack. */ 640433965Sjdp if (info->type_stack->type.ignorep) 6405130561Sobrien return TRUE; 640633965Sjdp 640733965Sjdp nindx = info->type_stack->type.classdef->indx; 640833965Sjdp 640933965Sjdp /* If we have a virtual table, we can write out the information now. */ 641033965Sjdp if (info->type_stack->type.classdef->vclass != NULL 641133965Sjdp || info->type_stack->type.classdef->ownvptr) 641233965Sjdp { 641333965Sjdp if (! ieee_change_buffer (info, 641433965Sjdp &info->type_stack->type.classdef->pmiscbuf) 641533965Sjdp || ! ieee_write_asn (info, nindx, 'z') 641633965Sjdp || ! ieee_write_atn65 (info, nindx, "") 641733965Sjdp || ! ieee_write_asn (info, nindx, 641833965Sjdp info->type_stack->type.classdef->voffset)) 6419130561Sobrien return FALSE; 642033965Sjdp if (info->type_stack->type.classdef->ownvptr) 642133965Sjdp { 642233965Sjdp if (! ieee_write_atn65 (info, nindx, "")) 6423130561Sobrien return FALSE; 642433965Sjdp } 642533965Sjdp else 642633965Sjdp { 642733965Sjdp if (! ieee_write_atn65 (info, nindx, 642833965Sjdp info->type_stack->type.classdef->vclass)) 6429130561Sobrien return FALSE; 643033965Sjdp } 643133965Sjdp if (! ieee_write_asn (info, nindx, 0)) 6432130561Sobrien return FALSE; 643333965Sjdp info->type_stack->type.classdef->pmisccount += 5; 643433965Sjdp } 643533965Sjdp 643633965Sjdp /* Now that we know the number of pmisc records, we can write out 643733965Sjdp the atn62 which starts the pmisc records, and append them to the 643833965Sjdp C++ buffers. */ 643933965Sjdp 644033965Sjdp if (! ieee_change_buffer (info, &info->cxx) 644133965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 644233965Sjdp || ! ieee_write_number (info, nindx) 644333965Sjdp || ! ieee_write_id (info, "") 644433965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 644533965Sjdp || ! ieee_write_number (info, nindx) 644633965Sjdp || ! ieee_write_number (info, 0) 644733965Sjdp || ! ieee_write_number (info, 62) 644833965Sjdp || ! ieee_write_number (info, 80) 644933965Sjdp || ! ieee_write_number (info, 645033965Sjdp info->type_stack->type.classdef->pmisccount)) 6451130561Sobrien return FALSE; 645233965Sjdp 645333965Sjdp if (! ieee_append_buffer (info, &info->cxx, 645433965Sjdp &info->type_stack->type.classdef->pmiscbuf)) 6455130561Sobrien return FALSE; 645633965Sjdp if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs)) 645733965Sjdp { 645833965Sjdp if (! ieee_append_buffer (info, &info->cxx, 645933965Sjdp &info->type_stack->type.classdef->refs)) 6460130561Sobrien return FALSE; 646133965Sjdp } 646233965Sjdp 646333965Sjdp return ieee_end_struct_type (p); 646433965Sjdp} 646533965Sjdp 646633965Sjdp/* Push a previously seen typedef onto the type stack. */ 646733965Sjdp 6468130561Sobrienstatic bfd_boolean 6469130561Sobrienieee_typedef_type (void *p, const char *name) 647033965Sjdp{ 647133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 647233965Sjdp struct ieee_name_type_hash_entry *h; 647333965Sjdp struct ieee_name_type *nt; 647433965Sjdp 6475130561Sobrien h = ieee_name_type_hash_lookup (&info->typedefs, name, FALSE, FALSE); 647633965Sjdp 647733965Sjdp /* h should never be NULL, since that would imply that the generic 647833965Sjdp debugging code has asked for a typedef which it has not yet 647933965Sjdp defined. */ 648033965Sjdp assert (h != NULL); 648133965Sjdp 648233965Sjdp /* We always use the most recently defined type for this name, which 648333965Sjdp will be the first one on the list. */ 648433965Sjdp 648533965Sjdp nt = h->types; 648633965Sjdp if (! ieee_push_type (info, nt->type.indx, nt->type.size, 648733965Sjdp nt->type.unsignedp, nt->type.localp)) 6488130561Sobrien return FALSE; 648933965Sjdp 649033965Sjdp /* Copy over any other type information we may have. */ 649133965Sjdp info->type_stack->type = nt->type; 649233965Sjdp 6493130561Sobrien return TRUE; 649433965Sjdp} 649533965Sjdp 649633965Sjdp/* Push a tagged type onto the type stack. */ 649733965Sjdp 6498130561Sobrienstatic bfd_boolean 6499130561Sobrienieee_tag_type (void *p, const char *name, unsigned int id, 6500130561Sobrien enum debug_type_kind kind) 650133965Sjdp{ 650233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 6503130561Sobrien bfd_boolean localp; 6504130561Sobrien bfd_boolean copy; 650533965Sjdp char ab[20]; 650633965Sjdp struct ieee_name_type_hash_entry *h; 650733965Sjdp struct ieee_name_type *nt; 650833965Sjdp 650933965Sjdp if (kind == DEBUG_KIND_ENUM) 651033965Sjdp { 651133965Sjdp struct ieee_defined_enum *e; 651233965Sjdp 651333965Sjdp if (name == NULL) 651433965Sjdp abort (); 651533965Sjdp for (e = info->enums; e != NULL; e = e->next) 651633965Sjdp if (e->tag != NULL && strcmp (e->tag, name) == 0) 6517130561Sobrien return ieee_push_type (info, e->indx, 0, TRUE, FALSE); 651833965Sjdp 651933965Sjdp e = (struct ieee_defined_enum *) xmalloc (sizeof *e); 652033965Sjdp memset (e, 0, sizeof *e); 652133965Sjdp 652233965Sjdp e->indx = info->type_indx; 652333965Sjdp ++info->type_indx; 652433965Sjdp e->tag = name; 6525130561Sobrien e->defined = FALSE; 652633965Sjdp 652733965Sjdp e->next = info->enums; 652833965Sjdp info->enums = e; 652933965Sjdp 6530130561Sobrien return ieee_push_type (info, e->indx, 0, TRUE, FALSE); 653133965Sjdp } 653233965Sjdp 6533130561Sobrien localp = FALSE; 653433965Sjdp 6535130561Sobrien copy = FALSE; 653633965Sjdp if (name == NULL) 653733965Sjdp { 653833965Sjdp sprintf (ab, "__anon%u", id); 653933965Sjdp name = ab; 6540130561Sobrien copy = TRUE; 654133965Sjdp } 654233965Sjdp 6543130561Sobrien h = ieee_name_type_hash_lookup (&info->tags, name, TRUE, copy); 654433965Sjdp if (h == NULL) 6545130561Sobrien return FALSE; 654633965Sjdp 654733965Sjdp for (nt = h->types; nt != NULL; nt = nt->next) 654833965Sjdp { 654933965Sjdp if (nt->id == id) 655033965Sjdp { 655133965Sjdp if (! ieee_push_type (info, nt->type.indx, nt->type.size, 655233965Sjdp nt->type.unsignedp, nt->type.localp)) 6553130561Sobrien return FALSE; 655433965Sjdp /* Copy over any other type information we may have. */ 655533965Sjdp info->type_stack->type = nt->type; 6556130561Sobrien return TRUE; 655733965Sjdp } 655833965Sjdp 655933965Sjdp if (! nt->type.localp) 656033965Sjdp { 656133965Sjdp /* This is a duplicate of a global type, so it must be 6562104834Sobrien local. */ 6563130561Sobrien localp = TRUE; 656433965Sjdp } 656533965Sjdp } 656633965Sjdp 656733965Sjdp nt = (struct ieee_name_type *) xmalloc (sizeof *nt); 656833965Sjdp memset (nt, 0, sizeof *nt); 656933965Sjdp 657033965Sjdp nt->id = id; 657133965Sjdp nt->type.name = h->root.string; 657233965Sjdp nt->type.indx = info->type_indx; 657333965Sjdp nt->type.localp = localp; 657433965Sjdp ++info->type_indx; 657533965Sjdp nt->kind = kind; 657633965Sjdp 657733965Sjdp nt->next = h->types; 657833965Sjdp h->types = nt; 657933965Sjdp 6580130561Sobrien if (! ieee_push_type (info, nt->type.indx, 0, FALSE, localp)) 6581130561Sobrien return FALSE; 658233965Sjdp 658333965Sjdp info->type_stack->type.name = h->root.string; 658433965Sjdp 6585130561Sobrien return TRUE; 658633965Sjdp} 658733965Sjdp 658833965Sjdp/* Output a typedef. */ 658933965Sjdp 6590130561Sobrienstatic bfd_boolean 6591130561Sobrienieee_typdef (void *p, const char *name) 659233965Sjdp{ 659333965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 659433965Sjdp struct ieee_write_type type; 659533965Sjdp unsigned int indx; 6596130561Sobrien bfd_boolean found; 6597130561Sobrien bfd_boolean localp; 659833965Sjdp struct ieee_name_type_hash_entry *h; 659933965Sjdp struct ieee_name_type *nt; 660033965Sjdp 660133965Sjdp type = info->type_stack->type; 660233965Sjdp indx = type.indx; 660333965Sjdp 660433965Sjdp /* If this is a simple builtin type using a builtin name, we don't 660533965Sjdp want to output the typedef itself. We also want to change the 660633965Sjdp type index to correspond to the name being used. We recognize 660733965Sjdp names used in stabs debugging output even if they don't exactly 660833965Sjdp correspond to the names used for the IEEE builtin types. */ 6609130561Sobrien found = FALSE; 661033965Sjdp if (indx <= (unsigned int) builtin_bcd_float) 661133965Sjdp { 661233965Sjdp switch ((enum builtin_types) indx) 661333965Sjdp { 661433965Sjdp default: 661533965Sjdp break; 661633965Sjdp 661733965Sjdp case builtin_void: 661833965Sjdp if (strcmp (name, "void") == 0) 6619130561Sobrien found = TRUE; 662033965Sjdp break; 662133965Sjdp 662233965Sjdp case builtin_signed_char: 662333965Sjdp case builtin_char: 662433965Sjdp if (strcmp (name, "signed char") == 0) 662533965Sjdp { 662633965Sjdp indx = (unsigned int) builtin_signed_char; 6627130561Sobrien found = TRUE; 662833965Sjdp } 662933965Sjdp else if (strcmp (name, "char") == 0) 663033965Sjdp { 663133965Sjdp indx = (unsigned int) builtin_char; 6632130561Sobrien found = TRUE; 663333965Sjdp } 663433965Sjdp break; 663533965Sjdp 663633965Sjdp case builtin_unsigned_char: 663733965Sjdp if (strcmp (name, "unsigned char") == 0) 6638130561Sobrien found = TRUE; 663933965Sjdp break; 664033965Sjdp 664133965Sjdp case builtin_signed_short_int: 664233965Sjdp case builtin_short: 664333965Sjdp case builtin_short_int: 664433965Sjdp case builtin_signed_short: 664533965Sjdp if (strcmp (name, "signed short int") == 0) 664633965Sjdp { 664733965Sjdp indx = (unsigned int) builtin_signed_short_int; 6648130561Sobrien found = TRUE; 664933965Sjdp } 665033965Sjdp else if (strcmp (name, "short") == 0) 665133965Sjdp { 665233965Sjdp indx = (unsigned int) builtin_short; 6653130561Sobrien found = TRUE; 665433965Sjdp } 665533965Sjdp else if (strcmp (name, "short int") == 0) 665633965Sjdp { 665733965Sjdp indx = (unsigned int) builtin_short_int; 6658130561Sobrien found = TRUE; 665933965Sjdp } 666033965Sjdp else if (strcmp (name, "signed short") == 0) 666133965Sjdp { 666233965Sjdp indx = (unsigned int) builtin_signed_short; 6663130561Sobrien found = TRUE; 666433965Sjdp } 666533965Sjdp break; 666633965Sjdp 666733965Sjdp case builtin_unsigned_short_int: 666833965Sjdp case builtin_unsigned_short: 666933965Sjdp if (strcmp (name, "unsigned short int") == 0 667033965Sjdp || strcmp (name, "short unsigned int") == 0) 667133965Sjdp { 667233965Sjdp indx = builtin_unsigned_short_int; 6673130561Sobrien found = TRUE; 667433965Sjdp } 667533965Sjdp else if (strcmp (name, "unsigned short") == 0) 667633965Sjdp { 667733965Sjdp indx = builtin_unsigned_short; 6678130561Sobrien found = TRUE; 667933965Sjdp } 668033965Sjdp break; 668133965Sjdp 668233965Sjdp case builtin_signed_long: 668333965Sjdp case builtin_int: /* FIXME: Size depends upon architecture. */ 668433965Sjdp case builtin_long: 668533965Sjdp if (strcmp (name, "signed long") == 0) 668633965Sjdp { 668733965Sjdp indx = builtin_signed_long; 6688130561Sobrien found = TRUE; 668933965Sjdp } 669033965Sjdp else if (strcmp (name, "int") == 0) 669133965Sjdp { 669233965Sjdp indx = builtin_int; 6693130561Sobrien found = TRUE; 669433965Sjdp } 669533965Sjdp else if (strcmp (name, "long") == 0 669633965Sjdp || strcmp (name, "long int") == 0) 669733965Sjdp { 669833965Sjdp indx = builtin_long; 6699130561Sobrien found = TRUE; 670033965Sjdp } 670133965Sjdp break; 670233965Sjdp 670333965Sjdp case builtin_unsigned_long: 670433965Sjdp case builtin_unsigned: /* FIXME: Size depends upon architecture. */ 670533965Sjdp case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */ 670633965Sjdp if (strcmp (name, "unsigned long") == 0 670733965Sjdp || strcmp (name, "long unsigned int") == 0) 670833965Sjdp { 670933965Sjdp indx = builtin_unsigned_long; 6710130561Sobrien found = TRUE; 671133965Sjdp } 671233965Sjdp else if (strcmp (name, "unsigned") == 0) 671333965Sjdp { 671433965Sjdp indx = builtin_unsigned; 6715130561Sobrien found = TRUE; 671633965Sjdp } 671733965Sjdp else if (strcmp (name, "unsigned int") == 0) 671833965Sjdp { 671933965Sjdp indx = builtin_unsigned_int; 6720130561Sobrien found = TRUE; 672133965Sjdp } 672233965Sjdp break; 672333965Sjdp 672433965Sjdp case builtin_signed_long_long: 672533965Sjdp if (strcmp (name, "signed long long") == 0 672633965Sjdp || strcmp (name, "long long int") == 0) 6727130561Sobrien found = TRUE; 672833965Sjdp break; 672933965Sjdp 673033965Sjdp case builtin_unsigned_long_long: 673133965Sjdp if (strcmp (name, "unsigned long long") == 0 673233965Sjdp || strcmp (name, "long long unsigned int") == 0) 6733130561Sobrien found = TRUE; 673433965Sjdp break; 673533965Sjdp 673633965Sjdp case builtin_float: 673733965Sjdp if (strcmp (name, "float") == 0) 6738130561Sobrien found = TRUE; 673933965Sjdp break; 674033965Sjdp 674133965Sjdp case builtin_double: 674233965Sjdp if (strcmp (name, "double") == 0) 6743130561Sobrien found = TRUE; 674433965Sjdp break; 674533965Sjdp 674633965Sjdp case builtin_long_double: 674733965Sjdp if (strcmp (name, "long double") == 0) 6748130561Sobrien found = TRUE; 674933965Sjdp break; 675033965Sjdp 675133965Sjdp case builtin_long_long_double: 675233965Sjdp if (strcmp (name, "long long double") == 0) 6753130561Sobrien found = TRUE; 675433965Sjdp break; 675533965Sjdp } 675633965Sjdp 675733965Sjdp if (found) 675833965Sjdp type.indx = indx; 675933965Sjdp } 676033965Sjdp 6761130561Sobrien h = ieee_name_type_hash_lookup (&info->typedefs, name, TRUE, FALSE); 676233965Sjdp if (h == NULL) 6763130561Sobrien return FALSE; 676433965Sjdp 676533965Sjdp /* See if we have already defined this type with this name. */ 676633965Sjdp localp = type.localp; 676733965Sjdp for (nt = h->types; nt != NULL; nt = nt->next) 676833965Sjdp { 676933965Sjdp if (nt->id == indx) 677033965Sjdp { 677133965Sjdp /* If this is a global definition, then we don't need to 677233965Sjdp do anything here. */ 677333965Sjdp if (! nt->type.localp) 677433965Sjdp { 677533965Sjdp ieee_pop_unused_type (info); 6776130561Sobrien return TRUE; 677733965Sjdp } 677833965Sjdp } 677933965Sjdp else 678033965Sjdp { 678133965Sjdp /* This is a duplicate definition, so make this one local. */ 6782130561Sobrien localp = TRUE; 678333965Sjdp } 678433965Sjdp } 678533965Sjdp 678633965Sjdp /* We need to add a new typedef for this type. */ 678733965Sjdp 678833965Sjdp nt = (struct ieee_name_type *) xmalloc (sizeof *nt); 678933965Sjdp memset (nt, 0, sizeof *nt); 679033965Sjdp nt->id = indx; 679133965Sjdp nt->type = type; 679233965Sjdp nt->type.name = name; 679333965Sjdp nt->type.localp = localp; 679433965Sjdp nt->kind = DEBUG_KIND_ILLEGAL; 679533965Sjdp 679633965Sjdp nt->next = h->types; 679733965Sjdp h->types = nt; 679833965Sjdp 679933965Sjdp if (found) 680033965Sjdp { 680133965Sjdp /* This is one of the builtin typedefs, so we don't need to 680233965Sjdp actually define it. */ 680333965Sjdp ieee_pop_unused_type (info); 6804130561Sobrien return TRUE; 680533965Sjdp } 680633965Sjdp 680733965Sjdp indx = ieee_pop_type (info); 680833965Sjdp 680933965Sjdp if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size, 681033965Sjdp type.unsignedp, localp, 681133965Sjdp (struct ieee_buflist *) NULL) 681233965Sjdp || ! ieee_write_number (info, 'T') 681333965Sjdp || ! ieee_write_number (info, indx)) 6814130561Sobrien return FALSE; 681533965Sjdp 681633965Sjdp /* Remove the type we just added to the type stack. This should not 681733965Sjdp be ieee_pop_unused_type, since the type is used, we just don't 681833965Sjdp need it now. */ 681933965Sjdp (void) ieee_pop_type (info); 682033965Sjdp 6821130561Sobrien return TRUE; 682233965Sjdp} 682333965Sjdp 682433965Sjdp/* Output a tag for a type. We don't have to do anything here. */ 682533965Sjdp 6826130561Sobrienstatic bfd_boolean 6827130561Sobrienieee_tag (void *p, const char *name ATTRIBUTE_UNUSED) 682833965Sjdp{ 682933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 683033965Sjdp 683133965Sjdp /* This should not be ieee_pop_unused_type, since we want the type 683233965Sjdp to be defined. */ 683333965Sjdp (void) ieee_pop_type (info); 6834130561Sobrien return TRUE; 683533965Sjdp} 683633965Sjdp 683733965Sjdp/* Output an integer constant. */ 683833965Sjdp 6839130561Sobrienstatic bfd_boolean 6840130561Sobrienieee_int_constant (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED, 6841130561Sobrien bfd_vma val ATTRIBUTE_UNUSED) 684233965Sjdp{ 684333965Sjdp /* FIXME. */ 6844130561Sobrien return TRUE; 684533965Sjdp} 684633965Sjdp 684733965Sjdp/* Output a floating point constant. */ 684833965Sjdp 6849130561Sobrienstatic bfd_boolean 6850130561Sobrienieee_float_constant (void *p ATTRIBUTE_UNUSED, 6851130561Sobrien const char *name ATTRIBUTE_UNUSED, 6852130561Sobrien double val ATTRIBUTE_UNUSED) 685333965Sjdp{ 685433965Sjdp /* FIXME. */ 6855130561Sobrien return TRUE; 685633965Sjdp} 685733965Sjdp 685833965Sjdp/* Output a typed constant. */ 685933965Sjdp 6860130561Sobrienstatic bfd_boolean 6861130561Sobrienieee_typed_constant (void *p, const char *name ATTRIBUTE_UNUSED, 6862130561Sobrien bfd_vma val ATTRIBUTE_UNUSED) 686333965Sjdp{ 686433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 686533965Sjdp 686633965Sjdp /* FIXME. */ 686733965Sjdp ieee_pop_unused_type (info); 6868130561Sobrien return TRUE; 686933965Sjdp} 687033965Sjdp 687133965Sjdp/* Output a variable. */ 687233965Sjdp 6873130561Sobrienstatic bfd_boolean 6874130561Sobrienieee_variable (void *p, const char *name, enum debug_var_kind kind, 6875130561Sobrien bfd_vma val) 687633965Sjdp{ 687733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 687833965Sjdp unsigned int name_indx; 687933965Sjdp unsigned int size; 6880130561Sobrien bfd_boolean referencep; 688133965Sjdp unsigned int type_indx; 6882130561Sobrien bfd_boolean asn; 688333965Sjdp int refflag; 688433965Sjdp 688533965Sjdp size = info->type_stack->type.size; 688633965Sjdp referencep = info->type_stack->type.referencep; 688733965Sjdp type_indx = ieee_pop_type (info); 688833965Sjdp 688933965Sjdp assert (! ieee_buffer_emptyp (&info->vars)); 689033965Sjdp if (! ieee_change_buffer (info, &info->vars)) 6891130561Sobrien return FALSE; 689233965Sjdp 689333965Sjdp name_indx = info->name_indx; 689433965Sjdp ++info->name_indx; 689533965Sjdp 689633965Sjdp /* Write out an NN and an ATN record for this variable. */ 689733965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 689833965Sjdp || ! ieee_write_number (info, name_indx) 689933965Sjdp || ! ieee_write_id (info, name) 690033965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 690133965Sjdp || ! ieee_write_number (info, name_indx) 690233965Sjdp || ! ieee_write_number (info, type_indx)) 6903130561Sobrien return FALSE; 690433965Sjdp switch (kind) 690533965Sjdp { 690633965Sjdp default: 690733965Sjdp abort (); 6908130561Sobrien return FALSE; 690933965Sjdp case DEBUG_GLOBAL: 691033965Sjdp if (! ieee_write_number (info, 8) 6911130561Sobrien || ! ieee_add_range (info, FALSE, val, val + size)) 6912130561Sobrien return FALSE; 691333965Sjdp refflag = 0; 6914130561Sobrien asn = TRUE; 691533965Sjdp break; 691633965Sjdp case DEBUG_STATIC: 691733965Sjdp if (! ieee_write_number (info, 3) 6918130561Sobrien || ! ieee_add_range (info, FALSE, val, val + size)) 6919130561Sobrien return FALSE; 692033965Sjdp refflag = 1; 6921130561Sobrien asn = TRUE; 692233965Sjdp break; 692333965Sjdp case DEBUG_LOCAL_STATIC: 692433965Sjdp if (! ieee_write_number (info, 3) 6925130561Sobrien || ! ieee_add_range (info, FALSE, val, val + size)) 6926130561Sobrien return FALSE; 692733965Sjdp refflag = 2; 6928130561Sobrien asn = TRUE; 692933965Sjdp break; 693033965Sjdp case DEBUG_LOCAL: 693133965Sjdp if (! ieee_write_number (info, 1) 693233965Sjdp || ! ieee_write_number (info, val)) 6933130561Sobrien return FALSE; 693433965Sjdp refflag = 2; 6935130561Sobrien asn = FALSE; 693633965Sjdp break; 693733965Sjdp case DEBUG_REGISTER: 693833965Sjdp if (! ieee_write_number (info, 2) 693933965Sjdp || ! ieee_write_number (info, 694033965Sjdp ieee_genreg_to_regno (info->abfd, val))) 6941130561Sobrien return FALSE; 694233965Sjdp refflag = 2; 6943130561Sobrien asn = FALSE; 694433965Sjdp break; 694533965Sjdp } 694633965Sjdp 694733965Sjdp if (asn) 694833965Sjdp { 694933965Sjdp if (! ieee_write_asn (info, name_indx, val)) 6950130561Sobrien return FALSE; 695133965Sjdp } 695233965Sjdp 695333965Sjdp /* If this is really a reference type, then we just output it with 695433965Sjdp pointer type, and must now output a C++ record indicating that it 695533965Sjdp is really reference type. */ 695633965Sjdp if (referencep) 695733965Sjdp { 695833965Sjdp unsigned int nindx; 695933965Sjdp 696033965Sjdp nindx = info->name_indx; 696133965Sjdp ++info->name_indx; 696233965Sjdp 696333965Sjdp /* If this is a global variable, we want to output the misc 696433965Sjdp record in the C++ misc record block. Otherwise, we want to 696533965Sjdp output it just after the variable definition, which is where 696633965Sjdp the current buffer is. */ 696733965Sjdp if (refflag != 2) 696833965Sjdp { 696933965Sjdp if (! ieee_change_buffer (info, &info->cxx)) 6970130561Sobrien return FALSE; 697133965Sjdp } 697233965Sjdp 697333965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 697433965Sjdp || ! ieee_write_number (info, nindx) 697533965Sjdp || ! ieee_write_id (info, "") 697633965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 697733965Sjdp || ! ieee_write_number (info, nindx) 697833965Sjdp || ! ieee_write_number (info, 0) 697933965Sjdp || ! ieee_write_number (info, 62) 698033965Sjdp || ! ieee_write_number (info, 80) 698133965Sjdp || ! ieee_write_number (info, 3) 698233965Sjdp || ! ieee_write_asn (info, nindx, 'R') 698333965Sjdp || ! ieee_write_asn (info, nindx, refflag) 698433965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 6985130561Sobrien return FALSE; 698633965Sjdp } 698733965Sjdp 6988130561Sobrien return TRUE; 698933965Sjdp} 699033965Sjdp 699133965Sjdp/* Start outputting information for a function. */ 699233965Sjdp 6993130561Sobrienstatic bfd_boolean 6994130561Sobrienieee_start_function (void *p, const char *name, bfd_boolean global) 699533965Sjdp{ 699633965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 6997130561Sobrien bfd_boolean referencep; 699833965Sjdp unsigned int retindx, typeindx; 699933965Sjdp 700033965Sjdp referencep = info->type_stack->type.referencep; 700133965Sjdp retindx = ieee_pop_type (info); 700233965Sjdp 700333965Sjdp /* Besides recording a BB4 or BB6 block, we record the type of the 700433965Sjdp function in the BB1 typedef block. We can't write out the full 700533965Sjdp type until we have seen all the parameters, so we accumulate it 700633965Sjdp in info->fntype and info->fnargs. */ 700733965Sjdp if (! ieee_buffer_emptyp (&info->fntype)) 700833965Sjdp { 700933965Sjdp /* FIXME: This might happen someday if we support nested 701033965Sjdp functions. */ 701133965Sjdp abort (); 701233965Sjdp } 701333965Sjdp 701433965Sjdp info->fnname = name; 701533965Sjdp 701633965Sjdp /* An attribute of 0x40 means that the push mask is unknown. */ 7017130561Sobrien if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, FALSE, TRUE, 701833965Sjdp &info->fntype) 701933965Sjdp || ! ieee_write_number (info, 'x') 702033965Sjdp || ! ieee_write_number (info, 0x40) 702133965Sjdp || ! ieee_write_number (info, 0) 702233965Sjdp || ! ieee_write_number (info, 0) 702333965Sjdp || ! ieee_write_number (info, retindx)) 7024130561Sobrien return FALSE; 702533965Sjdp 702633965Sjdp typeindx = ieee_pop_type (info); 702733965Sjdp 702833965Sjdp if (! ieee_init_buffer (info, &info->fnargs)) 7029130561Sobrien return FALSE; 703033965Sjdp info->fnargcount = 0; 703133965Sjdp 703233965Sjdp /* If the function return value is actually a reference type, we 703333965Sjdp must add a record indicating that. */ 703433965Sjdp if (referencep) 703533965Sjdp { 703633965Sjdp unsigned int nindx; 703733965Sjdp 703833965Sjdp nindx = info->name_indx; 703933965Sjdp ++info->name_indx; 704033965Sjdp if (! ieee_change_buffer (info, &info->cxx) 704133965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 704233965Sjdp || ! ieee_write_number (info, nindx) 704333965Sjdp || ! ieee_write_id (info, "") 704433965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 704533965Sjdp || ! ieee_write_number (info, nindx) 704633965Sjdp || ! ieee_write_number (info, 0) 704733965Sjdp || ! ieee_write_number (info, 62) 704833965Sjdp || ! ieee_write_number (info, 80) 704933965Sjdp || ! ieee_write_number (info, 3) 705033965Sjdp || ! ieee_write_asn (info, nindx, 'R') 705133965Sjdp || ! ieee_write_asn (info, nindx, global ? 0 : 1) 705233965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 7053130561Sobrien return FALSE; 705433965Sjdp } 705533965Sjdp 705633965Sjdp assert (! ieee_buffer_emptyp (&info->vars)); 705733965Sjdp if (! ieee_change_buffer (info, &info->vars)) 7058130561Sobrien return FALSE; 705933965Sjdp 706033965Sjdp /* The address is written out as the first block. */ 706133965Sjdp 706233965Sjdp ++info->block_depth; 706333965Sjdp 706433965Sjdp return (ieee_write_byte (info, (int) ieee_bb_record_enum) 706533965Sjdp && ieee_write_byte (info, global ? 4 : 6) 706633965Sjdp && ieee_write_number (info, 0) 706733965Sjdp && ieee_write_id (info, name) 706833965Sjdp && ieee_write_number (info, 0) 706933965Sjdp && ieee_write_number (info, typeindx)); 707033965Sjdp} 707133965Sjdp 707233965Sjdp/* Add a function parameter. This will normally be called before the 707333965Sjdp first block, so we postpone them until we see the block. */ 707433965Sjdp 7075130561Sobrienstatic bfd_boolean 7076130561Sobrienieee_function_parameter (void *p, const char *name, enum debug_parm_kind kind, 7077130561Sobrien bfd_vma val) 707833965Sjdp{ 707933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 708033965Sjdp struct ieee_pending_parm *m, **pm; 708133965Sjdp 708233965Sjdp assert (info->block_depth == 1); 708333965Sjdp 708433965Sjdp m = (struct ieee_pending_parm *) xmalloc (sizeof *m); 708533965Sjdp memset (m, 0, sizeof *m); 708633965Sjdp 708733965Sjdp m->next = NULL; 708833965Sjdp m->name = name; 708933965Sjdp m->referencep = info->type_stack->type.referencep; 709033965Sjdp m->type = ieee_pop_type (info); 709133965Sjdp m->kind = kind; 709233965Sjdp m->val = val; 709333965Sjdp 709433965Sjdp for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next) 709533965Sjdp ; 709633965Sjdp *pm = m; 709733965Sjdp 709833965Sjdp /* Add the type to the fnargs list. */ 709933965Sjdp if (! ieee_change_buffer (info, &info->fnargs) 710033965Sjdp || ! ieee_write_number (info, m->type)) 7101130561Sobrien return FALSE; 710233965Sjdp ++info->fnargcount; 710333965Sjdp 7104130561Sobrien return TRUE; 710533965Sjdp} 710633965Sjdp 710733965Sjdp/* Output pending function parameters. */ 710833965Sjdp 7109130561Sobrienstatic bfd_boolean 7110130561Sobrienieee_output_pending_parms (struct ieee_handle *info) 711133965Sjdp{ 711233965Sjdp struct ieee_pending_parm *m; 711333965Sjdp unsigned int refcount; 711433965Sjdp 711533965Sjdp refcount = 0; 711633965Sjdp for (m = info->pending_parms; m != NULL; m = m->next) 711733965Sjdp { 711833965Sjdp enum debug_var_kind vkind; 711933965Sjdp 712033965Sjdp switch (m->kind) 712133965Sjdp { 712233965Sjdp default: 712333965Sjdp abort (); 7124130561Sobrien return FALSE; 712533965Sjdp case DEBUG_PARM_STACK: 712633965Sjdp case DEBUG_PARM_REFERENCE: 712733965Sjdp vkind = DEBUG_LOCAL; 712833965Sjdp break; 712933965Sjdp case DEBUG_PARM_REG: 713033965Sjdp case DEBUG_PARM_REF_REG: 713133965Sjdp vkind = DEBUG_REGISTER; 713233965Sjdp break; 713333965Sjdp } 713433965Sjdp 7135130561Sobrien if (! ieee_push_type (info, m->type, 0, FALSE, FALSE)) 7136130561Sobrien return FALSE; 713733965Sjdp info->type_stack->type.referencep = m->referencep; 713833965Sjdp if (m->referencep) 713933965Sjdp ++refcount; 7140130561Sobrien if (! ieee_variable ((void *) info, m->name, vkind, m->val)) 7141130561Sobrien return FALSE; 714233965Sjdp } 714333965Sjdp 714433965Sjdp /* If there are any reference parameters, we need to output a 714533965Sjdp miscellaneous record indicating them. */ 714633965Sjdp if (refcount > 0) 714733965Sjdp { 714833965Sjdp unsigned int nindx, varindx; 714933965Sjdp 715033965Sjdp /* FIXME: The MRI compiler outputs the demangled function name 715133965Sjdp here, but we are outputting the mangled name. */ 715233965Sjdp nindx = info->name_indx; 715333965Sjdp ++info->name_indx; 715433965Sjdp if (! ieee_change_buffer (info, &info->vars) 715533965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 715633965Sjdp || ! ieee_write_number (info, nindx) 715733965Sjdp || ! ieee_write_id (info, "") 715833965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 715933965Sjdp || ! ieee_write_number (info, nindx) 716033965Sjdp || ! ieee_write_number (info, 0) 716133965Sjdp || ! ieee_write_number (info, 62) 716233965Sjdp || ! ieee_write_number (info, 80) 716333965Sjdp || ! ieee_write_number (info, refcount + 3) 716433965Sjdp || ! ieee_write_asn (info, nindx, 'B') 716533965Sjdp || ! ieee_write_atn65 (info, nindx, info->fnname) 716633965Sjdp || ! ieee_write_asn (info, nindx, 0)) 7167130561Sobrien return FALSE; 716833965Sjdp for (m = info->pending_parms, varindx = 1; 716933965Sjdp m != NULL; 717033965Sjdp m = m->next, varindx++) 717133965Sjdp { 717233965Sjdp if (m->referencep) 717333965Sjdp { 717433965Sjdp if (! ieee_write_asn (info, nindx, varindx)) 7175130561Sobrien return FALSE; 717633965Sjdp } 717733965Sjdp } 717833965Sjdp } 717933965Sjdp 718033965Sjdp m = info->pending_parms; 718133965Sjdp while (m != NULL) 718233965Sjdp { 718333965Sjdp struct ieee_pending_parm *next; 718433965Sjdp 718533965Sjdp next = m->next; 718633965Sjdp free (m); 718733965Sjdp m = next; 718833965Sjdp } 718933965Sjdp 719033965Sjdp info->pending_parms = NULL; 719133965Sjdp 7192130561Sobrien return TRUE; 719333965Sjdp} 719433965Sjdp 719533965Sjdp/* Start a block. If this is the first block, we output the address 719633965Sjdp to finish the BB4 or BB6, and then output the function parameters. */ 719733965Sjdp 7198130561Sobrienstatic bfd_boolean 7199130561Sobrienieee_start_block (void *p, bfd_vma addr) 720033965Sjdp{ 720133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 720233965Sjdp 720333965Sjdp if (! ieee_change_buffer (info, &info->vars)) 7204130561Sobrien return FALSE; 720533965Sjdp 720633965Sjdp if (info->block_depth == 1) 720733965Sjdp { 720833965Sjdp if (! ieee_write_number (info, addr) 720933965Sjdp || ! ieee_output_pending_parms (info)) 7210130561Sobrien return FALSE; 721133965Sjdp } 721233965Sjdp else 721333965Sjdp { 721433965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 721533965Sjdp || ! ieee_write_byte (info, 6) 721633965Sjdp || ! ieee_write_number (info, 0) 721733965Sjdp || ! ieee_write_id (info, "") 721833965Sjdp || ! ieee_write_number (info, 0) 721933965Sjdp || ! ieee_write_number (info, 0) 722033965Sjdp || ! ieee_write_number (info, addr)) 7221130561Sobrien return FALSE; 722233965Sjdp } 722333965Sjdp 722433965Sjdp if (! ieee_start_range (info, addr)) 7225130561Sobrien return FALSE; 722633965Sjdp 722733965Sjdp ++info->block_depth; 722833965Sjdp 7229130561Sobrien return TRUE; 723033965Sjdp} 723133965Sjdp 723233965Sjdp/* End a block. */ 723333965Sjdp 7234130561Sobrienstatic bfd_boolean 7235130561Sobrienieee_end_block (void *p, bfd_vma addr) 723633965Sjdp{ 723733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 723833965Sjdp 723933965Sjdp /* The address we are given is the end of the block, but IEEE seems 724033965Sjdp to want to the address of the last byte in the block, so we 724133965Sjdp subtract one. */ 724233965Sjdp if (! ieee_change_buffer (info, &info->vars) 724333965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 724433965Sjdp || ! ieee_write_number (info, addr - 1)) 7245130561Sobrien return FALSE; 724633965Sjdp 724733965Sjdp if (! ieee_end_range (info, addr)) 7248130561Sobrien return FALSE; 724933965Sjdp 725033965Sjdp --info->block_depth; 725133965Sjdp 725233965Sjdp if (addr > info->highaddr) 725333965Sjdp info->highaddr = addr; 725433965Sjdp 7255130561Sobrien return TRUE; 725633965Sjdp} 725733965Sjdp 725833965Sjdp/* End a function. */ 725933965Sjdp 7260130561Sobrienstatic bfd_boolean 7261130561Sobrienieee_end_function (void *p) 726233965Sjdp{ 726333965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 726433965Sjdp 726533965Sjdp assert (info->block_depth == 1); 726633965Sjdp 726733965Sjdp --info->block_depth; 726833965Sjdp 726933965Sjdp /* Now we can finish up fntype, and add it to the typdef section. 727033965Sjdp At this point, fntype is the 'x' type up to the argument count, 727133965Sjdp and fnargs is the argument types. We must add the argument 727233965Sjdp count, and we must add the level. FIXME: We don't record varargs 727333965Sjdp functions correctly. In fact, stabs debugging does not give us 727433965Sjdp enough information to do so. */ 727533965Sjdp if (! ieee_change_buffer (info, &info->fntype) 727633965Sjdp || ! ieee_write_number (info, info->fnargcount) 727733965Sjdp || ! ieee_change_buffer (info, &info->fnargs) 727833965Sjdp || ! ieee_write_number (info, 0)) 7279130561Sobrien return FALSE; 728033965Sjdp 728133965Sjdp /* Make sure the typdef block has been started. */ 728233965Sjdp if (ieee_buffer_emptyp (&info->types)) 728333965Sjdp { 728433965Sjdp if (! ieee_change_buffer (info, &info->types) 728533965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 728633965Sjdp || ! ieee_write_byte (info, 1) 728733965Sjdp || ! ieee_write_number (info, 0) 728833965Sjdp || ! ieee_write_id (info, info->modname)) 7289130561Sobrien return FALSE; 729033965Sjdp } 729133965Sjdp 729233965Sjdp if (! ieee_append_buffer (info, &info->types, &info->fntype) 729333965Sjdp || ! ieee_append_buffer (info, &info->types, &info->fnargs)) 7294130561Sobrien return FALSE; 729533965Sjdp 729633965Sjdp info->fnname = NULL; 729733965Sjdp if (! ieee_init_buffer (info, &info->fntype) 729833965Sjdp || ! ieee_init_buffer (info, &info->fnargs)) 7299130561Sobrien return FALSE; 730033965Sjdp info->fnargcount = 0; 730133965Sjdp 7302130561Sobrien return TRUE; 730333965Sjdp} 730433965Sjdp 730533965Sjdp/* Record line number information. */ 730633965Sjdp 7307130561Sobrienstatic bfd_boolean 7308130561Sobrienieee_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr) 730933965Sjdp{ 731033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 731133965Sjdp 731233965Sjdp assert (info->filename != NULL); 731333965Sjdp 731433965Sjdp /* The HP simulator seems to get confused when more than one line is 731533965Sjdp listed for the same address, at least if they are in different 731633965Sjdp files. We handle this by always listing the last line for a 731733965Sjdp given address, since that seems to be the one that gdb uses. */ 731833965Sjdp if (info->pending_lineno_filename != NULL 731933965Sjdp && addr != info->pending_lineno_addr) 732033965Sjdp { 732133965Sjdp /* Make sure we have a line number block. */ 732233965Sjdp if (! ieee_buffer_emptyp (&info->linenos)) 732333965Sjdp { 732433965Sjdp if (! ieee_change_buffer (info, &info->linenos)) 7325130561Sobrien return FALSE; 732633965Sjdp } 732733965Sjdp else 732833965Sjdp { 732933965Sjdp info->lineno_name_indx = info->name_indx; 733033965Sjdp ++info->name_indx; 733133965Sjdp if (! ieee_change_buffer (info, &info->linenos) 733233965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 733333965Sjdp || ! ieee_write_byte (info, 5) 733433965Sjdp || ! ieee_write_number (info, 0) 733533965Sjdp || ! ieee_write_id (info, info->filename) 733633965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 733733965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 733833965Sjdp || ! ieee_write_id (info, "")) 7339130561Sobrien return FALSE; 734033965Sjdp info->lineno_filename = info->filename; 734133965Sjdp } 734233965Sjdp 734333965Sjdp if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0) 734433965Sjdp { 734533965Sjdp if (strcmp (info->filename, info->lineno_filename) != 0) 734633965Sjdp { 734733965Sjdp /* We were not in the main file. Close the block for the 734833965Sjdp included file. */ 734933965Sjdp if (! ieee_write_byte (info, (int) ieee_be_record_enum)) 7350130561Sobrien return FALSE; 735133965Sjdp if (strcmp (info->filename, info->pending_lineno_filename) == 0) 735233965Sjdp { 735333965Sjdp /* We need a new NN record, and we aren't about to 735433965Sjdp output one. */ 735533965Sjdp info->lineno_name_indx = info->name_indx; 735633965Sjdp ++info->name_indx; 735733965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 735833965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 735933965Sjdp || ! ieee_write_id (info, "")) 7360130561Sobrien return FALSE; 736133965Sjdp } 736233965Sjdp } 736333965Sjdp if (strcmp (info->filename, info->pending_lineno_filename) != 0) 736433965Sjdp { 736533965Sjdp /* We are not changing to the main file. Open a block for 736633965Sjdp the new included file. */ 736733965Sjdp info->lineno_name_indx = info->name_indx; 736833965Sjdp ++info->name_indx; 736933965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 737033965Sjdp || ! ieee_write_byte (info, 5) 737133965Sjdp || ! ieee_write_number (info, 0) 737233965Sjdp || ! ieee_write_id (info, info->pending_lineno_filename) 737333965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 737433965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 737533965Sjdp || ! ieee_write_id (info, "")) 7376130561Sobrien return FALSE; 737733965Sjdp } 737833965Sjdp info->lineno_filename = info->pending_lineno_filename; 737933965Sjdp } 738033965Sjdp 738133965Sjdp if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 738233965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 738333965Sjdp || ! ieee_write_number (info, 0) 738433965Sjdp || ! ieee_write_number (info, 7) 738533965Sjdp || ! ieee_write_number (info, info->pending_lineno) 738633965Sjdp || ! ieee_write_number (info, 0) 738733965Sjdp || ! ieee_write_asn (info, info->lineno_name_indx, 738833965Sjdp info->pending_lineno_addr)) 7389130561Sobrien return FALSE; 739033965Sjdp } 739133965Sjdp 739233965Sjdp info->pending_lineno_filename = filename; 739333965Sjdp info->pending_lineno = lineno; 739433965Sjdp info->pending_lineno_addr = addr; 739533965Sjdp 7396130561Sobrien return TRUE; 739733965Sjdp} 7398