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