ieee.c revision 104834
133965Sjdp/* ieee.c -- Read and write IEEE-695 debugging information. 2104834Sobrien Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. 333965Sjdp Written by Ian Lance Taylor <ian@cygnus.com>. 433965Sjdp 533965Sjdp This file is part of GNU Binutils. 633965Sjdp 733965Sjdp This program is free software; you can redistribute it and/or modify 833965Sjdp it under the terms of the GNU General Public License as published by 933965Sjdp the Free Software Foundation; either version 2 of the License, or 1033965Sjdp (at your option) any later version. 1133965Sjdp 1233965Sjdp This program is distributed in the hope that it will be useful, 1333965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1433965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965Sjdp GNU General Public License for more details. 1633965Sjdp 1733965Sjdp You should have received a copy of the GNU General Public License 1833965Sjdp along with this program; if not, write to the Free Software 1933965Sjdp Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 2033965Sjdp 02111-1307, USA. */ 2133965Sjdp 2233965Sjdp/* This file reads and writes IEEE-695 debugging information. */ 2333965Sjdp 2433965Sjdp#include <stdio.h> 2533965Sjdp#include <assert.h> 2633965Sjdp 2733965Sjdp#include "bfd.h" 2833965Sjdp#include "ieee.h" 2933965Sjdp#include "bucomm.h" 3033965Sjdp#include "libiberty.h" 3133965Sjdp#include "debug.h" 3233965Sjdp#include "budbg.h" 3361843Sobrien#include "filenames.h" 3433965Sjdp 3533965Sjdp/* This structure holds an entry on the block stack. */ 3633965Sjdp 3733965Sjdpstruct ieee_block 3833965Sjdp{ 3933965Sjdp /* The kind of block. */ 4033965Sjdp int kind; 4133965Sjdp /* The source file name, for a BB5 block. */ 4233965Sjdp const char *filename; 4333965Sjdp /* The index of the function type, for a BB4 or BB6 block. */ 4433965Sjdp unsigned int fnindx; 4533965Sjdp /* True if this function is being skipped. */ 4633965Sjdp boolean skip; 4733965Sjdp}; 4833965Sjdp 4933965Sjdp/* This structure is the block stack. */ 5033965Sjdp 5133965Sjdp#define BLOCKSTACK_SIZE (16) 5233965Sjdp 5333965Sjdpstruct ieee_blockstack 5433965Sjdp{ 5533965Sjdp /* The stack pointer. */ 5633965Sjdp struct ieee_block *bsp; 5733965Sjdp /* The stack. */ 5833965Sjdp struct ieee_block stack[BLOCKSTACK_SIZE]; 5933965Sjdp}; 6033965Sjdp 6133965Sjdp/* This structure holds information for a variable. */ 6233965Sjdp 6333965Sjdpstruct ieee_var 6433965Sjdp{ 6533965Sjdp /* Start of name. */ 6633965Sjdp const char *name; 6733965Sjdp /* Length of name. */ 6833965Sjdp unsigned long namlen; 6933965Sjdp /* Type. */ 7033965Sjdp debug_type type; 7133965Sjdp /* Slot if we make an indirect type. */ 7233965Sjdp debug_type *pslot; 7333965Sjdp /* Kind of variable or function. */ 7433965Sjdp enum 7533965Sjdp { 7633965Sjdp IEEE_UNKNOWN, 7733965Sjdp IEEE_EXTERNAL, 7833965Sjdp IEEE_GLOBAL, 7933965Sjdp IEEE_STATIC, 8033965Sjdp IEEE_LOCAL, 8133965Sjdp IEEE_FUNCTION 8233965Sjdp } kind; 8333965Sjdp}; 8433965Sjdp 8533965Sjdp/* This structure holds all the variables. */ 8633965Sjdp 8733965Sjdpstruct ieee_vars 8833965Sjdp{ 8933965Sjdp /* Number of slots allocated. */ 9033965Sjdp unsigned int alloc; 9133965Sjdp /* Variables. */ 9233965Sjdp struct ieee_var *vars; 9333965Sjdp}; 9433965Sjdp 9533965Sjdp/* This structure holds information for a type. We need this because 9633965Sjdp we don't want to represent bitfields as real types. */ 9733965Sjdp 9833965Sjdpstruct ieee_type 9933965Sjdp{ 10033965Sjdp /* Type. */ 10133965Sjdp debug_type type; 10233965Sjdp /* Slot if this is type is referenced before it is defined. */ 10333965Sjdp debug_type *pslot; 10433965Sjdp /* Slots for arguments if we make indirect types for them. */ 10533965Sjdp debug_type *arg_slots; 10633965Sjdp /* If this is a bitfield, this is the size in bits. If this is not 10733965Sjdp a bitfield, this is zero. */ 10833965Sjdp unsigned long bitsize; 10933965Sjdp}; 11033965Sjdp 11133965Sjdp/* This structure holds all the type information. */ 11233965Sjdp 11333965Sjdpstruct ieee_types 11433965Sjdp{ 11533965Sjdp /* Number of slots allocated. */ 11633965Sjdp unsigned int alloc; 11733965Sjdp /* Types. */ 11833965Sjdp struct ieee_type *types; 11933965Sjdp /* Builtin types. */ 12033965Sjdp#define BUILTIN_TYPE_COUNT (60) 12133965Sjdp debug_type builtins[BUILTIN_TYPE_COUNT]; 12233965Sjdp}; 12333965Sjdp 12433965Sjdp/* This structure holds a linked last of structs with their tag names, 12533965Sjdp so that we can convert them to C++ classes if necessary. */ 12633965Sjdp 12733965Sjdpstruct ieee_tag 12833965Sjdp{ 12933965Sjdp /* Next tag. */ 13033965Sjdp struct ieee_tag *next; 13133965Sjdp /* This tag name. */ 13233965Sjdp const char *name; 13333965Sjdp /* The type of the tag. */ 13433965Sjdp debug_type type; 13533965Sjdp /* The tagged type is an indirect type pointing at this slot. */ 13633965Sjdp debug_type slot; 13733965Sjdp /* This is an array of slots used when a field type is converted 13833965Sjdp into a indirect type, in case it needs to be later converted into 13933965Sjdp a reference type. */ 14033965Sjdp debug_type *fslots; 14133965Sjdp}; 14233965Sjdp 14333965Sjdp/* This structure holds the information we pass around to the parsing 14433965Sjdp functions. */ 14533965Sjdp 14633965Sjdpstruct ieee_info 14733965Sjdp{ 14833965Sjdp /* The debugging handle. */ 14933965Sjdp PTR dhandle; 15033965Sjdp /* The BFD. */ 15133965Sjdp bfd *abfd; 15233965Sjdp /* The start of the bytes to be parsed. */ 15333965Sjdp const bfd_byte *bytes; 15433965Sjdp /* The end of the bytes to be parsed. */ 15533965Sjdp const bfd_byte *pend; 15633965Sjdp /* The block stack. */ 15733965Sjdp struct ieee_blockstack blockstack; 15833965Sjdp /* Whether we have seen a BB1 or BB2. */ 15933965Sjdp boolean saw_filename; 16033965Sjdp /* The variables. */ 16133965Sjdp struct ieee_vars vars; 16233965Sjdp /* The global variables, after a global typedef block. */ 16333965Sjdp struct ieee_vars *global_vars; 16433965Sjdp /* The types. */ 16533965Sjdp struct ieee_types types; 16633965Sjdp /* The global types, after a global typedef block. */ 16733965Sjdp struct ieee_types *global_types; 16833965Sjdp /* The list of tagged structs. */ 16933965Sjdp struct ieee_tag *tags; 17033965Sjdp}; 17133965Sjdp 17233965Sjdp/* Basic builtin types, not including the pointers. */ 17333965Sjdp 17433965Sjdpenum builtin_types 17533965Sjdp{ 17633965Sjdp builtin_unknown = 0, 17733965Sjdp builtin_void = 1, 17833965Sjdp builtin_signed_char = 2, 17933965Sjdp builtin_unsigned_char = 3, 18033965Sjdp builtin_signed_short_int = 4, 18133965Sjdp builtin_unsigned_short_int = 5, 18233965Sjdp builtin_signed_long = 6, 18333965Sjdp builtin_unsigned_long = 7, 18433965Sjdp builtin_signed_long_long = 8, 18533965Sjdp builtin_unsigned_long_long = 9, 18633965Sjdp builtin_float = 10, 18733965Sjdp builtin_double = 11, 18833965Sjdp builtin_long_double = 12, 18933965Sjdp builtin_long_long_double = 13, 19033965Sjdp builtin_quoted_string = 14, 19133965Sjdp builtin_instruction_address = 15, 19233965Sjdp builtin_int = 16, 19333965Sjdp builtin_unsigned = 17, 19433965Sjdp builtin_unsigned_int = 18, 19533965Sjdp builtin_char = 19, 19633965Sjdp builtin_long = 20, 19733965Sjdp builtin_short = 21, 19833965Sjdp builtin_unsigned_short = 22, 19933965Sjdp builtin_short_int = 23, 20033965Sjdp builtin_signed_short = 24, 20133965Sjdp builtin_bcd_float = 25 20233965Sjdp}; 20333965Sjdp 20433965Sjdp/* These are the values found in the derivation flags of a 'b' 20533965Sjdp component record of a 'T' type extension record in a C++ pmisc 20633965Sjdp record. These are bitmasks. */ 20733965Sjdp 20833965Sjdp/* Set for a private base class, clear for a public base class. 20933965Sjdp Protected base classes are not supported. */ 21033965Sjdp#define BASEFLAGS_PRIVATE (0x1) 21133965Sjdp/* Set for a virtual base class. */ 21233965Sjdp#define BASEFLAGS_VIRTUAL (0x2) 21333965Sjdp/* Set for a friend class, clear for a base class. */ 21433965Sjdp#define BASEFLAGS_FRIEND (0x10) 21533965Sjdp 21633965Sjdp/* These are the values found in the specs flags of a 'd', 'm', or 'v' 21733965Sjdp component record of a 'T' type extension record in a C++ pmisc 21833965Sjdp record. The same flags are used for a 'M' record in a C++ pmisc 21933965Sjdp record. */ 22033965Sjdp 22133965Sjdp/* The lower two bits hold visibility information. */ 22233965Sjdp#define CXXFLAGS_VISIBILITY (0x3) 22333965Sjdp/* This value in the lower two bits indicates a public member. */ 22433965Sjdp#define CXXFLAGS_VISIBILITY_PUBLIC (0x0) 22533965Sjdp/* This value in the lower two bits indicates a private member. */ 22633965Sjdp#define CXXFLAGS_VISIBILITY_PRIVATE (0x1) 22733965Sjdp/* This value in the lower two bits indicates a protected member. */ 22833965Sjdp#define CXXFLAGS_VISIBILITY_PROTECTED (0x2) 22933965Sjdp/* Set for a static member. */ 23033965Sjdp#define CXXFLAGS_STATIC (0x4) 23133965Sjdp/* Set for a virtual override. */ 23233965Sjdp#define CXXFLAGS_OVERRIDE (0x8) 23333965Sjdp/* Set for a friend function. */ 23433965Sjdp#define CXXFLAGS_FRIEND (0x10) 23533965Sjdp/* Set for a const function. */ 23633965Sjdp#define CXXFLAGS_CONST (0x20) 23733965Sjdp/* Set for a volatile function. */ 23833965Sjdp#define CXXFLAGS_VOLATILE (0x40) 23933965Sjdp/* Set for an overloaded function. */ 24033965Sjdp#define CXXFLAGS_OVERLOADED (0x80) 24133965Sjdp/* Set for an operator function. */ 24233965Sjdp#define CXXFLAGS_OPERATOR (0x100) 24333965Sjdp/* Set for a constructor or destructor. */ 24433965Sjdp#define CXXFLAGS_CTORDTOR (0x400) 24533965Sjdp/* Set for a constructor. */ 24633965Sjdp#define CXXFLAGS_CTOR (0x200) 24733965Sjdp/* Set for an inline function. */ 24833965Sjdp#define CXXFLAGS_INLINE (0x800) 24933965Sjdp 25033965Sjdp/* Local functions. */ 25133965Sjdp 25233965Sjdpstatic void ieee_error 25333965Sjdp PARAMS ((struct ieee_info *, const bfd_byte *, const char *)); 25433965Sjdpstatic void ieee_eof PARAMS ((struct ieee_info *)); 25533965Sjdpstatic char *savestring PARAMS ((const char *, unsigned long)); 25633965Sjdpstatic boolean ieee_read_number 25733965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); 25833965Sjdpstatic boolean ieee_read_optional_number 25933965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *, boolean *)); 26033965Sjdpstatic boolean ieee_read_id 26133965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, const char **, 26233965Sjdp unsigned long *)); 26333965Sjdpstatic boolean ieee_read_optional_id 26433965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, const char **, 26533965Sjdp unsigned long *, boolean *)); 26633965Sjdpstatic boolean ieee_read_expression 26733965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); 26833965Sjdpstatic debug_type ieee_builtin_type 26933965Sjdp PARAMS ((struct ieee_info *, const bfd_byte *, unsigned int)); 27033965Sjdpstatic boolean ieee_alloc_type 27133965Sjdp PARAMS ((struct ieee_info *, unsigned int, boolean)); 27233965Sjdpstatic boolean ieee_read_type_index 27333965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, debug_type *)); 27433965Sjdpstatic int ieee_regno_to_genreg PARAMS ((bfd *, int)); 27533965Sjdpstatic int ieee_genreg_to_regno PARAMS ((bfd *, int)); 27633965Sjdpstatic boolean parse_ieee_bb PARAMS ((struct ieee_info *, const bfd_byte **)); 27733965Sjdpstatic boolean parse_ieee_be PARAMS ((struct ieee_info *, const bfd_byte **)); 27833965Sjdpstatic boolean parse_ieee_nn PARAMS ((struct ieee_info *, const bfd_byte **)); 27933965Sjdpstatic boolean parse_ieee_ty PARAMS ((struct ieee_info *, const bfd_byte **)); 28033965Sjdpstatic boolean parse_ieee_atn PARAMS ((struct ieee_info *, const bfd_byte **)); 28133965Sjdpstatic boolean ieee_read_cxx_misc 28233965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); 28333965Sjdpstatic boolean ieee_read_cxx_class 28433965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); 28533965Sjdpstatic boolean ieee_read_cxx_defaults 28633965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, unsigned long)); 28733965Sjdpstatic boolean ieee_read_reference 28833965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **)); 28933965Sjdpstatic boolean ieee_require_asn 29033965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, bfd_vma *)); 29133965Sjdpstatic boolean ieee_require_atn65 29233965Sjdp PARAMS ((struct ieee_info *, const bfd_byte **, const char **, 29333965Sjdp unsigned long *)); 29433965Sjdp 29533965Sjdp/* Report an error in the IEEE debugging information. */ 29633965Sjdp 29733965Sjdpstatic void 29833965Sjdpieee_error (info, p, s) 29933965Sjdp struct ieee_info *info; 30033965Sjdp const bfd_byte *p; 30133965Sjdp const char *s; 30233965Sjdp{ 30333965Sjdp if (p != NULL) 30433965Sjdp fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd), 30533965Sjdp (unsigned long) (p - info->bytes), s, *p); 30633965Sjdp else 30733965Sjdp fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s); 30833965Sjdp} 30933965Sjdp 31033965Sjdp/* Report an unexpected EOF in the IEEE debugging information. */ 31133965Sjdp 31233965Sjdpstatic void 31333965Sjdpieee_eof (info) 31433965Sjdp struct ieee_info *info; 31533965Sjdp{ 31633965Sjdp ieee_error (info, (const bfd_byte *) NULL, 31760484Sobrien _("unexpected end of debugging information")); 31833965Sjdp} 31933965Sjdp 32033965Sjdp/* Save a string in memory. */ 32133965Sjdp 32233965Sjdpstatic char * 32333965Sjdpsavestring (start, len) 32433965Sjdp const char *start; 32533965Sjdp unsigned long len; 32633965Sjdp{ 32733965Sjdp char *ret; 32833965Sjdp 32933965Sjdp ret = (char *) xmalloc (len + 1); 33033965Sjdp memcpy (ret, start, len); 33133965Sjdp ret[len] = '\0'; 33233965Sjdp return ret; 33333965Sjdp} 33433965Sjdp 33533965Sjdp/* Read a number which must be present in an IEEE file. */ 33633965Sjdp 33733965Sjdpstatic boolean 33833965Sjdpieee_read_number (info, pp, pv) 33933965Sjdp struct ieee_info *info; 34033965Sjdp const bfd_byte **pp; 34133965Sjdp bfd_vma *pv; 34233965Sjdp{ 34333965Sjdp return ieee_read_optional_number (info, pp, pv, (boolean *) NULL); 34433965Sjdp} 34533965Sjdp 34633965Sjdp/* Read a number in an IEEE file. If ppresent is not NULL, the number 347104834Sobrien need not be there. */ 34833965Sjdp 34933965Sjdpstatic boolean 35033965Sjdpieee_read_optional_number (info, pp, pv, ppresent) 35133965Sjdp struct ieee_info *info; 35233965Sjdp const bfd_byte **pp; 35333965Sjdp bfd_vma *pv; 35433965Sjdp boolean *ppresent; 35533965Sjdp{ 35633965Sjdp ieee_record_enum_type b; 35733965Sjdp 35833965Sjdp if (*pp >= info->pend) 35933965Sjdp { 36033965Sjdp if (ppresent != NULL) 36133965Sjdp { 36233965Sjdp *ppresent = false; 36333965Sjdp return true; 36433965Sjdp } 36533965Sjdp ieee_eof (info); 36633965Sjdp return false; 36733965Sjdp } 36833965Sjdp 36933965Sjdp b = (ieee_record_enum_type) **pp; 37033965Sjdp ++*pp; 37133965Sjdp 37233965Sjdp if (b <= ieee_number_end_enum) 37333965Sjdp { 37433965Sjdp *pv = (bfd_vma) b; 37533965Sjdp if (ppresent != NULL) 37633965Sjdp *ppresent = true; 37733965Sjdp return true; 37833965Sjdp } 37933965Sjdp 38033965Sjdp if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum) 38133965Sjdp { 38233965Sjdp unsigned int i; 38333965Sjdp 38433965Sjdp i = (int) b - (int) ieee_number_repeat_start_enum; 38533965Sjdp if (*pp + i - 1 >= info->pend) 38633965Sjdp { 38733965Sjdp ieee_eof (info); 38833965Sjdp return false; 38933965Sjdp } 39033965Sjdp 39133965Sjdp *pv = 0; 39233965Sjdp for (; i > 0; i--) 39333965Sjdp { 39433965Sjdp *pv <<= 8; 39533965Sjdp *pv += **pp; 39633965Sjdp ++*pp; 39733965Sjdp } 39833965Sjdp 39933965Sjdp if (ppresent != NULL) 40033965Sjdp *ppresent = true; 40133965Sjdp 40233965Sjdp return true; 40333965Sjdp } 40433965Sjdp 40533965Sjdp if (ppresent != NULL) 40633965Sjdp { 40733965Sjdp --*pp; 40833965Sjdp *ppresent = false; 40933965Sjdp return true; 41033965Sjdp } 41133965Sjdp 41260484Sobrien ieee_error (info, *pp - 1, _("invalid number")); 41377298Sobrien return false; 41433965Sjdp} 41533965Sjdp 41633965Sjdp/* Read a required string from an IEEE file. */ 41733965Sjdp 41833965Sjdpstatic boolean 41933965Sjdpieee_read_id (info, pp, pname, pnamlen) 42033965Sjdp struct ieee_info *info; 42133965Sjdp const bfd_byte **pp; 42233965Sjdp const char **pname; 42333965Sjdp unsigned long *pnamlen; 42433965Sjdp{ 42533965Sjdp return ieee_read_optional_id (info, pp, pname, pnamlen, (boolean *) NULL); 42633965Sjdp} 42733965Sjdp 42833965Sjdp/* Read a string from an IEEE file. If ppresent is not NULL, the 42933965Sjdp string is optional. */ 43033965Sjdp 43133965Sjdpstatic boolean 43233965Sjdpieee_read_optional_id (info, pp, pname, pnamlen, ppresent) 43333965Sjdp struct ieee_info *info; 43433965Sjdp const bfd_byte **pp; 43533965Sjdp const char **pname; 43633965Sjdp unsigned long *pnamlen; 43733965Sjdp boolean *ppresent; 43833965Sjdp{ 43933965Sjdp bfd_byte b; 44033965Sjdp unsigned long len; 44133965Sjdp 44233965Sjdp if (*pp >= info->pend) 44333965Sjdp { 44433965Sjdp ieee_eof (info); 44533965Sjdp return false; 44633965Sjdp } 44733965Sjdp 44833965Sjdp b = **pp; 44933965Sjdp ++*pp; 45033965Sjdp 45133965Sjdp if (b <= 0x7f) 45233965Sjdp len = b; 45333965Sjdp else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum) 45433965Sjdp { 45533965Sjdp len = **pp; 45633965Sjdp ++*pp; 45733965Sjdp } 45833965Sjdp else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum) 45933965Sjdp { 46033965Sjdp len = (**pp << 8) + (*pp)[1]; 46133965Sjdp *pp += 2; 46233965Sjdp } 46333965Sjdp else 46433965Sjdp { 46533965Sjdp if (ppresent != NULL) 46633965Sjdp { 46733965Sjdp --*pp; 46833965Sjdp *ppresent = false; 46933965Sjdp return true; 47033965Sjdp } 47160484Sobrien ieee_error (info, *pp - 1, _("invalid string length")); 47233965Sjdp return false; 47333965Sjdp } 47433965Sjdp 47533965Sjdp if ((unsigned long) (info->pend - *pp) < len) 47633965Sjdp { 47733965Sjdp ieee_eof (info); 47833965Sjdp return false; 47933965Sjdp } 48033965Sjdp 48133965Sjdp *pname = (const char *) *pp; 48233965Sjdp *pnamlen = len; 48333965Sjdp *pp += len; 48433965Sjdp 48533965Sjdp if (ppresent != NULL) 48633965Sjdp *ppresent = true; 48733965Sjdp 48833965Sjdp return true; 48933965Sjdp} 49033965Sjdp 49133965Sjdp/* Read an expression from an IEEE file. Since this code is only used 49233965Sjdp to parse debugging information, I haven't bothered to write a full 49333965Sjdp blown IEEE expression parser. I've only thrown in the things I've 49433965Sjdp seen in debugging information. This can be easily extended if 49533965Sjdp necessary. */ 49633965Sjdp 49733965Sjdpstatic boolean 49833965Sjdpieee_read_expression (info, pp, pv) 49933965Sjdp struct ieee_info *info; 50033965Sjdp const bfd_byte **pp; 50133965Sjdp bfd_vma *pv; 50233965Sjdp{ 50333965Sjdp const bfd_byte *expr_start; 50433965Sjdp#define EXPR_STACK_SIZE (10) 50533965Sjdp bfd_vma expr_stack[EXPR_STACK_SIZE]; 50633965Sjdp bfd_vma *esp; 50733965Sjdp 50833965Sjdp expr_start = *pp; 50933965Sjdp 51033965Sjdp esp = expr_stack; 51133965Sjdp 51233965Sjdp while (1) 51333965Sjdp { 51433965Sjdp const bfd_byte *start; 51533965Sjdp bfd_vma val; 51633965Sjdp boolean present; 51733965Sjdp ieee_record_enum_type c; 51833965Sjdp 51933965Sjdp start = *pp; 52033965Sjdp 52133965Sjdp if (! ieee_read_optional_number (info, pp, &val, &present)) 52233965Sjdp return false; 52333965Sjdp 52433965Sjdp if (present) 52533965Sjdp { 52633965Sjdp if (esp - expr_stack >= EXPR_STACK_SIZE) 52733965Sjdp { 52860484Sobrien ieee_error (info, start, _("expression stack overflow")); 52933965Sjdp return false; 53033965Sjdp } 53133965Sjdp *esp++ = val; 53233965Sjdp continue; 53333965Sjdp } 53433965Sjdp 53533965Sjdp c = (ieee_record_enum_type) **pp; 53633965Sjdp 53733965Sjdp if (c >= ieee_module_beginning_enum) 53833965Sjdp break; 53933965Sjdp 54033965Sjdp ++*pp; 54133965Sjdp 54233965Sjdp if (c == ieee_comma) 54333965Sjdp break; 54433965Sjdp 54533965Sjdp switch (c) 54633965Sjdp { 54733965Sjdp default: 54860484Sobrien ieee_error (info, start, _("unsupported IEEE expression operator")); 54933965Sjdp break; 55033965Sjdp 55133965Sjdp case ieee_variable_R_enum: 55233965Sjdp { 55333965Sjdp bfd_vma indx; 55433965Sjdp asection *s; 55533965Sjdp 55633965Sjdp if (! ieee_read_number (info, pp, &indx)) 55733965Sjdp return false; 55833965Sjdp for (s = info->abfd->sections; s != NULL; s = s->next) 55933965Sjdp if ((bfd_vma) s->target_index == indx) 56033965Sjdp break; 56133965Sjdp if (s == NULL) 56233965Sjdp { 56360484Sobrien ieee_error (info, start, _("unknown section")); 56433965Sjdp return false; 56533965Sjdp } 56677298Sobrien 56733965Sjdp if (esp - expr_stack >= EXPR_STACK_SIZE) 56833965Sjdp { 56960484Sobrien ieee_error (info, start, _("expression stack overflow")); 57033965Sjdp return false; 57133965Sjdp } 57233965Sjdp 57333965Sjdp *esp++ = bfd_get_section_vma (info->abfd, s); 57433965Sjdp } 57533965Sjdp break; 57633965Sjdp 57733965Sjdp case ieee_function_plus_enum: 57833965Sjdp case ieee_function_minus_enum: 57933965Sjdp { 58033965Sjdp bfd_vma v1, v2; 58133965Sjdp 58233965Sjdp if (esp - expr_stack < 2) 58333965Sjdp { 58460484Sobrien ieee_error (info, start, _("expression stack underflow")); 58533965Sjdp return false; 58633965Sjdp } 58733965Sjdp 58833965Sjdp v1 = *--esp; 58933965Sjdp v2 = *--esp; 59033965Sjdp *esp++ = v1 + v2; 59133965Sjdp } 59233965Sjdp break; 59333965Sjdp } 59433965Sjdp } 59533965Sjdp 59633965Sjdp if (esp - 1 != expr_stack) 59733965Sjdp { 59860484Sobrien ieee_error (info, expr_start, _("expression stack mismatch")); 59933965Sjdp return false; 60033965Sjdp } 60133965Sjdp 60233965Sjdp *pv = *--esp; 60333965Sjdp 60433965Sjdp return true; 60533965Sjdp} 60633965Sjdp 60733965Sjdp/* Return an IEEE builtin type. */ 60833965Sjdp 60933965Sjdpstatic debug_type 61033965Sjdpieee_builtin_type (info, p, indx) 61133965Sjdp struct ieee_info *info; 61233965Sjdp const bfd_byte *p; 61333965Sjdp unsigned int indx; 61433965Sjdp{ 61533965Sjdp PTR dhandle; 61633965Sjdp debug_type type; 61733965Sjdp const char *name; 61833965Sjdp 61933965Sjdp if (indx < BUILTIN_TYPE_COUNT 62033965Sjdp && info->types.builtins[indx] != DEBUG_TYPE_NULL) 62133965Sjdp return info->types.builtins[indx]; 62233965Sjdp 62333965Sjdp dhandle = info->dhandle; 62433965Sjdp 62533965Sjdp if (indx >= 32 && indx < 64) 62633965Sjdp { 62733965Sjdp type = debug_make_pointer_type (dhandle, 62833965Sjdp ieee_builtin_type (info, p, indx - 32)); 62933965Sjdp assert (indx < BUILTIN_TYPE_COUNT); 63033965Sjdp info->types.builtins[indx] = type; 63133965Sjdp return type; 63233965Sjdp } 63333965Sjdp 63433965Sjdp switch ((enum builtin_types) indx) 63533965Sjdp { 63633965Sjdp default: 63760484Sobrien ieee_error (info, p, _("unknown builtin type")); 63833965Sjdp return NULL; 63933965Sjdp 64033965Sjdp case builtin_unknown: 64133965Sjdp type = debug_make_void_type (dhandle); 64233965Sjdp name = NULL; 64333965Sjdp break; 64433965Sjdp 64533965Sjdp case builtin_void: 64633965Sjdp type = debug_make_void_type (dhandle); 64733965Sjdp name = "void"; 64833965Sjdp break; 64933965Sjdp 65033965Sjdp case builtin_signed_char: 65133965Sjdp type = debug_make_int_type (dhandle, 1, false); 65233965Sjdp name = "signed char"; 65333965Sjdp break; 65433965Sjdp 65533965Sjdp case builtin_unsigned_char: 65633965Sjdp type = debug_make_int_type (dhandle, 1, true); 65733965Sjdp name = "unsigned char"; 65833965Sjdp break; 65933965Sjdp 66033965Sjdp case builtin_signed_short_int: 66133965Sjdp type = debug_make_int_type (dhandle, 2, false); 66233965Sjdp name = "signed short int"; 66333965Sjdp break; 66433965Sjdp 66533965Sjdp case builtin_unsigned_short_int: 66633965Sjdp type = debug_make_int_type (dhandle, 2, true); 66733965Sjdp name = "unsigned short int"; 66833965Sjdp break; 66933965Sjdp 67033965Sjdp case builtin_signed_long: 67133965Sjdp type = debug_make_int_type (dhandle, 4, false); 67233965Sjdp name = "signed long"; 67333965Sjdp break; 67433965Sjdp 67533965Sjdp case builtin_unsigned_long: 67633965Sjdp type = debug_make_int_type (dhandle, 4, true); 67733965Sjdp name = "unsigned long"; 67833965Sjdp break; 67933965Sjdp 68033965Sjdp case builtin_signed_long_long: 68133965Sjdp type = debug_make_int_type (dhandle, 8, false); 68233965Sjdp name = "signed long long"; 68333965Sjdp break; 68433965Sjdp 68533965Sjdp case builtin_unsigned_long_long: 68633965Sjdp type = debug_make_int_type (dhandle, 8, true); 68733965Sjdp name = "unsigned long long"; 68833965Sjdp break; 68933965Sjdp 69033965Sjdp case builtin_float: 69133965Sjdp type = debug_make_float_type (dhandle, 4); 69233965Sjdp name = "float"; 69333965Sjdp break; 69433965Sjdp 69533965Sjdp case builtin_double: 69633965Sjdp type = debug_make_float_type (dhandle, 8); 69733965Sjdp name = "double"; 69833965Sjdp break; 69933965Sjdp 70033965Sjdp case builtin_long_double: 70133965Sjdp /* FIXME: The size for this type should depend upon the 70233965Sjdp processor. */ 70333965Sjdp type = debug_make_float_type (dhandle, 12); 70433965Sjdp name = "long double"; 70533965Sjdp break; 70633965Sjdp 70733965Sjdp case builtin_long_long_double: 70833965Sjdp type = debug_make_float_type (dhandle, 16); 70933965Sjdp name = "long long double"; 71033965Sjdp break; 71133965Sjdp 71233965Sjdp case builtin_quoted_string: 71333965Sjdp type = debug_make_array_type (dhandle, 71433965Sjdp ieee_builtin_type (info, p, 71533965Sjdp ((unsigned int) 71633965Sjdp builtin_char)), 71733965Sjdp ieee_builtin_type (info, p, 71833965Sjdp ((unsigned int) 71933965Sjdp builtin_int)), 72033965Sjdp 0, -1, true); 72133965Sjdp name = "QUOTED STRING"; 72233965Sjdp break; 72333965Sjdp 72433965Sjdp case builtin_instruction_address: 72533965Sjdp /* FIXME: This should be a code address. */ 72633965Sjdp type = debug_make_int_type (dhandle, 4, true); 72733965Sjdp name = "instruction address"; 72833965Sjdp break; 72933965Sjdp 73033965Sjdp case builtin_int: 73133965Sjdp /* FIXME: The size for this type should depend upon the 73233965Sjdp processor. */ 73333965Sjdp type = debug_make_int_type (dhandle, 4, false); 73433965Sjdp name = "int"; 73533965Sjdp break; 73633965Sjdp 73733965Sjdp case builtin_unsigned: 73833965Sjdp /* FIXME: The size for this type should depend upon the 73933965Sjdp processor. */ 74033965Sjdp type = debug_make_int_type (dhandle, 4, true); 74133965Sjdp name = "unsigned"; 74233965Sjdp break; 74333965Sjdp 74433965Sjdp case builtin_unsigned_int: 74533965Sjdp /* FIXME: The size for this type should depend upon the 74633965Sjdp processor. */ 74733965Sjdp type = debug_make_int_type (dhandle, 4, true); 74833965Sjdp name = "unsigned int"; 74933965Sjdp break; 75033965Sjdp 75133965Sjdp case builtin_char: 75233965Sjdp type = debug_make_int_type (dhandle, 1, false); 75333965Sjdp name = "char"; 75433965Sjdp break; 75533965Sjdp 75633965Sjdp case builtin_long: 75733965Sjdp type = debug_make_int_type (dhandle, 4, false); 75833965Sjdp name = "long"; 75933965Sjdp break; 76033965Sjdp 76133965Sjdp case builtin_short: 76233965Sjdp type = debug_make_int_type (dhandle, 2, false); 76333965Sjdp name = "short"; 76433965Sjdp break; 76533965Sjdp 76633965Sjdp case builtin_unsigned_short: 76733965Sjdp type = debug_make_int_type (dhandle, 2, true); 76833965Sjdp name = "unsigned short"; 76933965Sjdp break; 77033965Sjdp 77133965Sjdp case builtin_short_int: 77233965Sjdp type = debug_make_int_type (dhandle, 2, false); 77333965Sjdp name = "short int"; 77433965Sjdp break; 77533965Sjdp 77633965Sjdp case builtin_signed_short: 77733965Sjdp type = debug_make_int_type (dhandle, 2, false); 77833965Sjdp name = "signed short"; 77933965Sjdp break; 78033965Sjdp 78133965Sjdp case builtin_bcd_float: 78260484Sobrien ieee_error (info, p, _("BCD float type not supported")); 78360484Sobrien return DEBUG_TYPE_NULL; 78433965Sjdp } 78533965Sjdp 78633965Sjdp if (name != NULL) 78733965Sjdp type = debug_name_type (dhandle, name, type); 78833965Sjdp 78933965Sjdp assert (indx < BUILTIN_TYPE_COUNT); 79033965Sjdp 79133965Sjdp info->types.builtins[indx] = type; 79233965Sjdp 79333965Sjdp return type; 79433965Sjdp} 79533965Sjdp 79633965Sjdp/* Allocate more space in the type table. If ref is true, this is a 79733965Sjdp reference to the type; if it is not already defined, we should set 79833965Sjdp up an indirect type. */ 79933965Sjdp 80033965Sjdpstatic boolean 80133965Sjdpieee_alloc_type (info, indx, ref) 80233965Sjdp struct ieee_info *info; 80333965Sjdp unsigned int indx; 80433965Sjdp boolean ref; 80533965Sjdp{ 80633965Sjdp unsigned int nalloc; 80733965Sjdp register struct ieee_type *t; 80833965Sjdp struct ieee_type *tend; 80933965Sjdp 81033965Sjdp if (indx >= info->types.alloc) 81133965Sjdp { 81233965Sjdp nalloc = info->types.alloc; 81333965Sjdp if (nalloc == 0) 81433965Sjdp nalloc = 4; 81533965Sjdp while (indx >= nalloc) 81633965Sjdp nalloc *= 2; 81733965Sjdp 81833965Sjdp info->types.types = ((struct ieee_type *) 81933965Sjdp xrealloc (info->types.types, 82033965Sjdp nalloc * sizeof *info->types.types)); 82133965Sjdp 82233965Sjdp memset (info->types.types + info->types.alloc, 0, 82333965Sjdp (nalloc - info->types.alloc) * sizeof *info->types.types); 82433965Sjdp 82533965Sjdp tend = info->types.types + nalloc; 82633965Sjdp for (t = info->types.types + info->types.alloc; t < tend; t++) 82733965Sjdp t->type = DEBUG_TYPE_NULL; 82833965Sjdp 82933965Sjdp info->types.alloc = nalloc; 83033965Sjdp } 83133965Sjdp 83233965Sjdp if (ref) 83333965Sjdp { 83433965Sjdp t = info->types.types + indx; 83533965Sjdp if (t->type == NULL) 83633965Sjdp { 83733965Sjdp t->pslot = (debug_type *) xmalloc (sizeof *t->pslot); 83833965Sjdp *t->pslot = DEBUG_TYPE_NULL; 83933965Sjdp t->type = debug_make_indirect_type (info->dhandle, t->pslot, 84033965Sjdp (const char *) NULL); 84133965Sjdp if (t->type == NULL) 84233965Sjdp return false; 84333965Sjdp } 84433965Sjdp } 84533965Sjdp 84633965Sjdp return true; 84733965Sjdp} 84833965Sjdp 84933965Sjdp/* Read a type index and return the corresponding type. */ 85033965Sjdp 85133965Sjdpstatic boolean 85233965Sjdpieee_read_type_index (info, pp, ptype) 85333965Sjdp struct ieee_info *info; 85433965Sjdp const bfd_byte **pp; 85533965Sjdp debug_type *ptype; 85633965Sjdp{ 85733965Sjdp const bfd_byte *start; 85833965Sjdp bfd_vma indx; 85933965Sjdp 86033965Sjdp start = *pp; 86133965Sjdp 86233965Sjdp if (! ieee_read_number (info, pp, &indx)) 86333965Sjdp return false; 86433965Sjdp 86533965Sjdp if (indx < 256) 86633965Sjdp { 86733965Sjdp *ptype = ieee_builtin_type (info, start, indx); 86833965Sjdp if (*ptype == NULL) 86933965Sjdp return false; 87033965Sjdp return true; 87133965Sjdp } 87233965Sjdp 87333965Sjdp indx -= 256; 87433965Sjdp if (! ieee_alloc_type (info, indx, true)) 87533965Sjdp return false; 87633965Sjdp 87733965Sjdp *ptype = info->types.types[indx].type; 87833965Sjdp 87933965Sjdp return true; 88033965Sjdp} 88133965Sjdp 88233965Sjdp/* Parse IEEE debugging information for a file. This is passed the 88333965Sjdp bytes which compose the Debug Information Part of an IEEE file. */ 88433965Sjdp 88533965Sjdpboolean 88633965Sjdpparse_ieee (dhandle, abfd, bytes, len) 88733965Sjdp PTR dhandle; 88833965Sjdp bfd *abfd; 88933965Sjdp const bfd_byte *bytes; 89033965Sjdp bfd_size_type len; 89133965Sjdp{ 89233965Sjdp struct ieee_info info; 89333965Sjdp unsigned int i; 89433965Sjdp const bfd_byte *p, *pend; 89533965Sjdp 89633965Sjdp info.dhandle = dhandle; 89733965Sjdp info.abfd = abfd; 89833965Sjdp info.bytes = bytes; 89933965Sjdp info.pend = bytes + len; 90033965Sjdp info.blockstack.bsp = info.blockstack.stack; 90133965Sjdp info.saw_filename = false; 90233965Sjdp info.vars.alloc = 0; 90333965Sjdp info.vars.vars = NULL; 90460484Sobrien info.global_vars = NULL; 90533965Sjdp info.types.alloc = 0; 90633965Sjdp info.types.types = NULL; 90760484Sobrien info.global_types = NULL; 90833965Sjdp info.tags = NULL; 90933965Sjdp for (i = 0; i < BUILTIN_TYPE_COUNT; i++) 91033965Sjdp info.types.builtins[i] = DEBUG_TYPE_NULL; 91133965Sjdp 91233965Sjdp p = bytes; 91333965Sjdp pend = info.pend; 91433965Sjdp while (p < pend) 91533965Sjdp { 91633965Sjdp const bfd_byte *record_start; 91733965Sjdp ieee_record_enum_type c; 91833965Sjdp 91933965Sjdp record_start = p; 92033965Sjdp 92133965Sjdp c = (ieee_record_enum_type) *p++; 92233965Sjdp 92333965Sjdp if (c == ieee_at_record_enum) 92433965Sjdp c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++); 92533965Sjdp 92633965Sjdp if (c <= ieee_number_repeat_end_enum) 92733965Sjdp { 92860484Sobrien ieee_error (&info, record_start, _("unexpected number")); 92933965Sjdp return false; 93033965Sjdp } 93133965Sjdp 93233965Sjdp switch (c) 93333965Sjdp { 93433965Sjdp default: 93560484Sobrien ieee_error (&info, record_start, _("unexpected record type")); 93633965Sjdp return false; 93733965Sjdp 93833965Sjdp case ieee_bb_record_enum: 93933965Sjdp if (! parse_ieee_bb (&info, &p)) 94033965Sjdp return false; 94133965Sjdp break; 94233965Sjdp 94333965Sjdp case ieee_be_record_enum: 94433965Sjdp if (! parse_ieee_be (&info, &p)) 94533965Sjdp return false; 94633965Sjdp break; 94733965Sjdp 94833965Sjdp case ieee_nn_record: 94933965Sjdp if (! parse_ieee_nn (&info, &p)) 95033965Sjdp return false; 95133965Sjdp break; 95233965Sjdp 95333965Sjdp case ieee_ty_record_enum: 95433965Sjdp if (! parse_ieee_ty (&info, &p)) 95533965Sjdp return false; 95633965Sjdp break; 95733965Sjdp 95833965Sjdp case ieee_atn_record_enum: 95933965Sjdp if (! parse_ieee_atn (&info, &p)) 96033965Sjdp return false; 96133965Sjdp break; 96233965Sjdp } 96333965Sjdp } 96433965Sjdp 96533965Sjdp if (info.blockstack.bsp != info.blockstack.stack) 96633965Sjdp { 96733965Sjdp ieee_error (&info, (const bfd_byte *) NULL, 96860484Sobrien _("blocks left on stack at end")); 96933965Sjdp return false; 97033965Sjdp } 97133965Sjdp 97233965Sjdp return true; 97333965Sjdp} 97433965Sjdp 97533965Sjdp/* Handle an IEEE BB record. */ 97633965Sjdp 97733965Sjdpstatic boolean 97833965Sjdpparse_ieee_bb (info, pp) 97933965Sjdp struct ieee_info *info; 98033965Sjdp const bfd_byte **pp; 98133965Sjdp{ 98233965Sjdp const bfd_byte *block_start; 98333965Sjdp bfd_byte b; 98433965Sjdp bfd_vma size; 98533965Sjdp const char *name; 98633965Sjdp unsigned long namlen; 98733965Sjdp char *namcopy = NULL; 98833965Sjdp unsigned int fnindx; 98933965Sjdp boolean skip; 99033965Sjdp 99133965Sjdp block_start = *pp; 99233965Sjdp 99333965Sjdp b = **pp; 99433965Sjdp ++*pp; 99533965Sjdp 99633965Sjdp if (! ieee_read_number (info, pp, &size) 99733965Sjdp || ! ieee_read_id (info, pp, &name, &namlen)) 99833965Sjdp return false; 99933965Sjdp 100033965Sjdp fnindx = (unsigned int) -1; 100133965Sjdp skip = false; 100233965Sjdp 100333965Sjdp switch (b) 100433965Sjdp { 100533965Sjdp case 1: 100633965Sjdp /* BB1: Type definitions local to a module. */ 100733965Sjdp namcopy = savestring (name, namlen); 100833965Sjdp if (namcopy == NULL) 100933965Sjdp return false; 101033965Sjdp if (! debug_set_filename (info->dhandle, namcopy)) 101133965Sjdp return false; 101233965Sjdp info->saw_filename = true; 101333965Sjdp 101433965Sjdp /* Discard any variables or types we may have seen before. */ 101533965Sjdp if (info->vars.vars != NULL) 101633965Sjdp free (info->vars.vars); 101733965Sjdp info->vars.vars = NULL; 101833965Sjdp info->vars.alloc = 0; 101933965Sjdp if (info->types.types != NULL) 102033965Sjdp free (info->types.types); 102133965Sjdp info->types.types = NULL; 102233965Sjdp info->types.alloc = 0; 102333965Sjdp 102433965Sjdp /* Initialize the types to the global types. */ 102533965Sjdp if (info->global_types != NULL) 102633965Sjdp { 102733965Sjdp info->types.alloc = info->global_types->alloc; 102833965Sjdp info->types.types = ((struct ieee_type *) 102933965Sjdp xmalloc (info->types.alloc 103033965Sjdp * sizeof (*info->types.types))); 103133965Sjdp memcpy (info->types.types, info->global_types->types, 103233965Sjdp info->types.alloc * sizeof (*info->types.types)); 103333965Sjdp } 103433965Sjdp 103533965Sjdp break; 103633965Sjdp 103733965Sjdp case 2: 103833965Sjdp /* BB2: Global type definitions. The name is supposed to be 1039104834Sobrien empty, but we don't check. */ 104033965Sjdp if (! debug_set_filename (info->dhandle, "*global*")) 104133965Sjdp return false; 104233965Sjdp info->saw_filename = true; 104333965Sjdp break; 104433965Sjdp 104533965Sjdp case 3: 104633965Sjdp /* BB3: High level module block begin. We don't have to do 104733965Sjdp anything here. The name is supposed to be the same as for 104833965Sjdp the BB1, but we don't check. */ 104933965Sjdp break; 105033965Sjdp 105133965Sjdp case 4: 105233965Sjdp /* BB4: Global function. */ 105333965Sjdp { 105433965Sjdp bfd_vma stackspace, typindx, offset; 105533965Sjdp debug_type return_type; 105633965Sjdp 105733965Sjdp if (! ieee_read_number (info, pp, &stackspace) 105833965Sjdp || ! ieee_read_number (info, pp, &typindx) 105933965Sjdp || ! ieee_read_expression (info, pp, &offset)) 106033965Sjdp return false; 106133965Sjdp 106233965Sjdp /* We have no way to record the stack space. FIXME. */ 106333965Sjdp 106433965Sjdp if (typindx < 256) 106533965Sjdp { 106633965Sjdp return_type = ieee_builtin_type (info, block_start, typindx); 106733965Sjdp if (return_type == DEBUG_TYPE_NULL) 106833965Sjdp return false; 106933965Sjdp } 107033965Sjdp else 107133965Sjdp { 107233965Sjdp typindx -= 256; 107333965Sjdp if (! ieee_alloc_type (info, typindx, true)) 107433965Sjdp return false; 107533965Sjdp fnindx = typindx; 107633965Sjdp return_type = info->types.types[typindx].type; 107733965Sjdp if (debug_get_type_kind (info->dhandle, return_type) 107833965Sjdp == DEBUG_KIND_FUNCTION) 107933965Sjdp return_type = debug_get_return_type (info->dhandle, 108033965Sjdp return_type); 108133965Sjdp } 108233965Sjdp 108333965Sjdp namcopy = savestring (name, namlen); 108433965Sjdp if (namcopy == NULL) 108533965Sjdp return false; 108633965Sjdp if (! debug_record_function (info->dhandle, namcopy, return_type, 108733965Sjdp true, offset)) 108833965Sjdp return false; 108933965Sjdp } 109033965Sjdp break; 109133965Sjdp 109233965Sjdp case 5: 109333965Sjdp /* BB5: File name for source line numbers. */ 109433965Sjdp { 109533965Sjdp unsigned int i; 109633965Sjdp 109733965Sjdp /* We ignore the date and time. FIXME. */ 109833965Sjdp for (i = 0; i < 6; i++) 109933965Sjdp { 110033965Sjdp bfd_vma ignore; 110133965Sjdp boolean present; 110233965Sjdp 110333965Sjdp if (! ieee_read_optional_number (info, pp, &ignore, &present)) 110433965Sjdp return false; 110533965Sjdp if (! present) 110633965Sjdp break; 110733965Sjdp } 110833965Sjdp 110933965Sjdp namcopy = savestring (name, namlen); 111033965Sjdp if (namcopy == NULL) 111133965Sjdp return false; 111233965Sjdp if (! debug_start_source (info->dhandle, namcopy)) 111333965Sjdp return false; 111433965Sjdp } 111533965Sjdp break; 111633965Sjdp 111733965Sjdp case 6: 111833965Sjdp /* BB6: Local function or block. */ 111933965Sjdp { 112033965Sjdp bfd_vma stackspace, typindx, offset; 112133965Sjdp 112233965Sjdp if (! ieee_read_number (info, pp, &stackspace) 112333965Sjdp || ! ieee_read_number (info, pp, &typindx) 112433965Sjdp || ! ieee_read_expression (info, pp, &offset)) 112533965Sjdp return false; 112633965Sjdp 112733965Sjdp /* We have no way to record the stack space. FIXME. */ 112833965Sjdp 112933965Sjdp if (namlen == 0) 113033965Sjdp { 113133965Sjdp if (! debug_start_block (info->dhandle, offset)) 113233965Sjdp return false; 113333965Sjdp /* Change b to indicate that this is a block 113433965Sjdp rather than a function. */ 113533965Sjdp b = 0x86; 113633965Sjdp } 113733965Sjdp else 113833965Sjdp { 113933965Sjdp /* The MRI C++ compiler will output a fake function named 114033965Sjdp __XRYCPP to hold C++ debugging information. We skip 114133965Sjdp that function. This is not crucial, but it makes 114233965Sjdp converting from IEEE to other debug formats work 114333965Sjdp better. */ 114433965Sjdp if (strncmp (name, "__XRYCPP", namlen) == 0) 114533965Sjdp skip = true; 114633965Sjdp else 114733965Sjdp { 114833965Sjdp debug_type return_type; 114933965Sjdp 115033965Sjdp if (typindx < 256) 115133965Sjdp { 115233965Sjdp return_type = ieee_builtin_type (info, block_start, 115333965Sjdp typindx); 115433965Sjdp if (return_type == NULL) 115533965Sjdp return false; 115633965Sjdp } 115733965Sjdp else 115833965Sjdp { 115933965Sjdp typindx -= 256; 116033965Sjdp if (! ieee_alloc_type (info, typindx, true)) 116133965Sjdp return false; 116233965Sjdp fnindx = typindx; 116333965Sjdp return_type = info->types.types[typindx].type; 116433965Sjdp if (debug_get_type_kind (info->dhandle, return_type) 116533965Sjdp == DEBUG_KIND_FUNCTION) 116633965Sjdp return_type = debug_get_return_type (info->dhandle, 116733965Sjdp return_type); 116833965Sjdp } 116933965Sjdp 117033965Sjdp namcopy = savestring (name, namlen); 117133965Sjdp if (namcopy == NULL) 117233965Sjdp return false; 117333965Sjdp if (! debug_record_function (info->dhandle, namcopy, 117433965Sjdp return_type, false, offset)) 117533965Sjdp return false; 117633965Sjdp } 117733965Sjdp } 117833965Sjdp } 117933965Sjdp break; 118033965Sjdp 118133965Sjdp case 10: 118233965Sjdp /* BB10: Assembler module scope. In the normal case, we 118333965Sjdp completely ignore all this information. FIXME. */ 118433965Sjdp { 118533965Sjdp const char *inam, *vstr; 118633965Sjdp unsigned long inamlen, vstrlen; 118733965Sjdp bfd_vma tool_type; 118833965Sjdp boolean present; 118933965Sjdp unsigned int i; 119033965Sjdp 119133965Sjdp if (! info->saw_filename) 119233965Sjdp { 119333965Sjdp namcopy = savestring (name, namlen); 119433965Sjdp if (namcopy == NULL) 119533965Sjdp return false; 119633965Sjdp if (! debug_set_filename (info->dhandle, namcopy)) 119733965Sjdp return false; 119833965Sjdp info->saw_filename = true; 119933965Sjdp } 120033965Sjdp 120133965Sjdp if (! ieee_read_id (info, pp, &inam, &inamlen) 120233965Sjdp || ! ieee_read_number (info, pp, &tool_type) 120333965Sjdp || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present)) 120433965Sjdp return false; 120533965Sjdp for (i = 0; i < 6; i++) 120633965Sjdp { 120733965Sjdp bfd_vma ignore; 120833965Sjdp 120933965Sjdp if (! ieee_read_optional_number (info, pp, &ignore, &present)) 121033965Sjdp return false; 121133965Sjdp if (! present) 121233965Sjdp break; 121333965Sjdp } 121433965Sjdp } 121533965Sjdp break; 121633965Sjdp 121733965Sjdp case 11: 121833965Sjdp /* BB11: Module section. We completely ignore all this 121933965Sjdp information. FIXME. */ 122033965Sjdp { 122133965Sjdp bfd_vma sectype, secindx, offset, map; 122233965Sjdp boolean present; 122333965Sjdp 122433965Sjdp if (! ieee_read_number (info, pp, §ype) 122533965Sjdp || ! ieee_read_number (info, pp, &secindx) 122633965Sjdp || ! ieee_read_expression (info, pp, &offset) 122733965Sjdp || ! ieee_read_optional_number (info, pp, &map, &present)) 122833965Sjdp return false; 122933965Sjdp } 123033965Sjdp break; 123133965Sjdp 123233965Sjdp default: 123360484Sobrien ieee_error (info, block_start, _("unknown BB type")); 123433965Sjdp return false; 123533965Sjdp } 123633965Sjdp 123733965Sjdp 123833965Sjdp /* Push this block on the block stack. */ 123933965Sjdp 124033965Sjdp if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE) 124133965Sjdp { 124260484Sobrien ieee_error (info, (const bfd_byte *) NULL, _("stack overflow")); 124333965Sjdp return false; 124433965Sjdp } 124533965Sjdp 124633965Sjdp info->blockstack.bsp->kind = b; 124733965Sjdp if (b == 5) 124833965Sjdp info->blockstack.bsp->filename = namcopy; 124933965Sjdp info->blockstack.bsp->fnindx = fnindx; 125033965Sjdp info->blockstack.bsp->skip = skip; 125133965Sjdp ++info->blockstack.bsp; 125233965Sjdp 125333965Sjdp return true; 125433965Sjdp} 125533965Sjdp 125633965Sjdp/* Handle an IEEE BE record. */ 125733965Sjdp 125833965Sjdpstatic boolean 125933965Sjdpparse_ieee_be (info, pp) 126033965Sjdp struct ieee_info *info; 126133965Sjdp const bfd_byte **pp; 126233965Sjdp{ 126333965Sjdp bfd_vma offset; 126433965Sjdp 126533965Sjdp if (info->blockstack.bsp <= info->blockstack.stack) 126633965Sjdp { 126760484Sobrien ieee_error (info, *pp, _("stack underflow")); 126833965Sjdp return false; 126933965Sjdp } 127033965Sjdp --info->blockstack.bsp; 127133965Sjdp 127233965Sjdp switch (info->blockstack.bsp->kind) 127333965Sjdp { 127433965Sjdp case 2: 127533965Sjdp /* When we end the global typedefs block, we copy out the the 127633965Sjdp contents of info->vars. This is because the variable indices 127733965Sjdp may be reused in the local blocks. However, we need to 127833965Sjdp preserve them so that we can locate a function returning a 127933965Sjdp reference variable whose type is named in the global typedef 128033965Sjdp block. */ 128133965Sjdp info->global_vars = ((struct ieee_vars *) 128233965Sjdp xmalloc (sizeof *info->global_vars)); 128333965Sjdp info->global_vars->alloc = info->vars.alloc; 128433965Sjdp info->global_vars->vars = ((struct ieee_var *) 128533965Sjdp xmalloc (info->vars.alloc 128633965Sjdp * sizeof (*info->vars.vars))); 128733965Sjdp memcpy (info->global_vars->vars, info->vars.vars, 128833965Sjdp info->vars.alloc * sizeof (*info->vars.vars)); 128933965Sjdp 129033965Sjdp /* We also copy out the non builtin parts of info->types, since 129133965Sjdp the types are discarded when we start a new block. */ 129233965Sjdp info->global_types = ((struct ieee_types *) 129333965Sjdp xmalloc (sizeof *info->global_types)); 129433965Sjdp info->global_types->alloc = info->types.alloc; 129533965Sjdp info->global_types->types = ((struct ieee_type *) 129633965Sjdp xmalloc (info->types.alloc 129733965Sjdp * sizeof (*info->types.types))); 129833965Sjdp memcpy (info->global_types->types, info->types.types, 129933965Sjdp info->types.alloc * sizeof (*info->types.types)); 130033965Sjdp memset (info->global_types->builtins, 0, 130133965Sjdp sizeof (info->global_types->builtins)); 130233965Sjdp 130333965Sjdp break; 130433965Sjdp 130533965Sjdp case 4: 130633965Sjdp case 6: 130733965Sjdp if (! ieee_read_expression (info, pp, &offset)) 130833965Sjdp return false; 130933965Sjdp if (! info->blockstack.bsp->skip) 131033965Sjdp { 131133965Sjdp if (! debug_end_function (info->dhandle, offset + 1)) 131233965Sjdp return false; 131333965Sjdp } 131433965Sjdp break; 131533965Sjdp 131633965Sjdp case 0x86: 131733965Sjdp /* This is BE6 when BB6 started a block rather than a local 131833965Sjdp function. */ 131933965Sjdp if (! ieee_read_expression (info, pp, &offset)) 132033965Sjdp return false; 132133965Sjdp if (! debug_end_block (info->dhandle, offset + 1)) 132233965Sjdp return false; 132333965Sjdp break; 132433965Sjdp 132533965Sjdp case 5: 132633965Sjdp /* When we end a BB5, we look up the stack for the last BB5, if 132733965Sjdp there is one, so that we can call debug_start_source. */ 132833965Sjdp if (info->blockstack.bsp > info->blockstack.stack) 132933965Sjdp { 133033965Sjdp struct ieee_block *bl; 133133965Sjdp 133233965Sjdp bl = info->blockstack.bsp; 133333965Sjdp do 133433965Sjdp { 133533965Sjdp --bl; 133633965Sjdp if (bl->kind == 5) 133733965Sjdp { 133833965Sjdp if (! debug_start_source (info->dhandle, bl->filename)) 133933965Sjdp return false; 134033965Sjdp break; 134133965Sjdp } 134233965Sjdp } 134333965Sjdp while (bl != info->blockstack.stack); 134433965Sjdp } 134533965Sjdp break; 134633965Sjdp 134733965Sjdp case 11: 134833965Sjdp if (! ieee_read_expression (info, pp, &offset)) 134933965Sjdp return false; 135033965Sjdp /* We just ignore the module size. FIXME. */ 135133965Sjdp break; 135233965Sjdp 135333965Sjdp default: 135433965Sjdp /* Other block types do not have any trailing information. */ 135533965Sjdp break; 135633965Sjdp } 135733965Sjdp 135833965Sjdp return true; 135933965Sjdp} 136033965Sjdp 136133965Sjdp/* Parse an NN record. */ 136233965Sjdp 136333965Sjdpstatic boolean 136433965Sjdpparse_ieee_nn (info, pp) 136533965Sjdp struct ieee_info *info; 136633965Sjdp const bfd_byte **pp; 136733965Sjdp{ 136833965Sjdp const bfd_byte *nn_start; 136933965Sjdp bfd_vma varindx; 137033965Sjdp const char *name; 137133965Sjdp unsigned long namlen; 137233965Sjdp 137333965Sjdp nn_start = *pp; 137433965Sjdp 137533965Sjdp if (! ieee_read_number (info, pp, &varindx) 137633965Sjdp || ! ieee_read_id (info, pp, &name, &namlen)) 137733965Sjdp return false; 137833965Sjdp 137933965Sjdp if (varindx < 32) 138033965Sjdp { 138160484Sobrien ieee_error (info, nn_start, _("illegal variable index")); 138233965Sjdp return false; 138333965Sjdp } 138433965Sjdp varindx -= 32; 138533965Sjdp 138633965Sjdp if (varindx >= info->vars.alloc) 138733965Sjdp { 138833965Sjdp unsigned int alloc; 138933965Sjdp 139033965Sjdp alloc = info->vars.alloc; 139133965Sjdp if (alloc == 0) 139233965Sjdp alloc = 4; 139333965Sjdp while (varindx >= alloc) 139433965Sjdp alloc *= 2; 139533965Sjdp info->vars.vars = ((struct ieee_var *) 139633965Sjdp xrealloc (info->vars.vars, 139733965Sjdp alloc * sizeof *info->vars.vars)); 139833965Sjdp memset (info->vars.vars + info->vars.alloc, 0, 139933965Sjdp (alloc - info->vars.alloc) * sizeof *info->vars.vars); 140033965Sjdp info->vars.alloc = alloc; 140133965Sjdp } 140233965Sjdp 140333965Sjdp info->vars.vars[varindx].name = name; 140433965Sjdp info->vars.vars[varindx].namlen = namlen; 140533965Sjdp 140633965Sjdp return true; 140733965Sjdp} 140833965Sjdp 140933965Sjdp/* Parse a TY record. */ 141033965Sjdp 141133965Sjdpstatic boolean 141233965Sjdpparse_ieee_ty (info, pp) 141333965Sjdp struct ieee_info *info; 141433965Sjdp const bfd_byte **pp; 141533965Sjdp{ 141633965Sjdp const bfd_byte *ty_start, *ty_var_start, *ty_code_start; 141733965Sjdp bfd_vma typeindx, varindx, tc; 141833965Sjdp PTR dhandle; 141933965Sjdp boolean tag, typdef; 142033965Sjdp debug_type *arg_slots; 142133965Sjdp unsigned long type_bitsize; 142233965Sjdp debug_type type; 142333965Sjdp 142433965Sjdp ty_start = *pp; 142533965Sjdp 142633965Sjdp if (! ieee_read_number (info, pp, &typeindx)) 142733965Sjdp return false; 142833965Sjdp 142933965Sjdp if (typeindx < 256) 143033965Sjdp { 143160484Sobrien ieee_error (info, ty_start, _("illegal type index")); 143233965Sjdp return false; 143333965Sjdp } 143433965Sjdp 143533965Sjdp typeindx -= 256; 143633965Sjdp if (! ieee_alloc_type (info, typeindx, false)) 143733965Sjdp return false; 143833965Sjdp 143933965Sjdp if (**pp != 0xce) 144033965Sjdp { 144160484Sobrien ieee_error (info, *pp, _("unknown TY code")); 144233965Sjdp return false; 144333965Sjdp } 144433965Sjdp ++*pp; 144533965Sjdp 144633965Sjdp ty_var_start = *pp; 144733965Sjdp 144833965Sjdp if (! ieee_read_number (info, pp, &varindx)) 144933965Sjdp return false; 145033965Sjdp 145133965Sjdp if (varindx < 32) 145233965Sjdp { 145360484Sobrien ieee_error (info, ty_var_start, _("illegal variable index")); 145433965Sjdp return false; 145533965Sjdp } 145633965Sjdp varindx -= 32; 145733965Sjdp 145833965Sjdp if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL) 145933965Sjdp { 146060484Sobrien ieee_error (info, ty_var_start, _("undefined variable in TY")); 146133965Sjdp return false; 146233965Sjdp } 146333965Sjdp 146433965Sjdp ty_code_start = *pp; 146533965Sjdp 146633965Sjdp if (! ieee_read_number (info, pp, &tc)) 146733965Sjdp return false; 146833965Sjdp 146933965Sjdp dhandle = info->dhandle; 147033965Sjdp 147133965Sjdp tag = false; 147233965Sjdp typdef = false; 147333965Sjdp arg_slots = NULL; 147433965Sjdp type_bitsize = 0; 147533965Sjdp switch (tc) 147633965Sjdp { 147733965Sjdp default: 147860484Sobrien ieee_error (info, ty_code_start, _("unknown TY code")); 147933965Sjdp return false; 148033965Sjdp 148133965Sjdp case '!': 148233965Sjdp /* Unknown type, with size. We treat it as int. FIXME. */ 148333965Sjdp { 148433965Sjdp bfd_vma size; 148533965Sjdp 148633965Sjdp if (! ieee_read_number (info, pp, &size)) 148733965Sjdp return false; 148833965Sjdp type = debug_make_int_type (dhandle, size, false); 148933965Sjdp } 149033965Sjdp break; 149133965Sjdp 149233965Sjdp case 'A': /* Array. */ 149333965Sjdp case 'a': /* FORTRAN array in column/row order. FIXME: Not 149433965Sjdp distinguished from normal array. */ 149533965Sjdp { 149633965Sjdp debug_type ele_type; 149733965Sjdp bfd_vma lower, upper; 149833965Sjdp 149933965Sjdp if (! ieee_read_type_index (info, pp, &ele_type) 150033965Sjdp || ! ieee_read_number (info, pp, &lower) 150133965Sjdp || ! ieee_read_number (info, pp, &upper)) 150233965Sjdp return false; 150333965Sjdp type = debug_make_array_type (dhandle, ele_type, 150433965Sjdp ieee_builtin_type (info, ty_code_start, 150533965Sjdp ((unsigned int) 150633965Sjdp builtin_int)), 150733965Sjdp (bfd_signed_vma) lower, 150833965Sjdp (bfd_signed_vma) upper, 150933965Sjdp false); 151033965Sjdp } 151133965Sjdp break; 151233965Sjdp 151333965Sjdp case 'E': 151433965Sjdp /* Simple enumeration. */ 151533965Sjdp { 151633965Sjdp bfd_vma size; 151733965Sjdp unsigned int alloc; 151833965Sjdp const char **names; 151933965Sjdp unsigned int c; 152033965Sjdp bfd_signed_vma *vals; 152133965Sjdp unsigned int i; 152233965Sjdp 152333965Sjdp if (! ieee_read_number (info, pp, &size)) 152433965Sjdp return false; 152533965Sjdp /* FIXME: we ignore the enumeration size. */ 152633965Sjdp 152733965Sjdp alloc = 10; 152833965Sjdp names = (const char **) xmalloc (alloc * sizeof *names); 152933965Sjdp memset (names, 0, alloc * sizeof *names); 153033965Sjdp c = 0; 153133965Sjdp while (1) 153233965Sjdp { 153333965Sjdp const char *name; 153433965Sjdp unsigned long namlen; 153533965Sjdp boolean present; 153633965Sjdp 153733965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 153833965Sjdp return false; 153933965Sjdp if (! present) 154033965Sjdp break; 154133965Sjdp 154233965Sjdp if (c + 1 >= alloc) 154333965Sjdp { 154433965Sjdp alloc += 10; 154533965Sjdp names = ((const char **) 154633965Sjdp xrealloc (names, alloc * sizeof *names)); 154733965Sjdp } 154833965Sjdp 154933965Sjdp names[c] = savestring (name, namlen); 155033965Sjdp if (names[c] == NULL) 155133965Sjdp return false; 155233965Sjdp ++c; 155333965Sjdp } 155433965Sjdp 155533965Sjdp names[c] = NULL; 155633965Sjdp 155733965Sjdp vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals); 155833965Sjdp for (i = 0; i < c; i++) 155933965Sjdp vals[i] = i; 156033965Sjdp 156133965Sjdp type = debug_make_enum_type (dhandle, names, vals); 156233965Sjdp tag = true; 156333965Sjdp } 156433965Sjdp break; 156533965Sjdp 156633965Sjdp case 'G': 156733965Sjdp /* Struct with bit fields. */ 156833965Sjdp { 156933965Sjdp bfd_vma size; 157033965Sjdp unsigned int alloc; 157133965Sjdp debug_field *fields; 157233965Sjdp unsigned int c; 157333965Sjdp 157433965Sjdp if (! ieee_read_number (info, pp, &size)) 157533965Sjdp return false; 157633965Sjdp 157733965Sjdp alloc = 10; 157833965Sjdp fields = (debug_field *) xmalloc (alloc * sizeof *fields); 157933965Sjdp c = 0; 158033965Sjdp while (1) 158133965Sjdp { 158233965Sjdp const char *name; 158333965Sjdp unsigned long namlen; 158433965Sjdp boolean present; 158533965Sjdp debug_type ftype; 158633965Sjdp bfd_vma bitpos, bitsize; 158733965Sjdp 158833965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 158933965Sjdp return false; 159033965Sjdp if (! present) 159133965Sjdp break; 159233965Sjdp if (! ieee_read_type_index (info, pp, &ftype) 159333965Sjdp || ! ieee_read_number (info, pp, &bitpos) 159433965Sjdp || ! ieee_read_number (info, pp, &bitsize)) 159533965Sjdp return false; 159633965Sjdp 159733965Sjdp if (c + 1 >= alloc) 159833965Sjdp { 159933965Sjdp alloc += 10; 160033965Sjdp fields = ((debug_field *) 160133965Sjdp xrealloc (fields, alloc * sizeof *fields)); 160233965Sjdp } 160333965Sjdp 160433965Sjdp fields[c] = debug_make_field (dhandle, savestring (name, namlen), 160533965Sjdp ftype, bitpos, bitsize, 160633965Sjdp DEBUG_VISIBILITY_PUBLIC); 160733965Sjdp if (fields[c] == NULL) 160833965Sjdp return false; 160933965Sjdp ++c; 161033965Sjdp } 161133965Sjdp 161233965Sjdp fields[c] = NULL; 161333965Sjdp 161433965Sjdp type = debug_make_struct_type (dhandle, true, size, fields); 161533965Sjdp tag = true; 161633965Sjdp } 161733965Sjdp break; 161833965Sjdp 161933965Sjdp case 'N': 162033965Sjdp /* Enumeration. */ 162133965Sjdp { 162233965Sjdp unsigned int alloc; 162333965Sjdp const char **names; 162433965Sjdp bfd_signed_vma *vals; 162533965Sjdp unsigned int c; 162633965Sjdp 162733965Sjdp alloc = 10; 162833965Sjdp names = (const char **) xmalloc (alloc * sizeof *names); 162933965Sjdp vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names); 163033965Sjdp c = 0; 163133965Sjdp while (1) 163233965Sjdp { 163333965Sjdp const char *name; 163433965Sjdp unsigned long namlen; 163533965Sjdp boolean present; 163633965Sjdp bfd_vma val; 163733965Sjdp 163833965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 163933965Sjdp return false; 164033965Sjdp if (! present) 164133965Sjdp break; 164233965Sjdp if (! ieee_read_number (info, pp, &val)) 164333965Sjdp return false; 164433965Sjdp 164533965Sjdp /* If the length of the name is zero, then the value is 164633965Sjdp actually the size of the enum. We ignore this 164733965Sjdp information. FIXME. */ 164833965Sjdp if (namlen == 0) 164933965Sjdp continue; 165033965Sjdp 165133965Sjdp if (c + 1 >= alloc) 165233965Sjdp { 165333965Sjdp alloc += 10; 165433965Sjdp names = ((const char **) 165533965Sjdp xrealloc (names, alloc * sizeof *names)); 165633965Sjdp vals = ((bfd_signed_vma *) 165733965Sjdp xrealloc (vals, alloc * sizeof *vals)); 165833965Sjdp } 165933965Sjdp 166033965Sjdp names[c] = savestring (name, namlen); 166133965Sjdp if (names[c] == NULL) 166233965Sjdp return false; 166333965Sjdp vals[c] = (bfd_signed_vma) val; 166433965Sjdp ++c; 166533965Sjdp } 166633965Sjdp 166733965Sjdp names[c] = NULL; 166833965Sjdp 166933965Sjdp type = debug_make_enum_type (dhandle, names, vals); 167033965Sjdp tag = true; 167133965Sjdp } 167233965Sjdp break; 167333965Sjdp 167433965Sjdp case 'O': /* Small pointer. We don't distinguish small and large 167533965Sjdp pointers. FIXME. */ 167633965Sjdp case 'P': /* Large pointer. */ 167733965Sjdp { 167833965Sjdp debug_type t; 167933965Sjdp 168033965Sjdp if (! ieee_read_type_index (info, pp, &t)) 168133965Sjdp return false; 168233965Sjdp type = debug_make_pointer_type (dhandle, t); 168333965Sjdp } 168433965Sjdp break; 168533965Sjdp 168633965Sjdp case 'R': 168733965Sjdp /* Range. */ 168833965Sjdp { 168933965Sjdp bfd_vma low, high, signedp, size; 169033965Sjdp 169133965Sjdp if (! ieee_read_number (info, pp, &low) 169233965Sjdp || ! ieee_read_number (info, pp, &high) 169333965Sjdp || ! ieee_read_number (info, pp, &signedp) 169433965Sjdp || ! ieee_read_number (info, pp, &size)) 169533965Sjdp return false; 169633965Sjdp 169733965Sjdp type = debug_make_range_type (dhandle, 169833965Sjdp debug_make_int_type (dhandle, size, 169933965Sjdp ! signedp), 170033965Sjdp (bfd_signed_vma) low, 170133965Sjdp (bfd_signed_vma) high); 170233965Sjdp } 170333965Sjdp break; 170433965Sjdp 170533965Sjdp case 'S': /* Struct. */ 170633965Sjdp case 'U': /* Union. */ 170733965Sjdp { 170833965Sjdp bfd_vma size; 170933965Sjdp unsigned int alloc; 171033965Sjdp debug_field *fields; 171133965Sjdp unsigned int c; 171233965Sjdp 171333965Sjdp if (! ieee_read_number (info, pp, &size)) 171433965Sjdp return false; 171533965Sjdp 171633965Sjdp alloc = 10; 171733965Sjdp fields = (debug_field *) xmalloc (alloc * sizeof *fields); 171833965Sjdp c = 0; 171933965Sjdp while (1) 172033965Sjdp { 172133965Sjdp const char *name; 172233965Sjdp unsigned long namlen; 172333965Sjdp boolean present; 172433965Sjdp bfd_vma tindx; 172533965Sjdp bfd_vma offset; 172633965Sjdp debug_type ftype; 172733965Sjdp bfd_vma bitsize; 172833965Sjdp 172933965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 173033965Sjdp return false; 173133965Sjdp if (! present) 173233965Sjdp break; 173333965Sjdp if (! ieee_read_number (info, pp, &tindx) 173433965Sjdp || ! ieee_read_number (info, pp, &offset)) 173533965Sjdp return false; 173633965Sjdp 173733965Sjdp if (tindx < 256) 173833965Sjdp { 173933965Sjdp ftype = ieee_builtin_type (info, ty_code_start, tindx); 174033965Sjdp bitsize = 0; 174133965Sjdp offset *= 8; 174233965Sjdp } 174333965Sjdp else 174433965Sjdp { 174533965Sjdp struct ieee_type *t; 174633965Sjdp 174733965Sjdp tindx -= 256; 174833965Sjdp if (! ieee_alloc_type (info, tindx, true)) 174933965Sjdp return false; 175033965Sjdp t = info->types.types + tindx; 175133965Sjdp ftype = t->type; 175233965Sjdp bitsize = t->bitsize; 175333965Sjdp if (bitsize == 0) 175433965Sjdp offset *= 8; 175533965Sjdp } 175633965Sjdp 175733965Sjdp if (c + 1 >= alloc) 175833965Sjdp { 175933965Sjdp alloc += 10; 176033965Sjdp fields = ((debug_field *) 176133965Sjdp xrealloc (fields, alloc * sizeof *fields)); 176233965Sjdp } 176333965Sjdp 176433965Sjdp fields[c] = debug_make_field (dhandle, savestring (name, namlen), 176533965Sjdp ftype, offset, bitsize, 176633965Sjdp DEBUG_VISIBILITY_PUBLIC); 176733965Sjdp if (fields[c] == NULL) 176833965Sjdp return false; 176933965Sjdp ++c; 177033965Sjdp } 177133965Sjdp 177233965Sjdp fields[c] = NULL; 177333965Sjdp 177433965Sjdp type = debug_make_struct_type (dhandle, tc == 'S', size, fields); 177533965Sjdp tag = true; 177633965Sjdp } 177733965Sjdp break; 177833965Sjdp 177933965Sjdp case 'T': 178033965Sjdp /* Typedef. */ 178133965Sjdp if (! ieee_read_type_index (info, pp, &type)) 178233965Sjdp return false; 178333965Sjdp typdef = true; 178433965Sjdp break; 178533965Sjdp 178633965Sjdp case 'X': 178733965Sjdp /* Procedure. FIXME: This is an extern declaration, which we 178833965Sjdp have no way of representing. */ 178933965Sjdp { 179033965Sjdp bfd_vma attr; 179133965Sjdp debug_type rtype; 179233965Sjdp bfd_vma nargs; 179333965Sjdp boolean present; 179433965Sjdp struct ieee_var *pv; 179533965Sjdp 179633965Sjdp /* FIXME: We ignore the attribute and the argument names. */ 179733965Sjdp 179833965Sjdp if (! ieee_read_number (info, pp, &attr) 179933965Sjdp || ! ieee_read_type_index (info, pp, &rtype) 180033965Sjdp || ! ieee_read_number (info, pp, &nargs)) 180133965Sjdp return false; 180233965Sjdp do 180333965Sjdp { 180433965Sjdp const char *name; 180533965Sjdp unsigned long namlen; 180633965Sjdp 180733965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 180833965Sjdp return false; 180933965Sjdp } 181033965Sjdp while (present); 181133965Sjdp 181233965Sjdp pv = info->vars.vars + varindx; 181333965Sjdp pv->kind = IEEE_EXTERNAL; 181433965Sjdp if (pv->namlen > 0 181533965Sjdp && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) 181633965Sjdp { 181733965Sjdp /* Set up the return type as an indirect type pointing to 181833965Sjdp the variable slot, so that we can change it to a 181933965Sjdp reference later if appropriate. */ 182033965Sjdp pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); 182133965Sjdp *pv->pslot = rtype; 182233965Sjdp rtype = debug_make_indirect_type (dhandle, pv->pslot, 182333965Sjdp (const char *) NULL); 182433965Sjdp } 182533965Sjdp 182633965Sjdp type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL, 182733965Sjdp false); 182833965Sjdp } 182933965Sjdp break; 183033965Sjdp 183133965Sjdp case 'V': 183233965Sjdp /* Void. This is not documented, but the MRI compiler emits it. */ 183333965Sjdp type = debug_make_void_type (dhandle); 183433965Sjdp break; 183533965Sjdp 183633965Sjdp case 'Z': 183733965Sjdp /* Array with 0 lower bound. */ 183833965Sjdp { 183933965Sjdp debug_type etype; 184033965Sjdp bfd_vma high; 184133965Sjdp 184233965Sjdp if (! ieee_read_type_index (info, pp, &etype) 184333965Sjdp || ! ieee_read_number (info, pp, &high)) 184433965Sjdp return false; 184533965Sjdp 184633965Sjdp type = debug_make_array_type (dhandle, etype, 184733965Sjdp ieee_builtin_type (info, ty_code_start, 184833965Sjdp ((unsigned int) 184933965Sjdp builtin_int)), 185033965Sjdp 0, (bfd_signed_vma) high, false); 185133965Sjdp } 185233965Sjdp break; 185333965Sjdp 185433965Sjdp case 'c': /* Complex. */ 185533965Sjdp case 'd': /* Double complex. */ 185633965Sjdp { 185733965Sjdp const char *name; 185833965Sjdp unsigned long namlen; 185933965Sjdp 186033965Sjdp /* FIXME: I don't know what the name means. */ 186133965Sjdp 186233965Sjdp if (! ieee_read_id (info, pp, &name, &namlen)) 186333965Sjdp return false; 186433965Sjdp 186533965Sjdp type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8); 186633965Sjdp } 186733965Sjdp break; 186833965Sjdp 186933965Sjdp case 'f': 187033965Sjdp /* Pascal file name. FIXME. */ 187160484Sobrien ieee_error (info, ty_code_start, _("Pascal file name not supported")); 187233965Sjdp return false; 187333965Sjdp 187433965Sjdp case 'g': 187533965Sjdp /* Bitfield type. */ 187633965Sjdp { 187733965Sjdp bfd_vma signedp, bitsize, dummy; 187833965Sjdp const bfd_byte *hold; 187933965Sjdp boolean present; 188033965Sjdp 188133965Sjdp if (! ieee_read_number (info, pp, &signedp) 188233965Sjdp || ! ieee_read_number (info, pp, &bitsize)) 188333965Sjdp return false; 188433965Sjdp 188533965Sjdp /* I think the documentation says that there is a type index, 188633965Sjdp but some actual files do not have one. */ 188733965Sjdp hold = *pp; 188833965Sjdp if (! ieee_read_optional_number (info, pp, &dummy, &present)) 188933965Sjdp return false; 189033965Sjdp if (! present) 189133965Sjdp { 189233965Sjdp /* FIXME: This is just a guess. */ 189333965Sjdp type = debug_make_int_type (dhandle, 4, 189433965Sjdp signedp ? false : true); 189533965Sjdp } 189633965Sjdp else 189733965Sjdp { 189833965Sjdp *pp = hold; 189933965Sjdp if (! ieee_read_type_index (info, pp, &type)) 190033965Sjdp return false; 190133965Sjdp } 190233965Sjdp type_bitsize = bitsize; 190333965Sjdp } 190433965Sjdp break; 190533965Sjdp 190633965Sjdp case 'n': 190733965Sjdp /* Qualifier. */ 190833965Sjdp { 190933965Sjdp bfd_vma kind; 191033965Sjdp debug_type t; 191133965Sjdp 191233965Sjdp if (! ieee_read_number (info, pp, &kind) 191333965Sjdp || ! ieee_read_type_index (info, pp, &t)) 191433965Sjdp return false; 191533965Sjdp 191633965Sjdp switch (kind) 191733965Sjdp { 191833965Sjdp default: 1919104834Sobrien ieee_error (info, ty_start, _("unsupported qualifier")); 192033965Sjdp return false; 192133965Sjdp 192233965Sjdp case 1: 192333965Sjdp type = debug_make_const_type (dhandle, t); 192433965Sjdp break; 192533965Sjdp 192633965Sjdp case 2: 192733965Sjdp type = debug_make_volatile_type (dhandle, t); 192833965Sjdp break; 192933965Sjdp } 193033965Sjdp } 193133965Sjdp break; 193233965Sjdp 193333965Sjdp case 's': 193433965Sjdp /* Set. */ 193533965Sjdp { 193633965Sjdp bfd_vma size; 193733965Sjdp debug_type etype; 193833965Sjdp 193933965Sjdp if (! ieee_read_number (info, pp, &size) 194033965Sjdp || ! ieee_read_type_index (info, pp, &etype)) 194133965Sjdp return false; 194233965Sjdp 194333965Sjdp /* FIXME: We ignore the size. */ 194433965Sjdp 194533965Sjdp type = debug_make_set_type (dhandle, etype, false); 194633965Sjdp } 194733965Sjdp break; 194833965Sjdp 194933965Sjdp case 'x': 195033965Sjdp /* Procedure with compiler dependencies. */ 195133965Sjdp { 195233965Sjdp struct ieee_var *pv; 195333965Sjdp bfd_vma attr, frame_type, push_mask, nargs, level, father; 195433965Sjdp debug_type rtype; 195533965Sjdp debug_type *arg_types; 195633965Sjdp boolean varargs; 195733965Sjdp boolean present; 195833965Sjdp 195933965Sjdp /* FIXME: We ignore some of this information. */ 196033965Sjdp 196133965Sjdp pv = info->vars.vars + varindx; 196233965Sjdp 196333965Sjdp if (! ieee_read_number (info, pp, &attr) 196433965Sjdp || ! ieee_read_number (info, pp, &frame_type) 196533965Sjdp || ! ieee_read_number (info, pp, &push_mask) 196633965Sjdp || ! ieee_read_type_index (info, pp, &rtype) 196733965Sjdp || ! ieee_read_number (info, pp, &nargs)) 196833965Sjdp return false; 196933965Sjdp if (nargs == (bfd_vma) -1) 197033965Sjdp { 197133965Sjdp arg_types = NULL; 197233965Sjdp varargs = false; 197333965Sjdp } 197433965Sjdp else 197533965Sjdp { 197633965Sjdp unsigned int i; 197733965Sjdp 197833965Sjdp arg_types = ((debug_type *) 197933965Sjdp xmalloc ((nargs + 1) * sizeof *arg_types)); 198033965Sjdp for (i = 0; i < nargs; i++) 198133965Sjdp if (! ieee_read_type_index (info, pp, arg_types + i)) 198233965Sjdp return false; 198333965Sjdp 198433965Sjdp /* If the last type is pointer to void, this is really a 198533965Sjdp varargs function. */ 198633965Sjdp varargs = false; 198733965Sjdp if (nargs > 0) 198833965Sjdp { 198933965Sjdp debug_type last; 199033965Sjdp 199133965Sjdp last = arg_types[nargs - 1]; 199233965Sjdp if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER 199333965Sjdp && (debug_get_type_kind (dhandle, 199433965Sjdp debug_get_target_type (dhandle, 199533965Sjdp last)) 199633965Sjdp == DEBUG_KIND_VOID)) 199733965Sjdp { 199833965Sjdp --nargs; 199933965Sjdp varargs = true; 200033965Sjdp } 200133965Sjdp } 200233965Sjdp 200333965Sjdp /* If there are any pointer arguments, turn them into 200433965Sjdp indirect types in case we later need to convert them to 200533965Sjdp reference types. */ 200633965Sjdp for (i = 0; i < nargs; i++) 200733965Sjdp { 200833965Sjdp if (debug_get_type_kind (dhandle, arg_types[i]) 200933965Sjdp == DEBUG_KIND_POINTER) 201033965Sjdp { 201133965Sjdp if (arg_slots == NULL) 201233965Sjdp { 201333965Sjdp arg_slots = ((debug_type *) 201433965Sjdp xmalloc (nargs * sizeof *arg_slots)); 201533965Sjdp memset (arg_slots, 0, nargs * sizeof *arg_slots); 201633965Sjdp } 201733965Sjdp arg_slots[i] = arg_types[i]; 201833965Sjdp arg_types[i] = 201933965Sjdp debug_make_indirect_type (dhandle, 202033965Sjdp arg_slots + i, 202133965Sjdp (const char *) NULL); 202233965Sjdp } 202333965Sjdp } 202433965Sjdp 202533965Sjdp arg_types[nargs] = DEBUG_TYPE_NULL; 202633965Sjdp } 202733965Sjdp if (! ieee_read_number (info, pp, &level) 202833965Sjdp || ! ieee_read_optional_number (info, pp, &father, &present)) 202933965Sjdp return false; 203033965Sjdp 203133965Sjdp /* We can't distinguish between a global function and a static 203233965Sjdp function. */ 203333965Sjdp pv->kind = IEEE_FUNCTION; 203433965Sjdp 203533965Sjdp if (pv->namlen > 0 203633965Sjdp && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER) 203733965Sjdp { 203833965Sjdp /* Set up the return type as an indirect type pointing to 203933965Sjdp the variable slot, so that we can change it to a 204033965Sjdp reference later if appropriate. */ 204133965Sjdp pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot); 204233965Sjdp *pv->pslot = rtype; 204333965Sjdp rtype = debug_make_indirect_type (dhandle, pv->pslot, 204433965Sjdp (const char *) NULL); 204533965Sjdp } 204633965Sjdp 204733965Sjdp type = debug_make_function_type (dhandle, rtype, arg_types, varargs); 204833965Sjdp } 204933965Sjdp break; 205033965Sjdp } 205133965Sjdp 205233965Sjdp /* Record the type in the table. */ 205333965Sjdp 205433965Sjdp if (type == DEBUG_TYPE_NULL) 205533965Sjdp return false; 205633965Sjdp 205733965Sjdp info->vars.vars[varindx].type = type; 205833965Sjdp 205933965Sjdp if ((tag || typdef) 206033965Sjdp && info->vars.vars[varindx].namlen > 0) 206133965Sjdp { 206233965Sjdp const char *name; 206333965Sjdp 206433965Sjdp name = savestring (info->vars.vars[varindx].name, 206533965Sjdp info->vars.vars[varindx].namlen); 206633965Sjdp if (typdef) 206733965Sjdp type = debug_name_type (dhandle, name, type); 206833965Sjdp else if (tc == 'E' || tc == 'N') 206933965Sjdp type = debug_tag_type (dhandle, name, type); 207033965Sjdp else 207133965Sjdp { 207233965Sjdp struct ieee_tag *it; 207333965Sjdp 207433965Sjdp /* We must allocate all struct tags as indirect types, so 207533965Sjdp that if we later see a definition of the tag as a C++ 207633965Sjdp record we can update the indirect slot and automatically 207733965Sjdp change all the existing references. */ 207833965Sjdp it = (struct ieee_tag *) xmalloc (sizeof *it); 207933965Sjdp memset (it, 0, sizeof *it); 208033965Sjdp it->next = info->tags; 208133965Sjdp info->tags = it; 208233965Sjdp it->name = name; 208333965Sjdp it->slot = type; 208433965Sjdp 208533965Sjdp type = debug_make_indirect_type (dhandle, &it->slot, name); 208633965Sjdp type = debug_tag_type (dhandle, name, type); 208733965Sjdp 208833965Sjdp it->type = type; 208933965Sjdp } 209033965Sjdp if (type == NULL) 209133965Sjdp return false; 209233965Sjdp } 209333965Sjdp 209433965Sjdp info->types.types[typeindx].type = type; 209533965Sjdp info->types.types[typeindx].arg_slots = arg_slots; 209633965Sjdp info->types.types[typeindx].bitsize = type_bitsize; 209733965Sjdp 209833965Sjdp /* We may have already allocated type as an indirect type pointing 209933965Sjdp to slot. It does no harm to replace the indirect type with the 210033965Sjdp real type. Filling in slot as well handles the indirect types 210133965Sjdp which are already hanging around. */ 210233965Sjdp if (info->types.types[typeindx].pslot != NULL) 210333965Sjdp *info->types.types[typeindx].pslot = type; 210433965Sjdp 210533965Sjdp return true; 210633965Sjdp} 210733965Sjdp 210833965Sjdp/* Parse an ATN record. */ 210933965Sjdp 211033965Sjdpstatic boolean 211133965Sjdpparse_ieee_atn (info, pp) 211233965Sjdp struct ieee_info *info; 211333965Sjdp const bfd_byte **pp; 211433965Sjdp{ 211533965Sjdp const bfd_byte *atn_start, *atn_code_start; 211633965Sjdp bfd_vma varindx; 211733965Sjdp struct ieee_var *pvar; 211833965Sjdp debug_type type; 211933965Sjdp bfd_vma atn_code; 212033965Sjdp PTR dhandle; 212133965Sjdp bfd_vma v, v2, v3, v4, v5; 212233965Sjdp const char *name; 212333965Sjdp unsigned long namlen; 212433965Sjdp char *namcopy; 212533965Sjdp boolean present; 212633965Sjdp int blocktype; 212733965Sjdp 212833965Sjdp atn_start = *pp; 212933965Sjdp 213033965Sjdp if (! ieee_read_number (info, pp, &varindx) 213133965Sjdp || ! ieee_read_type_index (info, pp, &type)) 213233965Sjdp return false; 213333965Sjdp 213433965Sjdp atn_code_start = *pp; 213533965Sjdp 213633965Sjdp if (! ieee_read_number (info, pp, &atn_code)) 213733965Sjdp return false; 213833965Sjdp 213933965Sjdp if (varindx == 0) 214033965Sjdp { 214133965Sjdp pvar = NULL; 214233965Sjdp name = ""; 214333965Sjdp namlen = 0; 214433965Sjdp } 214533965Sjdp else if (varindx < 32) 214633965Sjdp { 214760484Sobrien /* The MRI compiler reportedly sometimes emits variable lifetime 214860484Sobrien information for a register. We just ignore it. */ 214960484Sobrien if (atn_code == 9) 215060484Sobrien return ieee_read_number (info, pp, &v); 215160484Sobrien 215260484Sobrien ieee_error (info, atn_start, _("illegal variable index")); 215333965Sjdp return false; 215433965Sjdp } 215533965Sjdp else 215633965Sjdp { 215733965Sjdp varindx -= 32; 215833965Sjdp if (varindx >= info->vars.alloc 215933965Sjdp || info->vars.vars[varindx].name == NULL) 216033965Sjdp { 216133965Sjdp /* The MRI compiler or linker sometimes omits the NN record 216233965Sjdp for a pmisc record. */ 216333965Sjdp if (atn_code == 62) 216433965Sjdp { 216533965Sjdp if (varindx >= info->vars.alloc) 216633965Sjdp { 216733965Sjdp unsigned int alloc; 216833965Sjdp 216933965Sjdp alloc = info->vars.alloc; 217033965Sjdp if (alloc == 0) 217133965Sjdp alloc = 4; 217233965Sjdp while (varindx >= alloc) 217333965Sjdp alloc *= 2; 217433965Sjdp info->vars.vars = ((struct ieee_var *) 217533965Sjdp xrealloc (info->vars.vars, 217633965Sjdp (alloc 217733965Sjdp * sizeof *info->vars.vars))); 217833965Sjdp memset (info->vars.vars + info->vars.alloc, 0, 217933965Sjdp ((alloc - info->vars.alloc) 218033965Sjdp * sizeof *info->vars.vars)); 218133965Sjdp info->vars.alloc = alloc; 218233965Sjdp } 218333965Sjdp 218433965Sjdp pvar = info->vars.vars + varindx; 218533965Sjdp pvar->name = ""; 218633965Sjdp pvar->namlen = 0; 218733965Sjdp } 218833965Sjdp else 218933965Sjdp { 219060484Sobrien ieee_error (info, atn_start, _("undefined variable in ATN")); 219133965Sjdp return false; 219233965Sjdp } 219333965Sjdp } 219433965Sjdp 219533965Sjdp pvar = info->vars.vars + varindx; 219633965Sjdp 219733965Sjdp pvar->type = type; 219833965Sjdp 219933965Sjdp name = pvar->name; 220033965Sjdp namlen = pvar->namlen; 220133965Sjdp } 220233965Sjdp 220333965Sjdp dhandle = info->dhandle; 220433965Sjdp 220533965Sjdp /* If we are going to call debug_record_variable with a pointer 220633965Sjdp type, change the type to an indirect type so that we can later 220733965Sjdp change it to a reference type if we encounter a C++ pmisc 'R' 220833965Sjdp record. */ 220933965Sjdp if (pvar != NULL 221033965Sjdp && type != DEBUG_TYPE_NULL 221133965Sjdp && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER) 221233965Sjdp { 221333965Sjdp switch (atn_code) 221433965Sjdp { 221533965Sjdp case 1: 221633965Sjdp case 2: 221733965Sjdp case 3: 221833965Sjdp case 5: 221933965Sjdp case 8: 222033965Sjdp case 10: 222133965Sjdp pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot); 222233965Sjdp *pvar->pslot = type; 222333965Sjdp type = debug_make_indirect_type (dhandle, pvar->pslot, 222433965Sjdp (const char *) NULL); 222533965Sjdp pvar->type = type; 222633965Sjdp break; 222733965Sjdp } 222833965Sjdp } 222933965Sjdp 223033965Sjdp switch (atn_code) 223133965Sjdp { 223233965Sjdp default: 223360484Sobrien ieee_error (info, atn_code_start, _("unknown ATN type")); 223433965Sjdp return false; 223533965Sjdp 223633965Sjdp case 1: 223733965Sjdp /* Automatic variable. */ 223833965Sjdp if (! ieee_read_number (info, pp, &v)) 223933965Sjdp return false; 224033965Sjdp namcopy = savestring (name, namlen); 224133965Sjdp if (type == NULL) 224233965Sjdp type = debug_make_void_type (dhandle); 224333965Sjdp if (pvar != NULL) 224433965Sjdp pvar->kind = IEEE_LOCAL; 224533965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v); 224633965Sjdp 224733965Sjdp case 2: 224833965Sjdp /* Register variable. */ 224933965Sjdp if (! ieee_read_number (info, pp, &v)) 225033965Sjdp return false; 225133965Sjdp namcopy = savestring (name, namlen); 225233965Sjdp if (type == NULL) 225333965Sjdp type = debug_make_void_type (dhandle); 225433965Sjdp if (pvar != NULL) 225533965Sjdp pvar->kind = IEEE_LOCAL; 225633965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, 225733965Sjdp ieee_regno_to_genreg (info->abfd, v)); 225833965Sjdp 225933965Sjdp case 3: 226033965Sjdp /* Static variable. */ 226133965Sjdp if (! ieee_require_asn (info, pp, &v)) 226233965Sjdp return false; 226333965Sjdp namcopy = savestring (name, namlen); 226433965Sjdp if (type == NULL) 226533965Sjdp type = debug_make_void_type (dhandle); 226633965Sjdp if (info->blockstack.bsp <= info->blockstack.stack) 226733965Sjdp blocktype = 0; 226833965Sjdp else 226933965Sjdp blocktype = info->blockstack.bsp[-1].kind; 227033965Sjdp if (pvar != NULL) 227133965Sjdp { 227233965Sjdp if (blocktype == 4 || blocktype == 6) 227333965Sjdp pvar->kind = IEEE_LOCAL; 227433965Sjdp else 227533965Sjdp pvar->kind = IEEE_STATIC; 227633965Sjdp } 227733965Sjdp return debug_record_variable (dhandle, namcopy, type, 227833965Sjdp (blocktype == 4 || blocktype == 6 227933965Sjdp ? DEBUG_LOCAL_STATIC 228033965Sjdp : DEBUG_STATIC), 228133965Sjdp v); 228233965Sjdp 228333965Sjdp case 4: 228433965Sjdp /* External function. We don't currently record these. FIXME. */ 228533965Sjdp if (pvar != NULL) 228633965Sjdp pvar->kind = IEEE_EXTERNAL; 228733965Sjdp return true; 228833965Sjdp 228933965Sjdp case 5: 229033965Sjdp /* External variable. We don't currently record these. FIXME. */ 229133965Sjdp if (pvar != NULL) 229233965Sjdp pvar->kind = IEEE_EXTERNAL; 229333965Sjdp return true; 229433965Sjdp 229533965Sjdp case 7: 229633965Sjdp if (! ieee_read_number (info, pp, &v) 229733965Sjdp || ! ieee_read_number (info, pp, &v2) 229833965Sjdp || ! ieee_read_optional_number (info, pp, &v3, &present)) 229933965Sjdp return false; 230033965Sjdp if (present) 230133965Sjdp { 230233965Sjdp if (! ieee_read_optional_number (info, pp, &v4, &present)) 230333965Sjdp return false; 230433965Sjdp } 230533965Sjdp 230633965Sjdp /* We just ignore the two optional fields in v3 and v4, since 230733965Sjdp they are not defined. */ 230833965Sjdp 230933965Sjdp if (! ieee_require_asn (info, pp, &v3)) 231033965Sjdp return false; 231133965Sjdp 231233965Sjdp /* We have no way to record the column number. FIXME. */ 231333965Sjdp 231433965Sjdp return debug_record_line (dhandle, v, v3); 231533965Sjdp 231633965Sjdp case 8: 231733965Sjdp /* Global variable. */ 231833965Sjdp if (! ieee_require_asn (info, pp, &v)) 231933965Sjdp return false; 232033965Sjdp namcopy = savestring (name, namlen); 232133965Sjdp if (type == NULL) 232233965Sjdp type = debug_make_void_type (dhandle); 232333965Sjdp if (pvar != NULL) 232433965Sjdp pvar->kind = IEEE_GLOBAL; 232533965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v); 232633965Sjdp 232733965Sjdp case 9: 232833965Sjdp /* Variable lifetime information. */ 232933965Sjdp if (! ieee_read_number (info, pp, &v)) 233033965Sjdp return false; 233133965Sjdp 233233965Sjdp /* We have no way to record this information. FIXME. */ 233333965Sjdp return true; 233433965Sjdp 233533965Sjdp case 10: 233633965Sjdp /* Locked register. The spec says that there are two required 233733965Sjdp fields, but at least on occasion the MRI compiler only emits 233833965Sjdp one. */ 233933965Sjdp if (! ieee_read_number (info, pp, &v) 234033965Sjdp || ! ieee_read_optional_number (info, pp, &v2, &present)) 234133965Sjdp return false; 234233965Sjdp 234333965Sjdp /* I think this means a variable that is both in a register and 234433965Sjdp a frame slot. We ignore the frame slot. FIXME. */ 234533965Sjdp 234633965Sjdp namcopy = savestring (name, namlen); 234733965Sjdp if (type == NULL) 234833965Sjdp type = debug_make_void_type (dhandle); 234933965Sjdp if (pvar != NULL) 235033965Sjdp pvar->kind = IEEE_LOCAL; 235133965Sjdp return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v); 235233965Sjdp 235333965Sjdp case 11: 235433965Sjdp /* Reserved for FORTRAN common. */ 235560484Sobrien ieee_error (info, atn_code_start, _("unsupported ATN11")); 235633965Sjdp 235733965Sjdp /* Return true to keep going. */ 235833965Sjdp return true; 235933965Sjdp 236033965Sjdp case 12: 236133965Sjdp /* Based variable. */ 236233965Sjdp v3 = 0; 236333965Sjdp v4 = 0x80; 236433965Sjdp v5 = 0; 236533965Sjdp if (! ieee_read_number (info, pp, &v) 236633965Sjdp || ! ieee_read_number (info, pp, &v2) 236733965Sjdp || ! ieee_read_optional_number (info, pp, &v3, &present)) 236833965Sjdp return false; 236933965Sjdp if (present) 237033965Sjdp { 237133965Sjdp if (! ieee_read_optional_number (info, pp, &v4, &present)) 237233965Sjdp return false; 237333965Sjdp if (present) 237433965Sjdp { 237533965Sjdp if (! ieee_read_optional_number (info, pp, &v5, &present)) 237633965Sjdp return false; 237733965Sjdp } 237833965Sjdp } 237933965Sjdp 238033965Sjdp /* We have no way to record this information. FIXME. */ 238133965Sjdp 238260484Sobrien ieee_error (info, atn_code_start, _("unsupported ATN12")); 238333965Sjdp 238433965Sjdp /* Return true to keep going. */ 238533965Sjdp return true; 238633965Sjdp 238733965Sjdp case 16: 238833965Sjdp /* Constant. The description of this that I have is ambiguous, 238933965Sjdp so I'm not going to try to implement it. */ 239033965Sjdp if (! ieee_read_number (info, pp, &v) 239133965Sjdp || ! ieee_read_optional_number (info, pp, &v2, &present)) 239233965Sjdp return false; 239333965Sjdp if (present) 239433965Sjdp { 239533965Sjdp if (! ieee_read_optional_number (info, pp, &v2, &present)) 239633965Sjdp return false; 239733965Sjdp if (present) 239833965Sjdp { 239933965Sjdp if (! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 240033965Sjdp return false; 240133965Sjdp } 240233965Sjdp } 240333965Sjdp 240433965Sjdp if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum) 240533965Sjdp { 240633965Sjdp if (! ieee_require_asn (info, pp, &v3)) 240733965Sjdp return false; 240833965Sjdp } 240933965Sjdp 241033965Sjdp return true; 241133965Sjdp 241233965Sjdp case 19: 241333965Sjdp /* Static variable from assembler. */ 241433965Sjdp v2 = 0; 241533965Sjdp if (! ieee_read_number (info, pp, &v) 241633965Sjdp || ! ieee_read_optional_number (info, pp, &v2, &present) 241733965Sjdp || ! ieee_require_asn (info, pp, &v3)) 241833965Sjdp return false; 241933965Sjdp namcopy = savestring (name, namlen); 242033965Sjdp /* We don't really handle this correctly. FIXME. */ 242133965Sjdp return debug_record_variable (dhandle, namcopy, 242233965Sjdp debug_make_void_type (dhandle), 242333965Sjdp v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC, 242433965Sjdp v3); 242533965Sjdp 242633965Sjdp case 62: 242733965Sjdp /* Procedure miscellaneous information. */ 242833965Sjdp case 63: 242933965Sjdp /* Variable miscellaneous information. */ 243033965Sjdp case 64: 243133965Sjdp /* Module miscellaneous information. */ 243233965Sjdp if (! ieee_read_number (info, pp, &v) 243333965Sjdp || ! ieee_read_number (info, pp, &v2) 243433965Sjdp || ! ieee_read_optional_id (info, pp, &name, &namlen, &present)) 243533965Sjdp return false; 243633965Sjdp 243733965Sjdp if (atn_code == 62 && v == 80) 243833965Sjdp { 243933965Sjdp if (present) 244033965Sjdp { 244133965Sjdp ieee_error (info, atn_code_start, 244260484Sobrien _("unexpected string in C++ misc")); 244333965Sjdp return false; 244433965Sjdp } 244533965Sjdp return ieee_read_cxx_misc (info, pp, v2); 244633965Sjdp } 244733965Sjdp 244833965Sjdp /* We just ignore all of this stuff. FIXME. */ 244933965Sjdp 245033965Sjdp for (; v2 > 0; --v2) 245133965Sjdp { 245233965Sjdp switch ((ieee_record_enum_type) **pp) 245333965Sjdp { 245433965Sjdp default: 245560484Sobrien ieee_error (info, *pp, _("bad misc record")); 245633965Sjdp return false; 245733965Sjdp 245833965Sjdp case ieee_at_record_enum: 245933965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen)) 246033965Sjdp return false; 246133965Sjdp break; 246233965Sjdp 246333965Sjdp case ieee_e2_first_byte_enum: 246433965Sjdp if (! ieee_require_asn (info, pp, &v3)) 246533965Sjdp return false; 246633965Sjdp break; 246733965Sjdp } 246833965Sjdp } 246933965Sjdp 247033965Sjdp return true; 247133965Sjdp } 247233965Sjdp 247333965Sjdp /*NOTREACHED*/ 247433965Sjdp} 247533965Sjdp 247633965Sjdp/* Handle C++ debugging miscellaneous records. This is called for 247733965Sjdp procedure miscellaneous records of type 80. */ 247833965Sjdp 247933965Sjdpstatic boolean 248033965Sjdpieee_read_cxx_misc (info, pp, count) 248133965Sjdp struct ieee_info *info; 248233965Sjdp const bfd_byte **pp; 248333965Sjdp unsigned long count; 248433965Sjdp{ 248533965Sjdp const bfd_byte *start; 248633965Sjdp bfd_vma category; 248733965Sjdp 248833965Sjdp start = *pp; 248933965Sjdp 249033965Sjdp /* Get the category of C++ misc record. */ 249133965Sjdp if (! ieee_require_asn (info, pp, &category)) 249233965Sjdp return false; 249333965Sjdp --count; 249433965Sjdp 249533965Sjdp switch (category) 249633965Sjdp { 249733965Sjdp default: 249860484Sobrien ieee_error (info, start, _("unrecognized C++ misc record")); 249933965Sjdp return false; 250033965Sjdp 250133965Sjdp case 'T': 250233965Sjdp if (! ieee_read_cxx_class (info, pp, count)) 250333965Sjdp return false; 250433965Sjdp break; 250533965Sjdp 250633965Sjdp case 'M': 250733965Sjdp { 250833965Sjdp bfd_vma flags; 250933965Sjdp const char *name; 251033965Sjdp unsigned long namlen; 251133965Sjdp 251233965Sjdp /* The IEEE spec indicates that the 'M' record only has a 251333965Sjdp flags field. The MRI compiler also emits the name of the 251433965Sjdp function. */ 251533965Sjdp 251633965Sjdp if (! ieee_require_asn (info, pp, &flags)) 251733965Sjdp return false; 251833965Sjdp if (*pp < info->pend 251933965Sjdp && (ieee_record_enum_type) **pp == ieee_at_record_enum) 252033965Sjdp { 252133965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen)) 252233965Sjdp return false; 252333965Sjdp } 252433965Sjdp 252533965Sjdp /* This is emitted for method functions, but I don't think we 252633965Sjdp care very much. It might help if it told us useful 252733965Sjdp information like the class with which this function is 252833965Sjdp associated, but it doesn't, so it isn't helpful. */ 252933965Sjdp } 253033965Sjdp break; 253133965Sjdp 253233965Sjdp case 'B': 253333965Sjdp if (! ieee_read_cxx_defaults (info, pp, count)) 253433965Sjdp return false; 253533965Sjdp break; 253633965Sjdp 253733965Sjdp case 'z': 253833965Sjdp { 253933965Sjdp const char *name, *mangled, *class; 254033965Sjdp unsigned long namlen, mangledlen, classlen; 254133965Sjdp bfd_vma control; 254233965Sjdp 254333965Sjdp /* Pointer to member. */ 254433965Sjdp 254533965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen) 254633965Sjdp || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen) 254733965Sjdp || ! ieee_require_atn65 (info, pp, &class, &classlen) 254833965Sjdp || ! ieee_require_asn (info, pp, &control)) 254933965Sjdp return false; 255033965Sjdp 255133965Sjdp /* FIXME: We should now track down name and change its type. */ 255233965Sjdp } 255333965Sjdp break; 255433965Sjdp 255533965Sjdp case 'R': 255633965Sjdp if (! ieee_read_reference (info, pp)) 255733965Sjdp return false; 255833965Sjdp break; 255933965Sjdp } 256033965Sjdp 256133965Sjdp return true; 256233965Sjdp} 256333965Sjdp 256433965Sjdp/* Read a C++ class definition. This is a pmisc type 80 record of 256533965Sjdp category 'T'. */ 256633965Sjdp 256733965Sjdpstatic boolean 256833965Sjdpieee_read_cxx_class (info, pp, count) 256933965Sjdp struct ieee_info *info; 257033965Sjdp const bfd_byte **pp; 257133965Sjdp unsigned long count; 257233965Sjdp{ 257333965Sjdp const bfd_byte *start; 257433965Sjdp bfd_vma class; 257533965Sjdp const char *tag; 257633965Sjdp unsigned long taglen; 257733965Sjdp struct ieee_tag *it; 257833965Sjdp PTR dhandle; 257933965Sjdp debug_field *fields; 258033965Sjdp unsigned int field_count, field_alloc; 258133965Sjdp debug_baseclass *baseclasses; 258233965Sjdp unsigned int baseclasses_count, baseclasses_alloc; 258333965Sjdp const debug_field *structfields; 258433965Sjdp struct ieee_method 258533965Sjdp { 258633965Sjdp const char *name; 258733965Sjdp unsigned long namlen; 258833965Sjdp debug_method_variant *variants; 258933965Sjdp unsigned count; 259033965Sjdp unsigned int alloc; 259133965Sjdp } *methods; 259233965Sjdp unsigned int methods_count, methods_alloc; 259333965Sjdp debug_type vptrbase; 259433965Sjdp boolean ownvptr; 259533965Sjdp debug_method *dmethods; 259633965Sjdp 259733965Sjdp start = *pp; 259833965Sjdp 259933965Sjdp if (! ieee_require_asn (info, pp, &class)) 260033965Sjdp return false; 260133965Sjdp --count; 260233965Sjdp 260333965Sjdp if (! ieee_require_atn65 (info, pp, &tag, &taglen)) 260433965Sjdp return false; 260533965Sjdp --count; 260633965Sjdp 260733965Sjdp /* Find the C struct with this name. */ 260833965Sjdp for (it = info->tags; it != NULL; it = it->next) 260933965Sjdp if (it->name[0] == tag[0] 261033965Sjdp && strncmp (it->name, tag, taglen) == 0 261133965Sjdp && strlen (it->name) == taglen) 261233965Sjdp break; 261333965Sjdp if (it == NULL) 261433965Sjdp { 261560484Sobrien ieee_error (info, start, _("undefined C++ object")); 261633965Sjdp return false; 261733965Sjdp } 261833965Sjdp 261933965Sjdp dhandle = info->dhandle; 262033965Sjdp 262133965Sjdp fields = NULL; 262233965Sjdp field_count = 0; 262333965Sjdp field_alloc = 0; 262433965Sjdp baseclasses = NULL; 262533965Sjdp baseclasses_count = 0; 262633965Sjdp baseclasses_alloc = 0; 262733965Sjdp methods = NULL; 262833965Sjdp methods_count = 0; 262933965Sjdp methods_alloc = 0; 263033965Sjdp vptrbase = DEBUG_TYPE_NULL; 263133965Sjdp ownvptr = false; 263233965Sjdp 263333965Sjdp structfields = debug_get_fields (dhandle, it->type); 263433965Sjdp 263533965Sjdp while (count > 0) 263633965Sjdp { 263733965Sjdp bfd_vma id; 263833965Sjdp const bfd_byte *spec_start; 263933965Sjdp 264033965Sjdp spec_start = *pp; 264133965Sjdp 264233965Sjdp if (! ieee_require_asn (info, pp, &id)) 264333965Sjdp return false; 264433965Sjdp --count; 264533965Sjdp 264633965Sjdp switch (id) 264733965Sjdp { 264833965Sjdp default: 264960484Sobrien ieee_error (info, spec_start, _("unrecognized C++ object spec")); 265033965Sjdp return false; 265133965Sjdp 265233965Sjdp case 'b': 265333965Sjdp { 265433965Sjdp bfd_vma flags, cinline; 265533965Sjdp const char *basename, *fieldname; 265633965Sjdp unsigned long baselen, fieldlen; 265733965Sjdp char *basecopy; 265833965Sjdp debug_type basetype; 265933965Sjdp bfd_vma bitpos; 266033965Sjdp boolean virtualp; 266133965Sjdp enum debug_visibility visibility; 266233965Sjdp debug_baseclass baseclass; 266333965Sjdp 266433965Sjdp /* This represents a base or friend class. */ 266533965Sjdp 266633965Sjdp if (! ieee_require_asn (info, pp, &flags) 266733965Sjdp || ! ieee_require_atn65 (info, pp, &basename, &baselen) 266833965Sjdp || ! ieee_require_asn (info, pp, &cinline) 266933965Sjdp || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)) 267033965Sjdp return false; 267133965Sjdp count -= 4; 267233965Sjdp 267333965Sjdp /* We have no way of recording friend information, so we 267433965Sjdp just ignore it. */ 267533965Sjdp if ((flags & BASEFLAGS_FRIEND) != 0) 267633965Sjdp break; 267733965Sjdp 267833965Sjdp /* I assume that either all of the members of the 267933965Sjdp baseclass are included in the object, starting at the 268033965Sjdp beginning of the object, or that none of them are 268133965Sjdp included. */ 268233965Sjdp 268333965Sjdp if ((fieldlen == 0) == (cinline == 0)) 268433965Sjdp { 268560484Sobrien ieee_error (info, start, _("unsupported C++ object type")); 268633965Sjdp return false; 268733965Sjdp } 268833965Sjdp 268933965Sjdp basecopy = savestring (basename, baselen); 269033965Sjdp basetype = debug_find_tagged_type (dhandle, basecopy, 269133965Sjdp DEBUG_KIND_ILLEGAL); 269233965Sjdp free (basecopy); 269333965Sjdp if (basetype == DEBUG_TYPE_NULL) 269433965Sjdp { 269560484Sobrien ieee_error (info, start, _("C++ base class not defined")); 269633965Sjdp return false; 269733965Sjdp } 269833965Sjdp 269933965Sjdp if (fieldlen == 0) 270033965Sjdp bitpos = 0; 270133965Sjdp else 270233965Sjdp { 270333965Sjdp const debug_field *pf; 270433965Sjdp 270533965Sjdp if (structfields == NULL) 270633965Sjdp { 270760484Sobrien ieee_error (info, start, _("C++ object has no fields")); 270833965Sjdp return false; 270933965Sjdp } 271033965Sjdp 271133965Sjdp for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++) 271233965Sjdp { 271333965Sjdp const char *fname; 271433965Sjdp 271533965Sjdp fname = debug_get_field_name (dhandle, *pf); 271633965Sjdp if (fname == NULL) 271733965Sjdp return false; 271833965Sjdp if (fname[0] == fieldname[0] 271933965Sjdp && strncmp (fname, fieldname, fieldlen) == 0 272033965Sjdp && strlen (fname) == fieldlen) 272133965Sjdp break; 272233965Sjdp } 272333965Sjdp if (*pf == DEBUG_FIELD_NULL) 272433965Sjdp { 272533965Sjdp ieee_error (info, start, 272660484Sobrien _("C++ base class not found in container")); 272733965Sjdp return false; 272833965Sjdp } 272933965Sjdp 273033965Sjdp bitpos = debug_get_field_bitpos (dhandle, *pf); 273133965Sjdp } 273233965Sjdp 273333965Sjdp if ((flags & BASEFLAGS_VIRTUAL) != 0) 273433965Sjdp virtualp = true; 273533965Sjdp else 273633965Sjdp virtualp = false; 273733965Sjdp if ((flags & BASEFLAGS_PRIVATE) != 0) 273833965Sjdp visibility = DEBUG_VISIBILITY_PRIVATE; 273933965Sjdp else 274033965Sjdp visibility = DEBUG_VISIBILITY_PUBLIC; 274133965Sjdp 274233965Sjdp baseclass = debug_make_baseclass (dhandle, basetype, bitpos, 274333965Sjdp virtualp, visibility); 274433965Sjdp if (baseclass == DEBUG_BASECLASS_NULL) 274533965Sjdp return false; 274633965Sjdp 274733965Sjdp if (baseclasses_count + 1 >= baseclasses_alloc) 274833965Sjdp { 274933965Sjdp baseclasses_alloc += 10; 275033965Sjdp baseclasses = ((debug_baseclass *) 275133965Sjdp xrealloc (baseclasses, 275233965Sjdp (baseclasses_alloc 275333965Sjdp * sizeof *baseclasses))); 275433965Sjdp } 275533965Sjdp 275633965Sjdp baseclasses[baseclasses_count] = baseclass; 275733965Sjdp ++baseclasses_count; 275833965Sjdp baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL; 275933965Sjdp } 276033965Sjdp break; 276133965Sjdp 276233965Sjdp case 'd': 276333965Sjdp { 276433965Sjdp bfd_vma flags; 276533965Sjdp const char *fieldname, *mangledname; 276633965Sjdp unsigned long fieldlen, mangledlen; 276733965Sjdp char *fieldcopy; 276833965Sjdp boolean staticp; 276933965Sjdp debug_type ftype; 277033965Sjdp const debug_field *pf = NULL; 277133965Sjdp enum debug_visibility visibility; 277233965Sjdp debug_field field; 277333965Sjdp 277433965Sjdp /* This represents a data member. */ 277533965Sjdp 277633965Sjdp if (! ieee_require_asn (info, pp, &flags) 277733965Sjdp || ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen) 277833965Sjdp || ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen)) 277933965Sjdp return false; 278033965Sjdp count -= 3; 278133965Sjdp 278233965Sjdp fieldcopy = savestring (fieldname, fieldlen); 278333965Sjdp 278433965Sjdp staticp = (flags & CXXFLAGS_STATIC) != 0 ? true : false; 278533965Sjdp 278633965Sjdp if (staticp) 278733965Sjdp { 278833965Sjdp struct ieee_var *pv, *pvend; 278933965Sjdp 279033965Sjdp /* See if we can find a definition for this variable. */ 279133965Sjdp pv = info->vars.vars; 279233965Sjdp pvend = pv + info->vars.alloc; 279333965Sjdp for (; pv < pvend; pv++) 279433965Sjdp if (pv->namlen == mangledlen 279533965Sjdp && strncmp (pv->name, mangledname, mangledlen) == 0) 279633965Sjdp break; 279733965Sjdp if (pv < pvend) 279833965Sjdp ftype = pv->type; 279933965Sjdp else 280033965Sjdp { 280133965Sjdp /* This can happen if the variable is never used. */ 280233965Sjdp ftype = ieee_builtin_type (info, start, 280333965Sjdp (unsigned int) builtin_void); 280433965Sjdp } 280533965Sjdp } 280633965Sjdp else 280733965Sjdp { 280833965Sjdp unsigned int findx; 280933965Sjdp 281033965Sjdp if (structfields == NULL) 281133965Sjdp { 281260484Sobrien ieee_error (info, start, _("C++ object has no fields")); 281333965Sjdp return false; 281433965Sjdp } 281533965Sjdp 281633965Sjdp for (pf = structfields, findx = 0; 281733965Sjdp *pf != DEBUG_FIELD_NULL; 281833965Sjdp pf++, findx++) 281933965Sjdp { 282033965Sjdp const char *fname; 282133965Sjdp 282233965Sjdp fname = debug_get_field_name (dhandle, *pf); 282333965Sjdp if (fname == NULL) 282433965Sjdp return false; 282533965Sjdp if (fname[0] == mangledname[0] 282633965Sjdp && strncmp (fname, mangledname, mangledlen) == 0 282733965Sjdp && strlen (fname) == mangledlen) 282833965Sjdp break; 282933965Sjdp } 283033965Sjdp if (*pf == DEBUG_FIELD_NULL) 283133965Sjdp { 283233965Sjdp ieee_error (info, start, 283360484Sobrien _("C++ data member not found in container")); 283433965Sjdp return false; 283533965Sjdp } 283633965Sjdp 283733965Sjdp ftype = debug_get_field_type (dhandle, *pf); 283833965Sjdp 283933965Sjdp if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER) 284033965Sjdp { 284133965Sjdp /* We might need to convert this field into a 284233965Sjdp reference type later on, so make it an indirect 284333965Sjdp type. */ 284433965Sjdp if (it->fslots == NULL) 284533965Sjdp { 284633965Sjdp unsigned int fcnt; 284733965Sjdp const debug_field *pfcnt; 284833965Sjdp 284933965Sjdp fcnt = 0; 285033965Sjdp for (pfcnt = structfields; 285133965Sjdp *pfcnt != DEBUG_FIELD_NULL; 285233965Sjdp pfcnt++) 285333965Sjdp ++fcnt; 285433965Sjdp it->fslots = ((debug_type *) 285533965Sjdp xmalloc (fcnt * sizeof *it->fslots)); 285633965Sjdp memset (it->fslots, 0, 285733965Sjdp fcnt * sizeof *it->fslots); 285833965Sjdp } 285933965Sjdp 286033965Sjdp if (ftype == DEBUG_TYPE_NULL) 286133965Sjdp return false; 286233965Sjdp it->fslots[findx] = ftype; 286333965Sjdp ftype = debug_make_indirect_type (dhandle, 286433965Sjdp it->fslots + findx, 286533965Sjdp (const char *) NULL); 286633965Sjdp } 286733965Sjdp } 286833965Sjdp if (ftype == DEBUG_TYPE_NULL) 286933965Sjdp return false; 287033965Sjdp 287133965Sjdp switch (flags & CXXFLAGS_VISIBILITY) 287233965Sjdp { 287333965Sjdp default: 287460484Sobrien ieee_error (info, start, _("unknown C++ visibility")); 287533965Sjdp return false; 287633965Sjdp 287733965Sjdp case CXXFLAGS_VISIBILITY_PUBLIC: 287833965Sjdp visibility = DEBUG_VISIBILITY_PUBLIC; 287933965Sjdp break; 288033965Sjdp 288133965Sjdp case CXXFLAGS_VISIBILITY_PRIVATE: 288233965Sjdp visibility = DEBUG_VISIBILITY_PRIVATE; 288333965Sjdp break; 288433965Sjdp 288533965Sjdp case CXXFLAGS_VISIBILITY_PROTECTED: 288633965Sjdp visibility = DEBUG_VISIBILITY_PROTECTED; 288733965Sjdp break; 288833965Sjdp } 288933965Sjdp 289033965Sjdp if (staticp) 289133965Sjdp { 289233965Sjdp char *mangledcopy; 289333965Sjdp 289433965Sjdp mangledcopy = savestring (mangledname, mangledlen); 289533965Sjdp 289633965Sjdp field = debug_make_static_member (dhandle, fieldcopy, 289733965Sjdp ftype, mangledcopy, 289833965Sjdp visibility); 289933965Sjdp } 290033965Sjdp else 290133965Sjdp { 290233965Sjdp bfd_vma bitpos, bitsize; 290333965Sjdp 290433965Sjdp bitpos = debug_get_field_bitpos (dhandle, *pf); 290533965Sjdp bitsize = debug_get_field_bitsize (dhandle, *pf); 290633965Sjdp if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1) 290733965Sjdp { 290860484Sobrien ieee_error (info, start, _("bad C++ field bit pos or size")); 290933965Sjdp return false; 291033965Sjdp } 291133965Sjdp field = debug_make_field (dhandle, fieldcopy, ftype, bitpos, 291233965Sjdp bitsize, visibility); 291333965Sjdp } 291433965Sjdp 291533965Sjdp if (field == DEBUG_FIELD_NULL) 291633965Sjdp return false; 291733965Sjdp 291833965Sjdp if (field_count + 1 >= field_alloc) 291933965Sjdp { 292033965Sjdp field_alloc += 10; 292133965Sjdp fields = ((debug_field *) 292233965Sjdp xrealloc (fields, field_alloc * sizeof *fields)); 292333965Sjdp } 292433965Sjdp 292533965Sjdp fields[field_count] = field; 292633965Sjdp ++field_count; 292733965Sjdp fields[field_count] = DEBUG_FIELD_NULL; 292833965Sjdp } 292933965Sjdp break; 293033965Sjdp 293133965Sjdp case 'm': 293233965Sjdp case 'v': 293333965Sjdp { 293433965Sjdp bfd_vma flags, voffset, control; 293533965Sjdp const char *name, *mangled; 293633965Sjdp unsigned long namlen, mangledlen; 293733965Sjdp struct ieee_var *pv, *pvend; 293833965Sjdp debug_type type; 293933965Sjdp enum debug_visibility visibility; 294033965Sjdp boolean constp, volatilep; 294133965Sjdp char *mangledcopy; 294233965Sjdp debug_method_variant mv; 294333965Sjdp struct ieee_method *meth; 294433965Sjdp unsigned int im; 294533965Sjdp 294633965Sjdp if (! ieee_require_asn (info, pp, &flags) 294733965Sjdp || ! ieee_require_atn65 (info, pp, &name, &namlen) 294833965Sjdp || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) 294933965Sjdp return false; 295033965Sjdp count -= 3; 295133965Sjdp if (id != 'v') 295233965Sjdp voffset = 0; 295333965Sjdp else 295433965Sjdp { 295533965Sjdp if (! ieee_require_asn (info, pp, &voffset)) 295633965Sjdp return false; 295733965Sjdp --count; 295833965Sjdp } 295933965Sjdp if (! ieee_require_asn (info, pp, &control)) 296033965Sjdp return false; 296133965Sjdp --count; 296233965Sjdp 296333965Sjdp /* We just ignore the control information. */ 296433965Sjdp 296533965Sjdp /* We have no way to represent friend information, so we 296633965Sjdp just ignore it. */ 296733965Sjdp if ((flags & CXXFLAGS_FRIEND) != 0) 296833965Sjdp break; 296933965Sjdp 297033965Sjdp /* We should already have seen a type for the function. */ 297133965Sjdp pv = info->vars.vars; 297233965Sjdp pvend = pv + info->vars.alloc; 297333965Sjdp for (; pv < pvend; pv++) 297433965Sjdp if (pv->namlen == mangledlen 297533965Sjdp && strncmp (pv->name, mangled, mangledlen) == 0) 297633965Sjdp break; 297733965Sjdp 297833965Sjdp if (pv >= pvend) 297933965Sjdp { 298033965Sjdp /* We won't have type information for this function if 298133965Sjdp it is not included in this file. We don't try to 298233965Sjdp handle this case. FIXME. */ 298333965Sjdp type = (debug_make_function_type 298433965Sjdp (dhandle, 298533965Sjdp ieee_builtin_type (info, start, 298633965Sjdp (unsigned int) builtin_void), 298733965Sjdp (debug_type *) NULL, 298833965Sjdp false)); 298933965Sjdp } 299033965Sjdp else 299133965Sjdp { 299233965Sjdp debug_type return_type; 299333965Sjdp const debug_type *arg_types; 299433965Sjdp boolean varargs; 299533965Sjdp 299633965Sjdp if (debug_get_type_kind (dhandle, pv->type) 299733965Sjdp != DEBUG_KIND_FUNCTION) 299833965Sjdp { 299933965Sjdp ieee_error (info, start, 300060484Sobrien _("bad type for C++ method function")); 300133965Sjdp return false; 300233965Sjdp } 300333965Sjdp 300433965Sjdp return_type = debug_get_return_type (dhandle, pv->type); 300533965Sjdp arg_types = debug_get_parameter_types (dhandle, pv->type, 300633965Sjdp &varargs); 300733965Sjdp if (return_type == DEBUG_TYPE_NULL || arg_types == NULL) 300833965Sjdp { 300933965Sjdp ieee_error (info, start, 301060484Sobrien _("no type information for C++ method function")); 301133965Sjdp return false; 301233965Sjdp } 301333965Sjdp 301433965Sjdp type = debug_make_method_type (dhandle, return_type, it->type, 301533965Sjdp (debug_type *) arg_types, 301633965Sjdp varargs); 301733965Sjdp } 301833965Sjdp if (type == DEBUG_TYPE_NULL) 301933965Sjdp return false; 302033965Sjdp 302133965Sjdp switch (flags & CXXFLAGS_VISIBILITY) 302233965Sjdp { 302333965Sjdp default: 302460484Sobrien ieee_error (info, start, _("unknown C++ visibility")); 302533965Sjdp return false; 302633965Sjdp 302733965Sjdp case CXXFLAGS_VISIBILITY_PUBLIC: 302833965Sjdp visibility = DEBUG_VISIBILITY_PUBLIC; 302933965Sjdp break; 303033965Sjdp 303133965Sjdp case CXXFLAGS_VISIBILITY_PRIVATE: 303233965Sjdp visibility = DEBUG_VISIBILITY_PRIVATE; 303333965Sjdp break; 303433965Sjdp 303533965Sjdp case CXXFLAGS_VISIBILITY_PROTECTED: 303633965Sjdp visibility = DEBUG_VISIBILITY_PROTECTED; 303733965Sjdp break; 303833965Sjdp } 303933965Sjdp 304033965Sjdp constp = (flags & CXXFLAGS_CONST) != 0 ? true : false; 304133965Sjdp volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? true : false; 304233965Sjdp 304333965Sjdp mangledcopy = savestring (mangled, mangledlen); 304433965Sjdp 304533965Sjdp if ((flags & CXXFLAGS_STATIC) != 0) 304633965Sjdp { 304733965Sjdp if (id == 'v') 304833965Sjdp { 304960484Sobrien ieee_error (info, start, _("C++ static virtual method")); 305033965Sjdp return false; 305133965Sjdp } 305233965Sjdp mv = debug_make_static_method_variant (dhandle, mangledcopy, 305333965Sjdp type, visibility, 305433965Sjdp constp, volatilep); 305533965Sjdp } 305633965Sjdp else 305733965Sjdp { 305833965Sjdp debug_type vcontext; 305933965Sjdp 306033965Sjdp if (id != 'v') 306133965Sjdp vcontext = DEBUG_TYPE_NULL; 306233965Sjdp else 306333965Sjdp { 306433965Sjdp /* FIXME: How can we calculate this correctly? */ 306533965Sjdp vcontext = it->type; 306633965Sjdp } 306733965Sjdp mv = debug_make_method_variant (dhandle, mangledcopy, type, 306833965Sjdp visibility, constp, 306933965Sjdp volatilep, voffset, 307033965Sjdp vcontext); 307133965Sjdp } 307233965Sjdp if (mv == DEBUG_METHOD_VARIANT_NULL) 307333965Sjdp return false; 307433965Sjdp 307533965Sjdp for (meth = methods, im = 0; im < methods_count; meth++, im++) 307633965Sjdp if (meth->namlen == namlen 307733965Sjdp && strncmp (meth->name, name, namlen) == 0) 307833965Sjdp break; 307933965Sjdp if (im >= methods_count) 308033965Sjdp { 308133965Sjdp if (methods_count >= methods_alloc) 308233965Sjdp { 308333965Sjdp methods_alloc += 10; 308433965Sjdp methods = ((struct ieee_method *) 308533965Sjdp xrealloc (methods, 308633965Sjdp methods_alloc * sizeof *methods)); 308733965Sjdp } 308833965Sjdp methods[methods_count].name = name; 308933965Sjdp methods[methods_count].namlen = namlen; 309033965Sjdp methods[methods_count].variants = NULL; 309133965Sjdp methods[methods_count].count = 0; 309233965Sjdp methods[methods_count].alloc = 0; 309333965Sjdp meth = methods + methods_count; 309433965Sjdp ++methods_count; 309533965Sjdp } 309633965Sjdp 309733965Sjdp if (meth->count + 1 >= meth->alloc) 309833965Sjdp { 309933965Sjdp meth->alloc += 10; 310033965Sjdp meth->variants = ((debug_method_variant *) 310133965Sjdp xrealloc (meth->variants, 310233965Sjdp (meth->alloc 310333965Sjdp * sizeof *meth->variants))); 310433965Sjdp } 310533965Sjdp 310633965Sjdp meth->variants[meth->count] = mv; 310733965Sjdp ++meth->count; 310833965Sjdp meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL; 310933965Sjdp } 311033965Sjdp break; 311133965Sjdp 311233965Sjdp case 'o': 311333965Sjdp { 311433965Sjdp bfd_vma spec; 311533965Sjdp 311633965Sjdp /* We have no way to store this information, so we just 311733965Sjdp ignore it. */ 311833965Sjdp if (! ieee_require_asn (info, pp, &spec)) 311933965Sjdp return false; 312033965Sjdp --count; 312133965Sjdp if ((spec & 4) != 0) 312233965Sjdp { 312333965Sjdp const char *filename; 312433965Sjdp unsigned long filenamlen; 312533965Sjdp bfd_vma lineno; 312633965Sjdp 312733965Sjdp if (! ieee_require_atn65 (info, pp, &filename, &filenamlen) 312833965Sjdp || ! ieee_require_asn (info, pp, &lineno)) 312933965Sjdp return false; 313033965Sjdp count -= 2; 313133965Sjdp } 313233965Sjdp else if ((spec & 8) != 0) 313333965Sjdp { 313433965Sjdp const char *mangled; 313533965Sjdp unsigned long mangledlen; 313633965Sjdp 313733965Sjdp if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen)) 313833965Sjdp return false; 313933965Sjdp --count; 314033965Sjdp } 314133965Sjdp else 314233965Sjdp { 314333965Sjdp ieee_error (info, start, 314460484Sobrien _("unrecognized C++ object overhead spec")); 314533965Sjdp return false; 314633965Sjdp } 314733965Sjdp } 314833965Sjdp break; 314933965Sjdp 315033965Sjdp case 'z': 315133965Sjdp { 315233965Sjdp const char *vname, *basename; 315333965Sjdp unsigned long vnamelen, baselen; 315433965Sjdp bfd_vma vsize, control; 315533965Sjdp 315633965Sjdp /* A virtual table pointer. */ 315733965Sjdp 315833965Sjdp if (! ieee_require_atn65 (info, pp, &vname, &vnamelen) 315933965Sjdp || ! ieee_require_asn (info, pp, &vsize) 316033965Sjdp || ! ieee_require_atn65 (info, pp, &basename, &baselen) 316133965Sjdp || ! ieee_require_asn (info, pp, &control)) 316233965Sjdp return false; 316333965Sjdp count -= 4; 316433965Sjdp 316533965Sjdp /* We just ignore the control number. We don't care what 316633965Sjdp the virtual table name is. We have no way to store the 316733965Sjdp virtual table size, and I don't think we care anyhow. */ 316833965Sjdp 316933965Sjdp /* FIXME: We can't handle multiple virtual table pointers. */ 317033965Sjdp 317133965Sjdp if (baselen == 0) 317233965Sjdp ownvptr = true; 317333965Sjdp else 317433965Sjdp { 317533965Sjdp char *basecopy; 317633965Sjdp 317733965Sjdp basecopy = savestring (basename, baselen); 317833965Sjdp vptrbase = debug_find_tagged_type (dhandle, basecopy, 317933965Sjdp DEBUG_KIND_ILLEGAL); 318033965Sjdp free (basecopy); 318133965Sjdp if (vptrbase == DEBUG_TYPE_NULL) 318233965Sjdp { 318360484Sobrien ieee_error (info, start, _("undefined C++ vtable")); 318433965Sjdp return false; 318533965Sjdp } 318633965Sjdp } 318733965Sjdp } 318833965Sjdp break; 318933965Sjdp } 319033965Sjdp } 319133965Sjdp 319233965Sjdp /* Now that we have seen all the method variants, we can call 319333965Sjdp debug_make_method for each one. */ 319433965Sjdp 319533965Sjdp if (methods_count == 0) 319633965Sjdp dmethods = NULL; 319733965Sjdp else 319833965Sjdp { 319933965Sjdp unsigned int i; 320033965Sjdp 320133965Sjdp dmethods = ((debug_method *) 320233965Sjdp xmalloc ((methods_count + 1) * sizeof *dmethods)); 320333965Sjdp for (i = 0; i < methods_count; i++) 320433965Sjdp { 320533965Sjdp char *namcopy; 320633965Sjdp 320733965Sjdp namcopy = savestring (methods[i].name, methods[i].namlen); 320833965Sjdp dmethods[i] = debug_make_method (dhandle, namcopy, 320933965Sjdp methods[i].variants); 321033965Sjdp if (dmethods[i] == DEBUG_METHOD_NULL) 321133965Sjdp return false; 321233965Sjdp } 321333965Sjdp dmethods[i] = DEBUG_METHOD_NULL; 321433965Sjdp free (methods); 321533965Sjdp } 321633965Sjdp 321733965Sjdp /* The struct type was created as an indirect type pointing at 321833965Sjdp it->slot. We update it->slot to automatically update all 321933965Sjdp references to this struct. */ 322033965Sjdp it->slot = debug_make_object_type (dhandle, 322133965Sjdp class != 'u', 322233965Sjdp debug_get_type_size (dhandle, 322333965Sjdp it->slot), 322433965Sjdp fields, baseclasses, dmethods, 322533965Sjdp vptrbase, ownvptr); 322633965Sjdp if (it->slot == DEBUG_TYPE_NULL) 322733965Sjdp return false; 322833965Sjdp 322933965Sjdp return true; 323033965Sjdp} 323133965Sjdp 323233965Sjdp/* Read C++ default argument value and reference type information. */ 323333965Sjdp 323433965Sjdpstatic boolean 323533965Sjdpieee_read_cxx_defaults (info, pp, count) 323633965Sjdp struct ieee_info *info; 323733965Sjdp const bfd_byte **pp; 323833965Sjdp unsigned long count; 323933965Sjdp{ 324033965Sjdp const bfd_byte *start; 324133965Sjdp const char *fnname; 324233965Sjdp unsigned long fnlen; 324333965Sjdp bfd_vma defcount; 324433965Sjdp 324533965Sjdp start = *pp; 324633965Sjdp 324733965Sjdp /* Giving the function name before the argument count is an addendum 324833965Sjdp to the spec. The function name is demangled, though, so this 324933965Sjdp record must always refer to the current function. */ 325033965Sjdp 325133965Sjdp if (info->blockstack.bsp <= info->blockstack.stack 325233965Sjdp || info->blockstack.bsp[-1].fnindx == (unsigned int) -1) 325333965Sjdp { 325460484Sobrien ieee_error (info, start, _("C++ default values not in a function")); 325533965Sjdp return false; 325633965Sjdp } 325733965Sjdp 325833965Sjdp if (! ieee_require_atn65 (info, pp, &fnname, &fnlen) 325933965Sjdp || ! ieee_require_asn (info, pp, &defcount)) 326033965Sjdp return false; 326133965Sjdp count -= 2; 326233965Sjdp 326333965Sjdp while (defcount-- > 0) 326433965Sjdp { 326533965Sjdp bfd_vma type, val; 326633965Sjdp const char *strval; 326733965Sjdp unsigned long strvallen; 326833965Sjdp 326933965Sjdp if (! ieee_require_asn (info, pp, &type)) 327033965Sjdp return false; 327133965Sjdp --count; 327233965Sjdp 327333965Sjdp switch (type) 327433965Sjdp { 327533965Sjdp case 0: 327633965Sjdp case 4: 327733965Sjdp break; 327833965Sjdp 327933965Sjdp case 1: 328033965Sjdp case 2: 328133965Sjdp if (! ieee_require_asn (info, pp, &val)) 328233965Sjdp return false; 328333965Sjdp --count; 328433965Sjdp break; 328533965Sjdp 328633965Sjdp case 3: 328733965Sjdp case 7: 328833965Sjdp if (! ieee_require_atn65 (info, pp, &strval, &strvallen)) 328933965Sjdp return false; 329033965Sjdp --count; 329133965Sjdp break; 329233965Sjdp 329333965Sjdp default: 329460484Sobrien ieee_error (info, start, _("unrecognized C++ default type")); 329533965Sjdp return false; 329633965Sjdp } 329733965Sjdp 329833965Sjdp /* We have no way to record the default argument values, so we 329933965Sjdp just ignore them. FIXME. */ 330033965Sjdp } 330133965Sjdp 330233965Sjdp /* Any remaining arguments are indices of parameters that are really 330333965Sjdp reference type. */ 330433965Sjdp if (count > 0) 330533965Sjdp { 330633965Sjdp PTR dhandle; 330733965Sjdp debug_type *arg_slots; 330833965Sjdp 330933965Sjdp dhandle = info->dhandle; 331033965Sjdp arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots; 331133965Sjdp while (count-- > 0) 331233965Sjdp { 331333965Sjdp bfd_vma indx; 331433965Sjdp debug_type target; 331533965Sjdp 331633965Sjdp if (! ieee_require_asn (info, pp, &indx)) 331733965Sjdp return false; 331833965Sjdp /* The index is 1 based. */ 331933965Sjdp --indx; 332033965Sjdp if (arg_slots == NULL 332133965Sjdp || arg_slots[indx] == DEBUG_TYPE_NULL 332233965Sjdp || (debug_get_type_kind (dhandle, arg_slots[indx]) 332333965Sjdp != DEBUG_KIND_POINTER)) 332433965Sjdp { 332560484Sobrien ieee_error (info, start, _("reference parameter is not a pointer")); 332633965Sjdp return false; 332733965Sjdp } 332833965Sjdp 332933965Sjdp target = debug_get_target_type (dhandle, arg_slots[indx]); 333033965Sjdp arg_slots[indx] = debug_make_reference_type (dhandle, target); 333133965Sjdp if (arg_slots[indx] == DEBUG_TYPE_NULL) 333233965Sjdp return false; 333333965Sjdp } 333433965Sjdp } 333533965Sjdp 333633965Sjdp return true; 333733965Sjdp} 333833965Sjdp 333933965Sjdp/* Read a C++ reference definition. */ 334033965Sjdp 334133965Sjdpstatic boolean 334233965Sjdpieee_read_reference (info, pp) 334333965Sjdp struct ieee_info *info; 334433965Sjdp const bfd_byte **pp; 334533965Sjdp{ 334633965Sjdp const bfd_byte *start; 334733965Sjdp bfd_vma flags; 334833965Sjdp const char *class, *name; 334933965Sjdp unsigned long classlen, namlen; 335033965Sjdp debug_type *pslot; 335133965Sjdp debug_type target; 335233965Sjdp 335333965Sjdp start = *pp; 335433965Sjdp 335533965Sjdp if (! ieee_require_asn (info, pp, &flags)) 335633965Sjdp return false; 335733965Sjdp 335833965Sjdp /* Giving the class name before the member name is in an addendum to 335933965Sjdp the spec. */ 336033965Sjdp if (flags == 3) 336133965Sjdp { 336233965Sjdp if (! ieee_require_atn65 (info, pp, &class, &classlen)) 336333965Sjdp return false; 336433965Sjdp } 336533965Sjdp 336633965Sjdp if (! ieee_require_atn65 (info, pp, &name, &namlen)) 336733965Sjdp return false; 336833965Sjdp 336933965Sjdp pslot = NULL; 337033965Sjdp if (flags != 3) 337133965Sjdp { 337233965Sjdp int pass; 337333965Sjdp 337433965Sjdp /* We search from the last variable indices to the first in 337533965Sjdp hopes of finding local variables correctly. We search the 337633965Sjdp local variables on the first pass, and the global variables 337733965Sjdp on the second. FIXME: This probably won't work in all cases. 337833965Sjdp On the other hand, I don't know what will. */ 337933965Sjdp for (pass = 0; pass < 2; pass++) 338033965Sjdp { 338133965Sjdp struct ieee_vars *vars; 338233965Sjdp int i; 338333965Sjdp struct ieee_var *pv = NULL; 338433965Sjdp 338533965Sjdp if (pass == 0) 338633965Sjdp vars = &info->vars; 338733965Sjdp else 338833965Sjdp { 338933965Sjdp vars = info->global_vars; 339033965Sjdp if (vars == NULL) 339133965Sjdp break; 339233965Sjdp } 339333965Sjdp 339433965Sjdp for (i = (int) vars->alloc - 1; i >= 0; i--) 339533965Sjdp { 339633965Sjdp boolean found; 339733965Sjdp 339833965Sjdp pv = vars->vars + i; 339933965Sjdp 340033965Sjdp if (pv->pslot == NULL 340133965Sjdp || pv->namlen != namlen 340233965Sjdp || strncmp (pv->name, name, namlen) != 0) 340333965Sjdp continue; 340433965Sjdp 340533965Sjdp found = false; 340633965Sjdp switch (flags) 340733965Sjdp { 340833965Sjdp default: 340933965Sjdp ieee_error (info, start, 341060484Sobrien _("unrecognized C++ reference type")); 341133965Sjdp return false; 341233965Sjdp 341333965Sjdp case 0: 341433965Sjdp /* Global variable or function. */ 341533965Sjdp if (pv->kind == IEEE_GLOBAL 341633965Sjdp || pv->kind == IEEE_EXTERNAL 341733965Sjdp || pv->kind == IEEE_FUNCTION) 341833965Sjdp found = true; 341933965Sjdp break; 342033965Sjdp 342133965Sjdp case 1: 342233965Sjdp /* Global static variable or function. */ 342333965Sjdp if (pv->kind == IEEE_STATIC 342433965Sjdp || pv->kind == IEEE_FUNCTION) 342533965Sjdp found = true; 342633965Sjdp break; 342733965Sjdp 342833965Sjdp case 2: 342933965Sjdp /* Local variable. */ 343033965Sjdp if (pv->kind == IEEE_LOCAL) 343133965Sjdp found = true; 343233965Sjdp break; 343333965Sjdp } 343433965Sjdp 343533965Sjdp if (found) 343633965Sjdp break; 343733965Sjdp } 343833965Sjdp 343933965Sjdp if (i >= 0) 344033965Sjdp { 344133965Sjdp pslot = pv->pslot; 344233965Sjdp break; 344333965Sjdp } 344433965Sjdp } 344533965Sjdp } 344633965Sjdp else 344733965Sjdp { 344833965Sjdp struct ieee_tag *it; 344933965Sjdp 345033965Sjdp for (it = info->tags; it != NULL; it = it->next) 345133965Sjdp { 345233965Sjdp if (it->name[0] == class[0] 345333965Sjdp && strncmp (it->name, class, classlen) == 0 345433965Sjdp && strlen (it->name) == classlen) 345533965Sjdp { 345633965Sjdp if (it->fslots != NULL) 345733965Sjdp { 345833965Sjdp const debug_field *pf; 345933965Sjdp unsigned int findx; 346033965Sjdp 346133965Sjdp pf = debug_get_fields (info->dhandle, it->type); 346233965Sjdp if (pf == NULL) 346333965Sjdp { 346433965Sjdp ieee_error (info, start, 346533965Sjdp "C++ reference in class with no fields"); 346633965Sjdp return false; 346733965Sjdp } 346833965Sjdp 346933965Sjdp for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++) 347033965Sjdp { 347133965Sjdp const char *fname; 347233965Sjdp 347333965Sjdp fname = debug_get_field_name (info->dhandle, *pf); 347433965Sjdp if (fname == NULL) 347533965Sjdp return false; 347633965Sjdp if (strncmp (fname, name, namlen) == 0 347733965Sjdp && strlen (fname) == namlen) 347833965Sjdp { 347933965Sjdp pslot = it->fslots + findx; 348033965Sjdp break; 348133965Sjdp } 348233965Sjdp } 348333965Sjdp } 348433965Sjdp 348533965Sjdp break; 348633965Sjdp } 348733965Sjdp } 348833965Sjdp } 348933965Sjdp 349033965Sjdp if (pslot == NULL) 349133965Sjdp { 349260484Sobrien ieee_error (info, start, _("C++ reference not found")); 349333965Sjdp return false; 349433965Sjdp } 349533965Sjdp 349633965Sjdp /* We allocated the type of the object as an indirect type pointing 349733965Sjdp to *pslot, which we can now update to be a reference type. */ 349833965Sjdp if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER) 349933965Sjdp { 350060484Sobrien ieee_error (info, start, _("C++ reference is not pointer")); 350133965Sjdp return false; 350233965Sjdp } 350333965Sjdp 350433965Sjdp target = debug_get_target_type (info->dhandle, *pslot); 350533965Sjdp *pslot = debug_make_reference_type (info->dhandle, target); 350633965Sjdp if (*pslot == DEBUG_TYPE_NULL) 350733965Sjdp return false; 350833965Sjdp 350933965Sjdp return true; 351033965Sjdp} 351133965Sjdp 351233965Sjdp/* Require an ASN record. */ 351333965Sjdp 351433965Sjdpstatic boolean 351533965Sjdpieee_require_asn (info, pp, pv) 351633965Sjdp struct ieee_info *info; 351733965Sjdp const bfd_byte **pp; 351833965Sjdp bfd_vma *pv; 351933965Sjdp{ 352033965Sjdp const bfd_byte *start; 352133965Sjdp ieee_record_enum_type c; 352233965Sjdp bfd_vma varindx; 352333965Sjdp 352433965Sjdp start = *pp; 352533965Sjdp 352633965Sjdp c = (ieee_record_enum_type) **pp; 352733965Sjdp if (c != ieee_e2_first_byte_enum) 352833965Sjdp { 352960484Sobrien ieee_error (info, start, _("missing required ASN")); 353033965Sjdp return false; 353133965Sjdp } 353233965Sjdp ++*pp; 353333965Sjdp 353433965Sjdp c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); 353533965Sjdp if (c != ieee_asn_record_enum) 353633965Sjdp { 353760484Sobrien ieee_error (info, start, _("missing required ASN")); 353833965Sjdp return false; 353933965Sjdp } 354033965Sjdp ++*pp; 354133965Sjdp 354233965Sjdp /* Just ignore the variable index. */ 354333965Sjdp if (! ieee_read_number (info, pp, &varindx)) 354433965Sjdp return false; 354533965Sjdp 354633965Sjdp return ieee_read_expression (info, pp, pv); 354733965Sjdp} 354833965Sjdp 354933965Sjdp/* Require an ATN65 record. */ 355033965Sjdp 355133965Sjdpstatic boolean 355233965Sjdpieee_require_atn65 (info, pp, pname, pnamlen) 355333965Sjdp struct ieee_info *info; 355433965Sjdp const bfd_byte **pp; 355533965Sjdp const char **pname; 355633965Sjdp unsigned long *pnamlen; 355733965Sjdp{ 355833965Sjdp const bfd_byte *start; 355933965Sjdp ieee_record_enum_type c; 356033965Sjdp bfd_vma name_indx, type_indx, atn_code; 356133965Sjdp 356233965Sjdp start = *pp; 356333965Sjdp 356433965Sjdp c = (ieee_record_enum_type) **pp; 356533965Sjdp if (c != ieee_at_record_enum) 356633965Sjdp { 356760484Sobrien ieee_error (info, start, _("missing required ATN65")); 356833965Sjdp return false; 356933965Sjdp } 357033965Sjdp ++*pp; 357133965Sjdp 357233965Sjdp c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp); 357333965Sjdp if (c != ieee_atn_record_enum) 357433965Sjdp { 357560484Sobrien ieee_error (info, start, _("missing required ATN65")); 357633965Sjdp return false; 357733965Sjdp } 357833965Sjdp ++*pp; 357933965Sjdp 358033965Sjdp if (! ieee_read_number (info, pp, &name_indx) 358133965Sjdp || ! ieee_read_number (info, pp, &type_indx) 358233965Sjdp || ! ieee_read_number (info, pp, &atn_code)) 358333965Sjdp return false; 358433965Sjdp 358533965Sjdp /* Just ignore name_indx. */ 358633965Sjdp 358733965Sjdp if (type_indx != 0 || atn_code != 65) 358833965Sjdp { 358960484Sobrien ieee_error (info, start, _("bad ATN65 record")); 359033965Sjdp return false; 359133965Sjdp } 359233965Sjdp 359333965Sjdp return ieee_read_id (info, pp, pname, pnamlen); 359433965Sjdp} 359533965Sjdp 359633965Sjdp/* Convert a register number in IEEE debugging information into a 359733965Sjdp generic register number. */ 359833965Sjdp 359933965Sjdpstatic int 360033965Sjdpieee_regno_to_genreg (abfd, r) 360133965Sjdp bfd *abfd; 360233965Sjdp int r; 360333965Sjdp{ 360433965Sjdp switch (bfd_get_arch (abfd)) 360533965Sjdp { 360633965Sjdp case bfd_arch_m68k: 360733965Sjdp /* For some reasons stabs adds 2 to the floating point register 360833965Sjdp numbers. */ 360933965Sjdp if (r >= 16) 361033965Sjdp r += 2; 361133965Sjdp break; 361233965Sjdp 361333965Sjdp case bfd_arch_i960: 361433965Sjdp /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and 361533965Sjdp 32 to 35 for fp0 to fp3. */ 361633965Sjdp --r; 361733965Sjdp break; 361833965Sjdp 361933965Sjdp default: 362033965Sjdp break; 362133965Sjdp } 362233965Sjdp 362333965Sjdp return r; 362433965Sjdp} 362533965Sjdp 362633965Sjdp/* Convert a generic register number to an IEEE specific one. */ 362733965Sjdp 362833965Sjdpstatic int 362933965Sjdpieee_genreg_to_regno (abfd, r) 363033965Sjdp bfd *abfd; 363133965Sjdp int r; 363233965Sjdp{ 363333965Sjdp switch (bfd_get_arch (abfd)) 363433965Sjdp { 363533965Sjdp case bfd_arch_m68k: 363633965Sjdp /* For some reason stabs add 2 to the floating point register 363733965Sjdp numbers. */ 363833965Sjdp if (r >= 18) 363933965Sjdp r -= 2; 364033965Sjdp break; 364133965Sjdp 364233965Sjdp case bfd_arch_i960: 364333965Sjdp /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and 364433965Sjdp 32 to 35 for fp0 to fp3. */ 364533965Sjdp ++r; 364633965Sjdp break; 364733965Sjdp 364833965Sjdp default: 364933965Sjdp break; 365033965Sjdp } 365133965Sjdp 365233965Sjdp return r; 365333965Sjdp} 365433965Sjdp 365533965Sjdp/* These routines build IEEE debugging information out of the generic 365633965Sjdp debugging information. */ 365733965Sjdp 365833965Sjdp/* We build the IEEE debugging information byte by byte. Rather than 365933965Sjdp waste time copying data around, we use a linked list of buffers to 366033965Sjdp hold the data. */ 366133965Sjdp 366233965Sjdp#define IEEE_BUFSIZE (490) 366333965Sjdp 366433965Sjdpstruct ieee_buf 366533965Sjdp{ 366633965Sjdp /* Next buffer. */ 366733965Sjdp struct ieee_buf *next; 366833965Sjdp /* Number of data bytes in this buffer. */ 366933965Sjdp unsigned int c; 367033965Sjdp /* Bytes. */ 367133965Sjdp bfd_byte buf[IEEE_BUFSIZE]; 367233965Sjdp}; 367333965Sjdp 367433965Sjdp/* A list of buffers. */ 367533965Sjdp 367633965Sjdpstruct ieee_buflist 367733965Sjdp{ 367833965Sjdp /* Head of list. */ 367933965Sjdp struct ieee_buf *head; 368033965Sjdp /* Tail--last buffer on list. */ 368133965Sjdp struct ieee_buf *tail; 368233965Sjdp}; 368333965Sjdp 368433965Sjdp/* In order to generate the BB11 blocks required by the HP emulator, 368533965Sjdp we keep track of ranges of addresses which correspond to a given 368633965Sjdp compilation unit. */ 368733965Sjdp 368833965Sjdpstruct ieee_range 368933965Sjdp{ 369033965Sjdp /* Next range. */ 369133965Sjdp struct ieee_range *next; 369233965Sjdp /* Low address. */ 369333965Sjdp bfd_vma low; 369433965Sjdp /* High address. */ 369533965Sjdp bfd_vma high; 369633965Sjdp}; 369733965Sjdp 369833965Sjdp/* This structure holds information for a class on the type stack. */ 369933965Sjdp 370033965Sjdpstruct ieee_type_class 370133965Sjdp{ 370233965Sjdp /* The name index in the debugging information. */ 370333965Sjdp unsigned int indx; 370433965Sjdp /* The pmisc records for the class. */ 370533965Sjdp struct ieee_buflist pmiscbuf; 370633965Sjdp /* The number of pmisc records. */ 370733965Sjdp unsigned int pmisccount; 370833965Sjdp /* The name of the class holding the virtual table, if not this 370933965Sjdp class. */ 371033965Sjdp const char *vclass; 371133965Sjdp /* Whether this class holds its own virtual table. */ 371233965Sjdp boolean ownvptr; 371333965Sjdp /* The largest virtual table offset seen so far. */ 371433965Sjdp bfd_vma voffset; 371533965Sjdp /* The current method. */ 371633965Sjdp const char *method; 371733965Sjdp /* Additional pmisc records used to record fields of reference type. */ 371833965Sjdp struct ieee_buflist refs; 371933965Sjdp}; 372033965Sjdp 372133965Sjdp/* This is how we store types for the writing routines. Most types 372233965Sjdp are simply represented by a type index. */ 372333965Sjdp 372433965Sjdpstruct ieee_write_type 372533965Sjdp{ 372633965Sjdp /* Type index. */ 372733965Sjdp unsigned int indx; 372833965Sjdp /* The size of the type, if known. */ 372933965Sjdp unsigned int size; 373033965Sjdp /* The name of the type, if any. */ 373133965Sjdp const char *name; 373233965Sjdp /* If this is a function or method type, we build the type here, and 373333965Sjdp only add it to the output buffers if we need it. */ 373433965Sjdp struct ieee_buflist fndef; 373533965Sjdp /* If this is a struct, this is where the struct definition is 373633965Sjdp built. */ 373733965Sjdp struct ieee_buflist strdef; 373833965Sjdp /* If this is a class, this is where the class information is built. */ 373933965Sjdp struct ieee_type_class *classdef; 374033965Sjdp /* Whether the type is unsigned. */ 374133965Sjdp unsigned int unsignedp : 1; 374233965Sjdp /* Whether this is a reference type. */ 374333965Sjdp unsigned int referencep : 1; 374433965Sjdp /* Whether this is in the local type block. */ 374533965Sjdp unsigned int localp : 1; 374633965Sjdp /* Whether this is a duplicate struct definition which we are 374733965Sjdp ignoring. */ 374833965Sjdp unsigned int ignorep : 1; 374933965Sjdp}; 375033965Sjdp 375133965Sjdp/* This is the type stack used by the debug writing routines. FIXME: 375233965Sjdp We could generate more efficient output if we remembered when we 375333965Sjdp have output a particular type before. */ 375433965Sjdp 375533965Sjdpstruct ieee_type_stack 375633965Sjdp{ 375733965Sjdp /* Next entry on stack. */ 375833965Sjdp struct ieee_type_stack *next; 375933965Sjdp /* Type information. */ 376033965Sjdp struct ieee_write_type type; 376133965Sjdp}; 376233965Sjdp 376333965Sjdp/* This is a list of associations between a name and some types. 376433965Sjdp These are used for typedefs and tags. */ 376533965Sjdp 376633965Sjdpstruct ieee_name_type 376733965Sjdp{ 376833965Sjdp /* Next type for this name. */ 376933965Sjdp struct ieee_name_type *next; 377033965Sjdp /* ID number. For a typedef, this is the index of the type to which 377133965Sjdp this name is typedefed. */ 377233965Sjdp unsigned int id; 377333965Sjdp /* Type. */ 377433965Sjdp struct ieee_write_type type; 377533965Sjdp /* If this is a tag which has not yet been defined, this is the 377633965Sjdp kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */ 377733965Sjdp enum debug_type_kind kind; 377833965Sjdp}; 377933965Sjdp 378033965Sjdp/* We use a hash table to associate names and types. */ 378133965Sjdp 378233965Sjdpstruct ieee_name_type_hash_table 378333965Sjdp{ 378433965Sjdp struct bfd_hash_table root; 378533965Sjdp}; 378633965Sjdp 378733965Sjdpstruct ieee_name_type_hash_entry 378833965Sjdp{ 378933965Sjdp struct bfd_hash_entry root; 379033965Sjdp /* Information for this name. */ 379133965Sjdp struct ieee_name_type *types; 379233965Sjdp}; 379333965Sjdp 379433965Sjdp/* This is a list of enums. */ 379533965Sjdp 379633965Sjdpstruct ieee_defined_enum 379733965Sjdp{ 379833965Sjdp /* Next enum. */ 379933965Sjdp struct ieee_defined_enum *next; 380033965Sjdp /* Type index. */ 380133965Sjdp unsigned int indx; 380233965Sjdp /* Whether this enum has been defined. */ 380333965Sjdp boolean defined; 380433965Sjdp /* Tag. */ 380533965Sjdp const char *tag; 380633965Sjdp /* Names. */ 380733965Sjdp const char **names; 380833965Sjdp /* Values. */ 380933965Sjdp bfd_signed_vma *vals; 381033965Sjdp}; 381133965Sjdp 381233965Sjdp/* We keep a list of modified versions of types, so that we don't 381333965Sjdp output them more than once. */ 381433965Sjdp 381533965Sjdpstruct ieee_modified_type 381633965Sjdp{ 381733965Sjdp /* Pointer to this type. */ 381833965Sjdp unsigned int pointer; 381933965Sjdp /* Function with unknown arguments returning this type. */ 382033965Sjdp unsigned int function; 382133965Sjdp /* Const version of this type. */ 382233965Sjdp unsigned int const_qualified; 382333965Sjdp /* Volatile version of this type. */ 382433965Sjdp unsigned int volatile_qualified; 382533965Sjdp /* List of arrays of this type of various bounds. */ 382633965Sjdp struct ieee_modified_array_type *arrays; 382733965Sjdp}; 382833965Sjdp 382933965Sjdp/* A list of arrays bounds. */ 383033965Sjdp 383133965Sjdpstruct ieee_modified_array_type 383233965Sjdp{ 383333965Sjdp /* Next array bounds. */ 383433965Sjdp struct ieee_modified_array_type *next; 383533965Sjdp /* Type index with these bounds. */ 383633965Sjdp unsigned int indx; 383733965Sjdp /* Low bound. */ 383833965Sjdp bfd_signed_vma low; 383933965Sjdp /* High bound. */ 384033965Sjdp bfd_signed_vma high; 384133965Sjdp}; 384233965Sjdp 384333965Sjdp/* This is a list of pending function parameter information. We don't 384433965Sjdp output them until we see the first block. */ 384533965Sjdp 384633965Sjdpstruct ieee_pending_parm 384733965Sjdp{ 384833965Sjdp /* Next pending parameter. */ 384933965Sjdp struct ieee_pending_parm *next; 385033965Sjdp /* Name. */ 385133965Sjdp const char *name; 385233965Sjdp /* Type index. */ 385333965Sjdp unsigned int type; 385433965Sjdp /* Whether the type is a reference. */ 385533965Sjdp boolean referencep; 385633965Sjdp /* Kind. */ 385733965Sjdp enum debug_parm_kind kind; 385833965Sjdp /* Value. */ 385933965Sjdp bfd_vma val; 386033965Sjdp}; 386133965Sjdp 386233965Sjdp/* This is the handle passed down by debug_write. */ 386333965Sjdp 386433965Sjdpstruct ieee_handle 386533965Sjdp{ 386633965Sjdp /* BFD we are writing to. */ 386733965Sjdp bfd *abfd; 386833965Sjdp /* Whether we got an error in a subroutine called via traverse or 386933965Sjdp map_over_sections. */ 387033965Sjdp boolean error; 387133965Sjdp /* Current data buffer list. */ 387233965Sjdp struct ieee_buflist *current; 387333965Sjdp /* Current data buffer. */ 387433965Sjdp struct ieee_buf *curbuf; 387533965Sjdp /* Filename of current compilation unit. */ 387633965Sjdp const char *filename; 387733965Sjdp /* Module name of current compilation unit. */ 387833965Sjdp const char *modname; 387933965Sjdp /* List of buffer for global types. */ 388033965Sjdp struct ieee_buflist global_types; 388133965Sjdp /* List of finished data buffers. */ 388233965Sjdp struct ieee_buflist data; 388333965Sjdp /* List of buffers for typedefs in the current compilation unit. */ 388433965Sjdp struct ieee_buflist types; 388533965Sjdp /* List of buffers for variables and functions in the current 388633965Sjdp compilation unit. */ 388733965Sjdp struct ieee_buflist vars; 388833965Sjdp /* List of buffers for C++ class definitions in the current 388933965Sjdp compilation unit. */ 389033965Sjdp struct ieee_buflist cxx; 389133965Sjdp /* List of buffers for line numbers in the current compilation unit. */ 389233965Sjdp struct ieee_buflist linenos; 389333965Sjdp /* Ranges for the current compilation unit. */ 389433965Sjdp struct ieee_range *ranges; 389533965Sjdp /* Ranges for all debugging information. */ 389633965Sjdp struct ieee_range *global_ranges; 389733965Sjdp /* Nested pending ranges. */ 389833965Sjdp struct ieee_range *pending_ranges; 389933965Sjdp /* Type stack. */ 390033965Sjdp struct ieee_type_stack *type_stack; 390133965Sjdp /* Next unallocated type index. */ 390233965Sjdp unsigned int type_indx; 390333965Sjdp /* Next unallocated name index. */ 390433965Sjdp unsigned int name_indx; 390533965Sjdp /* Typedefs. */ 390633965Sjdp struct ieee_name_type_hash_table typedefs; 390733965Sjdp /* Tags. */ 390833965Sjdp struct ieee_name_type_hash_table tags; 390933965Sjdp /* Enums. */ 391033965Sjdp struct ieee_defined_enum *enums; 391133965Sjdp /* Modified versions of types. */ 391233965Sjdp struct ieee_modified_type *modified; 391333965Sjdp /* Number of entries allocated in modified. */ 391433965Sjdp unsigned int modified_alloc; 391533965Sjdp /* 4 byte complex type. */ 391633965Sjdp unsigned int complex_float_index; 391733965Sjdp /* 8 byte complex type. */ 391833965Sjdp unsigned int complex_double_index; 391933965Sjdp /* The depth of block nesting. This is 0 outside a function, and 1 392033965Sjdp just after start_function is called. */ 392133965Sjdp unsigned int block_depth; 392233965Sjdp /* The name of the current function. */ 392333965Sjdp const char *fnname; 392433965Sjdp /* List of buffers for the type of the function we are currently 392533965Sjdp writing out. */ 392633965Sjdp struct ieee_buflist fntype; 392733965Sjdp /* List of buffers for the parameters of the function we are 392833965Sjdp currently writing out. */ 392933965Sjdp struct ieee_buflist fnargs; 393033965Sjdp /* Number of arguments written to fnargs. */ 393133965Sjdp unsigned int fnargcount; 393233965Sjdp /* Pending function parameters. */ 393333965Sjdp struct ieee_pending_parm *pending_parms; 393433965Sjdp /* Current line number filename. */ 393533965Sjdp const char *lineno_filename; 393633965Sjdp /* Line number name index. */ 393733965Sjdp unsigned int lineno_name_indx; 393833965Sjdp /* Filename of pending line number. */ 393933965Sjdp const char *pending_lineno_filename; 394033965Sjdp /* Pending line number. */ 394133965Sjdp unsigned long pending_lineno; 394233965Sjdp /* Address of pending line number. */ 394333965Sjdp bfd_vma pending_lineno_addr; 394433965Sjdp /* Highest address seen at end of procedure. */ 394533965Sjdp bfd_vma highaddr; 394633965Sjdp}; 394733965Sjdp 394833965Sjdpstatic boolean ieee_init_buffer 394933965Sjdp PARAMS ((struct ieee_handle *, struct ieee_buflist *)); 395033965Sjdpstatic boolean ieee_change_buffer 395133965Sjdp PARAMS ((struct ieee_handle *, struct ieee_buflist *)); 395233965Sjdpstatic boolean ieee_append_buffer 395333965Sjdp PARAMS ((struct ieee_handle *, struct ieee_buflist *, 395433965Sjdp struct ieee_buflist *)); 395533965Sjdpstatic boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int)); 395633965Sjdpstatic boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int)); 395733965Sjdpstatic boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma)); 395833965Sjdpstatic boolean ieee_write_id PARAMS ((struct ieee_handle *, const char *)); 395933965Sjdpstatic boolean ieee_write_asn 396033965Sjdp PARAMS ((struct ieee_handle *, unsigned int, bfd_vma)); 396133965Sjdpstatic boolean ieee_write_atn65 396233965Sjdp PARAMS ((struct ieee_handle *, unsigned int, const char *)); 396333965Sjdpstatic boolean ieee_push_type 396433965Sjdp PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean, 396533965Sjdp boolean)); 396633965Sjdpstatic unsigned int ieee_pop_type PARAMS ((struct ieee_handle *)); 396733965Sjdpstatic void ieee_pop_unused_type PARAMS ((struct ieee_handle *)); 396833965Sjdpstatic unsigned int ieee_pop_type_used 396933965Sjdp PARAMS ((struct ieee_handle *, boolean)); 397033965Sjdpstatic boolean ieee_add_range 397133965Sjdp PARAMS ((struct ieee_handle *, boolean, bfd_vma, bfd_vma)); 397233965Sjdpstatic boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma)); 397333965Sjdpstatic boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma)); 397433965Sjdpstatic boolean ieee_define_type 397533965Sjdp PARAMS ((struct ieee_handle *, unsigned int, boolean, boolean)); 397633965Sjdpstatic boolean ieee_define_named_type 397733965Sjdp PARAMS ((struct ieee_handle *, const char *, unsigned int, unsigned int, 397833965Sjdp boolean, boolean, struct ieee_buflist *)); 397933965Sjdpstatic struct ieee_modified_type *ieee_get_modified_info 398033965Sjdp PARAMS ((struct ieee_handle *, unsigned int)); 398133965Sjdpstatic struct bfd_hash_entry *ieee_name_type_newfunc 398233965Sjdp PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); 398333965Sjdpstatic boolean ieee_write_undefined_tag 398433965Sjdp PARAMS ((struct ieee_name_type_hash_entry *, PTR)); 398533965Sjdpstatic boolean ieee_finish_compilation_unit PARAMS ((struct ieee_handle *)); 398633965Sjdpstatic void ieee_add_bb11_blocks PARAMS ((bfd *, asection *, PTR)); 398733965Sjdpstatic boolean ieee_add_bb11 398833965Sjdp PARAMS ((struct ieee_handle *, asection *, bfd_vma, bfd_vma)); 398933965Sjdpstatic boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *)); 399033965Sjdpstatic unsigned int ieee_vis_to_flags PARAMS ((enum debug_visibility)); 399133965Sjdpstatic boolean ieee_class_method_var 399233965Sjdp PARAMS ((struct ieee_handle *, const char *, enum debug_visibility, boolean, 399333965Sjdp boolean, boolean, bfd_vma, boolean)); 399433965Sjdp 399533965Sjdpstatic boolean ieee_start_compilation_unit PARAMS ((PTR, const char *)); 399633965Sjdpstatic boolean ieee_start_source PARAMS ((PTR, const char *)); 399733965Sjdpstatic boolean ieee_empty_type PARAMS ((PTR)); 399833965Sjdpstatic boolean ieee_void_type PARAMS ((PTR)); 399933965Sjdpstatic boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean)); 400033965Sjdpstatic boolean ieee_float_type PARAMS ((PTR, unsigned int)); 400133965Sjdpstatic boolean ieee_complex_type PARAMS ((PTR, unsigned int)); 400233965Sjdpstatic boolean ieee_bool_type PARAMS ((PTR, unsigned int)); 400333965Sjdpstatic boolean ieee_enum_type 400433965Sjdp PARAMS ((PTR, const char *, const char **, bfd_signed_vma *)); 400533965Sjdpstatic boolean ieee_pointer_type PARAMS ((PTR)); 400633965Sjdpstatic boolean ieee_function_type PARAMS ((PTR, int, boolean)); 400733965Sjdpstatic boolean ieee_reference_type PARAMS ((PTR)); 400833965Sjdpstatic boolean ieee_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma)); 400933965Sjdpstatic boolean ieee_array_type 401033965Sjdp PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean)); 401133965Sjdpstatic boolean ieee_set_type PARAMS ((PTR, boolean)); 401233965Sjdpstatic boolean ieee_offset_type PARAMS ((PTR)); 401333965Sjdpstatic boolean ieee_method_type PARAMS ((PTR, boolean, int, boolean)); 401433965Sjdpstatic boolean ieee_const_type PARAMS ((PTR)); 401533965Sjdpstatic boolean ieee_volatile_type PARAMS ((PTR)); 401633965Sjdpstatic boolean ieee_start_struct_type 401733965Sjdp PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int)); 401833965Sjdpstatic boolean ieee_struct_field 401933965Sjdp PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility)); 402033965Sjdpstatic boolean ieee_end_struct_type PARAMS ((PTR)); 402133965Sjdpstatic boolean ieee_start_class_type 402233965Sjdp PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean, 402333965Sjdp boolean)); 402433965Sjdpstatic boolean ieee_class_static_member 402533965Sjdp PARAMS ((PTR, const char *, const char *, enum debug_visibility)); 402633965Sjdpstatic boolean ieee_class_baseclass 402733965Sjdp PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility)); 402833965Sjdpstatic boolean ieee_class_start_method PARAMS ((PTR, const char *)); 402933965Sjdpstatic boolean ieee_class_method_variant 403033965Sjdp PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean, 403133965Sjdp bfd_vma, boolean)); 403233965Sjdpstatic boolean ieee_class_static_method_variant 403333965Sjdp PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean)); 403433965Sjdpstatic boolean ieee_class_end_method PARAMS ((PTR)); 403533965Sjdpstatic boolean ieee_end_class_type PARAMS ((PTR)); 403633965Sjdpstatic boolean ieee_typedef_type PARAMS ((PTR, const char *)); 403733965Sjdpstatic boolean ieee_tag_type 403833965Sjdp PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind)); 403933965Sjdpstatic boolean ieee_typdef PARAMS ((PTR, const char *)); 404033965Sjdpstatic boolean ieee_tag PARAMS ((PTR, const char *)); 404133965Sjdpstatic boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma)); 404233965Sjdpstatic boolean ieee_float_constant PARAMS ((PTR, const char *, double)); 404333965Sjdpstatic boolean ieee_typed_constant PARAMS ((PTR, const char *, bfd_vma)); 404433965Sjdpstatic boolean ieee_variable 404533965Sjdp PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma)); 404633965Sjdpstatic boolean ieee_start_function PARAMS ((PTR, const char *, boolean)); 404733965Sjdpstatic boolean ieee_function_parameter 404833965Sjdp PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma)); 404933965Sjdpstatic boolean ieee_start_block PARAMS ((PTR, bfd_vma)); 405033965Sjdpstatic boolean ieee_end_block PARAMS ((PTR, bfd_vma)); 405133965Sjdpstatic boolean ieee_end_function PARAMS ((PTR)); 405233965Sjdpstatic boolean ieee_lineno 405333965Sjdp PARAMS ((PTR, const char *, unsigned long, bfd_vma)); 405433965Sjdp 405533965Sjdpstatic const struct debug_write_fns ieee_fns = 405633965Sjdp{ 405733965Sjdp ieee_start_compilation_unit, 405833965Sjdp ieee_start_source, 405933965Sjdp ieee_empty_type, 406033965Sjdp ieee_void_type, 406133965Sjdp ieee_int_type, 406233965Sjdp ieee_float_type, 406333965Sjdp ieee_complex_type, 406433965Sjdp ieee_bool_type, 406533965Sjdp ieee_enum_type, 406633965Sjdp ieee_pointer_type, 406733965Sjdp ieee_function_type, 406833965Sjdp ieee_reference_type, 406933965Sjdp ieee_range_type, 407033965Sjdp ieee_array_type, 407133965Sjdp ieee_set_type, 407233965Sjdp ieee_offset_type, 407333965Sjdp ieee_method_type, 407433965Sjdp ieee_const_type, 407533965Sjdp ieee_volatile_type, 407633965Sjdp ieee_start_struct_type, 407733965Sjdp ieee_struct_field, 407833965Sjdp ieee_end_struct_type, 407933965Sjdp ieee_start_class_type, 408033965Sjdp ieee_class_static_member, 408133965Sjdp ieee_class_baseclass, 408233965Sjdp ieee_class_start_method, 408333965Sjdp ieee_class_method_variant, 408433965Sjdp ieee_class_static_method_variant, 408533965Sjdp ieee_class_end_method, 408633965Sjdp ieee_end_class_type, 408733965Sjdp ieee_typedef_type, 408833965Sjdp ieee_tag_type, 408933965Sjdp ieee_typdef, 409033965Sjdp ieee_tag, 409133965Sjdp ieee_int_constant, 409233965Sjdp ieee_float_constant, 409333965Sjdp ieee_typed_constant, 409433965Sjdp ieee_variable, 409533965Sjdp ieee_start_function, 409633965Sjdp ieee_function_parameter, 409733965Sjdp ieee_start_block, 409833965Sjdp ieee_end_block, 409933965Sjdp ieee_end_function, 410033965Sjdp ieee_lineno 410133965Sjdp}; 410233965Sjdp 410333965Sjdp/* Initialize a buffer to be empty. */ 410433965Sjdp 410533965Sjdpstatic boolean 410633965Sjdpieee_init_buffer (info, buflist) 410760484Sobrien struct ieee_handle *info ATTRIBUTE_UNUSED; 410833965Sjdp struct ieee_buflist *buflist; 410933965Sjdp{ 411033965Sjdp buflist->head = NULL; 411133965Sjdp buflist->tail = NULL; 411233965Sjdp return true; 411333965Sjdp} 411433965Sjdp 411533965Sjdp/* See whether a buffer list has any data. */ 411633965Sjdp 411733965Sjdp#define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL) 411833965Sjdp 411933965Sjdp/* Change the current buffer to a specified buffer chain. */ 412033965Sjdp 412133965Sjdpstatic boolean 412233965Sjdpieee_change_buffer (info, buflist) 412333965Sjdp struct ieee_handle *info; 412433965Sjdp struct ieee_buflist *buflist; 412533965Sjdp{ 412633965Sjdp if (buflist->head == NULL) 412733965Sjdp { 412833965Sjdp struct ieee_buf *buf; 412933965Sjdp 413033965Sjdp buf = (struct ieee_buf *) xmalloc (sizeof *buf); 413133965Sjdp buf->next = NULL; 413233965Sjdp buf->c = 0; 413333965Sjdp buflist->head = buf; 413433965Sjdp buflist->tail = buf; 413533965Sjdp } 413633965Sjdp 413733965Sjdp info->current = buflist; 413833965Sjdp info->curbuf = buflist->tail; 413933965Sjdp 414033965Sjdp return true; 414133965Sjdp} 414233965Sjdp 414333965Sjdp/* Append a buffer chain. */ 414433965Sjdp 414533965Sjdpstatic boolean 414633965Sjdpieee_append_buffer (info, mainbuf, newbuf) 414760484Sobrien struct ieee_handle *info ATTRIBUTE_UNUSED; 414833965Sjdp struct ieee_buflist *mainbuf; 414933965Sjdp struct ieee_buflist *newbuf; 415033965Sjdp{ 415133965Sjdp if (newbuf->head != NULL) 415233965Sjdp { 415333965Sjdp if (mainbuf->head == NULL) 415433965Sjdp mainbuf->head = newbuf->head; 415533965Sjdp else 415633965Sjdp mainbuf->tail->next = newbuf->head; 415733965Sjdp mainbuf->tail = newbuf->tail; 415833965Sjdp } 415933965Sjdp return true; 416033965Sjdp} 416133965Sjdp 416233965Sjdp/* Write a byte into the buffer. We use a macro for speed and a 416333965Sjdp function for the complex cases. */ 416433965Sjdp 416533965Sjdp#define ieee_write_byte(info, b) \ 416633965Sjdp ((info)->curbuf->c < IEEE_BUFSIZE \ 416733965Sjdp ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), true) \ 416833965Sjdp : ieee_real_write_byte ((info), (b))) 416933965Sjdp 417033965Sjdpstatic boolean 417133965Sjdpieee_real_write_byte (info, b) 417233965Sjdp struct ieee_handle *info; 417333965Sjdp int b; 417433965Sjdp{ 417533965Sjdp if (info->curbuf->c >= IEEE_BUFSIZE) 417633965Sjdp { 417733965Sjdp struct ieee_buf *n; 417833965Sjdp 417933965Sjdp n = (struct ieee_buf *) xmalloc (sizeof *n); 418033965Sjdp n->next = NULL; 418133965Sjdp n->c = 0; 418233965Sjdp if (info->current->head == NULL) 418333965Sjdp info->current->head = n; 418433965Sjdp else 418533965Sjdp info->current->tail->next = n; 418633965Sjdp info->current->tail = n; 418733965Sjdp info->curbuf = n; 418833965Sjdp } 418933965Sjdp 419033965Sjdp info->curbuf->buf[info->curbuf->c] = b; 419133965Sjdp ++info->curbuf->c; 419233965Sjdp 419333965Sjdp return true; 419433965Sjdp} 419533965Sjdp 419633965Sjdp/* Write out two bytes. */ 419733965Sjdp 419833965Sjdpstatic boolean 419933965Sjdpieee_write_2bytes (info, i) 420033965Sjdp struct ieee_handle *info; 420133965Sjdp int i; 420233965Sjdp{ 420333965Sjdp return (ieee_write_byte (info, i >> 8) 420433965Sjdp && ieee_write_byte (info, i & 0xff)); 420533965Sjdp} 420633965Sjdp 420733965Sjdp/* Write out an integer. */ 420833965Sjdp 420933965Sjdpstatic boolean 421033965Sjdpieee_write_number (info, v) 421133965Sjdp struct ieee_handle *info; 421233965Sjdp bfd_vma v; 421333965Sjdp{ 421433965Sjdp bfd_vma t; 421533965Sjdp bfd_byte ab[20]; 421633965Sjdp bfd_byte *p; 421733965Sjdp unsigned int c; 421833965Sjdp 421933965Sjdp if (v <= (bfd_vma) ieee_number_end_enum) 422033965Sjdp return ieee_write_byte (info, (int) v); 422133965Sjdp 422233965Sjdp t = v; 422333965Sjdp p = ab + sizeof ab; 422433965Sjdp while (t != 0) 422533965Sjdp { 422633965Sjdp *--p = t & 0xff; 422733965Sjdp t >>= 8; 422833965Sjdp } 422933965Sjdp c = (ab + 20) - p; 423033965Sjdp 423133965Sjdp if (c > (unsigned int) (ieee_number_repeat_end_enum 423233965Sjdp - ieee_number_repeat_start_enum)) 423333965Sjdp { 423460484Sobrien fprintf (stderr, _("IEEE numeric overflow: 0x")); 423533965Sjdp fprintf_vma (stderr, v); 423633965Sjdp fprintf (stderr, "\n"); 423733965Sjdp return false; 423833965Sjdp } 423933965Sjdp 424033965Sjdp if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c)) 424133965Sjdp return false; 424233965Sjdp for (; c > 0; --c, ++p) 424333965Sjdp { 424433965Sjdp if (! ieee_write_byte (info, *p)) 424533965Sjdp return false; 424633965Sjdp } 424733965Sjdp 424833965Sjdp return true; 424933965Sjdp} 425033965Sjdp 425133965Sjdp/* Write out a string. */ 425233965Sjdp 425333965Sjdpstatic boolean 425433965Sjdpieee_write_id (info, s) 425533965Sjdp struct ieee_handle *info; 425633965Sjdp const char *s; 425733965Sjdp{ 425833965Sjdp unsigned int len; 425933965Sjdp 426033965Sjdp len = strlen (s); 426133965Sjdp if (len <= 0x7f) 426233965Sjdp { 426333965Sjdp if (! ieee_write_byte (info, len)) 426433965Sjdp return false; 426533965Sjdp } 426633965Sjdp else if (len <= 0xff) 426733965Sjdp { 426833965Sjdp if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum) 426933965Sjdp || ! ieee_write_byte (info, len)) 427033965Sjdp return false; 427133965Sjdp } 427233965Sjdp else if (len <= 0xffff) 427333965Sjdp { 427433965Sjdp if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum) 427533965Sjdp || ! ieee_write_2bytes (info, len)) 427633965Sjdp return false; 427733965Sjdp } 427833965Sjdp else 427933965Sjdp { 428060484Sobrien fprintf (stderr, _("IEEE string length overflow: %u\n"), len); 428133965Sjdp return false; 428233965Sjdp } 428333965Sjdp 428433965Sjdp for (; *s != '\0'; s++) 428533965Sjdp if (! ieee_write_byte (info, *s)) 428633965Sjdp return false; 428733965Sjdp 428833965Sjdp return true; 428933965Sjdp} 429033965Sjdp 429133965Sjdp/* Write out an ASN record. */ 429233965Sjdp 429333965Sjdpstatic boolean 429433965Sjdpieee_write_asn (info, indx, val) 429533965Sjdp struct ieee_handle *info; 429633965Sjdp unsigned int indx; 429733965Sjdp bfd_vma val; 429833965Sjdp{ 429933965Sjdp return (ieee_write_2bytes (info, (int) ieee_asn_record_enum) 430033965Sjdp && ieee_write_number (info, indx) 430133965Sjdp && ieee_write_number (info, val)); 430233965Sjdp} 430333965Sjdp 430433965Sjdp/* Write out an ATN65 record. */ 430533965Sjdp 430633965Sjdpstatic boolean 430733965Sjdpieee_write_atn65 (info, indx, s) 430833965Sjdp struct ieee_handle *info; 430933965Sjdp unsigned int indx; 431033965Sjdp const char *s; 431133965Sjdp{ 431233965Sjdp return (ieee_write_2bytes (info, (int) ieee_atn_record_enum) 431333965Sjdp && ieee_write_number (info, indx) 431433965Sjdp && ieee_write_number (info, 0) 431533965Sjdp && ieee_write_number (info, 65) 431633965Sjdp && ieee_write_id (info, s)); 431733965Sjdp} 431833965Sjdp 431933965Sjdp/* Push a type index onto the type stack. */ 432033965Sjdp 432133965Sjdpstatic boolean 432233965Sjdpieee_push_type (info, indx, size, unsignedp, localp) 432333965Sjdp struct ieee_handle *info; 432433965Sjdp unsigned int indx; 432533965Sjdp unsigned int size; 432633965Sjdp boolean unsignedp; 432733965Sjdp boolean localp; 432833965Sjdp{ 432933965Sjdp struct ieee_type_stack *ts; 433033965Sjdp 433133965Sjdp ts = (struct ieee_type_stack *) xmalloc (sizeof *ts); 433233965Sjdp memset (ts, 0, sizeof *ts); 433333965Sjdp 433433965Sjdp ts->type.indx = indx; 433533965Sjdp ts->type.size = size; 433633965Sjdp ts->type.unsignedp = unsignedp; 433733965Sjdp ts->type.localp = localp; 433833965Sjdp 433933965Sjdp ts->next = info->type_stack; 434033965Sjdp info->type_stack = ts; 434133965Sjdp 434233965Sjdp return true; 434333965Sjdp} 434433965Sjdp 434533965Sjdp/* Pop a type index off the type stack. */ 434633965Sjdp 434733965Sjdpstatic unsigned int 434833965Sjdpieee_pop_type (info) 434933965Sjdp struct ieee_handle *info; 435033965Sjdp{ 435133965Sjdp return ieee_pop_type_used (info, true); 435233965Sjdp} 435333965Sjdp 435433965Sjdp/* Pop an unused type index off the type stack. */ 435533965Sjdp 435633965Sjdpstatic void 435733965Sjdpieee_pop_unused_type (info) 435833965Sjdp struct ieee_handle *info; 435933965Sjdp{ 436033965Sjdp (void) ieee_pop_type_used (info, false); 436133965Sjdp} 436233965Sjdp 436333965Sjdp/* Pop a used or unused type index off the type stack. */ 436433965Sjdp 436533965Sjdpstatic unsigned int 436633965Sjdpieee_pop_type_used (info, used) 436733965Sjdp struct ieee_handle *info; 436833965Sjdp boolean used; 436933965Sjdp{ 437033965Sjdp struct ieee_type_stack *ts; 437133965Sjdp unsigned int ret; 437233965Sjdp 437333965Sjdp ts = info->type_stack; 437433965Sjdp assert (ts != NULL); 437533965Sjdp 437633965Sjdp /* If this is a function type, and we need it, we need to append the 437733965Sjdp actual definition to the typedef block now. */ 437833965Sjdp if (used && ! ieee_buffer_emptyp (&ts->type.fndef)) 437933965Sjdp { 438033965Sjdp struct ieee_buflist *buflist; 438133965Sjdp 438233965Sjdp if (ts->type.localp) 438333965Sjdp { 438433965Sjdp /* Make sure we have started the types block. */ 438533965Sjdp if (ieee_buffer_emptyp (&info->types)) 438633965Sjdp { 438733965Sjdp if (! ieee_change_buffer (info, &info->types) 438833965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 438933965Sjdp || ! ieee_write_byte (info, 1) 439033965Sjdp || ! ieee_write_number (info, 0) 439133965Sjdp || ! ieee_write_id (info, info->modname)) 439233965Sjdp return false; 439333965Sjdp } 439433965Sjdp buflist = &info->types; 439533965Sjdp } 439633965Sjdp else 439733965Sjdp { 439833965Sjdp /* Make sure we started the global type block. */ 439933965Sjdp if (ieee_buffer_emptyp (&info->global_types)) 440033965Sjdp { 440133965Sjdp if (! ieee_change_buffer (info, &info->global_types) 440233965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 440333965Sjdp || ! ieee_write_byte (info, 2) 440433965Sjdp || ! ieee_write_number (info, 0) 440533965Sjdp || ! ieee_write_id (info, "")) 440633965Sjdp return false; 440733965Sjdp } 440833965Sjdp buflist = &info->global_types; 440933965Sjdp } 441033965Sjdp 441133965Sjdp if (! ieee_append_buffer (info, buflist, &ts->type.fndef)) 441233965Sjdp return false; 441333965Sjdp } 441433965Sjdp 441533965Sjdp ret = ts->type.indx; 441633965Sjdp info->type_stack = ts->next; 441733965Sjdp free (ts); 441833965Sjdp return ret; 441933965Sjdp} 442033965Sjdp 442133965Sjdp/* Add a range of bytes included in the current compilation unit. */ 442233965Sjdp 442333965Sjdpstatic boolean 442433965Sjdpieee_add_range (info, global, low, high) 442533965Sjdp struct ieee_handle *info; 442633965Sjdp boolean global; 442733965Sjdp bfd_vma low; 442833965Sjdp bfd_vma high; 442933965Sjdp{ 443033965Sjdp struct ieee_range **plist, *r, **pr; 443133965Sjdp 443233965Sjdp if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high) 443333965Sjdp return true; 443433965Sjdp 443533965Sjdp if (global) 443633965Sjdp plist = &info->global_ranges; 443733965Sjdp else 443833965Sjdp plist = &info->ranges; 443933965Sjdp 444033965Sjdp for (r = *plist; r != NULL; r = r->next) 444133965Sjdp { 444233965Sjdp if (high >= r->low && low <= r->high) 444333965Sjdp { 444433965Sjdp /* The new range overlaps r. */ 444533965Sjdp if (low < r->low) 444633965Sjdp r->low = low; 444733965Sjdp if (high > r->high) 444833965Sjdp r->high = high; 444933965Sjdp pr = &r->next; 445033965Sjdp while (*pr != NULL && (*pr)->low <= r->high) 445133965Sjdp { 445233965Sjdp struct ieee_range *n; 445333965Sjdp 445433965Sjdp if ((*pr)->high > r->high) 445533965Sjdp r->high = (*pr)->high; 445633965Sjdp n = (*pr)->next; 445733965Sjdp free (*pr); 445833965Sjdp *pr = n; 445933965Sjdp } 446033965Sjdp return true; 446133965Sjdp } 446233965Sjdp } 446333965Sjdp 446433965Sjdp r = (struct ieee_range *) xmalloc (sizeof *r); 446533965Sjdp memset (r, 0, sizeof *r); 446633965Sjdp 446733965Sjdp r->low = low; 446833965Sjdp r->high = high; 446933965Sjdp 447033965Sjdp /* Store the ranges sorted by address. */ 447133965Sjdp for (pr = plist; *pr != NULL; pr = &(*pr)->next) 447233965Sjdp if ((*pr)->low > high) 447333965Sjdp break; 447433965Sjdp r->next = *pr; 447533965Sjdp *pr = r; 447633965Sjdp 447733965Sjdp return true; 447833965Sjdp} 447933965Sjdp 448033965Sjdp/* Start a new range for which we only have the low address. */ 448133965Sjdp 448233965Sjdpstatic boolean 448333965Sjdpieee_start_range (info, low) 448433965Sjdp struct ieee_handle *info; 448533965Sjdp bfd_vma low; 448633965Sjdp{ 448733965Sjdp struct ieee_range *r; 448833965Sjdp 448933965Sjdp r = (struct ieee_range *) xmalloc (sizeof *r); 449033965Sjdp memset (r, 0, sizeof *r); 449133965Sjdp r->low = low; 449233965Sjdp r->next = info->pending_ranges; 449333965Sjdp info->pending_ranges = r; 449433965Sjdp return true; 449577298Sobrien} 449633965Sjdp 449733965Sjdp/* Finish a range started by ieee_start_range. */ 449833965Sjdp 449933965Sjdpstatic boolean 450033965Sjdpieee_end_range (info, high) 450133965Sjdp struct ieee_handle *info; 450233965Sjdp bfd_vma high; 450333965Sjdp{ 450433965Sjdp struct ieee_range *r; 450533965Sjdp bfd_vma low; 450633965Sjdp 450733965Sjdp assert (info->pending_ranges != NULL); 450833965Sjdp r = info->pending_ranges; 450933965Sjdp low = r->low; 451033965Sjdp info->pending_ranges = r->next; 451133965Sjdp free (r); 451233965Sjdp return ieee_add_range (info, false, low, high); 451333965Sjdp} 451433965Sjdp 451533965Sjdp/* Start defining a type. */ 451633965Sjdp 451733965Sjdpstatic boolean 451833965Sjdpieee_define_type (info, size, unsignedp, localp) 451933965Sjdp struct ieee_handle *info; 452033965Sjdp unsigned int size; 452133965Sjdp boolean unsignedp; 452233965Sjdp boolean localp; 452333965Sjdp{ 452433965Sjdp return ieee_define_named_type (info, (const char *) NULL, 452533965Sjdp (unsigned int) -1, size, unsignedp, 452633965Sjdp localp, (struct ieee_buflist *) NULL); 452733965Sjdp} 452833965Sjdp 452933965Sjdp/* Start defining a named type. */ 453033965Sjdp 453133965Sjdpstatic boolean 453233965Sjdpieee_define_named_type (info, name, indx, size, unsignedp, localp, buflist) 453333965Sjdp struct ieee_handle *info; 453433965Sjdp const char *name; 453533965Sjdp unsigned int indx; 453633965Sjdp unsigned int size; 453733965Sjdp boolean unsignedp; 453833965Sjdp boolean localp; 453933965Sjdp struct ieee_buflist *buflist; 454033965Sjdp{ 454133965Sjdp unsigned int type_indx; 454233965Sjdp unsigned int name_indx; 454333965Sjdp 454433965Sjdp if (indx != (unsigned int) -1) 454533965Sjdp type_indx = indx; 454633965Sjdp else 454733965Sjdp { 454833965Sjdp type_indx = info->type_indx; 454933965Sjdp ++info->type_indx; 455033965Sjdp } 455133965Sjdp 455233965Sjdp name_indx = info->name_indx; 455333965Sjdp ++info->name_indx; 455433965Sjdp 455533965Sjdp if (name == NULL) 455633965Sjdp name = ""; 455733965Sjdp 455833965Sjdp /* If we were given a buffer, use it; otherwise, use either the 455933965Sjdp local or the global type information, and make sure that the type 456033965Sjdp block is started. */ 456133965Sjdp if (buflist != NULL) 456233965Sjdp { 456333965Sjdp if (! ieee_change_buffer (info, buflist)) 456433965Sjdp return false; 456533965Sjdp } 456633965Sjdp else if (localp) 456733965Sjdp { 456833965Sjdp if (! ieee_buffer_emptyp (&info->types)) 456933965Sjdp { 457033965Sjdp if (! ieee_change_buffer (info, &info->types)) 457133965Sjdp return false; 457233965Sjdp } 457333965Sjdp else 457433965Sjdp { 457533965Sjdp if (! ieee_change_buffer (info, &info->types) 457633965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 457733965Sjdp || ! ieee_write_byte (info, 1) 457833965Sjdp || ! ieee_write_number (info, 0) 457933965Sjdp || ! ieee_write_id (info, info->modname)) 458033965Sjdp return false; 458133965Sjdp } 458233965Sjdp } 458333965Sjdp else 458433965Sjdp { 458533965Sjdp if (! ieee_buffer_emptyp (&info->global_types)) 458633965Sjdp { 458733965Sjdp if (! ieee_change_buffer (info, &info->global_types)) 458833965Sjdp return false; 458933965Sjdp } 459033965Sjdp else 459133965Sjdp { 459233965Sjdp if (! ieee_change_buffer (info, &info->global_types) 459333965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 459433965Sjdp || ! ieee_write_byte (info, 2) 459533965Sjdp || ! ieee_write_number (info, 0) 459633965Sjdp || ! ieee_write_id (info, "")) 459733965Sjdp return false; 459833965Sjdp } 459933965Sjdp } 460033965Sjdp 460133965Sjdp /* Push the new type on the type stack, write out an NN record, and 460233965Sjdp write out the start of a TY record. The caller will then finish 460333965Sjdp the TY record. */ 460433965Sjdp if (! ieee_push_type (info, type_indx, size, unsignedp, localp)) 460533965Sjdp return false; 460633965Sjdp 460733965Sjdp return (ieee_write_byte (info, (int) ieee_nn_record) 460833965Sjdp && ieee_write_number (info, name_indx) 460933965Sjdp && ieee_write_id (info, name) 461033965Sjdp && ieee_write_byte (info, (int) ieee_ty_record_enum) 461133965Sjdp && ieee_write_number (info, type_indx) 461233965Sjdp && ieee_write_byte (info, 0xce) 461333965Sjdp && ieee_write_number (info, name_indx)); 461433965Sjdp} 461533965Sjdp 461633965Sjdp/* Get an entry to the list of modified versions of a type. */ 461733965Sjdp 461833965Sjdpstatic struct ieee_modified_type * 461933965Sjdpieee_get_modified_info (info, indx) 462033965Sjdp struct ieee_handle *info; 462133965Sjdp unsigned int indx; 462233965Sjdp{ 462333965Sjdp if (indx >= info->modified_alloc) 462433965Sjdp { 462533965Sjdp unsigned int nalloc; 462633965Sjdp 462733965Sjdp nalloc = info->modified_alloc; 462833965Sjdp if (nalloc == 0) 462933965Sjdp nalloc = 16; 463033965Sjdp while (indx >= nalloc) 463133965Sjdp nalloc *= 2; 463233965Sjdp info->modified = ((struct ieee_modified_type *) 463333965Sjdp xrealloc (info->modified, 463433965Sjdp nalloc * sizeof *info->modified)); 463533965Sjdp memset (info->modified + info->modified_alloc, 0, 463633965Sjdp (nalloc - info->modified_alloc) * sizeof *info->modified); 463733965Sjdp info->modified_alloc = nalloc; 463833965Sjdp } 463933965Sjdp 464033965Sjdp return info->modified + indx; 464133965Sjdp} 464233965Sjdp 464333965Sjdp/* Routines for the hash table mapping names to types. */ 464433965Sjdp 464533965Sjdp/* Initialize an entry in the hash table. */ 464633965Sjdp 464733965Sjdpstatic struct bfd_hash_entry * 464833965Sjdpieee_name_type_newfunc (entry, table, string) 464933965Sjdp struct bfd_hash_entry *entry; 465033965Sjdp struct bfd_hash_table *table; 465133965Sjdp const char *string; 465233965Sjdp{ 465333965Sjdp struct ieee_name_type_hash_entry *ret = 465433965Sjdp (struct ieee_name_type_hash_entry *) entry; 465533965Sjdp 465633965Sjdp /* Allocate the structure if it has not already been allocated by a 465733965Sjdp subclass. */ 465833965Sjdp if (ret == NULL) 465933965Sjdp ret = ((struct ieee_name_type_hash_entry *) 466033965Sjdp bfd_hash_allocate (table, sizeof *ret)); 466133965Sjdp if (ret == NULL) 466233965Sjdp return NULL; 466333965Sjdp 466433965Sjdp /* Call the allocation method of the superclass. */ 466533965Sjdp ret = ((struct ieee_name_type_hash_entry *) 466633965Sjdp bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 466733965Sjdp if (ret) 466833965Sjdp { 466933965Sjdp /* Set local fields. */ 467033965Sjdp ret->types = NULL; 467133965Sjdp } 467233965Sjdp 467333965Sjdp return (struct bfd_hash_entry *) ret; 467433965Sjdp} 467533965Sjdp 467633965Sjdp/* Look up an entry in the hash table. */ 467733965Sjdp 467833965Sjdp#define ieee_name_type_hash_lookup(table, string, create, copy) \ 467933965Sjdp ((struct ieee_name_type_hash_entry *) \ 468033965Sjdp bfd_hash_lookup (&(table)->root, (string), (create), (copy))) 468133965Sjdp 468233965Sjdp/* Traverse the hash table. */ 468333965Sjdp 468433965Sjdp#define ieee_name_type_hash_traverse(table, func, info) \ 468533965Sjdp (bfd_hash_traverse \ 468633965Sjdp (&(table)->root, \ 468733965Sjdp (boolean (*) PARAMS ((struct bfd_hash_entry *, PTR))) (func), \ 468833965Sjdp (info))) 468933965Sjdp 469033965Sjdp/* The general routine to write out IEEE debugging information. */ 469133965Sjdp 469233965Sjdpboolean 469333965Sjdpwrite_ieee_debugging_info (abfd, dhandle) 469433965Sjdp bfd *abfd; 469533965Sjdp PTR dhandle; 469633965Sjdp{ 469733965Sjdp struct ieee_handle info; 469833965Sjdp asection *s; 469933965Sjdp const char *err; 470033965Sjdp struct ieee_buf *b; 470133965Sjdp 470233965Sjdp memset (&info, 0, sizeof info); 470333965Sjdp info.abfd = abfd; 470433965Sjdp info.type_indx = 256; 470533965Sjdp info.name_indx = 32; 470633965Sjdp 470733965Sjdp if (! bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc) 470833965Sjdp || ! bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc)) 470933965Sjdp return false; 471033965Sjdp 471133965Sjdp if (! ieee_init_buffer (&info, &info.global_types) 471233965Sjdp || ! ieee_init_buffer (&info, &info.data) 471333965Sjdp || ! ieee_init_buffer (&info, &info.types) 471433965Sjdp || ! ieee_init_buffer (&info, &info.vars) 471533965Sjdp || ! ieee_init_buffer (&info, &info.cxx) 471633965Sjdp || ! ieee_init_buffer (&info, &info.linenos) 471733965Sjdp || ! ieee_init_buffer (&info, &info.fntype) 471833965Sjdp || ! ieee_init_buffer (&info, &info.fnargs)) 471933965Sjdp return false; 472033965Sjdp 472133965Sjdp if (! debug_write (dhandle, &ieee_fns, (PTR) &info)) 472233965Sjdp return false; 472333965Sjdp 472433965Sjdp if (info.filename != NULL) 472533965Sjdp { 472633965Sjdp if (! ieee_finish_compilation_unit (&info)) 472733965Sjdp return false; 472833965Sjdp } 472933965Sjdp 473033965Sjdp /* Put any undefined tags in the global typedef information. */ 473133965Sjdp info.error = false; 473233965Sjdp ieee_name_type_hash_traverse (&info.tags, 473333965Sjdp ieee_write_undefined_tag, 473433965Sjdp (PTR) &info); 473533965Sjdp if (info.error) 473633965Sjdp return false; 473733965Sjdp 473833965Sjdp /* Prepend the global typedef information to the other data. */ 473933965Sjdp if (! ieee_buffer_emptyp (&info.global_types)) 474033965Sjdp { 474133965Sjdp /* The HP debugger seems to have a bug in which it ignores the 474233965Sjdp last entry in the global types, so we add a dummy entry. */ 474333965Sjdp if (! ieee_change_buffer (&info, &info.global_types) 474433965Sjdp || ! ieee_write_byte (&info, (int) ieee_nn_record) 474533965Sjdp || ! ieee_write_number (&info, info.name_indx) 474633965Sjdp || ! ieee_write_id (&info, "") 474733965Sjdp || ! ieee_write_byte (&info, (int) ieee_ty_record_enum) 474833965Sjdp || ! ieee_write_number (&info, info.type_indx) 474933965Sjdp || ! ieee_write_byte (&info, 0xce) 475033965Sjdp || ! ieee_write_number (&info, info.name_indx) 475133965Sjdp || ! ieee_write_number (&info, 'P') 475233965Sjdp || ! ieee_write_number (&info, (int) builtin_void + 32) 475333965Sjdp || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) 475433965Sjdp return false; 475533965Sjdp 475633965Sjdp if (! ieee_append_buffer (&info, &info.global_types, &info.data)) 475733965Sjdp return false; 475833965Sjdp info.data = info.global_types; 475933965Sjdp } 476033965Sjdp 476133965Sjdp /* Make sure that we have declare BB11 blocks for each range in the 476233965Sjdp file. They are added to info->vars. */ 476333965Sjdp info.error = false; 476433965Sjdp if (! ieee_init_buffer (&info, &info.vars)) 476533965Sjdp return false; 476633965Sjdp bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (PTR) &info); 476733965Sjdp if (info.error) 476833965Sjdp return false; 476933965Sjdp if (! ieee_buffer_emptyp (&info.vars)) 477033965Sjdp { 477133965Sjdp if (! ieee_change_buffer (&info, &info.vars) 477233965Sjdp || ! ieee_write_byte (&info, (int) ieee_be_record_enum)) 477333965Sjdp return false; 477433965Sjdp 477533965Sjdp if (! ieee_append_buffer (&info, &info.data, &info.vars)) 477633965Sjdp return false; 477733965Sjdp } 477833965Sjdp 477933965Sjdp /* Now all the data is in info.data. Write it out to the BFD. We 478033965Sjdp normally would need to worry about whether all the other sections 478133965Sjdp are set up yet, but the IEEE backend will handle this particular 478233965Sjdp case correctly regardless. */ 478333965Sjdp if (ieee_buffer_emptyp (&info.data)) 478433965Sjdp { 478533965Sjdp /* There is no debugging information. */ 478633965Sjdp return true; 478733965Sjdp } 478833965Sjdp err = NULL; 478933965Sjdp s = bfd_make_section (abfd, ".debug"); 479033965Sjdp if (s == NULL) 479133965Sjdp err = "bfd_make_section"; 479233965Sjdp if (err == NULL) 479333965Sjdp { 479433965Sjdp if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS)) 479533965Sjdp err = "bfd_set_section_flags"; 479633965Sjdp } 479733965Sjdp if (err == NULL) 479833965Sjdp { 479933965Sjdp bfd_size_type size; 480033965Sjdp 480133965Sjdp size = 0; 480233965Sjdp for (b = info.data.head; b != NULL; b = b->next) 480333965Sjdp size += b->c; 480433965Sjdp if (! bfd_set_section_size (abfd, s, size)) 480533965Sjdp err = "bfd_set_section_size"; 480633965Sjdp } 480733965Sjdp if (err == NULL) 480833965Sjdp { 480933965Sjdp file_ptr offset; 481033965Sjdp 481133965Sjdp offset = 0; 481233965Sjdp for (b = info.data.head; b != NULL; b = b->next) 481333965Sjdp { 481433965Sjdp if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c)) 481533965Sjdp { 481633965Sjdp err = "bfd_set_section_contents"; 481733965Sjdp break; 481833965Sjdp } 481933965Sjdp offset += b->c; 482033965Sjdp } 482133965Sjdp } 482233965Sjdp 482333965Sjdp if (err != NULL) 482433965Sjdp { 482533965Sjdp fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err, 482633965Sjdp bfd_errmsg (bfd_get_error ())); 482733965Sjdp return false; 482833965Sjdp } 482933965Sjdp 483033965Sjdp bfd_hash_table_free (&info.typedefs.root); 483133965Sjdp bfd_hash_table_free (&info.tags.root); 483233965Sjdp 483333965Sjdp return true; 483433965Sjdp} 483533965Sjdp 483633965Sjdp/* Write out information for an undefined tag. This is called via 483733965Sjdp ieee_name_type_hash_traverse. */ 483833965Sjdp 483933965Sjdpstatic boolean 484033965Sjdpieee_write_undefined_tag (h, p) 484133965Sjdp struct ieee_name_type_hash_entry *h; 484233965Sjdp PTR p; 484333965Sjdp{ 484433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 484533965Sjdp struct ieee_name_type *nt; 484633965Sjdp 484733965Sjdp for (nt = h->types; nt != NULL; nt = nt->next) 484833965Sjdp { 484933965Sjdp unsigned int name_indx; 485033965Sjdp char code; 485133965Sjdp 485233965Sjdp if (nt->kind == DEBUG_KIND_ILLEGAL) 485333965Sjdp continue; 485433965Sjdp 485533965Sjdp if (ieee_buffer_emptyp (&info->global_types)) 485633965Sjdp { 485733965Sjdp if (! ieee_change_buffer (info, &info->global_types) 485833965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 485933965Sjdp || ! ieee_write_byte (info, 2) 486033965Sjdp || ! ieee_write_number (info, 0) 486133965Sjdp || ! ieee_write_id (info, "")) 486233965Sjdp { 486333965Sjdp info->error = true; 486433965Sjdp return false; 486533965Sjdp } 486633965Sjdp } 486733965Sjdp else 486833965Sjdp { 486933965Sjdp if (! ieee_change_buffer (info, &info->global_types)) 487033965Sjdp { 487133965Sjdp info->error = true; 487233965Sjdp return false; 487333965Sjdp } 487433965Sjdp } 487533965Sjdp 487633965Sjdp name_indx = info->name_indx; 487733965Sjdp ++info->name_indx; 487833965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 487933965Sjdp || ! ieee_write_number (info, name_indx) 488033965Sjdp || ! ieee_write_id (info, nt->type.name) 488133965Sjdp || ! ieee_write_byte (info, (int) ieee_ty_record_enum) 488233965Sjdp || ! ieee_write_number (info, nt->type.indx) 488333965Sjdp || ! ieee_write_byte (info, 0xce) 488433965Sjdp || ! ieee_write_number (info, name_indx)) 488533965Sjdp { 488633965Sjdp info->error = true; 488733965Sjdp return false; 488833965Sjdp } 488933965Sjdp 489033965Sjdp switch (nt->kind) 489133965Sjdp { 489233965Sjdp default: 489333965Sjdp abort (); 489433965Sjdp info->error = true; 489533965Sjdp return false; 489633965Sjdp case DEBUG_KIND_STRUCT: 489733965Sjdp case DEBUG_KIND_CLASS: 489833965Sjdp code = 'S'; 489933965Sjdp break; 490033965Sjdp case DEBUG_KIND_UNION: 490133965Sjdp case DEBUG_KIND_UNION_CLASS: 490233965Sjdp code = 'U'; 490333965Sjdp break; 490433965Sjdp case DEBUG_KIND_ENUM: 490533965Sjdp code = 'E'; 490633965Sjdp break; 490733965Sjdp } 490833965Sjdp if (! ieee_write_number (info, code) 490933965Sjdp || ! ieee_write_number (info, 0)) 491033965Sjdp { 491133965Sjdp info->error = true; 491233965Sjdp return false; 491333965Sjdp } 491433965Sjdp } 491533965Sjdp 491633965Sjdp return true; 491733965Sjdp} 491833965Sjdp 491933965Sjdp/* Start writing out information for a compilation unit. */ 492033965Sjdp 492133965Sjdpstatic boolean 492233965Sjdpieee_start_compilation_unit (p, filename) 492333965Sjdp PTR p; 492433965Sjdp const char *filename; 492533965Sjdp{ 492633965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 492733965Sjdp const char *modname; 492877298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 492961843Sobrien const char *backslash; 493077298Sobrien#endif 493133965Sjdp char *c, *s; 493233965Sjdp unsigned int nindx; 493333965Sjdp 493433965Sjdp if (info->filename != NULL) 493533965Sjdp { 493633965Sjdp if (! ieee_finish_compilation_unit (info)) 493733965Sjdp return false; 493833965Sjdp } 493933965Sjdp 494033965Sjdp info->filename = filename; 494133965Sjdp modname = strrchr (filename, '/'); 494277298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 494361843Sobrien /* We could have a mixed forward/back slash case. */ 494477298Sobrien backslash = strrchr (filename, '\\'); 494577298Sobrien if (modname == NULL || (backslash != NULL && backslash > modname)) 494661843Sobrien modname = backslash; 494777298Sobrien#endif 494861843Sobrien 494933965Sjdp if (modname != NULL) 495033965Sjdp ++modname; 495161843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 495261843Sobrien else if (filename[0] && filename[1] == ':') 495361843Sobrien modname = filename + 2; 495461843Sobrien#endif 495533965Sjdp else 495661843Sobrien modname = filename; 495761843Sobrien 495833965Sjdp c = xstrdup (modname); 495933965Sjdp s = strrchr (c, '.'); 496033965Sjdp if (s != NULL) 496133965Sjdp *s = '\0'; 496233965Sjdp info->modname = c; 496333965Sjdp 496433965Sjdp if (! ieee_init_buffer (info, &info->types) 496533965Sjdp || ! ieee_init_buffer (info, &info->vars) 496633965Sjdp || ! ieee_init_buffer (info, &info->cxx) 496733965Sjdp || ! ieee_init_buffer (info, &info->linenos)) 496833965Sjdp return false; 496933965Sjdp info->ranges = NULL; 497033965Sjdp 497133965Sjdp /* Always include a BB1 and a BB3 block. That is what the output of 497233965Sjdp the MRI linker seems to look like. */ 497333965Sjdp if (! ieee_change_buffer (info, &info->types) 497433965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 497533965Sjdp || ! ieee_write_byte (info, 1) 497633965Sjdp || ! ieee_write_number (info, 0) 497733965Sjdp || ! ieee_write_id (info, info->modname)) 497833965Sjdp return false; 497933965Sjdp 498033965Sjdp nindx = info->name_indx; 498133965Sjdp ++info->name_indx; 498233965Sjdp if (! ieee_change_buffer (info, &info->vars) 498333965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 498433965Sjdp || ! ieee_write_byte (info, 3) 498533965Sjdp || ! ieee_write_number (info, 0) 498633965Sjdp || ! ieee_write_id (info, info->modname)) 498733965Sjdp return false; 498833965Sjdp 498933965Sjdp return true; 499033965Sjdp} 499133965Sjdp 499233965Sjdp/* Finish up a compilation unit. */ 499333965Sjdp 499433965Sjdpstatic boolean 499533965Sjdpieee_finish_compilation_unit (info) 499633965Sjdp struct ieee_handle *info; 499733965Sjdp{ 499833965Sjdp struct ieee_range *r; 499933965Sjdp 500033965Sjdp if (! ieee_buffer_emptyp (&info->types)) 500133965Sjdp { 500233965Sjdp if (! ieee_change_buffer (info, &info->types) 500333965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum)) 500433965Sjdp return false; 500533965Sjdp } 500633965Sjdp 500733965Sjdp if (! ieee_buffer_emptyp (&info->cxx)) 500833965Sjdp { 500933965Sjdp /* Append any C++ information to the global function and 501033965Sjdp variable information. */ 501133965Sjdp assert (! ieee_buffer_emptyp (&info->vars)); 501233965Sjdp if (! ieee_change_buffer (info, &info->vars)) 501333965Sjdp return false; 501433965Sjdp 501533965Sjdp /* We put the pmisc records in a dummy procedure, just as the 501633965Sjdp MRI compiler does. */ 501733965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 501833965Sjdp || ! ieee_write_byte (info, 6) 501933965Sjdp || ! ieee_write_number (info, 0) 502033965Sjdp || ! ieee_write_id (info, "__XRYCPP") 502133965Sjdp || ! ieee_write_number (info, 0) 502233965Sjdp || ! ieee_write_number (info, 0) 502333965Sjdp || ! ieee_write_number (info, info->highaddr - 1) 502433965Sjdp || ! ieee_append_buffer (info, &info->vars, &info->cxx) 502533965Sjdp || ! ieee_change_buffer (info, &info->vars) 502633965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 502733965Sjdp || ! ieee_write_number (info, info->highaddr - 1)) 502833965Sjdp return false; 502933965Sjdp } 503033965Sjdp 503133965Sjdp if (! ieee_buffer_emptyp (&info->vars)) 503233965Sjdp { 503333965Sjdp if (! ieee_change_buffer (info, &info->vars) 503433965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum)) 503533965Sjdp return false; 503633965Sjdp } 503733965Sjdp 503833965Sjdp if (info->pending_lineno_filename != NULL) 503933965Sjdp { 504033965Sjdp /* Force out the pending line number. */ 504133965Sjdp if (! ieee_lineno ((PTR) info, (const char *) NULL, 0, (bfd_vma) -1)) 504233965Sjdp return false; 504333965Sjdp } 504433965Sjdp if (! ieee_buffer_emptyp (&info->linenos)) 504533965Sjdp { 504633965Sjdp if (! ieee_change_buffer (info, &info->linenos) 504733965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum)) 504833965Sjdp return false; 504933965Sjdp if (strcmp (info->filename, info->lineno_filename) != 0) 505033965Sjdp { 505133965Sjdp /* We were not in the main file. We just closed the 505233965Sjdp included line number block, and now we must close the 505333965Sjdp main line number block. */ 505433965Sjdp if (! ieee_write_byte (info, (int) ieee_be_record_enum)) 505533965Sjdp return false; 505633965Sjdp } 505733965Sjdp } 505833965Sjdp 505933965Sjdp if (! ieee_append_buffer (info, &info->data, &info->types) 506033965Sjdp || ! ieee_append_buffer (info, &info->data, &info->vars) 506133965Sjdp || ! ieee_append_buffer (info, &info->data, &info->linenos)) 506233965Sjdp return false; 506333965Sjdp 506433965Sjdp /* Build BB10/BB11 blocks based on the ranges we recorded. */ 506533965Sjdp if (! ieee_change_buffer (info, &info->data)) 506633965Sjdp return false; 506733965Sjdp 506833965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 506933965Sjdp || ! ieee_write_byte (info, 10) 507033965Sjdp || ! ieee_write_number (info, 0) 507133965Sjdp || ! ieee_write_id (info, info->modname) 507233965Sjdp || ! ieee_write_id (info, "") 507333965Sjdp || ! ieee_write_number (info, 0) 507433965Sjdp || ! ieee_write_id (info, "GNU objcopy")) 507533965Sjdp return false; 507633965Sjdp 507733965Sjdp for (r = info->ranges; r != NULL; r = r->next) 507833965Sjdp { 507933965Sjdp bfd_vma low, high; 508033965Sjdp asection *s; 508133965Sjdp int kind; 508233965Sjdp 508333965Sjdp low = r->low; 508433965Sjdp high = r->high; 508533965Sjdp 508633965Sjdp /* Find the section corresponding to this range. */ 508733965Sjdp for (s = info->abfd->sections; s != NULL; s = s->next) 508833965Sjdp { 508933965Sjdp if (bfd_get_section_vma (info->abfd, s) <= low 509033965Sjdp && high <= (bfd_get_section_vma (info->abfd, s) 509133965Sjdp + bfd_section_size (info->abfd, s))) 509233965Sjdp break; 509333965Sjdp } 509433965Sjdp 509533965Sjdp if (s == NULL) 509633965Sjdp { 509733965Sjdp /* Just ignore this range. */ 509833965Sjdp continue; 509933965Sjdp } 510033965Sjdp 510133965Sjdp /* Coalesce ranges if it seems reasonable. */ 510233965Sjdp while (r->next != NULL 510333965Sjdp && high + 0x1000 >= r->next->low 510433965Sjdp && (r->next->high 510533965Sjdp <= (bfd_get_section_vma (info->abfd, s) 510633965Sjdp + bfd_section_size (info->abfd, s)))) 510733965Sjdp { 510833965Sjdp r = r->next; 510933965Sjdp high = r->high; 511033965Sjdp } 511133965Sjdp 511233965Sjdp if ((s->flags & SEC_CODE) != 0) 511333965Sjdp kind = 1; 511433965Sjdp else if ((s->flags & SEC_READONLY) != 0) 511533965Sjdp kind = 3; 511633965Sjdp else 511733965Sjdp kind = 2; 511833965Sjdp 511933965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 512033965Sjdp || ! ieee_write_byte (info, 11) 512133965Sjdp || ! ieee_write_number (info, 0) 512233965Sjdp || ! ieee_write_id (info, "") 512333965Sjdp || ! ieee_write_number (info, kind) 512433965Sjdp || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE) 512533965Sjdp || ! ieee_write_number (info, low) 512633965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 512733965Sjdp || ! ieee_write_number (info, high - low)) 512833965Sjdp return false; 512933965Sjdp 513033965Sjdp /* Add this range to the list of global ranges. */ 513133965Sjdp if (! ieee_add_range (info, true, low, high)) 513233965Sjdp return false; 513333965Sjdp } 513433965Sjdp 513533965Sjdp if (! ieee_write_byte (info, (int) ieee_be_record_enum)) 513633965Sjdp return false; 513733965Sjdp 513833965Sjdp return true; 513933965Sjdp} 514033965Sjdp 514133965Sjdp/* Add BB11 blocks describing each range that we have not already 514233965Sjdp described. */ 514333965Sjdp 514433965Sjdpstatic void 514533965Sjdpieee_add_bb11_blocks (abfd, sec, data) 514660484Sobrien bfd *abfd ATTRIBUTE_UNUSED; 514733965Sjdp asection *sec; 514833965Sjdp PTR data; 514933965Sjdp{ 515033965Sjdp struct ieee_handle *info = (struct ieee_handle *) data; 515133965Sjdp bfd_vma low, high; 515233965Sjdp struct ieee_range *r; 515333965Sjdp 515433965Sjdp low = bfd_get_section_vma (abfd, sec); 515533965Sjdp high = low + bfd_section_size (abfd, sec); 515633965Sjdp 515733965Sjdp /* Find the first range at or after this section. The ranges are 515833965Sjdp sorted by address. */ 515933965Sjdp for (r = info->global_ranges; r != NULL; r = r->next) 516033965Sjdp if (r->high > low) 516133965Sjdp break; 516233965Sjdp 516333965Sjdp while (low < high) 516433965Sjdp { 516533965Sjdp if (r == NULL || r->low >= high) 516633965Sjdp { 516733965Sjdp if (! ieee_add_bb11 (info, sec, low, high)) 516833965Sjdp info->error = true; 516933965Sjdp return; 517033965Sjdp } 517133965Sjdp 517233965Sjdp if (low < r->low 517333965Sjdp && r->low - low > 0x100) 517433965Sjdp { 517533965Sjdp if (! ieee_add_bb11 (info, sec, low, r->low)) 517633965Sjdp { 517733965Sjdp info->error = true; 517833965Sjdp return; 517933965Sjdp } 518033965Sjdp } 518133965Sjdp low = r->high; 518233965Sjdp 518333965Sjdp r = r->next; 518433965Sjdp } 518533965Sjdp} 518633965Sjdp 518733965Sjdp/* Add a single BB11 block for a range. We add it to info->vars. */ 518833965Sjdp 518933965Sjdpstatic boolean 519033965Sjdpieee_add_bb11 (info, sec, low, high) 519133965Sjdp struct ieee_handle *info; 519233965Sjdp asection *sec; 519333965Sjdp bfd_vma low; 519433965Sjdp bfd_vma high; 519533965Sjdp{ 519633965Sjdp int kind; 519733965Sjdp 519833965Sjdp if (! ieee_buffer_emptyp (&info->vars)) 519933965Sjdp { 520033965Sjdp if (! ieee_change_buffer (info, &info->vars)) 520133965Sjdp return false; 520233965Sjdp } 520333965Sjdp else 520433965Sjdp { 520577298Sobrien const char *filename, *modname; 520677298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 520777298Sobrien const char *backslash; 520877298Sobrien#endif 520933965Sjdp char *c, *s; 521033965Sjdp 521133965Sjdp /* Start the enclosing BB10 block. */ 521233965Sjdp filename = bfd_get_filename (info->abfd); 521333965Sjdp modname = strrchr (filename, '/'); 521477298Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 521577298Sobrien backslash = strrchr (filename, '\\'); 521677298Sobrien if (modname == NULL || (backslash != NULL && backslash > modname)) 521761843Sobrien modname = backslash; 521877298Sobrien#endif 521961843Sobrien 522033965Sjdp if (modname != NULL) 522133965Sjdp ++modname; 522261843Sobrien#ifdef HAVE_DOS_BASED_FILE_SYSTEM 522361843Sobrien else if (filename[0] && filename[1] == ':') 522461843Sobrien modname = filename + 2; 522561843Sobrien#endif 522633965Sjdp else 522761843Sobrien modname = filename; 522861843Sobrien 522933965Sjdp c = xstrdup (modname); 523033965Sjdp s = strrchr (c, '.'); 523133965Sjdp if (s != NULL) 523233965Sjdp *s = '\0'; 523333965Sjdp 523433965Sjdp if (! ieee_change_buffer (info, &info->vars) 523533965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 523633965Sjdp || ! ieee_write_byte (info, 10) 523733965Sjdp || ! ieee_write_number (info, 0) 523833965Sjdp || ! ieee_write_id (info, c) 523933965Sjdp || ! ieee_write_id (info, "") 524033965Sjdp || ! ieee_write_number (info, 0) 524133965Sjdp || ! ieee_write_id (info, "GNU objcopy")) 524233965Sjdp return false; 524333965Sjdp 524433965Sjdp free (c); 524533965Sjdp } 524633965Sjdp 524733965Sjdp if ((sec->flags & SEC_CODE) != 0) 524833965Sjdp kind = 1; 524933965Sjdp else if ((sec->flags & SEC_READONLY) != 0) 525033965Sjdp kind = 3; 525133965Sjdp else 525233965Sjdp kind = 2; 525333965Sjdp 525433965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 525533965Sjdp || ! ieee_write_byte (info, 11) 525633965Sjdp || ! ieee_write_number (info, 0) 525733965Sjdp || ! ieee_write_id (info, "") 525833965Sjdp || ! ieee_write_number (info, kind) 525933965Sjdp || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE) 526033965Sjdp || ! ieee_write_number (info, low) 526133965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 526233965Sjdp || ! ieee_write_number (info, high - low)) 526333965Sjdp return false; 526433965Sjdp 526533965Sjdp return true; 526633965Sjdp} 526733965Sjdp 526833965Sjdp/* Start recording information from a particular source file. This is 526933965Sjdp used to record which file defined which types, variables, etc. It 527033965Sjdp is not used for line numbers, since the lineno entry point passes 527133965Sjdp down the file name anyhow. IEEE debugging information doesn't seem 527233965Sjdp to store this information anywhere. */ 527333965Sjdp 527433965Sjdpstatic boolean 527533965Sjdpieee_start_source (p, filename) 527660484Sobrien PTR p ATTRIBUTE_UNUSED; 527760484Sobrien const char *filename ATTRIBUTE_UNUSED; 527833965Sjdp{ 527933965Sjdp return true; 528033965Sjdp} 528133965Sjdp 528233965Sjdp/* Make an empty type. */ 528333965Sjdp 528433965Sjdpstatic boolean 528533965Sjdpieee_empty_type (p) 528633965Sjdp PTR p; 528733965Sjdp{ 528833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 528933965Sjdp 529033965Sjdp return ieee_push_type (info, (int) builtin_unknown, 0, false, false); 529133965Sjdp} 529233965Sjdp 529333965Sjdp/* Make a void type. */ 529433965Sjdp 529533965Sjdpstatic boolean 529633965Sjdpieee_void_type (p) 529733965Sjdp PTR p; 529833965Sjdp{ 529933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 530033965Sjdp 530133965Sjdp return ieee_push_type (info, (int) builtin_void, 0, false, false); 530233965Sjdp} 530333965Sjdp 530433965Sjdp/* Make an integer type. */ 530533965Sjdp 530633965Sjdpstatic boolean 530733965Sjdpieee_int_type (p, size, unsignedp) 530833965Sjdp PTR p; 530933965Sjdp unsigned int size; 531033965Sjdp boolean unsignedp; 531133965Sjdp{ 531233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 531333965Sjdp unsigned int indx; 531433965Sjdp 531533965Sjdp switch (size) 531633965Sjdp { 531733965Sjdp case 1: 531833965Sjdp indx = (int) builtin_signed_char; 531933965Sjdp break; 532033965Sjdp case 2: 532133965Sjdp indx = (int) builtin_signed_short_int; 532233965Sjdp break; 532333965Sjdp case 4: 532433965Sjdp indx = (int) builtin_signed_long; 532533965Sjdp break; 532633965Sjdp case 8: 532733965Sjdp indx = (int) builtin_signed_long_long; 532833965Sjdp break; 532933965Sjdp default: 533060484Sobrien fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size); 533133965Sjdp return false; 533233965Sjdp } 533333965Sjdp 533433965Sjdp if (unsignedp) 533533965Sjdp ++indx; 533633965Sjdp 533733965Sjdp return ieee_push_type (info, indx, size, unsignedp, false); 533833965Sjdp} 533933965Sjdp 534033965Sjdp/* Make a floating point type. */ 534133965Sjdp 534233965Sjdpstatic boolean 534333965Sjdpieee_float_type (p, size) 534433965Sjdp PTR p; 534533965Sjdp unsigned int size; 534633965Sjdp{ 534733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 534833965Sjdp unsigned int indx; 534933965Sjdp 535033965Sjdp switch (size) 535133965Sjdp { 535233965Sjdp case 4: 535333965Sjdp indx = (int) builtin_float; 535433965Sjdp break; 535533965Sjdp case 8: 535633965Sjdp indx = (int) builtin_double; 535733965Sjdp break; 535833965Sjdp case 12: 535933965Sjdp /* FIXME: This size really depends upon the processor. */ 536033965Sjdp indx = (int) builtin_long_double; 536133965Sjdp break; 536233965Sjdp case 16: 536333965Sjdp indx = (int) builtin_long_long_double; 536433965Sjdp break; 536533965Sjdp default: 536660484Sobrien fprintf (stderr, _("IEEE unsupported float type size %u\n"), size); 536733965Sjdp return false; 536833965Sjdp } 536933965Sjdp 537033965Sjdp return ieee_push_type (info, indx, size, false, false); 537133965Sjdp} 537233965Sjdp 537333965Sjdp/* Make a complex type. */ 537433965Sjdp 537533965Sjdpstatic boolean 537633965Sjdpieee_complex_type (p, size) 537733965Sjdp PTR p; 537833965Sjdp unsigned int size; 537933965Sjdp{ 538033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 538133965Sjdp char code; 538233965Sjdp 538333965Sjdp switch (size) 538433965Sjdp { 538533965Sjdp case 4: 538633965Sjdp if (info->complex_float_index != 0) 538733965Sjdp return ieee_push_type (info, info->complex_float_index, size * 2, 538833965Sjdp false, false); 538933965Sjdp code = 'c'; 539033965Sjdp break; 539133965Sjdp case 12: 539233965Sjdp case 16: 539333965Sjdp /* These cases can be output by gcc -gstabs. Outputting the 539433965Sjdp wrong type is better than crashing. */ 539533965Sjdp case 8: 539633965Sjdp if (info->complex_double_index != 0) 539733965Sjdp return ieee_push_type (info, info->complex_double_index, size * 2, 539833965Sjdp false, false); 539933965Sjdp code = 'd'; 540033965Sjdp break; 540133965Sjdp default: 540260484Sobrien fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size); 540333965Sjdp return false; 540433965Sjdp } 540533965Sjdp 540633965Sjdp /* FIXME: I don't know what the string is for. */ 540733965Sjdp if (! ieee_define_type (info, size * 2, false, false) 540833965Sjdp || ! ieee_write_number (info, code) 540933965Sjdp || ! ieee_write_id (info, "")) 541033965Sjdp return false; 541133965Sjdp 541233965Sjdp if (size == 4) 541333965Sjdp info->complex_float_index = info->type_stack->type.indx; 541433965Sjdp else 541533965Sjdp info->complex_double_index = info->type_stack->type.indx; 541633965Sjdp 541733965Sjdp return true; 541833965Sjdp} 541933965Sjdp 542033965Sjdp/* Make a boolean type. IEEE doesn't support these, so we just make 542133965Sjdp an integer type instead. */ 542233965Sjdp 542333965Sjdpstatic boolean 542433965Sjdpieee_bool_type (p, size) 542533965Sjdp PTR p; 542633965Sjdp unsigned int size; 542733965Sjdp{ 542833965Sjdp return ieee_int_type (p, size, true); 542933965Sjdp} 543033965Sjdp 543133965Sjdp/* Make an enumeration. */ 543233965Sjdp 543333965Sjdpstatic boolean 543433965Sjdpieee_enum_type (p, tag, names, vals) 543533965Sjdp PTR p; 543633965Sjdp const char *tag; 543733965Sjdp const char **names; 543833965Sjdp bfd_signed_vma *vals; 543933965Sjdp{ 544033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 544133965Sjdp struct ieee_defined_enum *e; 544233965Sjdp boolean localp, simple; 544333965Sjdp unsigned int indx; 544433965Sjdp int i = 0; 544533965Sjdp 544633965Sjdp localp = false; 544733965Sjdp indx = (unsigned int) -1; 544833965Sjdp for (e = info->enums; e != NULL; e = e->next) 544933965Sjdp { 545033965Sjdp if (tag == NULL) 545133965Sjdp { 545233965Sjdp if (e->tag != NULL) 545333965Sjdp continue; 545433965Sjdp } 545533965Sjdp else 545633965Sjdp { 545733965Sjdp if (e->tag == NULL 545833965Sjdp || tag[0] != e->tag[0] 545933965Sjdp || strcmp (tag, e->tag) != 0) 546033965Sjdp continue; 546133965Sjdp } 546233965Sjdp 546333965Sjdp if (! e->defined) 546433965Sjdp { 546533965Sjdp /* This enum tag has been seen but not defined. */ 546633965Sjdp indx = e->indx; 546733965Sjdp break; 546833965Sjdp } 546933965Sjdp 547033965Sjdp if (names != NULL && e->names != NULL) 547133965Sjdp { 547233965Sjdp for (i = 0; names[i] != NULL && e->names[i] != NULL; i++) 547333965Sjdp { 547433965Sjdp if (names[i][0] != e->names[i][0] 547533965Sjdp || vals[i] != e->vals[i] 547633965Sjdp || strcmp (names[i], e->names[i]) != 0) 547733965Sjdp break; 547833965Sjdp } 547933965Sjdp } 548033965Sjdp 548133965Sjdp if ((names == NULL && e->names == NULL) 548233965Sjdp || (names != NULL 548333965Sjdp && e->names != NULL 548433965Sjdp && names[i] == NULL 548533965Sjdp && e->names[i] == NULL)) 548633965Sjdp { 548733965Sjdp /* We've seen this enum before. */ 548833965Sjdp return ieee_push_type (info, e->indx, 0, true, false); 548933965Sjdp } 549033965Sjdp 549133965Sjdp if (tag != NULL) 549233965Sjdp { 549333965Sjdp /* We've already seen an enum of the same name, so we must make 549433965Sjdp sure to output this one locally. */ 549533965Sjdp localp = true; 549633965Sjdp break; 549733965Sjdp } 549833965Sjdp } 549933965Sjdp 550033965Sjdp /* If this is a simple enumeration, in which the values start at 0 550133965Sjdp and always increment by 1, we can use type E. Otherwise we must 550233965Sjdp use type N. */ 550333965Sjdp 550433965Sjdp simple = true; 550533965Sjdp if (names != NULL) 550633965Sjdp { 550733965Sjdp for (i = 0; names[i] != NULL; i++) 550833965Sjdp { 550933965Sjdp if (vals[i] != i) 551033965Sjdp { 551133965Sjdp simple = false; 551233965Sjdp break; 551333965Sjdp } 551433965Sjdp } 551533965Sjdp } 551633965Sjdp 551733965Sjdp if (! ieee_define_named_type (info, tag, indx, 0, true, localp, 551833965Sjdp (struct ieee_buflist *) NULL) 551933965Sjdp || ! ieee_write_number (info, simple ? 'E' : 'N')) 552033965Sjdp return false; 552133965Sjdp if (simple) 552233965Sjdp { 552333965Sjdp /* FIXME: This is supposed to be the enumeration size, but we 552433965Sjdp don't store that. */ 552533965Sjdp if (! ieee_write_number (info, 4)) 552633965Sjdp return false; 552733965Sjdp } 552833965Sjdp if (names != NULL) 552933965Sjdp { 553033965Sjdp for (i = 0; names[i] != NULL; i++) 553133965Sjdp { 553233965Sjdp if (! ieee_write_id (info, names[i])) 553333965Sjdp return false; 553433965Sjdp if (! simple) 553533965Sjdp { 553633965Sjdp if (! ieee_write_number (info, vals[i])) 553733965Sjdp return false; 553833965Sjdp } 553933965Sjdp } 554033965Sjdp } 554133965Sjdp 554233965Sjdp if (! localp) 554333965Sjdp { 554433965Sjdp if (indx == (unsigned int) -1) 554533965Sjdp { 554633965Sjdp e = (struct ieee_defined_enum *) xmalloc (sizeof *e); 554733965Sjdp memset (e, 0, sizeof *e); 554833965Sjdp e->indx = info->type_stack->type.indx; 554933965Sjdp e->tag = tag; 555033965Sjdp 555133965Sjdp e->next = info->enums; 555233965Sjdp info->enums = e; 555333965Sjdp } 555433965Sjdp 555533965Sjdp e->names = names; 555633965Sjdp e->vals = vals; 555733965Sjdp e->defined = true; 555833965Sjdp } 555933965Sjdp 556033965Sjdp return true; 556133965Sjdp} 556233965Sjdp 556333965Sjdp/* Make a pointer type. */ 556433965Sjdp 556533965Sjdpstatic boolean 556633965Sjdpieee_pointer_type (p) 556733965Sjdp PTR p; 556833965Sjdp{ 556933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 557033965Sjdp boolean localp; 557133965Sjdp unsigned int indx; 557233965Sjdp struct ieee_modified_type *m = NULL; 557333965Sjdp 557433965Sjdp localp = info->type_stack->type.localp; 557533965Sjdp indx = ieee_pop_type (info); 557633965Sjdp 557733965Sjdp /* A pointer to a simple builtin type can be obtained by adding 32. 557833965Sjdp FIXME: Will this be a short pointer, and will that matter? */ 557933965Sjdp if (indx < 32) 558033965Sjdp return ieee_push_type (info, indx + 32, 0, true, false); 558133965Sjdp 558233965Sjdp if (! localp) 558333965Sjdp { 558433965Sjdp m = ieee_get_modified_info (p, indx); 558533965Sjdp if (m == NULL) 558633965Sjdp return false; 558733965Sjdp 558833965Sjdp /* FIXME: The size should depend upon the architecture. */ 558933965Sjdp if (m->pointer > 0) 559033965Sjdp return ieee_push_type (info, m->pointer, 4, true, false); 559133965Sjdp } 559233965Sjdp 559333965Sjdp if (! ieee_define_type (info, 4, true, localp) 559433965Sjdp || ! ieee_write_number (info, 'P') 559533965Sjdp || ! ieee_write_number (info, indx)) 559633965Sjdp return false; 559733965Sjdp 559833965Sjdp if (! localp) 559933965Sjdp m->pointer = info->type_stack->type.indx; 560033965Sjdp 560133965Sjdp return true; 560233965Sjdp} 560333965Sjdp 560433965Sjdp/* Make a function type. This will be called for a method, but we 560533965Sjdp don't want to actually add it to the type table in that case. We 560633965Sjdp handle this by defining the type in a private buffer, and only 560733965Sjdp adding that buffer to the typedef block if we are going to use it. */ 560833965Sjdp 560933965Sjdpstatic boolean 561033965Sjdpieee_function_type (p, argcount, varargs) 561133965Sjdp PTR p; 561233965Sjdp int argcount; 561333965Sjdp boolean varargs; 561433965Sjdp{ 561533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 561633965Sjdp boolean localp; 561733965Sjdp unsigned int *args = NULL; 561833965Sjdp int i; 561933965Sjdp unsigned int retindx; 562033965Sjdp struct ieee_buflist fndef; 562133965Sjdp struct ieee_modified_type *m; 562233965Sjdp 562333965Sjdp localp = false; 562433965Sjdp 562533965Sjdp if (argcount > 0) 562633965Sjdp { 562733965Sjdp args = (unsigned int *) xmalloc (argcount * sizeof *args); 562833965Sjdp for (i = argcount - 1; i >= 0; i--) 562933965Sjdp { 563033965Sjdp if (info->type_stack->type.localp) 563133965Sjdp localp = true; 563233965Sjdp args[i] = ieee_pop_type (info); 563333965Sjdp } 563433965Sjdp } 563533965Sjdp else if (argcount < 0) 563633965Sjdp varargs = false; 563733965Sjdp 563833965Sjdp if (info->type_stack->type.localp) 563933965Sjdp localp = true; 564033965Sjdp retindx = ieee_pop_type (info); 564133965Sjdp 564233965Sjdp m = NULL; 564333965Sjdp if (argcount < 0 && ! localp) 564433965Sjdp { 564533965Sjdp m = ieee_get_modified_info (p, retindx); 564633965Sjdp if (m == NULL) 564733965Sjdp return false; 564833965Sjdp 564933965Sjdp if (m->function > 0) 565033965Sjdp return ieee_push_type (info, m->function, 0, true, false); 565133965Sjdp } 565233965Sjdp 565333965Sjdp /* An attribute of 0x41 means that the frame and push mask are 565433965Sjdp unknown. */ 565533965Sjdp if (! ieee_init_buffer (info, &fndef) 565633965Sjdp || ! ieee_define_named_type (info, (const char *) NULL, 565733965Sjdp (unsigned int) -1, 0, true, localp, 565833965Sjdp &fndef) 565933965Sjdp || ! ieee_write_number (info, 'x') 566033965Sjdp || ! ieee_write_number (info, 0x41) 566133965Sjdp || ! ieee_write_number (info, 0) 566233965Sjdp || ! ieee_write_number (info, 0) 566333965Sjdp || ! ieee_write_number (info, retindx) 566433965Sjdp || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0))) 566533965Sjdp return false; 566633965Sjdp if (argcount > 0) 566733965Sjdp { 566833965Sjdp for (i = 0; i < argcount; i++) 566933965Sjdp if (! ieee_write_number (info, args[i])) 567033965Sjdp return false; 567133965Sjdp free (args); 567233965Sjdp } 567333965Sjdp if (varargs) 567433965Sjdp { 567533965Sjdp /* A varargs function is represented by writing out the last 567633965Sjdp argument as type void *, although this makes little sense. */ 567733965Sjdp if (! ieee_write_number (info, (bfd_vma) builtin_void + 32)) 567833965Sjdp return false; 567933965Sjdp } 568033965Sjdp 568133965Sjdp if (! ieee_write_number (info, 0)) 568233965Sjdp return false; 568333965Sjdp 568433965Sjdp /* We wrote the information into fndef, in case we don't need it. 568533965Sjdp It will be appended to info->types by ieee_pop_type. */ 568633965Sjdp info->type_stack->type.fndef = fndef; 568733965Sjdp 568833965Sjdp if (m != NULL) 568933965Sjdp m->function = info->type_stack->type.indx; 569033965Sjdp 569133965Sjdp return true; 569233965Sjdp} 569333965Sjdp 569433965Sjdp/* Make a reference type. */ 569533965Sjdp 569633965Sjdpstatic boolean 569733965Sjdpieee_reference_type (p) 569833965Sjdp PTR p; 569933965Sjdp{ 570033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 570133965Sjdp 570233965Sjdp /* IEEE appears to record a normal pointer type, and then use a 570333965Sjdp pmisc record to indicate that it is really a reference. */ 570433965Sjdp 570533965Sjdp if (! ieee_pointer_type (p)) 570633965Sjdp return false; 570733965Sjdp info->type_stack->type.referencep = true; 570833965Sjdp return true; 570933965Sjdp} 571033965Sjdp 571133965Sjdp/* Make a range type. */ 571233965Sjdp 571333965Sjdpstatic boolean 571433965Sjdpieee_range_type (p, low, high) 571533965Sjdp PTR p; 571633965Sjdp bfd_signed_vma low; 571733965Sjdp bfd_signed_vma high; 571833965Sjdp{ 571933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 572033965Sjdp unsigned int size; 572133965Sjdp boolean unsignedp, localp; 572233965Sjdp 572333965Sjdp size = info->type_stack->type.size; 572433965Sjdp unsignedp = info->type_stack->type.unsignedp; 572533965Sjdp localp = info->type_stack->type.localp; 572633965Sjdp ieee_pop_unused_type (info); 572733965Sjdp return (ieee_define_type (info, size, unsignedp, localp) 572833965Sjdp && ieee_write_number (info, 'R') 572933965Sjdp && ieee_write_number (info, (bfd_vma) low) 573033965Sjdp && ieee_write_number (info, (bfd_vma) high) 573133965Sjdp && ieee_write_number (info, unsignedp ? 0 : 1) 573233965Sjdp && ieee_write_number (info, size)); 573333965Sjdp} 573433965Sjdp 573533965Sjdp/* Make an array type. */ 573633965Sjdp 573733965Sjdpstatic boolean 573833965Sjdpieee_array_type (p, low, high, stringp) 573933965Sjdp PTR p; 574033965Sjdp bfd_signed_vma low; 574133965Sjdp bfd_signed_vma high; 574260484Sobrien boolean stringp ATTRIBUTE_UNUSED; 574333965Sjdp{ 574433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 574533965Sjdp unsigned int eleindx; 574633965Sjdp boolean localp; 574733965Sjdp unsigned int size; 574833965Sjdp struct ieee_modified_type *m = NULL; 574933965Sjdp struct ieee_modified_array_type *a; 575033965Sjdp 575133965Sjdp /* IEEE does not store the range, so we just ignore it. */ 575233965Sjdp ieee_pop_unused_type (info); 575333965Sjdp localp = info->type_stack->type.localp; 575433965Sjdp size = info->type_stack->type.size; 575533965Sjdp eleindx = ieee_pop_type (info); 575633965Sjdp 575733965Sjdp /* If we don't know the range, treat the size as exactly one 575833965Sjdp element. */ 575933965Sjdp if (low < high) 576033965Sjdp size *= (high - low) + 1; 576133965Sjdp 576233965Sjdp if (! localp) 576333965Sjdp { 576433965Sjdp m = ieee_get_modified_info (info, eleindx); 576533965Sjdp if (m == NULL) 576633965Sjdp return false; 576733965Sjdp 576833965Sjdp for (a = m->arrays; a != NULL; a = a->next) 576933965Sjdp { 577033965Sjdp if (a->low == low && a->high == high) 577133965Sjdp return ieee_push_type (info, a->indx, size, false, false); 577233965Sjdp } 577333965Sjdp } 577433965Sjdp 577533965Sjdp if (! ieee_define_type (info, size, false, localp) 577633965Sjdp || ! ieee_write_number (info, low == 0 ? 'Z' : 'C') 577733965Sjdp || ! ieee_write_number (info, eleindx)) 577833965Sjdp return false; 577933965Sjdp if (low != 0) 578033965Sjdp { 578133965Sjdp if (! ieee_write_number (info, low)) 578233965Sjdp return false; 578333965Sjdp } 578433965Sjdp 578533965Sjdp if (! ieee_write_number (info, high + 1)) 578633965Sjdp return false; 578733965Sjdp 578833965Sjdp if (! localp) 578933965Sjdp { 579033965Sjdp a = (struct ieee_modified_array_type *) xmalloc (sizeof *a); 579133965Sjdp memset (a, 0, sizeof *a); 579233965Sjdp 579333965Sjdp a->indx = info->type_stack->type.indx; 579433965Sjdp a->low = low; 579533965Sjdp a->high = high; 579633965Sjdp 579733965Sjdp a->next = m->arrays; 579833965Sjdp m->arrays = a; 579933965Sjdp } 580033965Sjdp 580133965Sjdp return true; 580233965Sjdp} 580333965Sjdp 580433965Sjdp/* Make a set type. */ 580533965Sjdp 580633965Sjdpstatic boolean 580733965Sjdpieee_set_type (p, bitstringp) 580833965Sjdp PTR p; 580960484Sobrien boolean bitstringp ATTRIBUTE_UNUSED; 581033965Sjdp{ 581133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 581233965Sjdp boolean localp; 581333965Sjdp unsigned int eleindx; 581433965Sjdp 581533965Sjdp localp = info->type_stack->type.localp; 581633965Sjdp eleindx = ieee_pop_type (info); 581733965Sjdp 581833965Sjdp /* FIXME: We don't know the size, so we just use 4. */ 581933965Sjdp 582033965Sjdp return (ieee_define_type (info, 0, true, localp) 582133965Sjdp && ieee_write_number (info, 's') 582233965Sjdp && ieee_write_number (info, 4) 582333965Sjdp && ieee_write_number (info, eleindx)); 582433965Sjdp} 582533965Sjdp 582633965Sjdp/* Make an offset type. */ 582733965Sjdp 582833965Sjdpstatic boolean 582933965Sjdpieee_offset_type (p) 583033965Sjdp PTR p; 583133965Sjdp{ 583233965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 583333965Sjdp unsigned int targetindx, baseindx; 583433965Sjdp 583533965Sjdp targetindx = ieee_pop_type (info); 583633965Sjdp baseindx = ieee_pop_type (info); 583733965Sjdp 583833965Sjdp /* FIXME: The MRI C++ compiler does not appear to generate any 583933965Sjdp useful type information about an offset type. It just records a 584033965Sjdp pointer to member as an integer. The MRI/HP IEEE spec does 584133965Sjdp describe a pmisc record which can be used for a pointer to 584233965Sjdp member. Unfortunately, it does not describe the target type, 584333965Sjdp which seems pretty important. I'm going to punt this for now. */ 584433965Sjdp 584533965Sjdp return ieee_int_type (p, 4, true); 584677298Sobrien} 584733965Sjdp 584833965Sjdp/* Make a method type. */ 584933965Sjdp 585033965Sjdpstatic boolean 585133965Sjdpieee_method_type (p, domain, argcount, varargs) 585233965Sjdp PTR p; 585333965Sjdp boolean domain; 585433965Sjdp int argcount; 585533965Sjdp boolean varargs; 585633965Sjdp{ 585733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 585833965Sjdp 585933965Sjdp /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a 586033965Sjdp method, but the definition is incomplete. We just output an 'x' 586133965Sjdp type. */ 586233965Sjdp 586333965Sjdp if (domain) 586433965Sjdp ieee_pop_unused_type (info); 586533965Sjdp 586633965Sjdp return ieee_function_type (p, argcount, varargs); 586733965Sjdp} 586833965Sjdp 586933965Sjdp/* Make a const qualified type. */ 587033965Sjdp 587133965Sjdpstatic boolean 587233965Sjdpieee_const_type (p) 587333965Sjdp PTR p; 587433965Sjdp{ 587533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 587633965Sjdp unsigned int size; 587733965Sjdp boolean unsignedp, localp; 587833965Sjdp unsigned int indx; 587933965Sjdp struct ieee_modified_type *m = NULL; 588033965Sjdp 588133965Sjdp size = info->type_stack->type.size; 588233965Sjdp unsignedp = info->type_stack->type.unsignedp; 588333965Sjdp localp = info->type_stack->type.localp; 588433965Sjdp indx = ieee_pop_type (info); 588533965Sjdp 588633965Sjdp if (! localp) 588733965Sjdp { 588833965Sjdp m = ieee_get_modified_info (info, indx); 588933965Sjdp if (m == NULL) 589033965Sjdp return false; 589133965Sjdp 589233965Sjdp if (m->const_qualified > 0) 589333965Sjdp return ieee_push_type (info, m->const_qualified, size, unsignedp, 589433965Sjdp false); 589533965Sjdp } 589633965Sjdp 589733965Sjdp if (! ieee_define_type (info, size, unsignedp, localp) 589833965Sjdp || ! ieee_write_number (info, 'n') 589933965Sjdp || ! ieee_write_number (info, 1) 590033965Sjdp || ! ieee_write_number (info, indx)) 590133965Sjdp return false; 590233965Sjdp 590333965Sjdp if (! localp) 590433965Sjdp m->const_qualified = info->type_stack->type.indx; 590533965Sjdp 590633965Sjdp return true; 590733965Sjdp} 590833965Sjdp 590933965Sjdp/* Make a volatile qualified type. */ 591033965Sjdp 591133965Sjdpstatic boolean 591233965Sjdpieee_volatile_type (p) 591333965Sjdp PTR p; 591433965Sjdp{ 591533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 591633965Sjdp unsigned int size; 591733965Sjdp boolean unsignedp, localp; 591833965Sjdp unsigned int indx; 591933965Sjdp struct ieee_modified_type *m = NULL; 592033965Sjdp 592133965Sjdp size = info->type_stack->type.size; 592233965Sjdp unsignedp = info->type_stack->type.unsignedp; 592333965Sjdp localp = info->type_stack->type.localp; 592433965Sjdp indx = ieee_pop_type (info); 592533965Sjdp 592633965Sjdp if (! localp) 592733965Sjdp { 592833965Sjdp m = ieee_get_modified_info (info, indx); 592933965Sjdp if (m == NULL) 593033965Sjdp return false; 593133965Sjdp 593233965Sjdp if (m->volatile_qualified > 0) 593333965Sjdp return ieee_push_type (info, m->volatile_qualified, size, unsignedp, 593433965Sjdp false); 593533965Sjdp } 593633965Sjdp 593733965Sjdp if (! ieee_define_type (info, size, unsignedp, localp) 593833965Sjdp || ! ieee_write_number (info, 'n') 593933965Sjdp || ! ieee_write_number (info, 2) 594033965Sjdp || ! ieee_write_number (info, indx)) 594133965Sjdp return false; 594233965Sjdp 594333965Sjdp if (! localp) 594433965Sjdp m->volatile_qualified = info->type_stack->type.indx; 594533965Sjdp 594633965Sjdp return true; 594733965Sjdp} 594833965Sjdp 594933965Sjdp/* Convert an enum debug_visibility into a CXXFLAGS value. */ 595033965Sjdp 595133965Sjdpstatic unsigned int 595233965Sjdpieee_vis_to_flags (visibility) 595333965Sjdp enum debug_visibility visibility; 595433965Sjdp{ 595533965Sjdp switch (visibility) 595633965Sjdp { 595733965Sjdp default: 595833965Sjdp abort (); 595933965Sjdp case DEBUG_VISIBILITY_PUBLIC: 596033965Sjdp return CXXFLAGS_VISIBILITY_PUBLIC; 596133965Sjdp case DEBUG_VISIBILITY_PRIVATE: 596233965Sjdp return CXXFLAGS_VISIBILITY_PRIVATE; 596333965Sjdp case DEBUG_VISIBILITY_PROTECTED: 596433965Sjdp return CXXFLAGS_VISIBILITY_PROTECTED; 596533965Sjdp } 596633965Sjdp /*NOTREACHED*/ 596733965Sjdp} 596833965Sjdp 596933965Sjdp/* Start defining a struct type. We build it in the strdef field on 597033965Sjdp the stack, to avoid confusing type definitions required by the 597133965Sjdp fields with the struct type itself. */ 597233965Sjdp 597333965Sjdpstatic boolean 597433965Sjdpieee_start_struct_type (p, tag, id, structp, size) 597533965Sjdp PTR p; 597633965Sjdp const char *tag; 597733965Sjdp unsigned int id; 597833965Sjdp boolean structp; 597933965Sjdp unsigned int size; 598033965Sjdp{ 598133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 598233965Sjdp boolean localp, ignorep; 598333965Sjdp boolean copy; 598433965Sjdp char ab[20]; 598533965Sjdp const char *look; 598633965Sjdp struct ieee_name_type_hash_entry *h; 598733965Sjdp struct ieee_name_type *nt, *ntlook; 598833965Sjdp struct ieee_buflist strdef; 598933965Sjdp 599033965Sjdp localp = false; 599133965Sjdp ignorep = false; 599233965Sjdp 599333965Sjdp /* We need to create a tag for internal use even if we don't want 599433965Sjdp one for external use. This will let us refer to an anonymous 599533965Sjdp struct. */ 599633965Sjdp if (tag != NULL) 599733965Sjdp { 599833965Sjdp look = tag; 599933965Sjdp copy = false; 600033965Sjdp } 600133965Sjdp else 600233965Sjdp { 600333965Sjdp sprintf (ab, "__anon%u", id); 600433965Sjdp look = ab; 600533965Sjdp copy = true; 600633965Sjdp } 600733965Sjdp 600833965Sjdp /* If we already have references to the tag, we must use the 600933965Sjdp existing type index. */ 601033965Sjdp h = ieee_name_type_hash_lookup (&info->tags, look, true, copy); 601133965Sjdp if (h == NULL) 601233965Sjdp return false; 601333965Sjdp 601433965Sjdp nt = NULL; 601533965Sjdp for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next) 601633965Sjdp { 601733965Sjdp if (ntlook->id == id) 601833965Sjdp nt = ntlook; 601933965Sjdp else if (! ntlook->type.localp) 602033965Sjdp { 602133965Sjdp /* We are creating a duplicate definition of a globally 602233965Sjdp defined tag. Force it to be local to avoid 602333965Sjdp confusion. */ 602433965Sjdp localp = true; 602533965Sjdp } 602633965Sjdp } 602733965Sjdp 602833965Sjdp if (nt != NULL) 602933965Sjdp { 603033965Sjdp assert (localp == nt->type.localp); 603133965Sjdp if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp) 603233965Sjdp { 603333965Sjdp /* We've already seen a global definition of the type. 603433965Sjdp Ignore this new definition. */ 603533965Sjdp ignorep = true; 603633965Sjdp } 603733965Sjdp } 603833965Sjdp else 603933965Sjdp { 604033965Sjdp nt = (struct ieee_name_type *) xmalloc (sizeof *nt); 604133965Sjdp memset (nt, 0, sizeof *nt); 604233965Sjdp nt->id = id; 604333965Sjdp nt->type.name = h->root.string; 604433965Sjdp nt->next = h->types; 604533965Sjdp h->types = nt; 604633965Sjdp nt->type.indx = info->type_indx; 604733965Sjdp ++info->type_indx; 604833965Sjdp } 604933965Sjdp 605033965Sjdp nt->kind = DEBUG_KIND_ILLEGAL; 605133965Sjdp 605233965Sjdp if (! ieee_init_buffer (info, &strdef) 605333965Sjdp || ! ieee_define_named_type (info, tag, nt->type.indx, size, true, 605433965Sjdp localp, &strdef) 605533965Sjdp || ! ieee_write_number (info, structp ? 'S' : 'U') 605633965Sjdp || ! ieee_write_number (info, size)) 605733965Sjdp return false; 605833965Sjdp 605933965Sjdp if (! ignorep) 606033965Sjdp { 606133965Sjdp const char *hold; 606233965Sjdp 606333965Sjdp /* We never want nt->type.name to be NULL. We want the rest of 606433965Sjdp the type to be the object set up on the type stack; it will 606533965Sjdp have a NULL name if tag is NULL. */ 606633965Sjdp hold = nt->type.name; 606733965Sjdp nt->type = info->type_stack->type; 606833965Sjdp nt->type.name = hold; 606933965Sjdp } 607033965Sjdp 607133965Sjdp info->type_stack->type.name = tag; 607233965Sjdp info->type_stack->type.strdef = strdef; 607333965Sjdp info->type_stack->type.ignorep = ignorep; 607433965Sjdp 607533965Sjdp return true; 607633965Sjdp} 607733965Sjdp 607833965Sjdp/* Add a field to a struct. */ 607933965Sjdp 608033965Sjdpstatic boolean 608133965Sjdpieee_struct_field (p, name, bitpos, bitsize, visibility) 608233965Sjdp PTR p; 608333965Sjdp const char *name; 608433965Sjdp bfd_vma bitpos; 608533965Sjdp bfd_vma bitsize; 608633965Sjdp enum debug_visibility visibility; 608733965Sjdp{ 608833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 608933965Sjdp unsigned int size; 609033965Sjdp boolean unsignedp; 609133965Sjdp boolean referencep; 609233965Sjdp boolean localp; 609333965Sjdp unsigned int indx; 609433965Sjdp bfd_vma offset; 609533965Sjdp 609633965Sjdp assert (info->type_stack != NULL 609733965Sjdp && info->type_stack->next != NULL 609833965Sjdp && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); 609933965Sjdp 610033965Sjdp /* If we are ignoring this struct definition, just pop and ignore 610133965Sjdp the type. */ 610233965Sjdp if (info->type_stack->next->type.ignorep) 610333965Sjdp { 610433965Sjdp ieee_pop_unused_type (info); 610533965Sjdp return true; 610633965Sjdp } 610733965Sjdp 610833965Sjdp size = info->type_stack->type.size; 610933965Sjdp unsignedp = info->type_stack->type.unsignedp; 611033965Sjdp referencep = info->type_stack->type.referencep; 611133965Sjdp localp = info->type_stack->type.localp; 611233965Sjdp indx = ieee_pop_type (info); 611333965Sjdp 611433965Sjdp if (localp) 611533965Sjdp info->type_stack->type.localp = true; 611633965Sjdp 611733965Sjdp if (info->type_stack->type.classdef != NULL) 611833965Sjdp { 611933965Sjdp unsigned int flags; 612033965Sjdp unsigned int nindx; 612133965Sjdp 612233965Sjdp /* This is a class. We must add a description of this field to 612333965Sjdp the class records we are building. */ 612433965Sjdp 612533965Sjdp flags = ieee_vis_to_flags (visibility); 612633965Sjdp nindx = info->type_stack->type.classdef->indx; 612733965Sjdp if (! ieee_change_buffer (info, 612833965Sjdp &info->type_stack->type.classdef->pmiscbuf) 612933965Sjdp || ! ieee_write_asn (info, nindx, 'd') 613033965Sjdp || ! ieee_write_asn (info, nindx, flags) 613133965Sjdp || ! ieee_write_atn65 (info, nindx, name) 613233965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 613333965Sjdp return false; 613433965Sjdp info->type_stack->type.classdef->pmisccount += 4; 613533965Sjdp 613633965Sjdp if (referencep) 613733965Sjdp { 613833965Sjdp unsigned int nindx; 613933965Sjdp 614033965Sjdp /* We need to output a record recording that this field is 614133965Sjdp really of reference type. We put this on the refs field 614233965Sjdp of classdef, so that it can be appended to the C++ 614333965Sjdp records after the class is defined. */ 614433965Sjdp 614533965Sjdp nindx = info->name_indx; 614633965Sjdp ++info->name_indx; 614733965Sjdp 614833965Sjdp if (! ieee_change_buffer (info, 614933965Sjdp &info->type_stack->type.classdef->refs) 615033965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 615133965Sjdp || ! ieee_write_number (info, nindx) 615233965Sjdp || ! ieee_write_id (info, "") 615333965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 615433965Sjdp || ! ieee_write_number (info, nindx) 615533965Sjdp || ! ieee_write_number (info, 0) 615633965Sjdp || ! ieee_write_number (info, 62) 615733965Sjdp || ! ieee_write_number (info, 80) 615833965Sjdp || ! ieee_write_number (info, 4) 615933965Sjdp || ! ieee_write_asn (info, nindx, 'R') 616033965Sjdp || ! ieee_write_asn (info, nindx, 3) 616133965Sjdp || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name) 616233965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 616333965Sjdp return false; 616433965Sjdp } 616533965Sjdp } 616633965Sjdp 616733965Sjdp /* If the bitsize doesn't match the expected size, we need to output 616833965Sjdp a bitfield type. */ 616933965Sjdp if (size == 0 || bitsize == 0 || bitsize == size * 8) 617033965Sjdp offset = bitpos / 8; 617133965Sjdp else 617233965Sjdp { 617333965Sjdp if (! ieee_define_type (info, 0, unsignedp, 617433965Sjdp info->type_stack->type.localp) 617533965Sjdp || ! ieee_write_number (info, 'g') 617633965Sjdp || ! ieee_write_number (info, unsignedp ? 0 : 1) 617733965Sjdp || ! ieee_write_number (info, bitsize) 617833965Sjdp || ! ieee_write_number (info, indx)) 617933965Sjdp return false; 618033965Sjdp indx = ieee_pop_type (info); 618133965Sjdp offset = bitpos; 618233965Sjdp } 618333965Sjdp 618433965Sjdp /* Switch to the struct we are building in order to output this 618533965Sjdp field definition. */ 618633965Sjdp return (ieee_change_buffer (info, &info->type_stack->type.strdef) 618733965Sjdp && ieee_write_id (info, name) 618833965Sjdp && ieee_write_number (info, indx) 618933965Sjdp && ieee_write_number (info, offset)); 619033965Sjdp} 619133965Sjdp 619233965Sjdp/* Finish up a struct type. */ 619333965Sjdp 619433965Sjdpstatic boolean 619533965Sjdpieee_end_struct_type (p) 619633965Sjdp PTR p; 619733965Sjdp{ 619833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 619933965Sjdp struct ieee_buflist *pb; 620033965Sjdp 620133965Sjdp assert (info->type_stack != NULL 620233965Sjdp && ! ieee_buffer_emptyp (&info->type_stack->type.strdef)); 620333965Sjdp 620433965Sjdp /* If we were ignoring this struct definition because it was a 620533965Sjdp duplicate defintion, just through away whatever bytes we have 6206104834Sobrien accumulated. Leave the type on the stack. */ 620733965Sjdp if (info->type_stack->type.ignorep) 620833965Sjdp return true; 620933965Sjdp 621033965Sjdp /* If this is not a duplicate definition of this tag, then localp 621133965Sjdp will be false, and we can put it in the global type block. 621233965Sjdp FIXME: We should avoid outputting duplicate definitions which are 621333965Sjdp the same. */ 621433965Sjdp if (! info->type_stack->type.localp) 621533965Sjdp { 621633965Sjdp /* Make sure we have started the global type block. */ 621733965Sjdp if (ieee_buffer_emptyp (&info->global_types)) 621833965Sjdp { 621933965Sjdp if (! ieee_change_buffer (info, &info->global_types) 622033965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 622133965Sjdp || ! ieee_write_byte (info, 2) 622233965Sjdp || ! ieee_write_number (info, 0) 622333965Sjdp || ! ieee_write_id (info, "")) 622433965Sjdp return false; 622533965Sjdp } 622633965Sjdp pb = &info->global_types; 622733965Sjdp } 622833965Sjdp else 622933965Sjdp { 623033965Sjdp /* Make sure we have started the types block. */ 623133965Sjdp if (ieee_buffer_emptyp (&info->types)) 623233965Sjdp { 623333965Sjdp if (! ieee_change_buffer (info, &info->types) 623433965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 623533965Sjdp || ! ieee_write_byte (info, 1) 623633965Sjdp || ! ieee_write_number (info, 0) 623733965Sjdp || ! ieee_write_id (info, info->modname)) 623833965Sjdp return false; 623933965Sjdp } 624033965Sjdp pb = &info->types; 624133965Sjdp } 624233965Sjdp 624333965Sjdp /* Append the struct definition to the types. */ 624433965Sjdp if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef) 624533965Sjdp || ! ieee_init_buffer (info, &info->type_stack->type.strdef)) 624633965Sjdp return false; 624733965Sjdp 624833965Sjdp /* Leave the struct on the type stack. */ 624933965Sjdp 625033965Sjdp return true; 625133965Sjdp} 625233965Sjdp 625333965Sjdp/* Start a class type. */ 625433965Sjdp 625533965Sjdpstatic boolean 625633965Sjdpieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr) 625733965Sjdp PTR p; 625833965Sjdp const char *tag; 625933965Sjdp unsigned int id; 626033965Sjdp boolean structp; 626133965Sjdp unsigned int size; 626233965Sjdp boolean vptr; 626333965Sjdp boolean ownvptr; 626433965Sjdp{ 626533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 626633965Sjdp const char *vclass; 626733965Sjdp struct ieee_buflist pmiscbuf; 626833965Sjdp unsigned int indx; 626933965Sjdp struct ieee_type_class *classdef; 627033965Sjdp 627133965Sjdp /* A C++ class is output as a C++ struct along with a set of pmisc 627233965Sjdp records describing the class. */ 627333965Sjdp 627433965Sjdp /* We need to have a name so that we can associate the struct and 627533965Sjdp the class. */ 627633965Sjdp if (tag == NULL) 627733965Sjdp { 627833965Sjdp char *t; 627933965Sjdp 628033965Sjdp t = (char *) xmalloc (20); 628133965Sjdp sprintf (t, "__anon%u", id); 628233965Sjdp tag = t; 628333965Sjdp } 628433965Sjdp 628533965Sjdp /* We can't write out the virtual table information until we have 628633965Sjdp finished the class, because we don't know the virtual table size. 628733965Sjdp We get the size from the largest voffset we see. */ 628833965Sjdp vclass = NULL; 628933965Sjdp if (vptr && ! ownvptr) 629033965Sjdp { 629133965Sjdp vclass = info->type_stack->type.name; 629233965Sjdp assert (vclass != NULL); 629333965Sjdp /* We don't call ieee_pop_unused_type, since the class should 629433965Sjdp get defined. */ 629533965Sjdp (void) ieee_pop_type (info); 629633965Sjdp } 629733965Sjdp 629833965Sjdp if (! ieee_start_struct_type (p, tag, id, structp, size)) 629933965Sjdp return false; 630033965Sjdp 630133965Sjdp indx = info->name_indx; 630233965Sjdp ++info->name_indx; 630333965Sjdp 630433965Sjdp /* We write out pmisc records into the classdef field. We will 630533965Sjdp write out the pmisc start after we know the number of records we 630633965Sjdp need. */ 630733965Sjdp if (! ieee_init_buffer (info, &pmiscbuf) 630833965Sjdp || ! ieee_change_buffer (info, &pmiscbuf) 630933965Sjdp || ! ieee_write_asn (info, indx, 'T') 631033965Sjdp || ! ieee_write_asn (info, indx, structp ? 'o' : 'u') 631133965Sjdp || ! ieee_write_atn65 (info, indx, tag)) 631233965Sjdp return false; 631333965Sjdp 631433965Sjdp classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef); 631533965Sjdp memset (classdef, 0, sizeof *classdef); 631633965Sjdp 631733965Sjdp classdef->indx = indx; 631833965Sjdp classdef->pmiscbuf = pmiscbuf; 631933965Sjdp classdef->pmisccount = 3; 632033965Sjdp classdef->vclass = vclass; 632133965Sjdp classdef->ownvptr = ownvptr; 632233965Sjdp 632333965Sjdp info->type_stack->type.classdef = classdef; 632433965Sjdp 632533965Sjdp return true; 632633965Sjdp} 632733965Sjdp 632833965Sjdp/* Add a static member to a class. */ 632933965Sjdp 633033965Sjdpstatic boolean 633133965Sjdpieee_class_static_member (p, name, physname, visibility) 633233965Sjdp PTR p; 633333965Sjdp const char *name; 633433965Sjdp const char *physname; 633533965Sjdp enum debug_visibility visibility; 633633965Sjdp{ 633733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 633833965Sjdp unsigned int flags; 633933965Sjdp unsigned int nindx; 634033965Sjdp 634133965Sjdp /* We don't care about the type. Hopefully there will be a call to 634233965Sjdp ieee_variable declaring the physical name and the type, since 634333965Sjdp that is where an IEEE consumer must get the type. */ 634433965Sjdp ieee_pop_unused_type (info); 634533965Sjdp 634633965Sjdp assert (info->type_stack != NULL 634733965Sjdp && info->type_stack->type.classdef != NULL); 634833965Sjdp 634933965Sjdp flags = ieee_vis_to_flags (visibility); 635033965Sjdp flags |= CXXFLAGS_STATIC; 635133965Sjdp 635233965Sjdp nindx = info->type_stack->type.classdef->indx; 635333965Sjdp 635433965Sjdp if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) 635533965Sjdp || ! ieee_write_asn (info, nindx, 'd') 635633965Sjdp || ! ieee_write_asn (info, nindx, flags) 635733965Sjdp || ! ieee_write_atn65 (info, nindx, name) 635833965Sjdp || ! ieee_write_atn65 (info, nindx, physname)) 635933965Sjdp return false; 636033965Sjdp info->type_stack->type.classdef->pmisccount += 4; 636133965Sjdp 636233965Sjdp return true; 636333965Sjdp} 636433965Sjdp 636533965Sjdp/* Add a base class to a class. */ 636633965Sjdp 636733965Sjdpstatic boolean 636833965Sjdpieee_class_baseclass (p, bitpos, virtual, visibility) 636933965Sjdp PTR p; 637033965Sjdp bfd_vma bitpos; 637133965Sjdp boolean virtual; 637233965Sjdp enum debug_visibility visibility; 637333965Sjdp{ 637433965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 637533965Sjdp const char *bname; 637633965Sjdp boolean localp; 637733965Sjdp unsigned int bindx; 637833965Sjdp char *fname; 637933965Sjdp unsigned int flags; 638033965Sjdp unsigned int nindx; 638133965Sjdp 638233965Sjdp assert (info->type_stack != NULL 638333965Sjdp && info->type_stack->type.name != NULL 638433965Sjdp && info->type_stack->next != NULL 638533965Sjdp && info->type_stack->next->type.classdef != NULL 638633965Sjdp && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef)); 638733965Sjdp 638833965Sjdp bname = info->type_stack->type.name; 638933965Sjdp localp = info->type_stack->type.localp; 639033965Sjdp bindx = ieee_pop_type (info); 639133965Sjdp 639233965Sjdp /* We are currently defining both a struct and a class. We must 639333965Sjdp write out a field definition in the struct which holds the base 639433965Sjdp class. The stabs debugging reader will create a field named 639533965Sjdp _vb$CLASS for a virtual base class, so we just use that. FIXME: 639633965Sjdp we should not depend upon a detail of stabs debugging. */ 639733965Sjdp if (virtual) 639833965Sjdp { 639933965Sjdp fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$"); 640033965Sjdp sprintf (fname, "_vb$%s", bname); 640133965Sjdp flags = BASEFLAGS_VIRTUAL; 640233965Sjdp } 640333965Sjdp else 640433965Sjdp { 640533965Sjdp if (localp) 640633965Sjdp info->type_stack->type.localp = true; 640733965Sjdp 640833965Sjdp fname = (char *) xmalloc (strlen (bname) + sizeof "_b$"); 640933965Sjdp sprintf (fname, "_b$%s", bname); 641033965Sjdp 641133965Sjdp if (! ieee_change_buffer (info, &info->type_stack->type.strdef) 641233965Sjdp || ! ieee_write_id (info, fname) 641333965Sjdp || ! ieee_write_number (info, bindx) 641433965Sjdp || ! ieee_write_number (info, bitpos / 8)) 641533965Sjdp return false; 641633965Sjdp flags = 0; 641733965Sjdp } 641833965Sjdp 641933965Sjdp if (visibility == DEBUG_VISIBILITY_PRIVATE) 642033965Sjdp flags |= BASEFLAGS_PRIVATE; 642133965Sjdp 642233965Sjdp nindx = info->type_stack->type.classdef->indx; 642333965Sjdp 642433965Sjdp if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf) 642533965Sjdp || ! ieee_write_asn (info, nindx, 'b') 642633965Sjdp || ! ieee_write_asn (info, nindx, flags) 642733965Sjdp || ! ieee_write_atn65 (info, nindx, bname) 642833965Sjdp || ! ieee_write_asn (info, nindx, 0) 642933965Sjdp || ! ieee_write_atn65 (info, nindx, fname)) 643033965Sjdp return false; 643133965Sjdp info->type_stack->type.classdef->pmisccount += 5; 643233965Sjdp 643333965Sjdp free (fname); 643433965Sjdp 643533965Sjdp return true; 643633965Sjdp} 643733965Sjdp 643833965Sjdp/* Start building a method for a class. */ 643933965Sjdp 644033965Sjdpstatic boolean 644133965Sjdpieee_class_start_method (p, name) 644233965Sjdp PTR p; 644333965Sjdp const char *name; 644433965Sjdp{ 644533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 644633965Sjdp 644733965Sjdp assert (info->type_stack != NULL 644833965Sjdp && info->type_stack->type.classdef != NULL 644933965Sjdp && info->type_stack->type.classdef->method == NULL); 645033965Sjdp 645133965Sjdp info->type_stack->type.classdef->method = name; 645233965Sjdp 645333965Sjdp return true; 645433965Sjdp} 645533965Sjdp 645633965Sjdp/* Define a new method variant, either static or not. */ 645733965Sjdp 645833965Sjdpstatic boolean 645933965Sjdpieee_class_method_var (info, physname, visibility, staticp, constp, 646033965Sjdp volatilep, voffset, context) 646133965Sjdp struct ieee_handle *info; 646233965Sjdp const char *physname; 646333965Sjdp enum debug_visibility visibility; 646433965Sjdp boolean staticp; 646533965Sjdp boolean constp; 646633965Sjdp boolean volatilep; 646733965Sjdp bfd_vma voffset; 646833965Sjdp boolean context; 646933965Sjdp{ 647033965Sjdp unsigned int flags; 647133965Sjdp unsigned int nindx; 647233965Sjdp boolean virtual; 647333965Sjdp 647433965Sjdp /* We don't need the type of the method. An IEEE consumer which 647533965Sjdp wants the type must track down the function by the physical name 647633965Sjdp and get the type from that. */ 647733965Sjdp ieee_pop_unused_type (info); 647833965Sjdp 647933965Sjdp /* We don't use the context. FIXME: We probably ought to use it to 648033965Sjdp adjust the voffset somehow, but I don't really know how. */ 648133965Sjdp if (context) 648233965Sjdp ieee_pop_unused_type (info); 648333965Sjdp 648433965Sjdp assert (info->type_stack != NULL 648533965Sjdp && info->type_stack->type.classdef != NULL 648633965Sjdp && info->type_stack->type.classdef->method != NULL); 648733965Sjdp 648833965Sjdp flags = ieee_vis_to_flags (visibility); 648933965Sjdp 649033965Sjdp /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR, 649133965Sjdp CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE. */ 649233965Sjdp 649333965Sjdp if (staticp) 649433965Sjdp flags |= CXXFLAGS_STATIC; 649533965Sjdp if (constp) 649633965Sjdp flags |= CXXFLAGS_CONST; 649733965Sjdp if (volatilep) 649833965Sjdp flags |= CXXFLAGS_VOLATILE; 649933965Sjdp 650033965Sjdp nindx = info->type_stack->type.classdef->indx; 650133965Sjdp 650233965Sjdp virtual = context || voffset > 0; 650333965Sjdp 650433965Sjdp if (! ieee_change_buffer (info, 650533965Sjdp &info->type_stack->type.classdef->pmiscbuf) 650633965Sjdp || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm') 650733965Sjdp || ! ieee_write_asn (info, nindx, flags) 650833965Sjdp || ! ieee_write_atn65 (info, nindx, 650933965Sjdp info->type_stack->type.classdef->method) 651033965Sjdp || ! ieee_write_atn65 (info, nindx, physname)) 651133965Sjdp return false; 651233965Sjdp 651333965Sjdp if (virtual) 651433965Sjdp { 651533965Sjdp if (voffset > info->type_stack->type.classdef->voffset) 651633965Sjdp info->type_stack->type.classdef->voffset = voffset; 651733965Sjdp if (! ieee_write_asn (info, nindx, voffset)) 651833965Sjdp return false; 651933965Sjdp ++info->type_stack->type.classdef->pmisccount; 652033965Sjdp } 652133965Sjdp 652233965Sjdp if (! ieee_write_asn (info, nindx, 0)) 652333965Sjdp return false; 652433965Sjdp 652533965Sjdp info->type_stack->type.classdef->pmisccount += 5; 652633965Sjdp 652733965Sjdp return true; 652833965Sjdp} 652933965Sjdp 653033965Sjdp/* Define a new method variant. */ 653133965Sjdp 653233965Sjdpstatic boolean 653333965Sjdpieee_class_method_variant (p, physname, visibility, constp, volatilep, 653433965Sjdp voffset, context) 653533965Sjdp PTR p; 653633965Sjdp const char *physname; 653733965Sjdp enum debug_visibility visibility; 653833965Sjdp boolean constp; 653933965Sjdp boolean volatilep; 654033965Sjdp bfd_vma voffset; 654133965Sjdp boolean context; 654233965Sjdp{ 654333965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 654433965Sjdp 654533965Sjdp return ieee_class_method_var (info, physname, visibility, false, constp, 654633965Sjdp volatilep, voffset, context); 654733965Sjdp} 654833965Sjdp 654933965Sjdp/* Define a new static method variant. */ 655033965Sjdp 655133965Sjdpstatic boolean 655233965Sjdpieee_class_static_method_variant (p, physname, visibility, constp, volatilep) 655333965Sjdp PTR p; 655433965Sjdp const char *physname; 655533965Sjdp enum debug_visibility visibility; 655633965Sjdp boolean constp; 655733965Sjdp boolean volatilep; 655833965Sjdp{ 655933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 656033965Sjdp 656133965Sjdp return ieee_class_method_var (info, physname, visibility, true, constp, 656233965Sjdp volatilep, 0, false); 656333965Sjdp} 656433965Sjdp 656533965Sjdp/* Finish up a method. */ 656633965Sjdp 656733965Sjdpstatic boolean 656833965Sjdpieee_class_end_method (p) 656933965Sjdp PTR p; 657033965Sjdp{ 657133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 657233965Sjdp 657333965Sjdp assert (info->type_stack != NULL 657433965Sjdp && info->type_stack->type.classdef != NULL 657533965Sjdp && info->type_stack->type.classdef->method != NULL); 657633965Sjdp 657733965Sjdp info->type_stack->type.classdef->method = NULL; 657833965Sjdp 657933965Sjdp return true; 658033965Sjdp} 658133965Sjdp 658233965Sjdp/* Finish up a class. */ 658333965Sjdp 658433965Sjdpstatic boolean 658533965Sjdpieee_end_class_type (p) 658633965Sjdp PTR p; 658733965Sjdp{ 658833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 658933965Sjdp unsigned int nindx; 659033965Sjdp 659133965Sjdp assert (info->type_stack != NULL 659233965Sjdp && info->type_stack->type.classdef != NULL); 659333965Sjdp 659433965Sjdp /* If we were ignoring this class definition because it was a 659533965Sjdp duplicate definition, just through away whatever bytes we have 659633965Sjdp accumulated. Leave the type on the stack. */ 659733965Sjdp if (info->type_stack->type.ignorep) 659833965Sjdp return true; 659933965Sjdp 660033965Sjdp nindx = info->type_stack->type.classdef->indx; 660133965Sjdp 660233965Sjdp /* If we have a virtual table, we can write out the information now. */ 660333965Sjdp if (info->type_stack->type.classdef->vclass != NULL 660433965Sjdp || info->type_stack->type.classdef->ownvptr) 660533965Sjdp { 660633965Sjdp if (! ieee_change_buffer (info, 660733965Sjdp &info->type_stack->type.classdef->pmiscbuf) 660833965Sjdp || ! ieee_write_asn (info, nindx, 'z') 660933965Sjdp || ! ieee_write_atn65 (info, nindx, "") 661033965Sjdp || ! ieee_write_asn (info, nindx, 661133965Sjdp info->type_stack->type.classdef->voffset)) 661233965Sjdp return false; 661333965Sjdp if (info->type_stack->type.classdef->ownvptr) 661433965Sjdp { 661533965Sjdp if (! ieee_write_atn65 (info, nindx, "")) 661633965Sjdp return false; 661733965Sjdp } 661833965Sjdp else 661933965Sjdp { 662033965Sjdp if (! ieee_write_atn65 (info, nindx, 662133965Sjdp info->type_stack->type.classdef->vclass)) 662233965Sjdp return false; 662333965Sjdp } 662433965Sjdp if (! ieee_write_asn (info, nindx, 0)) 662533965Sjdp return false; 662633965Sjdp info->type_stack->type.classdef->pmisccount += 5; 662733965Sjdp } 662833965Sjdp 662933965Sjdp /* Now that we know the number of pmisc records, we can write out 663033965Sjdp the atn62 which starts the pmisc records, and append them to the 663133965Sjdp C++ buffers. */ 663233965Sjdp 663333965Sjdp if (! ieee_change_buffer (info, &info->cxx) 663433965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 663533965Sjdp || ! ieee_write_number (info, nindx) 663633965Sjdp || ! ieee_write_id (info, "") 663733965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 663833965Sjdp || ! ieee_write_number (info, nindx) 663933965Sjdp || ! ieee_write_number (info, 0) 664033965Sjdp || ! ieee_write_number (info, 62) 664133965Sjdp || ! ieee_write_number (info, 80) 664233965Sjdp || ! ieee_write_number (info, 664333965Sjdp info->type_stack->type.classdef->pmisccount)) 664433965Sjdp return false; 664533965Sjdp 664633965Sjdp if (! ieee_append_buffer (info, &info->cxx, 664733965Sjdp &info->type_stack->type.classdef->pmiscbuf)) 664833965Sjdp return false; 664933965Sjdp if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs)) 665033965Sjdp { 665133965Sjdp if (! ieee_append_buffer (info, &info->cxx, 665233965Sjdp &info->type_stack->type.classdef->refs)) 665333965Sjdp return false; 665433965Sjdp } 665533965Sjdp 665633965Sjdp return ieee_end_struct_type (p); 665733965Sjdp} 665833965Sjdp 665933965Sjdp/* Push a previously seen typedef onto the type stack. */ 666033965Sjdp 666133965Sjdpstatic boolean 666233965Sjdpieee_typedef_type (p, name) 666333965Sjdp PTR p; 666433965Sjdp const char *name; 666533965Sjdp{ 666633965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 666733965Sjdp struct ieee_name_type_hash_entry *h; 666833965Sjdp struct ieee_name_type *nt; 666933965Sjdp 667033965Sjdp h = ieee_name_type_hash_lookup (&info->typedefs, name, false, false); 667133965Sjdp 667233965Sjdp /* h should never be NULL, since that would imply that the generic 667333965Sjdp debugging code has asked for a typedef which it has not yet 667433965Sjdp defined. */ 667533965Sjdp assert (h != NULL); 667633965Sjdp 667733965Sjdp /* We always use the most recently defined type for this name, which 667833965Sjdp will be the first one on the list. */ 667933965Sjdp 668033965Sjdp nt = h->types; 668133965Sjdp if (! ieee_push_type (info, nt->type.indx, nt->type.size, 668233965Sjdp nt->type.unsignedp, nt->type.localp)) 668333965Sjdp return false; 668433965Sjdp 668533965Sjdp /* Copy over any other type information we may have. */ 668633965Sjdp info->type_stack->type = nt->type; 668733965Sjdp 668833965Sjdp return true; 668933965Sjdp} 669033965Sjdp 669133965Sjdp/* Push a tagged type onto the type stack. */ 669233965Sjdp 669333965Sjdpstatic boolean 669433965Sjdpieee_tag_type (p, name, id, kind) 669533965Sjdp PTR p; 669633965Sjdp const char *name; 669733965Sjdp unsigned int id; 669833965Sjdp enum debug_type_kind kind; 669933965Sjdp{ 670033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 670133965Sjdp boolean localp; 670233965Sjdp boolean copy; 670333965Sjdp char ab[20]; 670433965Sjdp struct ieee_name_type_hash_entry *h; 670533965Sjdp struct ieee_name_type *nt; 670633965Sjdp 670733965Sjdp if (kind == DEBUG_KIND_ENUM) 670833965Sjdp { 670933965Sjdp struct ieee_defined_enum *e; 671033965Sjdp 671133965Sjdp if (name == NULL) 671233965Sjdp abort (); 671333965Sjdp for (e = info->enums; e != NULL; e = e->next) 671433965Sjdp if (e->tag != NULL && strcmp (e->tag, name) == 0) 671533965Sjdp return ieee_push_type (info, e->indx, 0, true, false); 671633965Sjdp 671733965Sjdp e = (struct ieee_defined_enum *) xmalloc (sizeof *e); 671833965Sjdp memset (e, 0, sizeof *e); 671933965Sjdp 672033965Sjdp e->indx = info->type_indx; 672133965Sjdp ++info->type_indx; 672233965Sjdp e->tag = name; 672333965Sjdp e->defined = false; 672433965Sjdp 672533965Sjdp e->next = info->enums; 672633965Sjdp info->enums = e; 672733965Sjdp 672833965Sjdp return ieee_push_type (info, e->indx, 0, true, false); 672933965Sjdp } 673033965Sjdp 673133965Sjdp localp = false; 673233965Sjdp 673333965Sjdp copy = false; 673433965Sjdp if (name == NULL) 673533965Sjdp { 673633965Sjdp sprintf (ab, "__anon%u", id); 673733965Sjdp name = ab; 673833965Sjdp copy = true; 673933965Sjdp } 674033965Sjdp 674133965Sjdp h = ieee_name_type_hash_lookup (&info->tags, name, true, copy); 674233965Sjdp if (h == NULL) 674333965Sjdp return false; 674433965Sjdp 674533965Sjdp for (nt = h->types; nt != NULL; nt = nt->next) 674633965Sjdp { 674733965Sjdp if (nt->id == id) 674833965Sjdp { 674933965Sjdp if (! ieee_push_type (info, nt->type.indx, nt->type.size, 675033965Sjdp nt->type.unsignedp, nt->type.localp)) 675133965Sjdp return false; 675233965Sjdp /* Copy over any other type information we may have. */ 675333965Sjdp info->type_stack->type = nt->type; 675433965Sjdp return true; 675533965Sjdp } 675633965Sjdp 675733965Sjdp if (! nt->type.localp) 675833965Sjdp { 675933965Sjdp /* This is a duplicate of a global type, so it must be 6760104834Sobrien local. */ 676133965Sjdp localp = true; 676233965Sjdp } 676333965Sjdp } 676433965Sjdp 676533965Sjdp nt = (struct ieee_name_type *) xmalloc (sizeof *nt); 676633965Sjdp memset (nt, 0, sizeof *nt); 676733965Sjdp 676833965Sjdp nt->id = id; 676933965Sjdp nt->type.name = h->root.string; 677033965Sjdp nt->type.indx = info->type_indx; 677133965Sjdp nt->type.localp = localp; 677233965Sjdp ++info->type_indx; 677333965Sjdp nt->kind = kind; 677433965Sjdp 677533965Sjdp nt->next = h->types; 677633965Sjdp h->types = nt; 677733965Sjdp 677833965Sjdp if (! ieee_push_type (info, nt->type.indx, 0, false, localp)) 677933965Sjdp return false; 678033965Sjdp 678133965Sjdp info->type_stack->type.name = h->root.string; 678233965Sjdp 678333965Sjdp return true; 678433965Sjdp} 678533965Sjdp 678633965Sjdp/* Output a typedef. */ 678733965Sjdp 678833965Sjdpstatic boolean 678933965Sjdpieee_typdef (p, name) 679033965Sjdp PTR p; 679133965Sjdp const char *name; 679233965Sjdp{ 679333965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 679433965Sjdp struct ieee_write_type type; 679533965Sjdp unsigned int indx; 679633965Sjdp boolean found; 679733965Sjdp boolean localp; 679833965Sjdp struct ieee_name_type_hash_entry *h; 679933965Sjdp struct ieee_name_type *nt; 680033965Sjdp 680133965Sjdp type = info->type_stack->type; 680233965Sjdp indx = type.indx; 680333965Sjdp 680433965Sjdp /* If this is a simple builtin type using a builtin name, we don't 680533965Sjdp want to output the typedef itself. We also want to change the 680633965Sjdp type index to correspond to the name being used. We recognize 680733965Sjdp names used in stabs debugging output even if they don't exactly 680833965Sjdp correspond to the names used for the IEEE builtin types. */ 680933965Sjdp found = false; 681033965Sjdp if (indx <= (unsigned int) builtin_bcd_float) 681133965Sjdp { 681233965Sjdp switch ((enum builtin_types) indx) 681333965Sjdp { 681433965Sjdp default: 681533965Sjdp break; 681633965Sjdp 681733965Sjdp case builtin_void: 681833965Sjdp if (strcmp (name, "void") == 0) 681933965Sjdp found = true; 682033965Sjdp break; 682133965Sjdp 682233965Sjdp case builtin_signed_char: 682333965Sjdp case builtin_char: 682433965Sjdp if (strcmp (name, "signed char") == 0) 682533965Sjdp { 682633965Sjdp indx = (unsigned int) builtin_signed_char; 682733965Sjdp found = true; 682833965Sjdp } 682933965Sjdp else if (strcmp (name, "char") == 0) 683033965Sjdp { 683133965Sjdp indx = (unsigned int) builtin_char; 683233965Sjdp found = true; 683333965Sjdp } 683433965Sjdp break; 683533965Sjdp 683633965Sjdp case builtin_unsigned_char: 683733965Sjdp if (strcmp (name, "unsigned char") == 0) 683833965Sjdp found = true; 683933965Sjdp break; 684033965Sjdp 684133965Sjdp case builtin_signed_short_int: 684233965Sjdp case builtin_short: 684333965Sjdp case builtin_short_int: 684433965Sjdp case builtin_signed_short: 684533965Sjdp if (strcmp (name, "signed short int") == 0) 684633965Sjdp { 684733965Sjdp indx = (unsigned int) builtin_signed_short_int; 684833965Sjdp found = true; 684933965Sjdp } 685033965Sjdp else if (strcmp (name, "short") == 0) 685133965Sjdp { 685233965Sjdp indx = (unsigned int) builtin_short; 685333965Sjdp found = true; 685433965Sjdp } 685533965Sjdp else if (strcmp (name, "short int") == 0) 685633965Sjdp { 685733965Sjdp indx = (unsigned int) builtin_short_int; 685833965Sjdp found = true; 685933965Sjdp } 686033965Sjdp else if (strcmp (name, "signed short") == 0) 686133965Sjdp { 686233965Sjdp indx = (unsigned int) builtin_signed_short; 686333965Sjdp found = true; 686433965Sjdp } 686533965Sjdp break; 686633965Sjdp 686733965Sjdp case builtin_unsigned_short_int: 686833965Sjdp case builtin_unsigned_short: 686933965Sjdp if (strcmp (name, "unsigned short int") == 0 687033965Sjdp || strcmp (name, "short unsigned int") == 0) 687133965Sjdp { 687233965Sjdp indx = builtin_unsigned_short_int; 687333965Sjdp found = true; 687433965Sjdp } 687533965Sjdp else if (strcmp (name, "unsigned short") == 0) 687633965Sjdp { 687733965Sjdp indx = builtin_unsigned_short; 687833965Sjdp found = true; 687933965Sjdp } 688033965Sjdp break; 688133965Sjdp 688233965Sjdp case builtin_signed_long: 688333965Sjdp case builtin_int: /* FIXME: Size depends upon architecture. */ 688433965Sjdp case builtin_long: 688533965Sjdp if (strcmp (name, "signed long") == 0) 688633965Sjdp { 688733965Sjdp indx = builtin_signed_long; 688833965Sjdp found = true; 688933965Sjdp } 689033965Sjdp else if (strcmp (name, "int") == 0) 689133965Sjdp { 689233965Sjdp indx = builtin_int; 689333965Sjdp found = true; 689433965Sjdp } 689533965Sjdp else if (strcmp (name, "long") == 0 689633965Sjdp || strcmp (name, "long int") == 0) 689733965Sjdp { 689833965Sjdp indx = builtin_long; 689933965Sjdp found = true; 690033965Sjdp } 690133965Sjdp break; 690233965Sjdp 690333965Sjdp case builtin_unsigned_long: 690433965Sjdp case builtin_unsigned: /* FIXME: Size depends upon architecture. */ 690533965Sjdp case builtin_unsigned_int: /* FIXME: Like builtin_unsigned. */ 690633965Sjdp if (strcmp (name, "unsigned long") == 0 690733965Sjdp || strcmp (name, "long unsigned int") == 0) 690833965Sjdp { 690933965Sjdp indx = builtin_unsigned_long; 691033965Sjdp found = true; 691133965Sjdp } 691233965Sjdp else if (strcmp (name, "unsigned") == 0) 691333965Sjdp { 691433965Sjdp indx = builtin_unsigned; 691533965Sjdp found = true; 691633965Sjdp } 691733965Sjdp else if (strcmp (name, "unsigned int") == 0) 691833965Sjdp { 691933965Sjdp indx = builtin_unsigned_int; 692033965Sjdp found = true; 692133965Sjdp } 692233965Sjdp break; 692333965Sjdp 692433965Sjdp case builtin_signed_long_long: 692533965Sjdp if (strcmp (name, "signed long long") == 0 692633965Sjdp || strcmp (name, "long long int") == 0) 692733965Sjdp found = true; 692833965Sjdp break; 692933965Sjdp 693033965Sjdp case builtin_unsigned_long_long: 693133965Sjdp if (strcmp (name, "unsigned long long") == 0 693233965Sjdp || strcmp (name, "long long unsigned int") == 0) 693333965Sjdp found = true; 693433965Sjdp break; 693533965Sjdp 693633965Sjdp case builtin_float: 693733965Sjdp if (strcmp (name, "float") == 0) 693833965Sjdp found = true; 693933965Sjdp break; 694033965Sjdp 694133965Sjdp case builtin_double: 694233965Sjdp if (strcmp (name, "double") == 0) 694333965Sjdp found = true; 694433965Sjdp break; 694533965Sjdp 694633965Sjdp case builtin_long_double: 694733965Sjdp if (strcmp (name, "long double") == 0) 694833965Sjdp found = true; 694933965Sjdp break; 695033965Sjdp 695133965Sjdp case builtin_long_long_double: 695233965Sjdp if (strcmp (name, "long long double") == 0) 695333965Sjdp found = true; 695433965Sjdp break; 695533965Sjdp } 695633965Sjdp 695733965Sjdp if (found) 695833965Sjdp type.indx = indx; 695933965Sjdp } 696033965Sjdp 696133965Sjdp h = ieee_name_type_hash_lookup (&info->typedefs, name, true, false); 696233965Sjdp if (h == NULL) 696333965Sjdp return false; 696433965Sjdp 696533965Sjdp /* See if we have already defined this type with this name. */ 696633965Sjdp localp = type.localp; 696733965Sjdp for (nt = h->types; nt != NULL; nt = nt->next) 696833965Sjdp { 696933965Sjdp if (nt->id == indx) 697033965Sjdp { 697133965Sjdp /* If this is a global definition, then we don't need to 697233965Sjdp do anything here. */ 697333965Sjdp if (! nt->type.localp) 697433965Sjdp { 697533965Sjdp ieee_pop_unused_type (info); 697633965Sjdp return true; 697733965Sjdp } 697833965Sjdp } 697933965Sjdp else 698033965Sjdp { 698133965Sjdp /* This is a duplicate definition, so make this one local. */ 698233965Sjdp localp = true; 698333965Sjdp } 698433965Sjdp } 698533965Sjdp 698633965Sjdp /* We need to add a new typedef for this type. */ 698733965Sjdp 698833965Sjdp nt = (struct ieee_name_type *) xmalloc (sizeof *nt); 698933965Sjdp memset (nt, 0, sizeof *nt); 699033965Sjdp nt->id = indx; 699133965Sjdp nt->type = type; 699233965Sjdp nt->type.name = name; 699333965Sjdp nt->type.localp = localp; 699433965Sjdp nt->kind = DEBUG_KIND_ILLEGAL; 699533965Sjdp 699633965Sjdp nt->next = h->types; 699733965Sjdp h->types = nt; 699833965Sjdp 699933965Sjdp if (found) 700033965Sjdp { 700133965Sjdp /* This is one of the builtin typedefs, so we don't need to 700233965Sjdp actually define it. */ 700333965Sjdp ieee_pop_unused_type (info); 700433965Sjdp return true; 700533965Sjdp } 700633965Sjdp 700733965Sjdp indx = ieee_pop_type (info); 700833965Sjdp 700933965Sjdp if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size, 701033965Sjdp type.unsignedp, localp, 701133965Sjdp (struct ieee_buflist *) NULL) 701233965Sjdp || ! ieee_write_number (info, 'T') 701333965Sjdp || ! ieee_write_number (info, indx)) 701433965Sjdp return false; 701533965Sjdp 701633965Sjdp /* Remove the type we just added to the type stack. This should not 701733965Sjdp be ieee_pop_unused_type, since the type is used, we just don't 701833965Sjdp need it now. */ 701933965Sjdp (void) ieee_pop_type (info); 702033965Sjdp 702133965Sjdp return true; 702233965Sjdp} 702333965Sjdp 702433965Sjdp/* Output a tag for a type. We don't have to do anything here. */ 702533965Sjdp 702633965Sjdpstatic boolean 702733965Sjdpieee_tag (p, name) 702833965Sjdp PTR p; 702960484Sobrien const char *name ATTRIBUTE_UNUSED; 703033965Sjdp{ 703133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 703233965Sjdp 703333965Sjdp /* This should not be ieee_pop_unused_type, since we want the type 703433965Sjdp to be defined. */ 703533965Sjdp (void) ieee_pop_type (info); 703633965Sjdp return true; 703733965Sjdp} 703833965Sjdp 703933965Sjdp/* Output an integer constant. */ 704033965Sjdp 704133965Sjdpstatic boolean 704233965Sjdpieee_int_constant (p, name, val) 704360484Sobrien PTR p ATTRIBUTE_UNUSED; 704460484Sobrien const char *name ATTRIBUTE_UNUSED; 704560484Sobrien bfd_vma val ATTRIBUTE_UNUSED; 704633965Sjdp{ 704733965Sjdp /* FIXME. */ 704833965Sjdp return true; 704933965Sjdp} 705033965Sjdp 705133965Sjdp/* Output a floating point constant. */ 705233965Sjdp 705333965Sjdpstatic boolean 705433965Sjdpieee_float_constant (p, name, val) 705560484Sobrien PTR p ATTRIBUTE_UNUSED; 705660484Sobrien const char *name ATTRIBUTE_UNUSED; 705760484Sobrien double val ATTRIBUTE_UNUSED; 705833965Sjdp{ 705933965Sjdp /* FIXME. */ 706033965Sjdp return true; 706133965Sjdp} 706233965Sjdp 706333965Sjdp/* Output a typed constant. */ 706433965Sjdp 706533965Sjdpstatic boolean 706633965Sjdpieee_typed_constant (p, name, val) 706733965Sjdp PTR p; 706860484Sobrien const char *name ATTRIBUTE_UNUSED; 706960484Sobrien bfd_vma val ATTRIBUTE_UNUSED; 707033965Sjdp{ 707133965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 707233965Sjdp 707333965Sjdp /* FIXME. */ 707433965Sjdp ieee_pop_unused_type (info); 707533965Sjdp return true; 707633965Sjdp} 707733965Sjdp 707833965Sjdp/* Output a variable. */ 707933965Sjdp 708033965Sjdpstatic boolean 708133965Sjdpieee_variable (p, name, kind, val) 708233965Sjdp PTR p; 708333965Sjdp const char *name; 708433965Sjdp enum debug_var_kind kind; 708533965Sjdp bfd_vma val; 708633965Sjdp{ 708733965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 708833965Sjdp unsigned int name_indx; 708933965Sjdp unsigned int size; 709033965Sjdp boolean referencep; 709133965Sjdp unsigned int type_indx; 709233965Sjdp boolean asn; 709333965Sjdp int refflag; 709433965Sjdp 709533965Sjdp size = info->type_stack->type.size; 709633965Sjdp referencep = info->type_stack->type.referencep; 709733965Sjdp type_indx = ieee_pop_type (info); 709833965Sjdp 709933965Sjdp assert (! ieee_buffer_emptyp (&info->vars)); 710033965Sjdp if (! ieee_change_buffer (info, &info->vars)) 710133965Sjdp return false; 710233965Sjdp 710333965Sjdp name_indx = info->name_indx; 710433965Sjdp ++info->name_indx; 710533965Sjdp 710633965Sjdp /* Write out an NN and an ATN record for this variable. */ 710733965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 710833965Sjdp || ! ieee_write_number (info, name_indx) 710933965Sjdp || ! ieee_write_id (info, name) 711033965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 711133965Sjdp || ! ieee_write_number (info, name_indx) 711233965Sjdp || ! ieee_write_number (info, type_indx)) 711333965Sjdp return false; 711433965Sjdp switch (kind) 711533965Sjdp { 711633965Sjdp default: 711733965Sjdp abort (); 711833965Sjdp return false; 711933965Sjdp case DEBUG_GLOBAL: 712033965Sjdp if (! ieee_write_number (info, 8) 712133965Sjdp || ! ieee_add_range (info, false, val, val + size)) 712233965Sjdp return false; 712333965Sjdp refflag = 0; 712433965Sjdp asn = true; 712533965Sjdp break; 712633965Sjdp case DEBUG_STATIC: 712733965Sjdp if (! ieee_write_number (info, 3) 712833965Sjdp || ! ieee_add_range (info, false, val, val + size)) 712933965Sjdp return false; 713033965Sjdp refflag = 1; 713133965Sjdp asn = true; 713233965Sjdp break; 713333965Sjdp case DEBUG_LOCAL_STATIC: 713433965Sjdp if (! ieee_write_number (info, 3) 713533965Sjdp || ! ieee_add_range (info, false, val, val + size)) 713633965Sjdp return false; 713733965Sjdp refflag = 2; 713833965Sjdp asn = true; 713933965Sjdp break; 714033965Sjdp case DEBUG_LOCAL: 714133965Sjdp if (! ieee_write_number (info, 1) 714233965Sjdp || ! ieee_write_number (info, val)) 714333965Sjdp return false; 714433965Sjdp refflag = 2; 714533965Sjdp asn = false; 714633965Sjdp break; 714733965Sjdp case DEBUG_REGISTER: 714833965Sjdp if (! ieee_write_number (info, 2) 714933965Sjdp || ! ieee_write_number (info, 715033965Sjdp ieee_genreg_to_regno (info->abfd, val))) 715133965Sjdp return false; 715233965Sjdp refflag = 2; 715333965Sjdp asn = false; 715433965Sjdp break; 715533965Sjdp } 715633965Sjdp 715733965Sjdp if (asn) 715833965Sjdp { 715933965Sjdp if (! ieee_write_asn (info, name_indx, val)) 716033965Sjdp return false; 716133965Sjdp } 716233965Sjdp 716333965Sjdp /* If this is really a reference type, then we just output it with 716433965Sjdp pointer type, and must now output a C++ record indicating that it 716533965Sjdp is really reference type. */ 716633965Sjdp if (referencep) 716733965Sjdp { 716833965Sjdp unsigned int nindx; 716933965Sjdp 717033965Sjdp nindx = info->name_indx; 717133965Sjdp ++info->name_indx; 717233965Sjdp 717333965Sjdp /* If this is a global variable, we want to output the misc 717433965Sjdp record in the C++ misc record block. Otherwise, we want to 717533965Sjdp output it just after the variable definition, which is where 717633965Sjdp the current buffer is. */ 717733965Sjdp if (refflag != 2) 717833965Sjdp { 717933965Sjdp if (! ieee_change_buffer (info, &info->cxx)) 718033965Sjdp return false; 718133965Sjdp } 718233965Sjdp 718333965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 718433965Sjdp || ! ieee_write_number (info, nindx) 718533965Sjdp || ! ieee_write_id (info, "") 718633965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 718733965Sjdp || ! ieee_write_number (info, nindx) 718833965Sjdp || ! ieee_write_number (info, 0) 718933965Sjdp || ! ieee_write_number (info, 62) 719033965Sjdp || ! ieee_write_number (info, 80) 719133965Sjdp || ! ieee_write_number (info, 3) 719233965Sjdp || ! ieee_write_asn (info, nindx, 'R') 719333965Sjdp || ! ieee_write_asn (info, nindx, refflag) 719433965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 719533965Sjdp return false; 719633965Sjdp } 719733965Sjdp 719833965Sjdp return true; 719933965Sjdp} 720033965Sjdp 720133965Sjdp/* Start outputting information for a function. */ 720233965Sjdp 720333965Sjdpstatic boolean 720433965Sjdpieee_start_function (p, name, global) 720533965Sjdp PTR p; 720633965Sjdp const char *name; 720733965Sjdp boolean global; 720833965Sjdp{ 720933965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 721033965Sjdp boolean referencep; 721133965Sjdp unsigned int retindx, typeindx; 721233965Sjdp 721333965Sjdp referencep = info->type_stack->type.referencep; 721433965Sjdp retindx = ieee_pop_type (info); 721533965Sjdp 721633965Sjdp /* Besides recording a BB4 or BB6 block, we record the type of the 721733965Sjdp function in the BB1 typedef block. We can't write out the full 721833965Sjdp type until we have seen all the parameters, so we accumulate it 721933965Sjdp in info->fntype and info->fnargs. */ 722033965Sjdp if (! ieee_buffer_emptyp (&info->fntype)) 722133965Sjdp { 722233965Sjdp /* FIXME: This might happen someday if we support nested 722333965Sjdp functions. */ 722433965Sjdp abort (); 722533965Sjdp } 722633965Sjdp 722733965Sjdp info->fnname = name; 722833965Sjdp 722933965Sjdp /* An attribute of 0x40 means that the push mask is unknown. */ 723033965Sjdp if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, false, true, 723133965Sjdp &info->fntype) 723233965Sjdp || ! ieee_write_number (info, 'x') 723333965Sjdp || ! ieee_write_number (info, 0x40) 723433965Sjdp || ! ieee_write_number (info, 0) 723533965Sjdp || ! ieee_write_number (info, 0) 723633965Sjdp || ! ieee_write_number (info, retindx)) 723733965Sjdp return false; 723833965Sjdp 723933965Sjdp typeindx = ieee_pop_type (info); 724033965Sjdp 724133965Sjdp if (! ieee_init_buffer (info, &info->fnargs)) 724233965Sjdp return false; 724333965Sjdp info->fnargcount = 0; 724433965Sjdp 724533965Sjdp /* If the function return value is actually a reference type, we 724633965Sjdp must add a record indicating that. */ 724733965Sjdp if (referencep) 724833965Sjdp { 724933965Sjdp unsigned int nindx; 725033965Sjdp 725133965Sjdp nindx = info->name_indx; 725233965Sjdp ++info->name_indx; 725333965Sjdp if (! ieee_change_buffer (info, &info->cxx) 725433965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 725533965Sjdp || ! ieee_write_number (info, nindx) 725633965Sjdp || ! ieee_write_id (info, "") 725733965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 725833965Sjdp || ! ieee_write_number (info, nindx) 725933965Sjdp || ! ieee_write_number (info, 0) 726033965Sjdp || ! ieee_write_number (info, 62) 726133965Sjdp || ! ieee_write_number (info, 80) 726233965Sjdp || ! ieee_write_number (info, 3) 726333965Sjdp || ! ieee_write_asn (info, nindx, 'R') 726433965Sjdp || ! ieee_write_asn (info, nindx, global ? 0 : 1) 726533965Sjdp || ! ieee_write_atn65 (info, nindx, name)) 726633965Sjdp return false; 726733965Sjdp } 726833965Sjdp 726933965Sjdp assert (! ieee_buffer_emptyp (&info->vars)); 727033965Sjdp if (! ieee_change_buffer (info, &info->vars)) 727133965Sjdp return false; 727233965Sjdp 727333965Sjdp /* The address is written out as the first block. */ 727433965Sjdp 727533965Sjdp ++info->block_depth; 727633965Sjdp 727733965Sjdp return (ieee_write_byte (info, (int) ieee_bb_record_enum) 727833965Sjdp && ieee_write_byte (info, global ? 4 : 6) 727933965Sjdp && ieee_write_number (info, 0) 728033965Sjdp && ieee_write_id (info, name) 728133965Sjdp && ieee_write_number (info, 0) 728233965Sjdp && ieee_write_number (info, typeindx)); 728333965Sjdp} 728433965Sjdp 728533965Sjdp/* Add a function parameter. This will normally be called before the 728633965Sjdp first block, so we postpone them until we see the block. */ 728733965Sjdp 728833965Sjdpstatic boolean 728933965Sjdpieee_function_parameter (p, name, kind, val) 729033965Sjdp PTR p; 729133965Sjdp const char *name; 729233965Sjdp enum debug_parm_kind kind; 729333965Sjdp bfd_vma val; 729433965Sjdp{ 729533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 729633965Sjdp struct ieee_pending_parm *m, **pm; 729733965Sjdp 729833965Sjdp assert (info->block_depth == 1); 729933965Sjdp 730033965Sjdp m = (struct ieee_pending_parm *) xmalloc (sizeof *m); 730133965Sjdp memset (m, 0, sizeof *m); 730233965Sjdp 730333965Sjdp m->next = NULL; 730433965Sjdp m->name = name; 730533965Sjdp m->referencep = info->type_stack->type.referencep; 730633965Sjdp m->type = ieee_pop_type (info); 730733965Sjdp m->kind = kind; 730833965Sjdp m->val = val; 730933965Sjdp 731033965Sjdp for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next) 731133965Sjdp ; 731233965Sjdp *pm = m; 731333965Sjdp 731433965Sjdp /* Add the type to the fnargs list. */ 731533965Sjdp if (! ieee_change_buffer (info, &info->fnargs) 731633965Sjdp || ! ieee_write_number (info, m->type)) 731733965Sjdp return false; 731833965Sjdp ++info->fnargcount; 731933965Sjdp 732077298Sobrien return true; 732133965Sjdp} 732233965Sjdp 732333965Sjdp/* Output pending function parameters. */ 732433965Sjdp 732533965Sjdpstatic boolean 732633965Sjdpieee_output_pending_parms (info) 732733965Sjdp struct ieee_handle *info; 732833965Sjdp{ 732933965Sjdp struct ieee_pending_parm *m; 733033965Sjdp unsigned int refcount; 733133965Sjdp 733233965Sjdp refcount = 0; 733333965Sjdp for (m = info->pending_parms; m != NULL; m = m->next) 733433965Sjdp { 733533965Sjdp enum debug_var_kind vkind; 733633965Sjdp 733733965Sjdp switch (m->kind) 733833965Sjdp { 733933965Sjdp default: 734033965Sjdp abort (); 734133965Sjdp return false; 734233965Sjdp case DEBUG_PARM_STACK: 734333965Sjdp case DEBUG_PARM_REFERENCE: 734433965Sjdp vkind = DEBUG_LOCAL; 734533965Sjdp break; 734633965Sjdp case DEBUG_PARM_REG: 734733965Sjdp case DEBUG_PARM_REF_REG: 734833965Sjdp vkind = DEBUG_REGISTER; 734933965Sjdp break; 735033965Sjdp } 735133965Sjdp 735233965Sjdp if (! ieee_push_type (info, m->type, 0, false, false)) 735333965Sjdp return false; 735433965Sjdp info->type_stack->type.referencep = m->referencep; 735533965Sjdp if (m->referencep) 735633965Sjdp ++refcount; 735733965Sjdp if (! ieee_variable ((PTR) info, m->name, vkind, m->val)) 735833965Sjdp return false; 735933965Sjdp } 736033965Sjdp 736133965Sjdp /* If there are any reference parameters, we need to output a 736233965Sjdp miscellaneous record indicating them. */ 736333965Sjdp if (refcount > 0) 736433965Sjdp { 736533965Sjdp unsigned int nindx, varindx; 736633965Sjdp 736733965Sjdp /* FIXME: The MRI compiler outputs the demangled function name 736833965Sjdp here, but we are outputting the mangled name. */ 736933965Sjdp nindx = info->name_indx; 737033965Sjdp ++info->name_indx; 737133965Sjdp if (! ieee_change_buffer (info, &info->vars) 737233965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 737333965Sjdp || ! ieee_write_number (info, nindx) 737433965Sjdp || ! ieee_write_id (info, "") 737533965Sjdp || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 737633965Sjdp || ! ieee_write_number (info, nindx) 737733965Sjdp || ! ieee_write_number (info, 0) 737833965Sjdp || ! ieee_write_number (info, 62) 737933965Sjdp || ! ieee_write_number (info, 80) 738033965Sjdp || ! ieee_write_number (info, refcount + 3) 738133965Sjdp || ! ieee_write_asn (info, nindx, 'B') 738233965Sjdp || ! ieee_write_atn65 (info, nindx, info->fnname) 738333965Sjdp || ! ieee_write_asn (info, nindx, 0)) 738433965Sjdp return false; 738533965Sjdp for (m = info->pending_parms, varindx = 1; 738633965Sjdp m != NULL; 738733965Sjdp m = m->next, varindx++) 738833965Sjdp { 738933965Sjdp if (m->referencep) 739033965Sjdp { 739133965Sjdp if (! ieee_write_asn (info, nindx, varindx)) 739233965Sjdp return false; 739333965Sjdp } 739433965Sjdp } 739533965Sjdp } 739633965Sjdp 739733965Sjdp m = info->pending_parms; 739833965Sjdp while (m != NULL) 739933965Sjdp { 740033965Sjdp struct ieee_pending_parm *next; 740133965Sjdp 740233965Sjdp next = m->next; 740333965Sjdp free (m); 740433965Sjdp m = next; 740533965Sjdp } 740633965Sjdp 740733965Sjdp info->pending_parms = NULL; 740833965Sjdp 740933965Sjdp return true; 741033965Sjdp} 741133965Sjdp 741233965Sjdp/* Start a block. If this is the first block, we output the address 741333965Sjdp to finish the BB4 or BB6, and then output the function parameters. */ 741433965Sjdp 741533965Sjdpstatic boolean 741633965Sjdpieee_start_block (p, addr) 741733965Sjdp PTR p; 741833965Sjdp bfd_vma addr; 741933965Sjdp{ 742033965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 742133965Sjdp 742233965Sjdp if (! ieee_change_buffer (info, &info->vars)) 742333965Sjdp return false; 742433965Sjdp 742533965Sjdp if (info->block_depth == 1) 742633965Sjdp { 742733965Sjdp if (! ieee_write_number (info, addr) 742833965Sjdp || ! ieee_output_pending_parms (info)) 742933965Sjdp return false; 743033965Sjdp } 743133965Sjdp else 743233965Sjdp { 743333965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 743433965Sjdp || ! ieee_write_byte (info, 6) 743533965Sjdp || ! ieee_write_number (info, 0) 743633965Sjdp || ! ieee_write_id (info, "") 743733965Sjdp || ! ieee_write_number (info, 0) 743833965Sjdp || ! ieee_write_number (info, 0) 743933965Sjdp || ! ieee_write_number (info, addr)) 744033965Sjdp return false; 744133965Sjdp } 744233965Sjdp 744333965Sjdp if (! ieee_start_range (info, addr)) 744433965Sjdp return false; 744533965Sjdp 744633965Sjdp ++info->block_depth; 744733965Sjdp 744833965Sjdp return true; 744933965Sjdp} 745033965Sjdp 745133965Sjdp/* End a block. */ 745233965Sjdp 745333965Sjdpstatic boolean 745433965Sjdpieee_end_block (p, addr) 745533965Sjdp PTR p; 745633965Sjdp bfd_vma addr; 745733965Sjdp{ 745833965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 745933965Sjdp 746033965Sjdp /* The address we are given is the end of the block, but IEEE seems 746133965Sjdp to want to the address of the last byte in the block, so we 746233965Sjdp subtract one. */ 746333965Sjdp if (! ieee_change_buffer (info, &info->vars) 746433965Sjdp || ! ieee_write_byte (info, (int) ieee_be_record_enum) 746533965Sjdp || ! ieee_write_number (info, addr - 1)) 746633965Sjdp return false; 746733965Sjdp 746833965Sjdp if (! ieee_end_range (info, addr)) 746933965Sjdp return false; 747033965Sjdp 747133965Sjdp --info->block_depth; 747233965Sjdp 747333965Sjdp if (addr > info->highaddr) 747433965Sjdp info->highaddr = addr; 747533965Sjdp 747633965Sjdp return true; 747733965Sjdp} 747833965Sjdp 747933965Sjdp/* End a function. */ 748033965Sjdp 748133965Sjdpstatic boolean 748233965Sjdpieee_end_function (p) 748333965Sjdp PTR p; 748433965Sjdp{ 748533965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 748633965Sjdp 748733965Sjdp assert (info->block_depth == 1); 748833965Sjdp 748933965Sjdp --info->block_depth; 749033965Sjdp 749133965Sjdp /* Now we can finish up fntype, and add it to the typdef section. 749233965Sjdp At this point, fntype is the 'x' type up to the argument count, 749333965Sjdp and fnargs is the argument types. We must add the argument 749433965Sjdp count, and we must add the level. FIXME: We don't record varargs 749533965Sjdp functions correctly. In fact, stabs debugging does not give us 749633965Sjdp enough information to do so. */ 749733965Sjdp if (! ieee_change_buffer (info, &info->fntype) 749833965Sjdp || ! ieee_write_number (info, info->fnargcount) 749933965Sjdp || ! ieee_change_buffer (info, &info->fnargs) 750033965Sjdp || ! ieee_write_number (info, 0)) 750133965Sjdp return false; 750233965Sjdp 750333965Sjdp /* Make sure the typdef block has been started. */ 750433965Sjdp if (ieee_buffer_emptyp (&info->types)) 750533965Sjdp { 750633965Sjdp if (! ieee_change_buffer (info, &info->types) 750733965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 750833965Sjdp || ! ieee_write_byte (info, 1) 750933965Sjdp || ! ieee_write_number (info, 0) 751033965Sjdp || ! ieee_write_id (info, info->modname)) 751133965Sjdp return false; 751233965Sjdp } 751333965Sjdp 751433965Sjdp if (! ieee_append_buffer (info, &info->types, &info->fntype) 751533965Sjdp || ! ieee_append_buffer (info, &info->types, &info->fnargs)) 751633965Sjdp return false; 751733965Sjdp 751833965Sjdp info->fnname = NULL; 751933965Sjdp if (! ieee_init_buffer (info, &info->fntype) 752033965Sjdp || ! ieee_init_buffer (info, &info->fnargs)) 752133965Sjdp return false; 752233965Sjdp info->fnargcount = 0; 752333965Sjdp 752433965Sjdp return true; 752533965Sjdp} 752633965Sjdp 752733965Sjdp/* Record line number information. */ 752833965Sjdp 752933965Sjdpstatic boolean 753033965Sjdpieee_lineno (p, filename, lineno, addr) 753133965Sjdp PTR p; 753233965Sjdp const char *filename; 753333965Sjdp unsigned long lineno; 753433965Sjdp bfd_vma addr; 753533965Sjdp{ 753633965Sjdp struct ieee_handle *info = (struct ieee_handle *) p; 753733965Sjdp 753833965Sjdp assert (info->filename != NULL); 753933965Sjdp 754033965Sjdp /* The HP simulator seems to get confused when more than one line is 754133965Sjdp listed for the same address, at least if they are in different 754233965Sjdp files. We handle this by always listing the last line for a 754333965Sjdp given address, since that seems to be the one that gdb uses. */ 754433965Sjdp if (info->pending_lineno_filename != NULL 754533965Sjdp && addr != info->pending_lineno_addr) 754633965Sjdp { 754733965Sjdp /* Make sure we have a line number block. */ 754833965Sjdp if (! ieee_buffer_emptyp (&info->linenos)) 754933965Sjdp { 755033965Sjdp if (! ieee_change_buffer (info, &info->linenos)) 755133965Sjdp return false; 755233965Sjdp } 755333965Sjdp else 755433965Sjdp { 755533965Sjdp info->lineno_name_indx = info->name_indx; 755633965Sjdp ++info->name_indx; 755733965Sjdp if (! ieee_change_buffer (info, &info->linenos) 755833965Sjdp || ! ieee_write_byte (info, (int) ieee_bb_record_enum) 755933965Sjdp || ! ieee_write_byte (info, 5) 756033965Sjdp || ! ieee_write_number (info, 0) 756133965Sjdp || ! ieee_write_id (info, info->filename) 756233965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 756333965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 756433965Sjdp || ! ieee_write_id (info, "")) 756533965Sjdp return false; 756633965Sjdp info->lineno_filename = info->filename; 756733965Sjdp } 756833965Sjdp 756933965Sjdp if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0) 757033965Sjdp { 757133965Sjdp if (strcmp (info->filename, info->lineno_filename) != 0) 757233965Sjdp { 757333965Sjdp /* We were not in the main file. Close the block for the 757433965Sjdp included file. */ 757533965Sjdp if (! ieee_write_byte (info, (int) ieee_be_record_enum)) 757633965Sjdp return false; 757733965Sjdp if (strcmp (info->filename, info->pending_lineno_filename) == 0) 757833965Sjdp { 757933965Sjdp /* We need a new NN record, and we aren't about to 758033965Sjdp output one. */ 758133965Sjdp info->lineno_name_indx = info->name_indx; 758233965Sjdp ++info->name_indx; 758333965Sjdp if (! ieee_write_byte (info, (int) ieee_nn_record) 758433965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 758533965Sjdp || ! ieee_write_id (info, "")) 758633965Sjdp return false; 758733965Sjdp } 758833965Sjdp } 758933965Sjdp if (strcmp (info->filename, info->pending_lineno_filename) != 0) 759033965Sjdp { 759133965Sjdp /* We are not changing to the main file. Open a block for 759233965Sjdp the new included file. */ 759333965Sjdp info->lineno_name_indx = info->name_indx; 759433965Sjdp ++info->name_indx; 759533965Sjdp if (! ieee_write_byte (info, (int) ieee_bb_record_enum) 759633965Sjdp || ! ieee_write_byte (info, 5) 759733965Sjdp || ! ieee_write_number (info, 0) 759833965Sjdp || ! ieee_write_id (info, info->pending_lineno_filename) 759933965Sjdp || ! ieee_write_byte (info, (int) ieee_nn_record) 760033965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 760133965Sjdp || ! ieee_write_id (info, "")) 760233965Sjdp return false; 760333965Sjdp } 760433965Sjdp info->lineno_filename = info->pending_lineno_filename; 760533965Sjdp } 760633965Sjdp 760733965Sjdp if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum) 760833965Sjdp || ! ieee_write_number (info, info->lineno_name_indx) 760933965Sjdp || ! ieee_write_number (info, 0) 761033965Sjdp || ! ieee_write_number (info, 7) 761133965Sjdp || ! ieee_write_number (info, info->pending_lineno) 761233965Sjdp || ! ieee_write_number (info, 0) 761333965Sjdp || ! ieee_write_asn (info, info->lineno_name_indx, 761433965Sjdp info->pending_lineno_addr)) 761533965Sjdp return false; 761633965Sjdp } 761733965Sjdp 761833965Sjdp info->pending_lineno_filename = filename; 761933965Sjdp info->pending_lineno = lineno; 762033965Sjdp info->pending_lineno_addr = addr; 762133965Sjdp 762233965Sjdp return true; 762333965Sjdp} 7624