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, &sectype)
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