xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/ieee.c (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* ieee.c -- Read and write IEEE-695 debugging information.
2*3d8817e4Smiod    Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2006
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod    Written by Ian Lance Taylor <ian@cygnus.com>.
5*3d8817e4Smiod 
6*3d8817e4Smiod    This file is part of GNU Binutils.
7*3d8817e4Smiod 
8*3d8817e4Smiod    This program is free software; you can redistribute it and/or modify
9*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
10*3d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
11*3d8817e4Smiod    (at your option) any later version.
12*3d8817e4Smiod 
13*3d8817e4Smiod    This program is distributed in the hope that it will be useful,
14*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*3d8817e4Smiod    GNU General Public License for more details.
17*3d8817e4Smiod 
18*3d8817e4Smiod    You should have received a copy of the GNU General Public License
19*3d8817e4Smiod    along with this program; if not, write to the Free Software
20*3d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
21*3d8817e4Smiod    02110-1301, USA.  */
22*3d8817e4Smiod 
23*3d8817e4Smiod /* This file reads and writes IEEE-695 debugging information.  */
24*3d8817e4Smiod 
25*3d8817e4Smiod #include <stdio.h>
26*3d8817e4Smiod #include <assert.h>
27*3d8817e4Smiod 
28*3d8817e4Smiod #include "bfd.h"
29*3d8817e4Smiod #include "ieee.h"
30*3d8817e4Smiod #include "bucomm.h"
31*3d8817e4Smiod #include "libiberty.h"
32*3d8817e4Smiod #include "debug.h"
33*3d8817e4Smiod #include "budbg.h"
34*3d8817e4Smiod #include "filenames.h"
35*3d8817e4Smiod 
36*3d8817e4Smiod /* This structure holds an entry on the block stack.  */
37*3d8817e4Smiod 
38*3d8817e4Smiod struct ieee_block
39*3d8817e4Smiod {
40*3d8817e4Smiod   /* The kind of block.  */
41*3d8817e4Smiod   int kind;
42*3d8817e4Smiod   /* The source file name, for a BB5 block.  */
43*3d8817e4Smiod   const char *filename;
44*3d8817e4Smiod   /* The index of the function type, for a BB4 or BB6 block.  */
45*3d8817e4Smiod   unsigned int fnindx;
46*3d8817e4Smiod   /* TRUE if this function is being skipped.  */
47*3d8817e4Smiod   bfd_boolean skip;
48*3d8817e4Smiod };
49*3d8817e4Smiod 
50*3d8817e4Smiod /* This structure is the block stack.  */
51*3d8817e4Smiod 
52*3d8817e4Smiod #define BLOCKSTACK_SIZE (16)
53*3d8817e4Smiod 
54*3d8817e4Smiod struct ieee_blockstack
55*3d8817e4Smiod {
56*3d8817e4Smiod   /* The stack pointer.  */
57*3d8817e4Smiod   struct ieee_block *bsp;
58*3d8817e4Smiod   /* The stack.  */
59*3d8817e4Smiod   struct ieee_block stack[BLOCKSTACK_SIZE];
60*3d8817e4Smiod };
61*3d8817e4Smiod 
62*3d8817e4Smiod /* This structure holds information for a variable.  */
63*3d8817e4Smiod 
64*3d8817e4Smiod struct ieee_var
65*3d8817e4Smiod {
66*3d8817e4Smiod   /* Start of name.  */
67*3d8817e4Smiod   const char *name;
68*3d8817e4Smiod   /* Length of name.  */
69*3d8817e4Smiod   unsigned long namlen;
70*3d8817e4Smiod   /* Type.  */
71*3d8817e4Smiod   debug_type type;
72*3d8817e4Smiod   /* Slot if we make an indirect type.  */
73*3d8817e4Smiod   debug_type *pslot;
74*3d8817e4Smiod   /* Kind of variable or function.  */
75*3d8817e4Smiod   enum
76*3d8817e4Smiod     {
77*3d8817e4Smiod       IEEE_UNKNOWN,
78*3d8817e4Smiod       IEEE_EXTERNAL,
79*3d8817e4Smiod       IEEE_GLOBAL,
80*3d8817e4Smiod       IEEE_STATIC,
81*3d8817e4Smiod       IEEE_LOCAL,
82*3d8817e4Smiod       IEEE_FUNCTION
83*3d8817e4Smiod     } kind;
84*3d8817e4Smiod };
85*3d8817e4Smiod 
86*3d8817e4Smiod /* This structure holds all the variables.  */
87*3d8817e4Smiod 
88*3d8817e4Smiod struct ieee_vars
89*3d8817e4Smiod {
90*3d8817e4Smiod   /* Number of slots allocated.  */
91*3d8817e4Smiod   unsigned int alloc;
92*3d8817e4Smiod   /* Variables.  */
93*3d8817e4Smiod   struct ieee_var *vars;
94*3d8817e4Smiod };
95*3d8817e4Smiod 
96*3d8817e4Smiod /* This structure holds information for a type.  We need this because
97*3d8817e4Smiod    we don't want to represent bitfields as real types.  */
98*3d8817e4Smiod 
99*3d8817e4Smiod struct ieee_type
100*3d8817e4Smiod {
101*3d8817e4Smiod   /* Type.  */
102*3d8817e4Smiod   debug_type type;
103*3d8817e4Smiod   /* Slot if this is type is referenced before it is defined.  */
104*3d8817e4Smiod   debug_type *pslot;
105*3d8817e4Smiod   /* Slots for arguments if we make indirect types for them.  */
106*3d8817e4Smiod   debug_type *arg_slots;
107*3d8817e4Smiod   /* If this is a bitfield, this is the size in bits.  If this is not
108*3d8817e4Smiod      a bitfield, this is zero.  */
109*3d8817e4Smiod   unsigned long bitsize;
110*3d8817e4Smiod };
111*3d8817e4Smiod 
112*3d8817e4Smiod /* This structure holds all the type information.  */
113*3d8817e4Smiod 
114*3d8817e4Smiod struct ieee_types
115*3d8817e4Smiod {
116*3d8817e4Smiod   /* Number of slots allocated.  */
117*3d8817e4Smiod   unsigned int alloc;
118*3d8817e4Smiod   /* Types.  */
119*3d8817e4Smiod   struct ieee_type *types;
120*3d8817e4Smiod   /* Builtin types.  */
121*3d8817e4Smiod #define BUILTIN_TYPE_COUNT (60)
122*3d8817e4Smiod   debug_type builtins[BUILTIN_TYPE_COUNT];
123*3d8817e4Smiod };
124*3d8817e4Smiod 
125*3d8817e4Smiod /* This structure holds a linked last of structs with their tag names,
126*3d8817e4Smiod    so that we can convert them to C++ classes if necessary.  */
127*3d8817e4Smiod 
128*3d8817e4Smiod struct ieee_tag
129*3d8817e4Smiod {
130*3d8817e4Smiod   /* Next tag.  */
131*3d8817e4Smiod   struct ieee_tag *next;
132*3d8817e4Smiod   /* This tag name.  */
133*3d8817e4Smiod   const char *name;
134*3d8817e4Smiod   /* The type of the tag.  */
135*3d8817e4Smiod   debug_type type;
136*3d8817e4Smiod   /* The tagged type is an indirect type pointing at this slot.  */
137*3d8817e4Smiod   debug_type slot;
138*3d8817e4Smiod   /* This is an array of slots used when a field type is converted
139*3d8817e4Smiod      into a indirect type, in case it needs to be later converted into
140*3d8817e4Smiod      a reference type.  */
141*3d8817e4Smiod   debug_type *fslots;
142*3d8817e4Smiod };
143*3d8817e4Smiod 
144*3d8817e4Smiod /* This structure holds the information we pass around to the parsing
145*3d8817e4Smiod    functions.  */
146*3d8817e4Smiod 
147*3d8817e4Smiod struct ieee_info
148*3d8817e4Smiod {
149*3d8817e4Smiod   /* The debugging handle.  */
150*3d8817e4Smiod   void *dhandle;
151*3d8817e4Smiod   /* The BFD.  */
152*3d8817e4Smiod   bfd *abfd;
153*3d8817e4Smiod   /* The start of the bytes to be parsed.  */
154*3d8817e4Smiod   const bfd_byte *bytes;
155*3d8817e4Smiod   /* The end of the bytes to be parsed.  */
156*3d8817e4Smiod   const bfd_byte *pend;
157*3d8817e4Smiod   /* The block stack.  */
158*3d8817e4Smiod   struct ieee_blockstack blockstack;
159*3d8817e4Smiod   /* Whether we have seen a BB1 or BB2.  */
160*3d8817e4Smiod   bfd_boolean saw_filename;
161*3d8817e4Smiod   /* The variables.  */
162*3d8817e4Smiod   struct ieee_vars vars;
163*3d8817e4Smiod   /* The global variables, after a global typedef block.  */
164*3d8817e4Smiod   struct ieee_vars *global_vars;
165*3d8817e4Smiod   /* The types.  */
166*3d8817e4Smiod   struct ieee_types types;
167*3d8817e4Smiod   /* The global types, after a global typedef block.  */
168*3d8817e4Smiod   struct ieee_types *global_types;
169*3d8817e4Smiod   /* The list of tagged structs.  */
170*3d8817e4Smiod   struct ieee_tag *tags;
171*3d8817e4Smiod };
172*3d8817e4Smiod 
173*3d8817e4Smiod /* Basic builtin types, not including the pointers.  */
174*3d8817e4Smiod 
175*3d8817e4Smiod enum builtin_types
176*3d8817e4Smiod {
177*3d8817e4Smiod   builtin_unknown = 0,
178*3d8817e4Smiod   builtin_void = 1,
179*3d8817e4Smiod   builtin_signed_char = 2,
180*3d8817e4Smiod   builtin_unsigned_char = 3,
181*3d8817e4Smiod   builtin_signed_short_int = 4,
182*3d8817e4Smiod   builtin_unsigned_short_int = 5,
183*3d8817e4Smiod   builtin_signed_long = 6,
184*3d8817e4Smiod   builtin_unsigned_long = 7,
185*3d8817e4Smiod   builtin_signed_long_long = 8,
186*3d8817e4Smiod   builtin_unsigned_long_long = 9,
187*3d8817e4Smiod   builtin_float = 10,
188*3d8817e4Smiod   builtin_double = 11,
189*3d8817e4Smiod   builtin_long_double = 12,
190*3d8817e4Smiod   builtin_long_long_double = 13,
191*3d8817e4Smiod   builtin_quoted_string = 14,
192*3d8817e4Smiod   builtin_instruction_address = 15,
193*3d8817e4Smiod   builtin_int = 16,
194*3d8817e4Smiod   builtin_unsigned = 17,
195*3d8817e4Smiod   builtin_unsigned_int = 18,
196*3d8817e4Smiod   builtin_char = 19,
197*3d8817e4Smiod   builtin_long = 20,
198*3d8817e4Smiod   builtin_short = 21,
199*3d8817e4Smiod   builtin_unsigned_short = 22,
200*3d8817e4Smiod   builtin_short_int = 23,
201*3d8817e4Smiod   builtin_signed_short = 24,
202*3d8817e4Smiod   builtin_bcd_float = 25
203*3d8817e4Smiod };
204*3d8817e4Smiod 
205*3d8817e4Smiod /* These are the values found in the derivation flags of a 'b'
206*3d8817e4Smiod    component record of a 'T' type extension record in a C++ pmisc
207*3d8817e4Smiod    record.  These are bitmasks.  */
208*3d8817e4Smiod 
209*3d8817e4Smiod /* Set for a private base class, clear for a public base class.
210*3d8817e4Smiod    Protected base classes are not supported.  */
211*3d8817e4Smiod #define BASEFLAGS_PRIVATE (0x1)
212*3d8817e4Smiod /* Set for a virtual base class.  */
213*3d8817e4Smiod #define BASEFLAGS_VIRTUAL (0x2)
214*3d8817e4Smiod /* Set for a friend class, clear for a base class.  */
215*3d8817e4Smiod #define BASEFLAGS_FRIEND (0x10)
216*3d8817e4Smiod 
217*3d8817e4Smiod /* These are the values found in the specs flags of a 'd', 'm', or 'v'
218*3d8817e4Smiod    component record of a 'T' type extension record in a C++ pmisc
219*3d8817e4Smiod    record.  The same flags are used for a 'M' record in a C++ pmisc
220*3d8817e4Smiod    record.  */
221*3d8817e4Smiod 
222*3d8817e4Smiod /* The lower two bits hold visibility information.  */
223*3d8817e4Smiod #define CXXFLAGS_VISIBILITY (0x3)
224*3d8817e4Smiod /* This value in the lower two bits indicates a public member.  */
225*3d8817e4Smiod #define CXXFLAGS_VISIBILITY_PUBLIC (0x0)
226*3d8817e4Smiod /* This value in the lower two bits indicates a private member.  */
227*3d8817e4Smiod #define CXXFLAGS_VISIBILITY_PRIVATE (0x1)
228*3d8817e4Smiod /* This value in the lower two bits indicates a protected member.  */
229*3d8817e4Smiod #define CXXFLAGS_VISIBILITY_PROTECTED (0x2)
230*3d8817e4Smiod /* Set for a static member.  */
231*3d8817e4Smiod #define CXXFLAGS_STATIC (0x4)
232*3d8817e4Smiod /* Set for a virtual override.  */
233*3d8817e4Smiod #define CXXFLAGS_OVERRIDE (0x8)
234*3d8817e4Smiod /* Set for a friend function.  */
235*3d8817e4Smiod #define CXXFLAGS_FRIEND (0x10)
236*3d8817e4Smiod /* Set for a const function.  */
237*3d8817e4Smiod #define CXXFLAGS_CONST (0x20)
238*3d8817e4Smiod /* Set for a volatile function.  */
239*3d8817e4Smiod #define CXXFLAGS_VOLATILE (0x40)
240*3d8817e4Smiod /* Set for an overloaded function.  */
241*3d8817e4Smiod #define CXXFLAGS_OVERLOADED (0x80)
242*3d8817e4Smiod /* Set for an operator function.  */
243*3d8817e4Smiod #define CXXFLAGS_OPERATOR (0x100)
244*3d8817e4Smiod /* Set for a constructor or destructor.  */
245*3d8817e4Smiod #define CXXFLAGS_CTORDTOR (0x400)
246*3d8817e4Smiod /* Set for a constructor.  */
247*3d8817e4Smiod #define CXXFLAGS_CTOR (0x200)
248*3d8817e4Smiod /* Set for an inline function.  */
249*3d8817e4Smiod #define CXXFLAGS_INLINE (0x800)
250*3d8817e4Smiod 
251*3d8817e4Smiod /* Local functions.  */
252*3d8817e4Smiod 
253*3d8817e4Smiod static void ieee_error (struct ieee_info *, const bfd_byte *, const char *);
254*3d8817e4Smiod static void ieee_eof (struct ieee_info *);
255*3d8817e4Smiod static char *savestring (const char *, unsigned long);
256*3d8817e4Smiod static bfd_boolean ieee_read_number
257*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, bfd_vma *);
258*3d8817e4Smiod static bfd_boolean ieee_read_optional_number
259*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, bfd_vma *, bfd_boolean *);
260*3d8817e4Smiod static bfd_boolean ieee_read_id
261*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, const char **, unsigned long *);
262*3d8817e4Smiod static bfd_boolean ieee_read_optional_id
263*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, const char **, unsigned long *,
264*3d8817e4Smiod    bfd_boolean *);
265*3d8817e4Smiod static bfd_boolean ieee_read_expression
266*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, bfd_vma *);
267*3d8817e4Smiod static debug_type ieee_builtin_type
268*3d8817e4Smiod   (struct ieee_info *, const bfd_byte *, unsigned int);
269*3d8817e4Smiod static bfd_boolean ieee_alloc_type
270*3d8817e4Smiod   (struct ieee_info *, unsigned int, bfd_boolean);
271*3d8817e4Smiod static bfd_boolean ieee_read_type_index
272*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, debug_type *);
273*3d8817e4Smiod static int ieee_regno_to_genreg (bfd *, int);
274*3d8817e4Smiod static int ieee_genreg_to_regno (bfd *, int);
275*3d8817e4Smiod static bfd_boolean parse_ieee_bb (struct ieee_info *, const bfd_byte **);
276*3d8817e4Smiod static bfd_boolean parse_ieee_be (struct ieee_info *, const bfd_byte **);
277*3d8817e4Smiod static bfd_boolean parse_ieee_nn (struct ieee_info *, const bfd_byte **);
278*3d8817e4Smiod static bfd_boolean parse_ieee_ty (struct ieee_info *, const bfd_byte **);
279*3d8817e4Smiod static bfd_boolean parse_ieee_atn (struct ieee_info *, const bfd_byte **);
280*3d8817e4Smiod static bfd_boolean ieee_read_cxx_misc
281*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, unsigned long);
282*3d8817e4Smiod static bfd_boolean ieee_read_cxx_class
283*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, unsigned long);
284*3d8817e4Smiod static bfd_boolean ieee_read_cxx_defaults
285*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, unsigned long);
286*3d8817e4Smiod static bfd_boolean ieee_read_reference
287*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **);
288*3d8817e4Smiod static bfd_boolean ieee_require_asn
289*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, bfd_vma *);
290*3d8817e4Smiod static bfd_boolean ieee_require_atn65
291*3d8817e4Smiod   (struct ieee_info *, const bfd_byte **, const char **, unsigned long *);
292*3d8817e4Smiod 
293*3d8817e4Smiod /* Report an error in the IEEE debugging information.  */
294*3d8817e4Smiod 
295*3d8817e4Smiod static void
ieee_error(struct ieee_info * info,const bfd_byte * p,const char * s)296*3d8817e4Smiod ieee_error (struct ieee_info *info, const bfd_byte *p, const char *s)
297*3d8817e4Smiod {
298*3d8817e4Smiod   if (p != NULL)
299*3d8817e4Smiod     fprintf (stderr, "%s: 0x%lx: %s (0x%x)\n", bfd_get_filename (info->abfd),
300*3d8817e4Smiod 	     (unsigned long) (p - info->bytes), s, *p);
301*3d8817e4Smiod   else
302*3d8817e4Smiod     fprintf (stderr, "%s: %s\n", bfd_get_filename (info->abfd), s);
303*3d8817e4Smiod }
304*3d8817e4Smiod 
305*3d8817e4Smiod /* Report an unexpected EOF in the IEEE debugging information.  */
306*3d8817e4Smiod 
307*3d8817e4Smiod static void
ieee_eof(struct ieee_info * info)308*3d8817e4Smiod ieee_eof (struct ieee_info *info)
309*3d8817e4Smiod {
310*3d8817e4Smiod   ieee_error (info, (const bfd_byte *) NULL,
311*3d8817e4Smiod 	      _("unexpected end of debugging information"));
312*3d8817e4Smiod }
313*3d8817e4Smiod 
314*3d8817e4Smiod /* Save a string in memory.  */
315*3d8817e4Smiod 
316*3d8817e4Smiod static char *
savestring(const char * start,unsigned long len)317*3d8817e4Smiod savestring (const char *start, unsigned long len)
318*3d8817e4Smiod {
319*3d8817e4Smiod   char *ret;
320*3d8817e4Smiod 
321*3d8817e4Smiod   ret = (char *) xmalloc (len + 1);
322*3d8817e4Smiod   memcpy (ret, start, len);
323*3d8817e4Smiod   ret[len] = '\0';
324*3d8817e4Smiod   return ret;
325*3d8817e4Smiod }
326*3d8817e4Smiod 
327*3d8817e4Smiod /* Read a number which must be present in an IEEE file.  */
328*3d8817e4Smiod 
329*3d8817e4Smiod static bfd_boolean
ieee_read_number(struct ieee_info * info,const bfd_byte ** pp,bfd_vma * pv)330*3d8817e4Smiod ieee_read_number (struct ieee_info *info, const bfd_byte **pp, bfd_vma *pv)
331*3d8817e4Smiod {
332*3d8817e4Smiod   return ieee_read_optional_number (info, pp, pv, (bfd_boolean *) NULL);
333*3d8817e4Smiod }
334*3d8817e4Smiod 
335*3d8817e4Smiod /* Read a number in an IEEE file.  If ppresent is not NULL, the number
336*3d8817e4Smiod    need not be there.  */
337*3d8817e4Smiod 
338*3d8817e4Smiod static bfd_boolean
ieee_read_optional_number(struct ieee_info * info,const bfd_byte ** pp,bfd_vma * pv,bfd_boolean * ppresent)339*3d8817e4Smiod ieee_read_optional_number (struct ieee_info *info, const bfd_byte **pp,
340*3d8817e4Smiod 			   bfd_vma *pv, bfd_boolean *ppresent)
341*3d8817e4Smiod {
342*3d8817e4Smiod   ieee_record_enum_type b;
343*3d8817e4Smiod 
344*3d8817e4Smiod   if (*pp >= info->pend)
345*3d8817e4Smiod     {
346*3d8817e4Smiod       if (ppresent != NULL)
347*3d8817e4Smiod 	{
348*3d8817e4Smiod 	  *ppresent = FALSE;
349*3d8817e4Smiod 	  return TRUE;
350*3d8817e4Smiod 	}
351*3d8817e4Smiod       ieee_eof (info);
352*3d8817e4Smiod       return FALSE;
353*3d8817e4Smiod     }
354*3d8817e4Smiod 
355*3d8817e4Smiod   b = (ieee_record_enum_type) **pp;
356*3d8817e4Smiod   ++*pp;
357*3d8817e4Smiod 
358*3d8817e4Smiod   if (b <= ieee_number_end_enum)
359*3d8817e4Smiod     {
360*3d8817e4Smiod       *pv = (bfd_vma) b;
361*3d8817e4Smiod       if (ppresent != NULL)
362*3d8817e4Smiod 	*ppresent = TRUE;
363*3d8817e4Smiod       return TRUE;
364*3d8817e4Smiod     }
365*3d8817e4Smiod 
366*3d8817e4Smiod   if (b >= ieee_number_repeat_start_enum && b <= ieee_number_repeat_end_enum)
367*3d8817e4Smiod     {
368*3d8817e4Smiod       unsigned int i;
369*3d8817e4Smiod 
370*3d8817e4Smiod       i = (int) b - (int) ieee_number_repeat_start_enum;
371*3d8817e4Smiod       if (*pp + i - 1 >= info->pend)
372*3d8817e4Smiod 	{
373*3d8817e4Smiod 	  ieee_eof (info);
374*3d8817e4Smiod 	  return FALSE;
375*3d8817e4Smiod 	}
376*3d8817e4Smiod 
377*3d8817e4Smiod       *pv = 0;
378*3d8817e4Smiod       for (; i > 0; i--)
379*3d8817e4Smiod 	{
380*3d8817e4Smiod 	  *pv <<= 8;
381*3d8817e4Smiod 	  *pv += **pp;
382*3d8817e4Smiod 	  ++*pp;
383*3d8817e4Smiod 	}
384*3d8817e4Smiod 
385*3d8817e4Smiod       if (ppresent != NULL)
386*3d8817e4Smiod 	*ppresent = TRUE;
387*3d8817e4Smiod 
388*3d8817e4Smiod       return TRUE;
389*3d8817e4Smiod     }
390*3d8817e4Smiod 
391*3d8817e4Smiod   if (ppresent != NULL)
392*3d8817e4Smiod     {
393*3d8817e4Smiod       --*pp;
394*3d8817e4Smiod       *ppresent = FALSE;
395*3d8817e4Smiod       return TRUE;
396*3d8817e4Smiod     }
397*3d8817e4Smiod 
398*3d8817e4Smiod   ieee_error (info, *pp - 1, _("invalid number"));
399*3d8817e4Smiod   return FALSE;
400*3d8817e4Smiod }
401*3d8817e4Smiod 
402*3d8817e4Smiod /* Read a required string from an IEEE file.  */
403*3d8817e4Smiod 
404*3d8817e4Smiod static bfd_boolean
ieee_read_id(struct ieee_info * info,const bfd_byte ** pp,const char ** pname,unsigned long * pnamlen)405*3d8817e4Smiod ieee_read_id (struct ieee_info *info, const bfd_byte **pp,
406*3d8817e4Smiod 	      const char **pname, unsigned long *pnamlen)
407*3d8817e4Smiod {
408*3d8817e4Smiod   return ieee_read_optional_id (info, pp, pname, pnamlen, (bfd_boolean *) NULL);
409*3d8817e4Smiod }
410*3d8817e4Smiod 
411*3d8817e4Smiod /* Read a string from an IEEE file.  If ppresent is not NULL, the
412*3d8817e4Smiod    string is optional.  */
413*3d8817e4Smiod 
414*3d8817e4Smiod static bfd_boolean
ieee_read_optional_id(struct ieee_info * info,const bfd_byte ** pp,const char ** pname,unsigned long * pnamlen,bfd_boolean * ppresent)415*3d8817e4Smiod ieee_read_optional_id (struct ieee_info *info, const bfd_byte **pp,
416*3d8817e4Smiod 		       const char **pname, unsigned long *pnamlen,
417*3d8817e4Smiod 		       bfd_boolean *ppresent)
418*3d8817e4Smiod {
419*3d8817e4Smiod   bfd_byte b;
420*3d8817e4Smiod   unsigned long len;
421*3d8817e4Smiod 
422*3d8817e4Smiod   if (*pp >= info->pend)
423*3d8817e4Smiod     {
424*3d8817e4Smiod       ieee_eof (info);
425*3d8817e4Smiod       return FALSE;
426*3d8817e4Smiod     }
427*3d8817e4Smiod 
428*3d8817e4Smiod   b = **pp;
429*3d8817e4Smiod   ++*pp;
430*3d8817e4Smiod 
431*3d8817e4Smiod   if (b <= 0x7f)
432*3d8817e4Smiod     len = b;
433*3d8817e4Smiod   else if ((ieee_record_enum_type) b == ieee_extension_length_1_enum)
434*3d8817e4Smiod     {
435*3d8817e4Smiod       len = **pp;
436*3d8817e4Smiod       ++*pp;
437*3d8817e4Smiod     }
438*3d8817e4Smiod   else if ((ieee_record_enum_type) b == ieee_extension_length_2_enum)
439*3d8817e4Smiod     {
440*3d8817e4Smiod       len = (**pp << 8) + (*pp)[1];
441*3d8817e4Smiod       *pp += 2;
442*3d8817e4Smiod     }
443*3d8817e4Smiod   else
444*3d8817e4Smiod     {
445*3d8817e4Smiod       if (ppresent != NULL)
446*3d8817e4Smiod 	{
447*3d8817e4Smiod 	  --*pp;
448*3d8817e4Smiod 	  *ppresent = FALSE;
449*3d8817e4Smiod 	  return TRUE;
450*3d8817e4Smiod 	}
451*3d8817e4Smiod       ieee_error (info, *pp - 1, _("invalid string length"));
452*3d8817e4Smiod       return FALSE;
453*3d8817e4Smiod     }
454*3d8817e4Smiod 
455*3d8817e4Smiod   if ((unsigned long) (info->pend - *pp) < len)
456*3d8817e4Smiod     {
457*3d8817e4Smiod       ieee_eof (info);
458*3d8817e4Smiod       return FALSE;
459*3d8817e4Smiod     }
460*3d8817e4Smiod 
461*3d8817e4Smiod   *pname = (const char *) *pp;
462*3d8817e4Smiod   *pnamlen = len;
463*3d8817e4Smiod   *pp += len;
464*3d8817e4Smiod 
465*3d8817e4Smiod   if (ppresent != NULL)
466*3d8817e4Smiod     *ppresent = TRUE;
467*3d8817e4Smiod 
468*3d8817e4Smiod   return TRUE;
469*3d8817e4Smiod }
470*3d8817e4Smiod 
471*3d8817e4Smiod /* Read an expression from an IEEE file.  Since this code is only used
472*3d8817e4Smiod    to parse debugging information, I haven't bothered to write a full
473*3d8817e4Smiod    blown IEEE expression parser.  I've only thrown in the things I've
474*3d8817e4Smiod    seen in debugging information.  This can be easily extended if
475*3d8817e4Smiod    necessary.  */
476*3d8817e4Smiod 
477*3d8817e4Smiod static bfd_boolean
ieee_read_expression(struct ieee_info * info,const bfd_byte ** pp,bfd_vma * pv)478*3d8817e4Smiod ieee_read_expression (struct ieee_info *info, const bfd_byte **pp,
479*3d8817e4Smiod 		      bfd_vma *pv)
480*3d8817e4Smiod {
481*3d8817e4Smiod   const bfd_byte *expr_start;
482*3d8817e4Smiod #define EXPR_STACK_SIZE (10)
483*3d8817e4Smiod   bfd_vma expr_stack[EXPR_STACK_SIZE];
484*3d8817e4Smiod   bfd_vma *esp;
485*3d8817e4Smiod 
486*3d8817e4Smiod   expr_start = *pp;
487*3d8817e4Smiod 
488*3d8817e4Smiod   esp = expr_stack;
489*3d8817e4Smiod 
490*3d8817e4Smiod   while (1)
491*3d8817e4Smiod     {
492*3d8817e4Smiod       const bfd_byte *start;
493*3d8817e4Smiod       bfd_vma val;
494*3d8817e4Smiod       bfd_boolean present;
495*3d8817e4Smiod       ieee_record_enum_type c;
496*3d8817e4Smiod 
497*3d8817e4Smiod       start = *pp;
498*3d8817e4Smiod 
499*3d8817e4Smiod       if (! ieee_read_optional_number (info, pp, &val, &present))
500*3d8817e4Smiod 	return FALSE;
501*3d8817e4Smiod 
502*3d8817e4Smiod       if (present)
503*3d8817e4Smiod 	{
504*3d8817e4Smiod 	  if (esp - expr_stack >= EXPR_STACK_SIZE)
505*3d8817e4Smiod 	    {
506*3d8817e4Smiod 	      ieee_error (info, start, _("expression stack overflow"));
507*3d8817e4Smiod 	      return FALSE;
508*3d8817e4Smiod 	    }
509*3d8817e4Smiod 	  *esp++ = val;
510*3d8817e4Smiod 	  continue;
511*3d8817e4Smiod 	}
512*3d8817e4Smiod 
513*3d8817e4Smiod       c = (ieee_record_enum_type) **pp;
514*3d8817e4Smiod 
515*3d8817e4Smiod       if (c >= ieee_module_beginning_enum)
516*3d8817e4Smiod 	break;
517*3d8817e4Smiod 
518*3d8817e4Smiod       ++*pp;
519*3d8817e4Smiod 
520*3d8817e4Smiod       if (c == ieee_comma)
521*3d8817e4Smiod 	break;
522*3d8817e4Smiod 
523*3d8817e4Smiod       switch (c)
524*3d8817e4Smiod 	{
525*3d8817e4Smiod 	default:
526*3d8817e4Smiod 	  ieee_error (info, start, _("unsupported IEEE expression operator"));
527*3d8817e4Smiod 	  break;
528*3d8817e4Smiod 
529*3d8817e4Smiod 	case ieee_variable_R_enum:
530*3d8817e4Smiod 	  {
531*3d8817e4Smiod 	    bfd_vma indx;
532*3d8817e4Smiod 	    asection *s;
533*3d8817e4Smiod 
534*3d8817e4Smiod 	    if (! ieee_read_number (info, pp, &indx))
535*3d8817e4Smiod 	      return FALSE;
536*3d8817e4Smiod 	    for (s = info->abfd->sections; s != NULL; s = s->next)
537*3d8817e4Smiod 	      if ((bfd_vma) s->target_index == indx)
538*3d8817e4Smiod 		break;
539*3d8817e4Smiod 	    if (s == NULL)
540*3d8817e4Smiod 	      {
541*3d8817e4Smiod 		ieee_error (info, start, _("unknown section"));
542*3d8817e4Smiod 		return FALSE;
543*3d8817e4Smiod 	      }
544*3d8817e4Smiod 
545*3d8817e4Smiod 	    if (esp - expr_stack >= EXPR_STACK_SIZE)
546*3d8817e4Smiod 	      {
547*3d8817e4Smiod 		ieee_error (info, start, _("expression stack overflow"));
548*3d8817e4Smiod 		return FALSE;
549*3d8817e4Smiod 	      }
550*3d8817e4Smiod 
551*3d8817e4Smiod 	    *esp++ = bfd_get_section_vma (info->abfd, s);
552*3d8817e4Smiod 	  }
553*3d8817e4Smiod 	  break;
554*3d8817e4Smiod 
555*3d8817e4Smiod 	case ieee_function_plus_enum:
556*3d8817e4Smiod 	case ieee_function_minus_enum:
557*3d8817e4Smiod 	  {
558*3d8817e4Smiod 	    bfd_vma v1, v2;
559*3d8817e4Smiod 
560*3d8817e4Smiod 	    if (esp - expr_stack < 2)
561*3d8817e4Smiod 	      {
562*3d8817e4Smiod 		ieee_error (info, start, _("expression stack underflow"));
563*3d8817e4Smiod 		return FALSE;
564*3d8817e4Smiod 	      }
565*3d8817e4Smiod 
566*3d8817e4Smiod 	    v1 = *--esp;
567*3d8817e4Smiod 	    v2 = *--esp;
568*3d8817e4Smiod 	    *esp++ = v1 + v2;
569*3d8817e4Smiod 	  }
570*3d8817e4Smiod 	  break;
571*3d8817e4Smiod 	}
572*3d8817e4Smiod     }
573*3d8817e4Smiod 
574*3d8817e4Smiod   if (esp - 1 != expr_stack)
575*3d8817e4Smiod     {
576*3d8817e4Smiod       ieee_error (info, expr_start, _("expression stack mismatch"));
577*3d8817e4Smiod       return FALSE;
578*3d8817e4Smiod     }
579*3d8817e4Smiod 
580*3d8817e4Smiod   *pv = *--esp;
581*3d8817e4Smiod 
582*3d8817e4Smiod   return TRUE;
583*3d8817e4Smiod }
584*3d8817e4Smiod 
585*3d8817e4Smiod /* Return an IEEE builtin type.  */
586*3d8817e4Smiod 
587*3d8817e4Smiod static debug_type
ieee_builtin_type(struct ieee_info * info,const bfd_byte * p,unsigned int indx)588*3d8817e4Smiod ieee_builtin_type (struct ieee_info *info, const bfd_byte *p,
589*3d8817e4Smiod 		   unsigned int indx)
590*3d8817e4Smiod {
591*3d8817e4Smiod   void *dhandle;
592*3d8817e4Smiod   debug_type type;
593*3d8817e4Smiod   const char *name;
594*3d8817e4Smiod 
595*3d8817e4Smiod   if (indx < BUILTIN_TYPE_COUNT
596*3d8817e4Smiod       && info->types.builtins[indx] != DEBUG_TYPE_NULL)
597*3d8817e4Smiod     return info->types.builtins[indx];
598*3d8817e4Smiod 
599*3d8817e4Smiod   dhandle = info->dhandle;
600*3d8817e4Smiod 
601*3d8817e4Smiod   if (indx >= 32 && indx < 64)
602*3d8817e4Smiod     {
603*3d8817e4Smiod       type = debug_make_pointer_type (dhandle,
604*3d8817e4Smiod 				      ieee_builtin_type (info, p, indx - 32));
605*3d8817e4Smiod       assert (indx < BUILTIN_TYPE_COUNT);
606*3d8817e4Smiod       info->types.builtins[indx] = type;
607*3d8817e4Smiod       return type;
608*3d8817e4Smiod     }
609*3d8817e4Smiod 
610*3d8817e4Smiod   switch ((enum builtin_types) indx)
611*3d8817e4Smiod     {
612*3d8817e4Smiod     default:
613*3d8817e4Smiod       ieee_error (info, p, _("unknown builtin type"));
614*3d8817e4Smiod       return NULL;
615*3d8817e4Smiod 
616*3d8817e4Smiod     case builtin_unknown:
617*3d8817e4Smiod       type = debug_make_void_type (dhandle);
618*3d8817e4Smiod       name = NULL;
619*3d8817e4Smiod       break;
620*3d8817e4Smiod 
621*3d8817e4Smiod     case builtin_void:
622*3d8817e4Smiod       type = debug_make_void_type (dhandle);
623*3d8817e4Smiod       name = "void";
624*3d8817e4Smiod       break;
625*3d8817e4Smiod 
626*3d8817e4Smiod     case builtin_signed_char:
627*3d8817e4Smiod       type = debug_make_int_type (dhandle, 1, FALSE);
628*3d8817e4Smiod       name = "signed char";
629*3d8817e4Smiod       break;
630*3d8817e4Smiod 
631*3d8817e4Smiod     case builtin_unsigned_char:
632*3d8817e4Smiod       type = debug_make_int_type (dhandle, 1, TRUE);
633*3d8817e4Smiod       name = "unsigned char";
634*3d8817e4Smiod       break;
635*3d8817e4Smiod 
636*3d8817e4Smiod     case builtin_signed_short_int:
637*3d8817e4Smiod       type = debug_make_int_type (dhandle, 2, FALSE);
638*3d8817e4Smiod       name = "signed short int";
639*3d8817e4Smiod       break;
640*3d8817e4Smiod 
641*3d8817e4Smiod     case builtin_unsigned_short_int:
642*3d8817e4Smiod       type = debug_make_int_type (dhandle, 2, TRUE);
643*3d8817e4Smiod       name = "unsigned short int";
644*3d8817e4Smiod       break;
645*3d8817e4Smiod 
646*3d8817e4Smiod     case builtin_signed_long:
647*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, FALSE);
648*3d8817e4Smiod       name = "signed long";
649*3d8817e4Smiod       break;
650*3d8817e4Smiod 
651*3d8817e4Smiod     case builtin_unsigned_long:
652*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, TRUE);
653*3d8817e4Smiod       name = "unsigned long";
654*3d8817e4Smiod       break;
655*3d8817e4Smiod 
656*3d8817e4Smiod     case builtin_signed_long_long:
657*3d8817e4Smiod       type = debug_make_int_type (dhandle, 8, FALSE);
658*3d8817e4Smiod       name = "signed long long";
659*3d8817e4Smiod       break;
660*3d8817e4Smiod 
661*3d8817e4Smiod     case builtin_unsigned_long_long:
662*3d8817e4Smiod       type = debug_make_int_type (dhandle, 8, TRUE);
663*3d8817e4Smiod       name = "unsigned long long";
664*3d8817e4Smiod       break;
665*3d8817e4Smiod 
666*3d8817e4Smiod     case builtin_float:
667*3d8817e4Smiod       type = debug_make_float_type (dhandle, 4);
668*3d8817e4Smiod       name = "float";
669*3d8817e4Smiod       break;
670*3d8817e4Smiod 
671*3d8817e4Smiod     case builtin_double:
672*3d8817e4Smiod       type = debug_make_float_type (dhandle, 8);
673*3d8817e4Smiod       name = "double";
674*3d8817e4Smiod       break;
675*3d8817e4Smiod 
676*3d8817e4Smiod     case builtin_long_double:
677*3d8817e4Smiod       /* FIXME: The size for this type should depend upon the
678*3d8817e4Smiod          processor.  */
679*3d8817e4Smiod       type = debug_make_float_type (dhandle, 12);
680*3d8817e4Smiod       name = "long double";
681*3d8817e4Smiod       break;
682*3d8817e4Smiod 
683*3d8817e4Smiod     case builtin_long_long_double:
684*3d8817e4Smiod       type = debug_make_float_type (dhandle, 16);
685*3d8817e4Smiod       name = "long long double";
686*3d8817e4Smiod       break;
687*3d8817e4Smiod 
688*3d8817e4Smiod     case builtin_quoted_string:
689*3d8817e4Smiod       type = debug_make_array_type (dhandle,
690*3d8817e4Smiod 				    ieee_builtin_type (info, p,
691*3d8817e4Smiod 						       ((unsigned int)
692*3d8817e4Smiod 							builtin_char)),
693*3d8817e4Smiod 				    ieee_builtin_type (info, p,
694*3d8817e4Smiod 						       ((unsigned int)
695*3d8817e4Smiod 							builtin_int)),
696*3d8817e4Smiod 				    0, -1, TRUE);
697*3d8817e4Smiod       name = "QUOTED STRING";
698*3d8817e4Smiod       break;
699*3d8817e4Smiod 
700*3d8817e4Smiod     case builtin_instruction_address:
701*3d8817e4Smiod       /* FIXME: This should be a code address.  */
702*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, TRUE);
703*3d8817e4Smiod       name = "instruction address";
704*3d8817e4Smiod       break;
705*3d8817e4Smiod 
706*3d8817e4Smiod     case builtin_int:
707*3d8817e4Smiod       /* FIXME: The size for this type should depend upon the
708*3d8817e4Smiod          processor.  */
709*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, FALSE);
710*3d8817e4Smiod       name = "int";
711*3d8817e4Smiod       break;
712*3d8817e4Smiod 
713*3d8817e4Smiod     case builtin_unsigned:
714*3d8817e4Smiod       /* FIXME: The size for this type should depend upon the
715*3d8817e4Smiod          processor.  */
716*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, TRUE);
717*3d8817e4Smiod       name = "unsigned";
718*3d8817e4Smiod       break;
719*3d8817e4Smiod 
720*3d8817e4Smiod     case builtin_unsigned_int:
721*3d8817e4Smiod       /* FIXME: The size for this type should depend upon the
722*3d8817e4Smiod          processor.  */
723*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, TRUE);
724*3d8817e4Smiod       name = "unsigned int";
725*3d8817e4Smiod       break;
726*3d8817e4Smiod 
727*3d8817e4Smiod     case builtin_char:
728*3d8817e4Smiod       type = debug_make_int_type (dhandle, 1, FALSE);
729*3d8817e4Smiod       name = "char";
730*3d8817e4Smiod       break;
731*3d8817e4Smiod 
732*3d8817e4Smiod     case builtin_long:
733*3d8817e4Smiod       type = debug_make_int_type (dhandle, 4, FALSE);
734*3d8817e4Smiod       name = "long";
735*3d8817e4Smiod       break;
736*3d8817e4Smiod 
737*3d8817e4Smiod     case builtin_short:
738*3d8817e4Smiod       type = debug_make_int_type (dhandle, 2, FALSE);
739*3d8817e4Smiod       name = "short";
740*3d8817e4Smiod       break;
741*3d8817e4Smiod 
742*3d8817e4Smiod     case builtin_unsigned_short:
743*3d8817e4Smiod       type = debug_make_int_type (dhandle, 2, TRUE);
744*3d8817e4Smiod       name = "unsigned short";
745*3d8817e4Smiod       break;
746*3d8817e4Smiod 
747*3d8817e4Smiod     case builtin_short_int:
748*3d8817e4Smiod       type = debug_make_int_type (dhandle, 2, FALSE);
749*3d8817e4Smiod       name = "short int";
750*3d8817e4Smiod       break;
751*3d8817e4Smiod 
752*3d8817e4Smiod     case builtin_signed_short:
753*3d8817e4Smiod       type = debug_make_int_type (dhandle, 2, FALSE);
754*3d8817e4Smiod       name = "signed short";
755*3d8817e4Smiod       break;
756*3d8817e4Smiod 
757*3d8817e4Smiod     case builtin_bcd_float:
758*3d8817e4Smiod       ieee_error (info, p, _("BCD float type not supported"));
759*3d8817e4Smiod       return DEBUG_TYPE_NULL;
760*3d8817e4Smiod     }
761*3d8817e4Smiod 
762*3d8817e4Smiod   if (name != NULL)
763*3d8817e4Smiod     type = debug_name_type (dhandle, name, type);
764*3d8817e4Smiod 
765*3d8817e4Smiod   assert (indx < BUILTIN_TYPE_COUNT);
766*3d8817e4Smiod 
767*3d8817e4Smiod   info->types.builtins[indx] = type;
768*3d8817e4Smiod 
769*3d8817e4Smiod   return type;
770*3d8817e4Smiod }
771*3d8817e4Smiod 
772*3d8817e4Smiod /* Allocate more space in the type table.  If ref is TRUE, this is a
773*3d8817e4Smiod    reference to the type; if it is not already defined, we should set
774*3d8817e4Smiod    up an indirect type.  */
775*3d8817e4Smiod 
776*3d8817e4Smiod static bfd_boolean
ieee_alloc_type(struct ieee_info * info,unsigned int indx,bfd_boolean ref)777*3d8817e4Smiod ieee_alloc_type (struct ieee_info *info, unsigned int indx, bfd_boolean ref)
778*3d8817e4Smiod {
779*3d8817e4Smiod   unsigned int nalloc;
780*3d8817e4Smiod   register struct ieee_type *t;
781*3d8817e4Smiod   struct ieee_type *tend;
782*3d8817e4Smiod 
783*3d8817e4Smiod   if (indx >= info->types.alloc)
784*3d8817e4Smiod     {
785*3d8817e4Smiod       nalloc = info->types.alloc;
786*3d8817e4Smiod       if (nalloc == 0)
787*3d8817e4Smiod 	nalloc = 4;
788*3d8817e4Smiod       while (indx >= nalloc)
789*3d8817e4Smiod 	nalloc *= 2;
790*3d8817e4Smiod 
791*3d8817e4Smiod       info->types.types = ((struct ieee_type *)
792*3d8817e4Smiod 			   xrealloc (info->types.types,
793*3d8817e4Smiod 				     nalloc * sizeof *info->types.types));
794*3d8817e4Smiod 
795*3d8817e4Smiod       memset (info->types.types + info->types.alloc, 0,
796*3d8817e4Smiod 	      (nalloc - info->types.alloc) * sizeof *info->types.types);
797*3d8817e4Smiod 
798*3d8817e4Smiod       tend = info->types.types + nalloc;
799*3d8817e4Smiod       for (t = info->types.types + info->types.alloc; t < tend; t++)
800*3d8817e4Smiod 	t->type = DEBUG_TYPE_NULL;
801*3d8817e4Smiod 
802*3d8817e4Smiod       info->types.alloc = nalloc;
803*3d8817e4Smiod     }
804*3d8817e4Smiod 
805*3d8817e4Smiod   if (ref)
806*3d8817e4Smiod     {
807*3d8817e4Smiod       t = info->types.types + indx;
808*3d8817e4Smiod       if (t->type == NULL)
809*3d8817e4Smiod 	{
810*3d8817e4Smiod 	  t->pslot = (debug_type *) xmalloc (sizeof *t->pslot);
811*3d8817e4Smiod 	  *t->pslot = DEBUG_TYPE_NULL;
812*3d8817e4Smiod 	  t->type = debug_make_indirect_type (info->dhandle, t->pslot,
813*3d8817e4Smiod 					      (const char *) NULL);
814*3d8817e4Smiod 	  if (t->type == NULL)
815*3d8817e4Smiod 	    return FALSE;
816*3d8817e4Smiod 	}
817*3d8817e4Smiod     }
818*3d8817e4Smiod 
819*3d8817e4Smiod   return TRUE;
820*3d8817e4Smiod }
821*3d8817e4Smiod 
822*3d8817e4Smiod /* Read a type index and return the corresponding type.  */
823*3d8817e4Smiod 
824*3d8817e4Smiod static bfd_boolean
ieee_read_type_index(struct ieee_info * info,const bfd_byte ** pp,debug_type * ptype)825*3d8817e4Smiod ieee_read_type_index (struct ieee_info *info, const bfd_byte **pp,
826*3d8817e4Smiod 		      debug_type *ptype)
827*3d8817e4Smiod {
828*3d8817e4Smiod   const bfd_byte *start;
829*3d8817e4Smiod   bfd_vma indx;
830*3d8817e4Smiod 
831*3d8817e4Smiod   start = *pp;
832*3d8817e4Smiod 
833*3d8817e4Smiod   if (! ieee_read_number (info, pp, &indx))
834*3d8817e4Smiod     return FALSE;
835*3d8817e4Smiod 
836*3d8817e4Smiod   if (indx < 256)
837*3d8817e4Smiod     {
838*3d8817e4Smiod       *ptype = ieee_builtin_type (info, start, indx);
839*3d8817e4Smiod       if (*ptype == NULL)
840*3d8817e4Smiod 	return FALSE;
841*3d8817e4Smiod       return TRUE;
842*3d8817e4Smiod     }
843*3d8817e4Smiod 
844*3d8817e4Smiod   indx -= 256;
845*3d8817e4Smiod   if (! ieee_alloc_type (info, indx, TRUE))
846*3d8817e4Smiod     return FALSE;
847*3d8817e4Smiod 
848*3d8817e4Smiod   *ptype = info->types.types[indx].type;
849*3d8817e4Smiod 
850*3d8817e4Smiod   return TRUE;
851*3d8817e4Smiod }
852*3d8817e4Smiod 
853*3d8817e4Smiod /* Parse IEEE debugging information for a file.  This is passed the
854*3d8817e4Smiod    bytes which compose the Debug Information Part of an IEEE file.  */
855*3d8817e4Smiod 
856*3d8817e4Smiod bfd_boolean
parse_ieee(void * dhandle,bfd * abfd,const bfd_byte * bytes,bfd_size_type len)857*3d8817e4Smiod parse_ieee (void *dhandle, bfd *abfd, const bfd_byte *bytes, bfd_size_type len)
858*3d8817e4Smiod {
859*3d8817e4Smiod   struct ieee_info info;
860*3d8817e4Smiod   unsigned int i;
861*3d8817e4Smiod   const bfd_byte *p, *pend;
862*3d8817e4Smiod 
863*3d8817e4Smiod   info.dhandle = dhandle;
864*3d8817e4Smiod   info.abfd = abfd;
865*3d8817e4Smiod   info.bytes = bytes;
866*3d8817e4Smiod   info.pend = bytes + len;
867*3d8817e4Smiod   info.blockstack.bsp = info.blockstack.stack;
868*3d8817e4Smiod   info.saw_filename = FALSE;
869*3d8817e4Smiod   info.vars.alloc = 0;
870*3d8817e4Smiod   info.vars.vars = NULL;
871*3d8817e4Smiod   info.global_vars = NULL;
872*3d8817e4Smiod   info.types.alloc = 0;
873*3d8817e4Smiod   info.types.types = NULL;
874*3d8817e4Smiod   info.global_types = NULL;
875*3d8817e4Smiod   info.tags = NULL;
876*3d8817e4Smiod   for (i = 0; i < BUILTIN_TYPE_COUNT; i++)
877*3d8817e4Smiod     info.types.builtins[i] = DEBUG_TYPE_NULL;
878*3d8817e4Smiod 
879*3d8817e4Smiod   p = bytes;
880*3d8817e4Smiod   pend = info.pend;
881*3d8817e4Smiod   while (p < pend)
882*3d8817e4Smiod     {
883*3d8817e4Smiod       const bfd_byte *record_start;
884*3d8817e4Smiod       ieee_record_enum_type c;
885*3d8817e4Smiod 
886*3d8817e4Smiod       record_start = p;
887*3d8817e4Smiod 
888*3d8817e4Smiod       c = (ieee_record_enum_type) *p++;
889*3d8817e4Smiod 
890*3d8817e4Smiod       if (c == ieee_at_record_enum)
891*3d8817e4Smiod 	c = (ieee_record_enum_type) (((unsigned int) c << 8) | *p++);
892*3d8817e4Smiod 
893*3d8817e4Smiod       if (c <= ieee_number_repeat_end_enum)
894*3d8817e4Smiod 	{
895*3d8817e4Smiod 	  ieee_error (&info, record_start, _("unexpected number"));
896*3d8817e4Smiod 	  return FALSE;
897*3d8817e4Smiod 	}
898*3d8817e4Smiod 
899*3d8817e4Smiod       switch (c)
900*3d8817e4Smiod 	{
901*3d8817e4Smiod 	default:
902*3d8817e4Smiod 	  ieee_error (&info, record_start, _("unexpected record type"));
903*3d8817e4Smiod 	  return FALSE;
904*3d8817e4Smiod 
905*3d8817e4Smiod 	case ieee_bb_record_enum:
906*3d8817e4Smiod 	  if (! parse_ieee_bb (&info, &p))
907*3d8817e4Smiod 	    return FALSE;
908*3d8817e4Smiod 	  break;
909*3d8817e4Smiod 
910*3d8817e4Smiod 	case ieee_be_record_enum:
911*3d8817e4Smiod 	  if (! parse_ieee_be (&info, &p))
912*3d8817e4Smiod 	    return FALSE;
913*3d8817e4Smiod 	  break;
914*3d8817e4Smiod 
915*3d8817e4Smiod 	case ieee_nn_record:
916*3d8817e4Smiod 	  if (! parse_ieee_nn (&info, &p))
917*3d8817e4Smiod 	    return FALSE;
918*3d8817e4Smiod 	  break;
919*3d8817e4Smiod 
920*3d8817e4Smiod 	case ieee_ty_record_enum:
921*3d8817e4Smiod 	  if (! parse_ieee_ty (&info, &p))
922*3d8817e4Smiod 	    return FALSE;
923*3d8817e4Smiod 	  break;
924*3d8817e4Smiod 
925*3d8817e4Smiod 	case ieee_atn_record_enum:
926*3d8817e4Smiod 	  if (! parse_ieee_atn (&info, &p))
927*3d8817e4Smiod 	    return FALSE;
928*3d8817e4Smiod 	  break;
929*3d8817e4Smiod 	}
930*3d8817e4Smiod     }
931*3d8817e4Smiod 
932*3d8817e4Smiod   if (info.blockstack.bsp != info.blockstack.stack)
933*3d8817e4Smiod     {
934*3d8817e4Smiod       ieee_error (&info, (const bfd_byte *) NULL,
935*3d8817e4Smiod 		  _("blocks left on stack at end"));
936*3d8817e4Smiod       return FALSE;
937*3d8817e4Smiod     }
938*3d8817e4Smiod 
939*3d8817e4Smiod   return TRUE;
940*3d8817e4Smiod }
941*3d8817e4Smiod 
942*3d8817e4Smiod /* Handle an IEEE BB record.  */
943*3d8817e4Smiod 
944*3d8817e4Smiod static bfd_boolean
parse_ieee_bb(struct ieee_info * info,const bfd_byte ** pp)945*3d8817e4Smiod parse_ieee_bb (struct ieee_info *info, const bfd_byte **pp)
946*3d8817e4Smiod {
947*3d8817e4Smiod   const bfd_byte *block_start;
948*3d8817e4Smiod   bfd_byte b;
949*3d8817e4Smiod   bfd_vma size;
950*3d8817e4Smiod   const char *name;
951*3d8817e4Smiod   unsigned long namlen;
952*3d8817e4Smiod   char *namcopy = NULL;
953*3d8817e4Smiod   unsigned int fnindx;
954*3d8817e4Smiod   bfd_boolean skip;
955*3d8817e4Smiod 
956*3d8817e4Smiod   block_start = *pp;
957*3d8817e4Smiod 
958*3d8817e4Smiod   b = **pp;
959*3d8817e4Smiod   ++*pp;
960*3d8817e4Smiod 
961*3d8817e4Smiod   if (! ieee_read_number (info, pp, &size)
962*3d8817e4Smiod       || ! ieee_read_id (info, pp, &name, &namlen))
963*3d8817e4Smiod     return FALSE;
964*3d8817e4Smiod 
965*3d8817e4Smiod   fnindx = (unsigned int) -1;
966*3d8817e4Smiod   skip = FALSE;
967*3d8817e4Smiod 
968*3d8817e4Smiod   switch (b)
969*3d8817e4Smiod     {
970*3d8817e4Smiod     case 1:
971*3d8817e4Smiod       /* BB1: Type definitions local to a module.  */
972*3d8817e4Smiod       namcopy = savestring (name, namlen);
973*3d8817e4Smiod       if (namcopy == NULL)
974*3d8817e4Smiod 	return FALSE;
975*3d8817e4Smiod       if (! debug_set_filename (info->dhandle, namcopy))
976*3d8817e4Smiod 	return FALSE;
977*3d8817e4Smiod       info->saw_filename = TRUE;
978*3d8817e4Smiod 
979*3d8817e4Smiod       /* Discard any variables or types we may have seen before.  */
980*3d8817e4Smiod       if (info->vars.vars != NULL)
981*3d8817e4Smiod 	free (info->vars.vars);
982*3d8817e4Smiod       info->vars.vars = NULL;
983*3d8817e4Smiod       info->vars.alloc = 0;
984*3d8817e4Smiod       if (info->types.types != NULL)
985*3d8817e4Smiod 	free (info->types.types);
986*3d8817e4Smiod       info->types.types = NULL;
987*3d8817e4Smiod       info->types.alloc = 0;
988*3d8817e4Smiod 
989*3d8817e4Smiod       /* Initialize the types to the global types.  */
990*3d8817e4Smiod       if (info->global_types != NULL)
991*3d8817e4Smiod 	{
992*3d8817e4Smiod 	  info->types.alloc = info->global_types->alloc;
993*3d8817e4Smiod 	  info->types.types = ((struct ieee_type *)
994*3d8817e4Smiod 			       xmalloc (info->types.alloc
995*3d8817e4Smiod 					* sizeof (*info->types.types)));
996*3d8817e4Smiod 	  memcpy (info->types.types, info->global_types->types,
997*3d8817e4Smiod 		  info->types.alloc * sizeof (*info->types.types));
998*3d8817e4Smiod 	}
999*3d8817e4Smiod 
1000*3d8817e4Smiod       break;
1001*3d8817e4Smiod 
1002*3d8817e4Smiod     case 2:
1003*3d8817e4Smiod       /* BB2: Global type definitions.  The name is supposed to be
1004*3d8817e4Smiod 	 empty, but we don't check.  */
1005*3d8817e4Smiod       if (! debug_set_filename (info->dhandle, "*global*"))
1006*3d8817e4Smiod 	return FALSE;
1007*3d8817e4Smiod       info->saw_filename = TRUE;
1008*3d8817e4Smiod       break;
1009*3d8817e4Smiod 
1010*3d8817e4Smiod     case 3:
1011*3d8817e4Smiod       /* BB3: High level module block begin.  We don't have to do
1012*3d8817e4Smiod 	 anything here.  The name is supposed to be the same as for
1013*3d8817e4Smiod 	 the BB1, but we don't check.  */
1014*3d8817e4Smiod       break;
1015*3d8817e4Smiod 
1016*3d8817e4Smiod     case 4:
1017*3d8817e4Smiod       /* BB4: Global function.  */
1018*3d8817e4Smiod       {
1019*3d8817e4Smiod 	bfd_vma stackspace, typindx, offset;
1020*3d8817e4Smiod 	debug_type return_type;
1021*3d8817e4Smiod 
1022*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &stackspace)
1023*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &typindx)
1024*3d8817e4Smiod 	    || ! ieee_read_expression (info, pp, &offset))
1025*3d8817e4Smiod 	  return FALSE;
1026*3d8817e4Smiod 
1027*3d8817e4Smiod 	/* We have no way to record the stack space.  FIXME.  */
1028*3d8817e4Smiod 
1029*3d8817e4Smiod 	if (typindx < 256)
1030*3d8817e4Smiod 	  {
1031*3d8817e4Smiod 	    return_type = ieee_builtin_type (info, block_start, typindx);
1032*3d8817e4Smiod 	    if (return_type == DEBUG_TYPE_NULL)
1033*3d8817e4Smiod 	      return FALSE;
1034*3d8817e4Smiod 	  }
1035*3d8817e4Smiod 	else
1036*3d8817e4Smiod 	  {
1037*3d8817e4Smiod 	    typindx -= 256;
1038*3d8817e4Smiod 	    if (! ieee_alloc_type (info, typindx, TRUE))
1039*3d8817e4Smiod 	      return FALSE;
1040*3d8817e4Smiod 	    fnindx = typindx;
1041*3d8817e4Smiod 	    return_type = info->types.types[typindx].type;
1042*3d8817e4Smiod 	    if (debug_get_type_kind (info->dhandle, return_type)
1043*3d8817e4Smiod 		== DEBUG_KIND_FUNCTION)
1044*3d8817e4Smiod 	      return_type = debug_get_return_type (info->dhandle,
1045*3d8817e4Smiod 						   return_type);
1046*3d8817e4Smiod 	  }
1047*3d8817e4Smiod 
1048*3d8817e4Smiod 	namcopy = savestring (name, namlen);
1049*3d8817e4Smiod 	if (namcopy == NULL)
1050*3d8817e4Smiod 	  return FALSE;
1051*3d8817e4Smiod 	if (! debug_record_function (info->dhandle, namcopy, return_type,
1052*3d8817e4Smiod 				     TRUE, offset))
1053*3d8817e4Smiod 	  return FALSE;
1054*3d8817e4Smiod       }
1055*3d8817e4Smiod       break;
1056*3d8817e4Smiod 
1057*3d8817e4Smiod     case 5:
1058*3d8817e4Smiod       /* BB5: File name for source line numbers.  */
1059*3d8817e4Smiod       {
1060*3d8817e4Smiod 	unsigned int i;
1061*3d8817e4Smiod 
1062*3d8817e4Smiod 	/* We ignore the date and time.  FIXME.  */
1063*3d8817e4Smiod 	for (i = 0; i < 6; i++)
1064*3d8817e4Smiod 	  {
1065*3d8817e4Smiod 	    bfd_vma ignore;
1066*3d8817e4Smiod 	    bfd_boolean present;
1067*3d8817e4Smiod 
1068*3d8817e4Smiod 	    if (! ieee_read_optional_number (info, pp, &ignore, &present))
1069*3d8817e4Smiod 	      return FALSE;
1070*3d8817e4Smiod 	    if (! present)
1071*3d8817e4Smiod 	      break;
1072*3d8817e4Smiod 	  }
1073*3d8817e4Smiod 
1074*3d8817e4Smiod 	namcopy = savestring (name, namlen);
1075*3d8817e4Smiod 	if (namcopy == NULL)
1076*3d8817e4Smiod 	  return FALSE;
1077*3d8817e4Smiod 	if (! debug_start_source (info->dhandle, namcopy))
1078*3d8817e4Smiod 	  return FALSE;
1079*3d8817e4Smiod       }
1080*3d8817e4Smiod       break;
1081*3d8817e4Smiod 
1082*3d8817e4Smiod     case 6:
1083*3d8817e4Smiod       /* BB6: Local function or block.  */
1084*3d8817e4Smiod       {
1085*3d8817e4Smiod 	bfd_vma stackspace, typindx, offset;
1086*3d8817e4Smiod 
1087*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &stackspace)
1088*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &typindx)
1089*3d8817e4Smiod 	    || ! ieee_read_expression (info, pp, &offset))
1090*3d8817e4Smiod 	  return FALSE;
1091*3d8817e4Smiod 
1092*3d8817e4Smiod 	/* We have no way to record the stack space.  FIXME.  */
1093*3d8817e4Smiod 
1094*3d8817e4Smiod 	if (namlen == 0)
1095*3d8817e4Smiod 	  {
1096*3d8817e4Smiod 	    if (! debug_start_block (info->dhandle, offset))
1097*3d8817e4Smiod 	      return FALSE;
1098*3d8817e4Smiod 	    /* Change b to indicate that this is a block
1099*3d8817e4Smiod 	       rather than a function.  */
1100*3d8817e4Smiod 	    b = 0x86;
1101*3d8817e4Smiod 	  }
1102*3d8817e4Smiod 	else
1103*3d8817e4Smiod 	  {
1104*3d8817e4Smiod 	    /* The MRI C++ compiler will output a fake function named
1105*3d8817e4Smiod 	       __XRYCPP to hold C++ debugging information.  We skip
1106*3d8817e4Smiod 	       that function.  This is not crucial, but it makes
1107*3d8817e4Smiod 	       converting from IEEE to other debug formats work
1108*3d8817e4Smiod 	       better.  */
1109*3d8817e4Smiod 	    if (strncmp (name, "__XRYCPP", namlen) == 0)
1110*3d8817e4Smiod 	      skip = TRUE;
1111*3d8817e4Smiod 	    else
1112*3d8817e4Smiod 	      {
1113*3d8817e4Smiod 		debug_type return_type;
1114*3d8817e4Smiod 
1115*3d8817e4Smiod 		if (typindx < 256)
1116*3d8817e4Smiod 		  {
1117*3d8817e4Smiod 		    return_type = ieee_builtin_type (info, block_start,
1118*3d8817e4Smiod 						     typindx);
1119*3d8817e4Smiod 		    if (return_type == NULL)
1120*3d8817e4Smiod 		      return FALSE;
1121*3d8817e4Smiod 		  }
1122*3d8817e4Smiod 		else
1123*3d8817e4Smiod 		  {
1124*3d8817e4Smiod 		    typindx -= 256;
1125*3d8817e4Smiod 		    if (! ieee_alloc_type (info, typindx, TRUE))
1126*3d8817e4Smiod 		      return FALSE;
1127*3d8817e4Smiod 		    fnindx = typindx;
1128*3d8817e4Smiod 		    return_type = info->types.types[typindx].type;
1129*3d8817e4Smiod 		    if (debug_get_type_kind (info->dhandle, return_type)
1130*3d8817e4Smiod 			== DEBUG_KIND_FUNCTION)
1131*3d8817e4Smiod 		      return_type = debug_get_return_type (info->dhandle,
1132*3d8817e4Smiod 							   return_type);
1133*3d8817e4Smiod 		  }
1134*3d8817e4Smiod 
1135*3d8817e4Smiod 		namcopy = savestring (name, namlen);
1136*3d8817e4Smiod 		if (namcopy == NULL)
1137*3d8817e4Smiod 		  return FALSE;
1138*3d8817e4Smiod 		if (! debug_record_function (info->dhandle, namcopy,
1139*3d8817e4Smiod 					     return_type, FALSE, offset))
1140*3d8817e4Smiod 		  return FALSE;
1141*3d8817e4Smiod 	      }
1142*3d8817e4Smiod 	  }
1143*3d8817e4Smiod       }
1144*3d8817e4Smiod       break;
1145*3d8817e4Smiod 
1146*3d8817e4Smiod     case 10:
1147*3d8817e4Smiod       /* BB10: Assembler module scope.  In the normal case, we
1148*3d8817e4Smiod 	 completely ignore all this information.  FIXME.  */
1149*3d8817e4Smiod       {
1150*3d8817e4Smiod 	const char *inam, *vstr;
1151*3d8817e4Smiod 	unsigned long inamlen, vstrlen;
1152*3d8817e4Smiod 	bfd_vma tool_type;
1153*3d8817e4Smiod 	bfd_boolean present;
1154*3d8817e4Smiod 	unsigned int i;
1155*3d8817e4Smiod 
1156*3d8817e4Smiod 	if (! info->saw_filename)
1157*3d8817e4Smiod 	  {
1158*3d8817e4Smiod 	    namcopy = savestring (name, namlen);
1159*3d8817e4Smiod 	    if (namcopy == NULL)
1160*3d8817e4Smiod 	      return FALSE;
1161*3d8817e4Smiod 	    if (! debug_set_filename (info->dhandle, namcopy))
1162*3d8817e4Smiod 	      return FALSE;
1163*3d8817e4Smiod 	    info->saw_filename = TRUE;
1164*3d8817e4Smiod 	  }
1165*3d8817e4Smiod 
1166*3d8817e4Smiod 	if (! ieee_read_id (info, pp, &inam, &inamlen)
1167*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &tool_type)
1168*3d8817e4Smiod 	    || ! ieee_read_optional_id (info, pp, &vstr, &vstrlen, &present))
1169*3d8817e4Smiod 	  return FALSE;
1170*3d8817e4Smiod 	for (i = 0; i < 6; i++)
1171*3d8817e4Smiod 	  {
1172*3d8817e4Smiod 	    bfd_vma ignore;
1173*3d8817e4Smiod 
1174*3d8817e4Smiod 	    if (! ieee_read_optional_number (info, pp, &ignore, &present))
1175*3d8817e4Smiod 	      return FALSE;
1176*3d8817e4Smiod 	    if (! present)
1177*3d8817e4Smiod 	      break;
1178*3d8817e4Smiod 	  }
1179*3d8817e4Smiod       }
1180*3d8817e4Smiod       break;
1181*3d8817e4Smiod 
1182*3d8817e4Smiod     case 11:
1183*3d8817e4Smiod       /* BB11: Module section.  We completely ignore all this
1184*3d8817e4Smiod 	 information.  FIXME.  */
1185*3d8817e4Smiod       {
1186*3d8817e4Smiod 	bfd_vma sectype, secindx, offset, map;
1187*3d8817e4Smiod 	bfd_boolean present;
1188*3d8817e4Smiod 
1189*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &sectype)
1190*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &secindx)
1191*3d8817e4Smiod 	    || ! ieee_read_expression (info, pp, &offset)
1192*3d8817e4Smiod 	    || ! ieee_read_optional_number (info, pp, &map, &present))
1193*3d8817e4Smiod 	  return FALSE;
1194*3d8817e4Smiod       }
1195*3d8817e4Smiod       break;
1196*3d8817e4Smiod 
1197*3d8817e4Smiod     default:
1198*3d8817e4Smiod       ieee_error (info, block_start, _("unknown BB type"));
1199*3d8817e4Smiod       return FALSE;
1200*3d8817e4Smiod     }
1201*3d8817e4Smiod 
1202*3d8817e4Smiod 
1203*3d8817e4Smiod   /* Push this block on the block stack.  */
1204*3d8817e4Smiod 
1205*3d8817e4Smiod   if (info->blockstack.bsp >= info->blockstack.stack + BLOCKSTACK_SIZE)
1206*3d8817e4Smiod     {
1207*3d8817e4Smiod       ieee_error (info, (const bfd_byte *) NULL, _("stack overflow"));
1208*3d8817e4Smiod       return FALSE;
1209*3d8817e4Smiod     }
1210*3d8817e4Smiod 
1211*3d8817e4Smiod   info->blockstack.bsp->kind = b;
1212*3d8817e4Smiod   if (b == 5)
1213*3d8817e4Smiod     info->blockstack.bsp->filename = namcopy;
1214*3d8817e4Smiod   info->blockstack.bsp->fnindx = fnindx;
1215*3d8817e4Smiod   info->blockstack.bsp->skip = skip;
1216*3d8817e4Smiod   ++info->blockstack.bsp;
1217*3d8817e4Smiod 
1218*3d8817e4Smiod   return TRUE;
1219*3d8817e4Smiod }
1220*3d8817e4Smiod 
1221*3d8817e4Smiod /* Handle an IEEE BE record.  */
1222*3d8817e4Smiod 
1223*3d8817e4Smiod static bfd_boolean
parse_ieee_be(struct ieee_info * info,const bfd_byte ** pp)1224*3d8817e4Smiod parse_ieee_be (struct ieee_info *info, const bfd_byte **pp)
1225*3d8817e4Smiod {
1226*3d8817e4Smiod   bfd_vma offset;
1227*3d8817e4Smiod 
1228*3d8817e4Smiod   if (info->blockstack.bsp <= info->blockstack.stack)
1229*3d8817e4Smiod     {
1230*3d8817e4Smiod       ieee_error (info, *pp, _("stack underflow"));
1231*3d8817e4Smiod       return FALSE;
1232*3d8817e4Smiod     }
1233*3d8817e4Smiod   --info->blockstack.bsp;
1234*3d8817e4Smiod 
1235*3d8817e4Smiod   switch (info->blockstack.bsp->kind)
1236*3d8817e4Smiod     {
1237*3d8817e4Smiod     case 2:
1238*3d8817e4Smiod       /* When we end the global typedefs block, we copy out the
1239*3d8817e4Smiod          contents of info->vars.  This is because the variable indices
1240*3d8817e4Smiod          may be reused in the local blocks.  However, we need to
1241*3d8817e4Smiod          preserve them so that we can locate a function returning a
1242*3d8817e4Smiod          reference variable whose type is named in the global typedef
1243*3d8817e4Smiod          block.  */
1244*3d8817e4Smiod       info->global_vars = ((struct ieee_vars *)
1245*3d8817e4Smiod 			   xmalloc (sizeof *info->global_vars));
1246*3d8817e4Smiod       info->global_vars->alloc = info->vars.alloc;
1247*3d8817e4Smiod       info->global_vars->vars = ((struct ieee_var *)
1248*3d8817e4Smiod 				 xmalloc (info->vars.alloc
1249*3d8817e4Smiod 					  * sizeof (*info->vars.vars)));
1250*3d8817e4Smiod       memcpy (info->global_vars->vars, info->vars.vars,
1251*3d8817e4Smiod 	      info->vars.alloc * sizeof (*info->vars.vars));
1252*3d8817e4Smiod 
1253*3d8817e4Smiod       /* We also copy out the non builtin parts of info->types, since
1254*3d8817e4Smiod          the types are discarded when we start a new block.  */
1255*3d8817e4Smiod       info->global_types = ((struct ieee_types *)
1256*3d8817e4Smiod 			    xmalloc (sizeof *info->global_types));
1257*3d8817e4Smiod       info->global_types->alloc = info->types.alloc;
1258*3d8817e4Smiod       info->global_types->types = ((struct ieee_type *)
1259*3d8817e4Smiod 				   xmalloc (info->types.alloc
1260*3d8817e4Smiod 					    * sizeof (*info->types.types)));
1261*3d8817e4Smiod       memcpy (info->global_types->types, info->types.types,
1262*3d8817e4Smiod 	      info->types.alloc * sizeof (*info->types.types));
1263*3d8817e4Smiod       memset (info->global_types->builtins, 0,
1264*3d8817e4Smiod 	      sizeof (info->global_types->builtins));
1265*3d8817e4Smiod 
1266*3d8817e4Smiod       break;
1267*3d8817e4Smiod 
1268*3d8817e4Smiod     case 4:
1269*3d8817e4Smiod     case 6:
1270*3d8817e4Smiod       if (! ieee_read_expression (info, pp, &offset))
1271*3d8817e4Smiod 	return FALSE;
1272*3d8817e4Smiod       if (! info->blockstack.bsp->skip)
1273*3d8817e4Smiod 	{
1274*3d8817e4Smiod 	  if (! debug_end_function (info->dhandle, offset + 1))
1275*3d8817e4Smiod 	    return FALSE;
1276*3d8817e4Smiod 	}
1277*3d8817e4Smiod       break;
1278*3d8817e4Smiod 
1279*3d8817e4Smiod     case 0x86:
1280*3d8817e4Smiod       /* This is BE6 when BB6 started a block rather than a local
1281*3d8817e4Smiod 	 function.  */
1282*3d8817e4Smiod       if (! ieee_read_expression (info, pp, &offset))
1283*3d8817e4Smiod 	return FALSE;
1284*3d8817e4Smiod       if (! debug_end_block (info->dhandle, offset + 1))
1285*3d8817e4Smiod 	return FALSE;
1286*3d8817e4Smiod       break;
1287*3d8817e4Smiod 
1288*3d8817e4Smiod     case 5:
1289*3d8817e4Smiod       /* When we end a BB5, we look up the stack for the last BB5, if
1290*3d8817e4Smiod          there is one, so that we can call debug_start_source.  */
1291*3d8817e4Smiod       if (info->blockstack.bsp > info->blockstack.stack)
1292*3d8817e4Smiod 	{
1293*3d8817e4Smiod 	  struct ieee_block *bl;
1294*3d8817e4Smiod 
1295*3d8817e4Smiod 	  bl = info->blockstack.bsp;
1296*3d8817e4Smiod 	  do
1297*3d8817e4Smiod 	    {
1298*3d8817e4Smiod 	      --bl;
1299*3d8817e4Smiod 	      if (bl->kind == 5)
1300*3d8817e4Smiod 		{
1301*3d8817e4Smiod 		  if (! debug_start_source (info->dhandle, bl->filename))
1302*3d8817e4Smiod 		    return FALSE;
1303*3d8817e4Smiod 		  break;
1304*3d8817e4Smiod 		}
1305*3d8817e4Smiod 	    }
1306*3d8817e4Smiod 	  while (bl != info->blockstack.stack);
1307*3d8817e4Smiod 	}
1308*3d8817e4Smiod       break;
1309*3d8817e4Smiod 
1310*3d8817e4Smiod     case 11:
1311*3d8817e4Smiod       if (! ieee_read_expression (info, pp, &offset))
1312*3d8817e4Smiod 	return FALSE;
1313*3d8817e4Smiod       /* We just ignore the module size.  FIXME.  */
1314*3d8817e4Smiod       break;
1315*3d8817e4Smiod 
1316*3d8817e4Smiod     default:
1317*3d8817e4Smiod       /* Other block types do not have any trailing information.  */
1318*3d8817e4Smiod       break;
1319*3d8817e4Smiod     }
1320*3d8817e4Smiod 
1321*3d8817e4Smiod   return TRUE;
1322*3d8817e4Smiod }
1323*3d8817e4Smiod 
1324*3d8817e4Smiod /* Parse an NN record.  */
1325*3d8817e4Smiod 
1326*3d8817e4Smiod static bfd_boolean
parse_ieee_nn(struct ieee_info * info,const bfd_byte ** pp)1327*3d8817e4Smiod parse_ieee_nn (struct ieee_info *info, const bfd_byte **pp)
1328*3d8817e4Smiod {
1329*3d8817e4Smiod   const bfd_byte *nn_start;
1330*3d8817e4Smiod   bfd_vma varindx;
1331*3d8817e4Smiod   const char *name;
1332*3d8817e4Smiod   unsigned long namlen;
1333*3d8817e4Smiod 
1334*3d8817e4Smiod   nn_start = *pp;
1335*3d8817e4Smiod 
1336*3d8817e4Smiod   if (! ieee_read_number (info, pp, &varindx)
1337*3d8817e4Smiod       || ! ieee_read_id (info, pp, &name, &namlen))
1338*3d8817e4Smiod     return FALSE;
1339*3d8817e4Smiod 
1340*3d8817e4Smiod   if (varindx < 32)
1341*3d8817e4Smiod     {
1342*3d8817e4Smiod       ieee_error (info, nn_start, _("illegal variable index"));
1343*3d8817e4Smiod       return FALSE;
1344*3d8817e4Smiod     }
1345*3d8817e4Smiod   varindx -= 32;
1346*3d8817e4Smiod 
1347*3d8817e4Smiod   if (varindx >= info->vars.alloc)
1348*3d8817e4Smiod     {
1349*3d8817e4Smiod       unsigned int alloc;
1350*3d8817e4Smiod 
1351*3d8817e4Smiod       alloc = info->vars.alloc;
1352*3d8817e4Smiod       if (alloc == 0)
1353*3d8817e4Smiod 	alloc = 4;
1354*3d8817e4Smiod       while (varindx >= alloc)
1355*3d8817e4Smiod 	alloc *= 2;
1356*3d8817e4Smiod       info->vars.vars = ((struct ieee_var *)
1357*3d8817e4Smiod 			 xrealloc (info->vars.vars,
1358*3d8817e4Smiod 				   alloc * sizeof *info->vars.vars));
1359*3d8817e4Smiod       memset (info->vars.vars + info->vars.alloc, 0,
1360*3d8817e4Smiod 	      (alloc - info->vars.alloc) * sizeof *info->vars.vars);
1361*3d8817e4Smiod       info->vars.alloc = alloc;
1362*3d8817e4Smiod     }
1363*3d8817e4Smiod 
1364*3d8817e4Smiod   info->vars.vars[varindx].name = name;
1365*3d8817e4Smiod   info->vars.vars[varindx].namlen = namlen;
1366*3d8817e4Smiod 
1367*3d8817e4Smiod   return TRUE;
1368*3d8817e4Smiod }
1369*3d8817e4Smiod 
1370*3d8817e4Smiod /* Parse a TY record.  */
1371*3d8817e4Smiod 
1372*3d8817e4Smiod static bfd_boolean
parse_ieee_ty(struct ieee_info * info,const bfd_byte ** pp)1373*3d8817e4Smiod parse_ieee_ty (struct ieee_info *info, const bfd_byte **pp)
1374*3d8817e4Smiod {
1375*3d8817e4Smiod   const bfd_byte *ty_start, *ty_var_start, *ty_code_start;
1376*3d8817e4Smiod   bfd_vma typeindx, varindx, tc;
1377*3d8817e4Smiod   void *dhandle;
1378*3d8817e4Smiod   bfd_boolean tag, typdef;
1379*3d8817e4Smiod   debug_type *arg_slots;
1380*3d8817e4Smiod   unsigned long type_bitsize;
1381*3d8817e4Smiod   debug_type type;
1382*3d8817e4Smiod 
1383*3d8817e4Smiod   ty_start = *pp;
1384*3d8817e4Smiod 
1385*3d8817e4Smiod   if (! ieee_read_number (info, pp, &typeindx))
1386*3d8817e4Smiod     return FALSE;
1387*3d8817e4Smiod 
1388*3d8817e4Smiod   if (typeindx < 256)
1389*3d8817e4Smiod     {
1390*3d8817e4Smiod       ieee_error (info, ty_start, _("illegal type index"));
1391*3d8817e4Smiod       return FALSE;
1392*3d8817e4Smiod     }
1393*3d8817e4Smiod 
1394*3d8817e4Smiod   typeindx -= 256;
1395*3d8817e4Smiod   if (! ieee_alloc_type (info, typeindx, FALSE))
1396*3d8817e4Smiod     return FALSE;
1397*3d8817e4Smiod 
1398*3d8817e4Smiod   if (**pp != 0xce)
1399*3d8817e4Smiod     {
1400*3d8817e4Smiod       ieee_error (info, *pp, _("unknown TY code"));
1401*3d8817e4Smiod       return FALSE;
1402*3d8817e4Smiod     }
1403*3d8817e4Smiod   ++*pp;
1404*3d8817e4Smiod 
1405*3d8817e4Smiod   ty_var_start = *pp;
1406*3d8817e4Smiod 
1407*3d8817e4Smiod   if (! ieee_read_number (info, pp, &varindx))
1408*3d8817e4Smiod     return FALSE;
1409*3d8817e4Smiod 
1410*3d8817e4Smiod   if (varindx < 32)
1411*3d8817e4Smiod     {
1412*3d8817e4Smiod       ieee_error (info, ty_var_start, _("illegal variable index"));
1413*3d8817e4Smiod       return FALSE;
1414*3d8817e4Smiod     }
1415*3d8817e4Smiod   varindx -= 32;
1416*3d8817e4Smiod 
1417*3d8817e4Smiod   if (varindx >= info->vars.alloc || info->vars.vars[varindx].name == NULL)
1418*3d8817e4Smiod     {
1419*3d8817e4Smiod       ieee_error (info, ty_var_start, _("undefined variable in TY"));
1420*3d8817e4Smiod       return FALSE;
1421*3d8817e4Smiod     }
1422*3d8817e4Smiod 
1423*3d8817e4Smiod   ty_code_start = *pp;
1424*3d8817e4Smiod 
1425*3d8817e4Smiod   if (! ieee_read_number (info, pp, &tc))
1426*3d8817e4Smiod     return FALSE;
1427*3d8817e4Smiod 
1428*3d8817e4Smiod   dhandle = info->dhandle;
1429*3d8817e4Smiod 
1430*3d8817e4Smiod   tag = FALSE;
1431*3d8817e4Smiod   typdef = FALSE;
1432*3d8817e4Smiod   arg_slots = NULL;
1433*3d8817e4Smiod   type_bitsize = 0;
1434*3d8817e4Smiod   switch (tc)
1435*3d8817e4Smiod     {
1436*3d8817e4Smiod     default:
1437*3d8817e4Smiod       ieee_error (info, ty_code_start, _("unknown TY code"));
1438*3d8817e4Smiod       return FALSE;
1439*3d8817e4Smiod 
1440*3d8817e4Smiod     case '!':
1441*3d8817e4Smiod       /* Unknown type, with size.  We treat it as int.  FIXME.  */
1442*3d8817e4Smiod       {
1443*3d8817e4Smiod 	bfd_vma size;
1444*3d8817e4Smiod 
1445*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &size))
1446*3d8817e4Smiod 	  return FALSE;
1447*3d8817e4Smiod 	type = debug_make_int_type (dhandle, size, FALSE);
1448*3d8817e4Smiod       }
1449*3d8817e4Smiod       break;
1450*3d8817e4Smiod 
1451*3d8817e4Smiod     case 'A': /* Array.  */
1452*3d8817e4Smiod     case 'a': /* FORTRAN array in column/row order.  FIXME: Not
1453*3d8817e4Smiod 		 distinguished from normal array.  */
1454*3d8817e4Smiod       {
1455*3d8817e4Smiod 	debug_type ele_type;
1456*3d8817e4Smiod 	bfd_vma lower, upper;
1457*3d8817e4Smiod 
1458*3d8817e4Smiod 	if (! ieee_read_type_index (info, pp, &ele_type)
1459*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &lower)
1460*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &upper))
1461*3d8817e4Smiod 	  return FALSE;
1462*3d8817e4Smiod 	type = debug_make_array_type (dhandle, ele_type,
1463*3d8817e4Smiod 				      ieee_builtin_type (info, ty_code_start,
1464*3d8817e4Smiod 							 ((unsigned int)
1465*3d8817e4Smiod 							  builtin_int)),
1466*3d8817e4Smiod 				      (bfd_signed_vma) lower,
1467*3d8817e4Smiod 				      (bfd_signed_vma) upper,
1468*3d8817e4Smiod 				      FALSE);
1469*3d8817e4Smiod       }
1470*3d8817e4Smiod       break;
1471*3d8817e4Smiod 
1472*3d8817e4Smiod     case 'E':
1473*3d8817e4Smiod       /* Simple enumeration.  */
1474*3d8817e4Smiod       {
1475*3d8817e4Smiod 	bfd_vma size;
1476*3d8817e4Smiod 	unsigned int alloc;
1477*3d8817e4Smiod 	const char **names;
1478*3d8817e4Smiod 	unsigned int c;
1479*3d8817e4Smiod 	bfd_signed_vma *vals;
1480*3d8817e4Smiod 	unsigned int i;
1481*3d8817e4Smiod 
1482*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &size))
1483*3d8817e4Smiod 	  return FALSE;
1484*3d8817e4Smiod 	/* FIXME: we ignore the enumeration size.  */
1485*3d8817e4Smiod 
1486*3d8817e4Smiod 	alloc = 10;
1487*3d8817e4Smiod 	names = (const char **) xmalloc (alloc * sizeof *names);
1488*3d8817e4Smiod 	memset (names, 0, alloc * sizeof *names);
1489*3d8817e4Smiod 	c = 0;
1490*3d8817e4Smiod 	while (1)
1491*3d8817e4Smiod 	  {
1492*3d8817e4Smiod 	    const char *name;
1493*3d8817e4Smiod 	    unsigned long namlen;
1494*3d8817e4Smiod 	    bfd_boolean present;
1495*3d8817e4Smiod 
1496*3d8817e4Smiod 	    if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
1497*3d8817e4Smiod 	      return FALSE;
1498*3d8817e4Smiod 	    if (! present)
1499*3d8817e4Smiod 	      break;
1500*3d8817e4Smiod 
1501*3d8817e4Smiod 	    if (c + 1 >= alloc)
1502*3d8817e4Smiod 	      {
1503*3d8817e4Smiod 		alloc += 10;
1504*3d8817e4Smiod 		names = ((const char **)
1505*3d8817e4Smiod 			 xrealloc (names, alloc * sizeof *names));
1506*3d8817e4Smiod 	      }
1507*3d8817e4Smiod 
1508*3d8817e4Smiod 	    names[c] = savestring (name, namlen);
1509*3d8817e4Smiod 	    if (names[c] == NULL)
1510*3d8817e4Smiod 	      return FALSE;
1511*3d8817e4Smiod 	    ++c;
1512*3d8817e4Smiod 	  }
1513*3d8817e4Smiod 
1514*3d8817e4Smiod 	names[c] = NULL;
1515*3d8817e4Smiod 
1516*3d8817e4Smiod 	vals = (bfd_signed_vma *) xmalloc (c * sizeof *vals);
1517*3d8817e4Smiod 	for (i = 0; i < c; i++)
1518*3d8817e4Smiod 	  vals[i] = i;
1519*3d8817e4Smiod 
1520*3d8817e4Smiod 	type = debug_make_enum_type (dhandle, names, vals);
1521*3d8817e4Smiod 	tag = TRUE;
1522*3d8817e4Smiod       }
1523*3d8817e4Smiod       break;
1524*3d8817e4Smiod 
1525*3d8817e4Smiod     case 'G':
1526*3d8817e4Smiod       /* Struct with bit fields.  */
1527*3d8817e4Smiod       {
1528*3d8817e4Smiod 	bfd_vma size;
1529*3d8817e4Smiod 	unsigned int alloc;
1530*3d8817e4Smiod 	debug_field *fields;
1531*3d8817e4Smiod 	unsigned int c;
1532*3d8817e4Smiod 
1533*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &size))
1534*3d8817e4Smiod 	  return FALSE;
1535*3d8817e4Smiod 
1536*3d8817e4Smiod 	alloc = 10;
1537*3d8817e4Smiod 	fields = (debug_field *) xmalloc (alloc * sizeof *fields);
1538*3d8817e4Smiod 	c = 0;
1539*3d8817e4Smiod 	while (1)
1540*3d8817e4Smiod 	  {
1541*3d8817e4Smiod 	    const char *name;
1542*3d8817e4Smiod 	    unsigned long namlen;
1543*3d8817e4Smiod 	    bfd_boolean present;
1544*3d8817e4Smiod 	    debug_type ftype;
1545*3d8817e4Smiod 	    bfd_vma bitpos, bitsize;
1546*3d8817e4Smiod 
1547*3d8817e4Smiod 	    if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
1548*3d8817e4Smiod 	      return FALSE;
1549*3d8817e4Smiod 	    if (! present)
1550*3d8817e4Smiod 	      break;
1551*3d8817e4Smiod 	    if (! ieee_read_type_index (info, pp, &ftype)
1552*3d8817e4Smiod 		|| ! ieee_read_number (info, pp, &bitpos)
1553*3d8817e4Smiod 		|| ! ieee_read_number (info, pp, &bitsize))
1554*3d8817e4Smiod 	      return FALSE;
1555*3d8817e4Smiod 
1556*3d8817e4Smiod 	    if (c + 1 >= alloc)
1557*3d8817e4Smiod 	      {
1558*3d8817e4Smiod 		alloc += 10;
1559*3d8817e4Smiod 		fields = ((debug_field *)
1560*3d8817e4Smiod 			  xrealloc (fields, alloc * sizeof *fields));
1561*3d8817e4Smiod 	      }
1562*3d8817e4Smiod 
1563*3d8817e4Smiod 	    fields[c] = debug_make_field (dhandle, savestring (name, namlen),
1564*3d8817e4Smiod 					  ftype, bitpos, bitsize,
1565*3d8817e4Smiod 					  DEBUG_VISIBILITY_PUBLIC);
1566*3d8817e4Smiod 	    if (fields[c] == NULL)
1567*3d8817e4Smiod 	      return FALSE;
1568*3d8817e4Smiod 	    ++c;
1569*3d8817e4Smiod 	  }
1570*3d8817e4Smiod 
1571*3d8817e4Smiod 	fields[c] = NULL;
1572*3d8817e4Smiod 
1573*3d8817e4Smiod 	type = debug_make_struct_type (dhandle, TRUE, size, fields);
1574*3d8817e4Smiod 	tag = TRUE;
1575*3d8817e4Smiod       }
1576*3d8817e4Smiod       break;
1577*3d8817e4Smiod 
1578*3d8817e4Smiod     case 'N':
1579*3d8817e4Smiod       /* Enumeration.  */
1580*3d8817e4Smiod       {
1581*3d8817e4Smiod 	unsigned int alloc;
1582*3d8817e4Smiod 	const char **names;
1583*3d8817e4Smiod 	bfd_signed_vma *vals;
1584*3d8817e4Smiod 	unsigned int c;
1585*3d8817e4Smiod 
1586*3d8817e4Smiod 	alloc = 10;
1587*3d8817e4Smiod 	names = (const char **) xmalloc (alloc * sizeof *names);
1588*3d8817e4Smiod 	vals = (bfd_signed_vma *) xmalloc (alloc * sizeof *names);
1589*3d8817e4Smiod 	c = 0;
1590*3d8817e4Smiod 	while (1)
1591*3d8817e4Smiod 	  {
1592*3d8817e4Smiod 	    const char *name;
1593*3d8817e4Smiod 	    unsigned long namlen;
1594*3d8817e4Smiod 	    bfd_boolean present;
1595*3d8817e4Smiod 	    bfd_vma val;
1596*3d8817e4Smiod 
1597*3d8817e4Smiod 	    if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
1598*3d8817e4Smiod 	      return FALSE;
1599*3d8817e4Smiod 	    if (! present)
1600*3d8817e4Smiod 	      break;
1601*3d8817e4Smiod 	    if (! ieee_read_number (info, pp, &val))
1602*3d8817e4Smiod 	      return FALSE;
1603*3d8817e4Smiod 
1604*3d8817e4Smiod 	    /* If the length of the name is zero, then the value is
1605*3d8817e4Smiod                actually the size of the enum.  We ignore this
1606*3d8817e4Smiod                information.  FIXME.  */
1607*3d8817e4Smiod 	    if (namlen == 0)
1608*3d8817e4Smiod 	      continue;
1609*3d8817e4Smiod 
1610*3d8817e4Smiod 	    if (c + 1 >= alloc)
1611*3d8817e4Smiod 	      {
1612*3d8817e4Smiod 		alloc += 10;
1613*3d8817e4Smiod 		names = ((const char **)
1614*3d8817e4Smiod 			 xrealloc (names, alloc * sizeof *names));
1615*3d8817e4Smiod 		vals = ((bfd_signed_vma *)
1616*3d8817e4Smiod 			xrealloc (vals, alloc * sizeof *vals));
1617*3d8817e4Smiod 	      }
1618*3d8817e4Smiod 
1619*3d8817e4Smiod 	    names[c] = savestring (name, namlen);
1620*3d8817e4Smiod 	    if (names[c] == NULL)
1621*3d8817e4Smiod 	      return FALSE;
1622*3d8817e4Smiod 	    vals[c] = (bfd_signed_vma) val;
1623*3d8817e4Smiod 	    ++c;
1624*3d8817e4Smiod 	  }
1625*3d8817e4Smiod 
1626*3d8817e4Smiod 	names[c] = NULL;
1627*3d8817e4Smiod 
1628*3d8817e4Smiod 	type = debug_make_enum_type (dhandle, names, vals);
1629*3d8817e4Smiod 	tag = TRUE;
1630*3d8817e4Smiod       }
1631*3d8817e4Smiod       break;
1632*3d8817e4Smiod 
1633*3d8817e4Smiod     case 'O': /* Small pointer.  We don't distinguish small and large
1634*3d8817e4Smiod 		 pointers.  FIXME.  */
1635*3d8817e4Smiod     case 'P': /* Large pointer.  */
1636*3d8817e4Smiod       {
1637*3d8817e4Smiod 	debug_type t;
1638*3d8817e4Smiod 
1639*3d8817e4Smiod 	if (! ieee_read_type_index (info, pp, &t))
1640*3d8817e4Smiod 	  return FALSE;
1641*3d8817e4Smiod 	type = debug_make_pointer_type (dhandle, t);
1642*3d8817e4Smiod       }
1643*3d8817e4Smiod       break;
1644*3d8817e4Smiod 
1645*3d8817e4Smiod     case 'R':
1646*3d8817e4Smiod       /* Range.  */
1647*3d8817e4Smiod       {
1648*3d8817e4Smiod 	bfd_vma low, high, signedp, size;
1649*3d8817e4Smiod 
1650*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &low)
1651*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &high)
1652*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &signedp)
1653*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &size))
1654*3d8817e4Smiod 	  return FALSE;
1655*3d8817e4Smiod 
1656*3d8817e4Smiod 	type = debug_make_range_type (dhandle,
1657*3d8817e4Smiod 				      debug_make_int_type (dhandle, size,
1658*3d8817e4Smiod 							   ! signedp),
1659*3d8817e4Smiod 				      (bfd_signed_vma) low,
1660*3d8817e4Smiod 				      (bfd_signed_vma) high);
1661*3d8817e4Smiod       }
1662*3d8817e4Smiod       break;
1663*3d8817e4Smiod 
1664*3d8817e4Smiod     case 'S': /* Struct.  */
1665*3d8817e4Smiod     case 'U': /* Union.  */
1666*3d8817e4Smiod       {
1667*3d8817e4Smiod 	bfd_vma size;
1668*3d8817e4Smiod 	unsigned int alloc;
1669*3d8817e4Smiod 	debug_field *fields;
1670*3d8817e4Smiod 	unsigned int c;
1671*3d8817e4Smiod 
1672*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &size))
1673*3d8817e4Smiod 	  return FALSE;
1674*3d8817e4Smiod 
1675*3d8817e4Smiod 	alloc = 10;
1676*3d8817e4Smiod 	fields = (debug_field *) xmalloc (alloc * sizeof *fields);
1677*3d8817e4Smiod 	c = 0;
1678*3d8817e4Smiod 	while (1)
1679*3d8817e4Smiod 	  {
1680*3d8817e4Smiod 	    const char *name;
1681*3d8817e4Smiod 	    unsigned long namlen;
1682*3d8817e4Smiod 	    bfd_boolean present;
1683*3d8817e4Smiod 	    bfd_vma tindx;
1684*3d8817e4Smiod 	    bfd_vma offset;
1685*3d8817e4Smiod 	    debug_type ftype;
1686*3d8817e4Smiod 	    bfd_vma bitsize;
1687*3d8817e4Smiod 
1688*3d8817e4Smiod 	    if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
1689*3d8817e4Smiod 	      return FALSE;
1690*3d8817e4Smiod 	    if (! present)
1691*3d8817e4Smiod 	      break;
1692*3d8817e4Smiod 	    if (! ieee_read_number (info, pp, &tindx)
1693*3d8817e4Smiod 		|| ! ieee_read_number (info, pp, &offset))
1694*3d8817e4Smiod 	      return FALSE;
1695*3d8817e4Smiod 
1696*3d8817e4Smiod 	    if (tindx < 256)
1697*3d8817e4Smiod 	      {
1698*3d8817e4Smiod 		ftype = ieee_builtin_type (info, ty_code_start, tindx);
1699*3d8817e4Smiod 		bitsize = 0;
1700*3d8817e4Smiod 		offset *= 8;
1701*3d8817e4Smiod 	      }
1702*3d8817e4Smiod 	    else
1703*3d8817e4Smiod 	      {
1704*3d8817e4Smiod 		struct ieee_type *t;
1705*3d8817e4Smiod 
1706*3d8817e4Smiod 		tindx -= 256;
1707*3d8817e4Smiod 		if (! ieee_alloc_type (info, tindx, TRUE))
1708*3d8817e4Smiod 		  return FALSE;
1709*3d8817e4Smiod 		t = info->types.types + tindx;
1710*3d8817e4Smiod 		ftype = t->type;
1711*3d8817e4Smiod 		bitsize = t->bitsize;
1712*3d8817e4Smiod 		if (bitsize == 0)
1713*3d8817e4Smiod 		  offset *= 8;
1714*3d8817e4Smiod 	      }
1715*3d8817e4Smiod 
1716*3d8817e4Smiod 	    if (c + 1 >= alloc)
1717*3d8817e4Smiod 	      {
1718*3d8817e4Smiod 		alloc += 10;
1719*3d8817e4Smiod 		fields = ((debug_field *)
1720*3d8817e4Smiod 			  xrealloc (fields, alloc * sizeof *fields));
1721*3d8817e4Smiod 	      }
1722*3d8817e4Smiod 
1723*3d8817e4Smiod 	    fields[c] = debug_make_field (dhandle, savestring (name, namlen),
1724*3d8817e4Smiod 					  ftype, offset, bitsize,
1725*3d8817e4Smiod 					  DEBUG_VISIBILITY_PUBLIC);
1726*3d8817e4Smiod 	    if (fields[c] == NULL)
1727*3d8817e4Smiod 	      return FALSE;
1728*3d8817e4Smiod 	    ++c;
1729*3d8817e4Smiod 	  }
1730*3d8817e4Smiod 
1731*3d8817e4Smiod 	fields[c] = NULL;
1732*3d8817e4Smiod 
1733*3d8817e4Smiod 	type = debug_make_struct_type (dhandle, tc == 'S', size, fields);
1734*3d8817e4Smiod 	tag = TRUE;
1735*3d8817e4Smiod       }
1736*3d8817e4Smiod       break;
1737*3d8817e4Smiod 
1738*3d8817e4Smiod     case 'T':
1739*3d8817e4Smiod       /* Typedef.  */
1740*3d8817e4Smiod       if (! ieee_read_type_index (info, pp, &type))
1741*3d8817e4Smiod 	return FALSE;
1742*3d8817e4Smiod       typdef = TRUE;
1743*3d8817e4Smiod       break;
1744*3d8817e4Smiod 
1745*3d8817e4Smiod     case 'X':
1746*3d8817e4Smiod       /* Procedure.  FIXME: This is an extern declaration, which we
1747*3d8817e4Smiod          have no way of representing.  */
1748*3d8817e4Smiod       {
1749*3d8817e4Smiod 	bfd_vma attr;
1750*3d8817e4Smiod 	debug_type rtype;
1751*3d8817e4Smiod 	bfd_vma nargs;
1752*3d8817e4Smiod 	bfd_boolean present;
1753*3d8817e4Smiod 	struct ieee_var *pv;
1754*3d8817e4Smiod 
1755*3d8817e4Smiod 	/* FIXME: We ignore the attribute and the argument names.  */
1756*3d8817e4Smiod 
1757*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &attr)
1758*3d8817e4Smiod 	    || ! ieee_read_type_index (info, pp, &rtype)
1759*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &nargs))
1760*3d8817e4Smiod 	  return FALSE;
1761*3d8817e4Smiod 	do
1762*3d8817e4Smiod 	  {
1763*3d8817e4Smiod 	    const char *name;
1764*3d8817e4Smiod 	    unsigned long namlen;
1765*3d8817e4Smiod 
1766*3d8817e4Smiod 	    if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
1767*3d8817e4Smiod 	      return FALSE;
1768*3d8817e4Smiod 	  }
1769*3d8817e4Smiod 	while (present);
1770*3d8817e4Smiod 
1771*3d8817e4Smiod 	pv = info->vars.vars + varindx;
1772*3d8817e4Smiod 	pv->kind = IEEE_EXTERNAL;
1773*3d8817e4Smiod 	if (pv->namlen > 0
1774*3d8817e4Smiod 	    && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
1775*3d8817e4Smiod 	  {
1776*3d8817e4Smiod 	    /* Set up the return type as an indirect type pointing to
1777*3d8817e4Smiod                the variable slot, so that we can change it to a
1778*3d8817e4Smiod                reference later if appropriate.  */
1779*3d8817e4Smiod 	    pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
1780*3d8817e4Smiod 	    *pv->pslot = rtype;
1781*3d8817e4Smiod 	    rtype = debug_make_indirect_type (dhandle, pv->pslot,
1782*3d8817e4Smiod 					      (const char *) NULL);
1783*3d8817e4Smiod 	  }
1784*3d8817e4Smiod 
1785*3d8817e4Smiod 	type = debug_make_function_type (dhandle, rtype, (debug_type *) NULL,
1786*3d8817e4Smiod 					 FALSE);
1787*3d8817e4Smiod       }
1788*3d8817e4Smiod       break;
1789*3d8817e4Smiod 
1790*3d8817e4Smiod     case 'V':
1791*3d8817e4Smiod       /* Void.  This is not documented, but the MRI compiler emits it.  */
1792*3d8817e4Smiod       type = debug_make_void_type (dhandle);
1793*3d8817e4Smiod       break;
1794*3d8817e4Smiod 
1795*3d8817e4Smiod     case 'Z':
1796*3d8817e4Smiod       /* Array with 0 lower bound.  */
1797*3d8817e4Smiod       {
1798*3d8817e4Smiod 	debug_type etype;
1799*3d8817e4Smiod 	bfd_vma high;
1800*3d8817e4Smiod 
1801*3d8817e4Smiod 	if (! ieee_read_type_index (info, pp, &etype)
1802*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &high))
1803*3d8817e4Smiod 	  return FALSE;
1804*3d8817e4Smiod 
1805*3d8817e4Smiod 	type = debug_make_array_type (dhandle, etype,
1806*3d8817e4Smiod 				      ieee_builtin_type (info, ty_code_start,
1807*3d8817e4Smiod 							 ((unsigned int)
1808*3d8817e4Smiod 							  builtin_int)),
1809*3d8817e4Smiod 				      0, (bfd_signed_vma) high, FALSE);
1810*3d8817e4Smiod       }
1811*3d8817e4Smiod       break;
1812*3d8817e4Smiod 
1813*3d8817e4Smiod     case 'c': /* Complex.  */
1814*3d8817e4Smiod     case 'd': /* Double complex.  */
1815*3d8817e4Smiod       {
1816*3d8817e4Smiod 	const char *name;
1817*3d8817e4Smiod 	unsigned long namlen;
1818*3d8817e4Smiod 
1819*3d8817e4Smiod 	/* FIXME: I don't know what the name means.  */
1820*3d8817e4Smiod 
1821*3d8817e4Smiod 	if (! ieee_read_id (info, pp, &name, &namlen))
1822*3d8817e4Smiod 	  return FALSE;
1823*3d8817e4Smiod 
1824*3d8817e4Smiod 	type = debug_make_complex_type (dhandle, tc == 'c' ? 4 : 8);
1825*3d8817e4Smiod       }
1826*3d8817e4Smiod       break;
1827*3d8817e4Smiod 
1828*3d8817e4Smiod     case 'f':
1829*3d8817e4Smiod       /* Pascal file name.  FIXME.  */
1830*3d8817e4Smiod       ieee_error (info, ty_code_start, _("Pascal file name not supported"));
1831*3d8817e4Smiod       return FALSE;
1832*3d8817e4Smiod 
1833*3d8817e4Smiod     case 'g':
1834*3d8817e4Smiod       /* Bitfield type.  */
1835*3d8817e4Smiod       {
1836*3d8817e4Smiod 	bfd_vma signedp, bitsize, dummy;
1837*3d8817e4Smiod 	const bfd_byte *hold;
1838*3d8817e4Smiod 	bfd_boolean present;
1839*3d8817e4Smiod 
1840*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &signedp)
1841*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &bitsize))
1842*3d8817e4Smiod 	  return FALSE;
1843*3d8817e4Smiod 
1844*3d8817e4Smiod 	/* I think the documentation says that there is a type index,
1845*3d8817e4Smiod            but some actual files do not have one.  */
1846*3d8817e4Smiod 	hold = *pp;
1847*3d8817e4Smiod 	if (! ieee_read_optional_number (info, pp, &dummy, &present))
1848*3d8817e4Smiod 	  return FALSE;
1849*3d8817e4Smiod 	if (! present)
1850*3d8817e4Smiod 	  {
1851*3d8817e4Smiod 	    /* FIXME: This is just a guess.  */
1852*3d8817e4Smiod 	    type = debug_make_int_type (dhandle, 4,
1853*3d8817e4Smiod 					signedp ? FALSE : TRUE);
1854*3d8817e4Smiod 	  }
1855*3d8817e4Smiod 	else
1856*3d8817e4Smiod 	  {
1857*3d8817e4Smiod 	    *pp = hold;
1858*3d8817e4Smiod 	    if (! ieee_read_type_index (info, pp, &type))
1859*3d8817e4Smiod 	      return FALSE;
1860*3d8817e4Smiod 	  }
1861*3d8817e4Smiod 	type_bitsize = bitsize;
1862*3d8817e4Smiod       }
1863*3d8817e4Smiod       break;
1864*3d8817e4Smiod 
1865*3d8817e4Smiod     case 'n':
1866*3d8817e4Smiod       /* Qualifier.  */
1867*3d8817e4Smiod       {
1868*3d8817e4Smiod 	bfd_vma kind;
1869*3d8817e4Smiod 	debug_type t;
1870*3d8817e4Smiod 
1871*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &kind)
1872*3d8817e4Smiod 	    || ! ieee_read_type_index (info, pp, &t))
1873*3d8817e4Smiod 	  return FALSE;
1874*3d8817e4Smiod 
1875*3d8817e4Smiod 	switch (kind)
1876*3d8817e4Smiod 	  {
1877*3d8817e4Smiod 	  default:
1878*3d8817e4Smiod 	    ieee_error (info, ty_start, _("unsupported qualifier"));
1879*3d8817e4Smiod 	    return FALSE;
1880*3d8817e4Smiod 
1881*3d8817e4Smiod 	  case 1:
1882*3d8817e4Smiod 	    type = debug_make_const_type (dhandle, t);
1883*3d8817e4Smiod 	    break;
1884*3d8817e4Smiod 
1885*3d8817e4Smiod 	  case 2:
1886*3d8817e4Smiod 	    type = debug_make_volatile_type (dhandle, t);
1887*3d8817e4Smiod 	    break;
1888*3d8817e4Smiod 	  }
1889*3d8817e4Smiod       }
1890*3d8817e4Smiod       break;
1891*3d8817e4Smiod 
1892*3d8817e4Smiod     case 's':
1893*3d8817e4Smiod       /* Set.  */
1894*3d8817e4Smiod       {
1895*3d8817e4Smiod 	bfd_vma size;
1896*3d8817e4Smiod 	debug_type etype;
1897*3d8817e4Smiod 
1898*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &size)
1899*3d8817e4Smiod 	    || ! ieee_read_type_index (info, pp, &etype))
1900*3d8817e4Smiod 	  return FALSE;
1901*3d8817e4Smiod 
1902*3d8817e4Smiod 	/* FIXME: We ignore the size.  */
1903*3d8817e4Smiod 
1904*3d8817e4Smiod 	type = debug_make_set_type (dhandle, etype, FALSE);
1905*3d8817e4Smiod       }
1906*3d8817e4Smiod       break;
1907*3d8817e4Smiod 
1908*3d8817e4Smiod     case 'x':
1909*3d8817e4Smiod       /* Procedure with compiler dependencies.  */
1910*3d8817e4Smiod       {
1911*3d8817e4Smiod 	struct ieee_var *pv;
1912*3d8817e4Smiod 	bfd_vma attr, frame_type, push_mask, nargs, level, father;
1913*3d8817e4Smiod 	debug_type rtype;
1914*3d8817e4Smiod 	debug_type *arg_types;
1915*3d8817e4Smiod 	bfd_boolean varargs;
1916*3d8817e4Smiod 	bfd_boolean present;
1917*3d8817e4Smiod 
1918*3d8817e4Smiod 	/* FIXME: We ignore some of this information.  */
1919*3d8817e4Smiod 
1920*3d8817e4Smiod 	pv = info->vars.vars + varindx;
1921*3d8817e4Smiod 
1922*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &attr)
1923*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &frame_type)
1924*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &push_mask)
1925*3d8817e4Smiod 	    || ! ieee_read_type_index (info, pp, &rtype)
1926*3d8817e4Smiod 	    || ! ieee_read_number (info, pp, &nargs))
1927*3d8817e4Smiod 	  return FALSE;
1928*3d8817e4Smiod 	if (nargs == (bfd_vma) -1)
1929*3d8817e4Smiod 	  {
1930*3d8817e4Smiod 	    arg_types = NULL;
1931*3d8817e4Smiod 	    varargs = FALSE;
1932*3d8817e4Smiod 	  }
1933*3d8817e4Smiod 	else
1934*3d8817e4Smiod 	  {
1935*3d8817e4Smiod 	    unsigned int i;
1936*3d8817e4Smiod 
1937*3d8817e4Smiod 	    arg_types = ((debug_type *)
1938*3d8817e4Smiod 			 xmalloc ((nargs + 1) * sizeof *arg_types));
1939*3d8817e4Smiod 	    for (i = 0; i < nargs; i++)
1940*3d8817e4Smiod 	      if (! ieee_read_type_index (info, pp, arg_types + i))
1941*3d8817e4Smiod 		return FALSE;
1942*3d8817e4Smiod 
1943*3d8817e4Smiod 	    /* If the last type is pointer to void, this is really a
1944*3d8817e4Smiod                varargs function.  */
1945*3d8817e4Smiod 	    varargs = FALSE;
1946*3d8817e4Smiod 	    if (nargs > 0)
1947*3d8817e4Smiod 	      {
1948*3d8817e4Smiod 		debug_type last;
1949*3d8817e4Smiod 
1950*3d8817e4Smiod 		last = arg_types[nargs - 1];
1951*3d8817e4Smiod 		if (debug_get_type_kind (dhandle, last) == DEBUG_KIND_POINTER
1952*3d8817e4Smiod 		    && (debug_get_type_kind (dhandle,
1953*3d8817e4Smiod 					     debug_get_target_type (dhandle,
1954*3d8817e4Smiod 								    last))
1955*3d8817e4Smiod 			== DEBUG_KIND_VOID))
1956*3d8817e4Smiod 		  {
1957*3d8817e4Smiod 		    --nargs;
1958*3d8817e4Smiod 		    varargs = TRUE;
1959*3d8817e4Smiod 		  }
1960*3d8817e4Smiod 	      }
1961*3d8817e4Smiod 
1962*3d8817e4Smiod 	    /* If there are any pointer arguments, turn them into
1963*3d8817e4Smiod                indirect types in case we later need to convert them to
1964*3d8817e4Smiod                reference types.  */
1965*3d8817e4Smiod 	    for (i = 0; i < nargs; i++)
1966*3d8817e4Smiod 	      {
1967*3d8817e4Smiod 		if (debug_get_type_kind (dhandle, arg_types[i])
1968*3d8817e4Smiod 		    == DEBUG_KIND_POINTER)
1969*3d8817e4Smiod 		  {
1970*3d8817e4Smiod 		    if (arg_slots == NULL)
1971*3d8817e4Smiod 		      {
1972*3d8817e4Smiod 			arg_slots = ((debug_type *)
1973*3d8817e4Smiod 				     xmalloc (nargs * sizeof *arg_slots));
1974*3d8817e4Smiod 			memset (arg_slots, 0, nargs * sizeof *arg_slots);
1975*3d8817e4Smiod 		      }
1976*3d8817e4Smiod 		    arg_slots[i] = arg_types[i];
1977*3d8817e4Smiod 		    arg_types[i] =
1978*3d8817e4Smiod 		      debug_make_indirect_type (dhandle,
1979*3d8817e4Smiod 						arg_slots + i,
1980*3d8817e4Smiod 						(const char *) NULL);
1981*3d8817e4Smiod 		  }
1982*3d8817e4Smiod 	      }
1983*3d8817e4Smiod 
1984*3d8817e4Smiod 	    arg_types[nargs] = DEBUG_TYPE_NULL;
1985*3d8817e4Smiod 	  }
1986*3d8817e4Smiod 	if (! ieee_read_number (info, pp, &level)
1987*3d8817e4Smiod 	    || ! ieee_read_optional_number (info, pp, &father, &present))
1988*3d8817e4Smiod 	  return FALSE;
1989*3d8817e4Smiod 
1990*3d8817e4Smiod 	/* We can't distinguish between a global function and a static
1991*3d8817e4Smiod            function.  */
1992*3d8817e4Smiod 	pv->kind = IEEE_FUNCTION;
1993*3d8817e4Smiod 
1994*3d8817e4Smiod 	if (pv->namlen > 0
1995*3d8817e4Smiod 	    && debug_get_type_kind (dhandle, rtype) == DEBUG_KIND_POINTER)
1996*3d8817e4Smiod 	  {
1997*3d8817e4Smiod 	    /* Set up the return type as an indirect type pointing to
1998*3d8817e4Smiod                the variable slot, so that we can change it to a
1999*3d8817e4Smiod                reference later if appropriate.  */
2000*3d8817e4Smiod 	    pv->pslot = (debug_type *) xmalloc (sizeof *pv->pslot);
2001*3d8817e4Smiod 	    *pv->pslot = rtype;
2002*3d8817e4Smiod 	    rtype = debug_make_indirect_type (dhandle, pv->pslot,
2003*3d8817e4Smiod 					      (const char *) NULL);
2004*3d8817e4Smiod 	  }
2005*3d8817e4Smiod 
2006*3d8817e4Smiod 	type = debug_make_function_type (dhandle, rtype, arg_types, varargs);
2007*3d8817e4Smiod       }
2008*3d8817e4Smiod       break;
2009*3d8817e4Smiod     }
2010*3d8817e4Smiod 
2011*3d8817e4Smiod   /* Record the type in the table.  */
2012*3d8817e4Smiod 
2013*3d8817e4Smiod   if (type == DEBUG_TYPE_NULL)
2014*3d8817e4Smiod     return FALSE;
2015*3d8817e4Smiod 
2016*3d8817e4Smiod   info->vars.vars[varindx].type = type;
2017*3d8817e4Smiod 
2018*3d8817e4Smiod   if ((tag || typdef)
2019*3d8817e4Smiod       && info->vars.vars[varindx].namlen > 0)
2020*3d8817e4Smiod     {
2021*3d8817e4Smiod       const char *name;
2022*3d8817e4Smiod 
2023*3d8817e4Smiod       name = savestring (info->vars.vars[varindx].name,
2024*3d8817e4Smiod 			 info->vars.vars[varindx].namlen);
2025*3d8817e4Smiod       if (typdef)
2026*3d8817e4Smiod 	type = debug_name_type (dhandle, name, type);
2027*3d8817e4Smiod       else if (tc == 'E' || tc == 'N')
2028*3d8817e4Smiod 	type = debug_tag_type (dhandle, name, type);
2029*3d8817e4Smiod       else
2030*3d8817e4Smiod 	{
2031*3d8817e4Smiod 	  struct ieee_tag *it;
2032*3d8817e4Smiod 
2033*3d8817e4Smiod 	  /* We must allocate all struct tags as indirect types, so
2034*3d8817e4Smiod              that if we later see a definition of the tag as a C++
2035*3d8817e4Smiod              record we can update the indirect slot and automatically
2036*3d8817e4Smiod              change all the existing references.  */
2037*3d8817e4Smiod 	  it = (struct ieee_tag *) xmalloc (sizeof *it);
2038*3d8817e4Smiod 	  memset (it, 0, sizeof *it);
2039*3d8817e4Smiod 	  it->next = info->tags;
2040*3d8817e4Smiod 	  info->tags = it;
2041*3d8817e4Smiod 	  it->name = name;
2042*3d8817e4Smiod 	  it->slot = type;
2043*3d8817e4Smiod 
2044*3d8817e4Smiod 	  type = debug_make_indirect_type (dhandle, &it->slot, name);
2045*3d8817e4Smiod 	  type = debug_tag_type (dhandle, name, type);
2046*3d8817e4Smiod 
2047*3d8817e4Smiod 	  it->type = type;
2048*3d8817e4Smiod 	}
2049*3d8817e4Smiod       if (type == NULL)
2050*3d8817e4Smiod 	return FALSE;
2051*3d8817e4Smiod     }
2052*3d8817e4Smiod 
2053*3d8817e4Smiod   info->types.types[typeindx].type = type;
2054*3d8817e4Smiod   info->types.types[typeindx].arg_slots = arg_slots;
2055*3d8817e4Smiod   info->types.types[typeindx].bitsize = type_bitsize;
2056*3d8817e4Smiod 
2057*3d8817e4Smiod   /* We may have already allocated type as an indirect type pointing
2058*3d8817e4Smiod      to slot.  It does no harm to replace the indirect type with the
2059*3d8817e4Smiod      real type.  Filling in slot as well handles the indirect types
2060*3d8817e4Smiod      which are already hanging around.  */
2061*3d8817e4Smiod   if (info->types.types[typeindx].pslot != NULL)
2062*3d8817e4Smiod     *info->types.types[typeindx].pslot = type;
2063*3d8817e4Smiod 
2064*3d8817e4Smiod   return TRUE;
2065*3d8817e4Smiod }
2066*3d8817e4Smiod 
2067*3d8817e4Smiod /* Parse an ATN record.  */
2068*3d8817e4Smiod 
2069*3d8817e4Smiod static bfd_boolean
parse_ieee_atn(struct ieee_info * info,const bfd_byte ** pp)2070*3d8817e4Smiod parse_ieee_atn (struct ieee_info *info, const bfd_byte **pp)
2071*3d8817e4Smiod {
2072*3d8817e4Smiod   const bfd_byte *atn_start, *atn_code_start;
2073*3d8817e4Smiod   bfd_vma varindx;
2074*3d8817e4Smiod   struct ieee_var *pvar;
2075*3d8817e4Smiod   debug_type type;
2076*3d8817e4Smiod   bfd_vma atn_code;
2077*3d8817e4Smiod   void *dhandle;
2078*3d8817e4Smiod   bfd_vma v, v2, v3, v4, v5;
2079*3d8817e4Smiod   const char *name;
2080*3d8817e4Smiod   unsigned long namlen;
2081*3d8817e4Smiod   char *namcopy;
2082*3d8817e4Smiod   bfd_boolean present;
2083*3d8817e4Smiod   int blocktype;
2084*3d8817e4Smiod 
2085*3d8817e4Smiod   atn_start = *pp;
2086*3d8817e4Smiod 
2087*3d8817e4Smiod   if (! ieee_read_number (info, pp, &varindx)
2088*3d8817e4Smiod       || ! ieee_read_type_index (info, pp, &type))
2089*3d8817e4Smiod     return FALSE;
2090*3d8817e4Smiod 
2091*3d8817e4Smiod   atn_code_start = *pp;
2092*3d8817e4Smiod 
2093*3d8817e4Smiod   if (! ieee_read_number (info, pp, &atn_code))
2094*3d8817e4Smiod     return FALSE;
2095*3d8817e4Smiod 
2096*3d8817e4Smiod   if (varindx == 0)
2097*3d8817e4Smiod     {
2098*3d8817e4Smiod       pvar = NULL;
2099*3d8817e4Smiod       name = "";
2100*3d8817e4Smiod       namlen = 0;
2101*3d8817e4Smiod     }
2102*3d8817e4Smiod   else if (varindx < 32)
2103*3d8817e4Smiod     {
2104*3d8817e4Smiod       /* The MRI compiler reportedly sometimes emits variable lifetime
2105*3d8817e4Smiod          information for a register.  We just ignore it.  */
2106*3d8817e4Smiod       if (atn_code == 9)
2107*3d8817e4Smiod 	return ieee_read_number (info, pp, &v);
2108*3d8817e4Smiod 
2109*3d8817e4Smiod       ieee_error (info, atn_start, _("illegal variable index"));
2110*3d8817e4Smiod       return FALSE;
2111*3d8817e4Smiod     }
2112*3d8817e4Smiod   else
2113*3d8817e4Smiod     {
2114*3d8817e4Smiod       varindx -= 32;
2115*3d8817e4Smiod       if (varindx >= info->vars.alloc
2116*3d8817e4Smiod 	  || info->vars.vars[varindx].name == NULL)
2117*3d8817e4Smiod 	{
2118*3d8817e4Smiod 	  /* The MRI compiler or linker sometimes omits the NN record
2119*3d8817e4Smiod              for a pmisc record.  */
2120*3d8817e4Smiod 	  if (atn_code == 62)
2121*3d8817e4Smiod 	    {
2122*3d8817e4Smiod 	      if (varindx >= info->vars.alloc)
2123*3d8817e4Smiod 		{
2124*3d8817e4Smiod 		  unsigned int alloc;
2125*3d8817e4Smiod 
2126*3d8817e4Smiod 		  alloc = info->vars.alloc;
2127*3d8817e4Smiod 		  if (alloc == 0)
2128*3d8817e4Smiod 		    alloc = 4;
2129*3d8817e4Smiod 		  while (varindx >= alloc)
2130*3d8817e4Smiod 		    alloc *= 2;
2131*3d8817e4Smiod 		  info->vars.vars = ((struct ieee_var *)
2132*3d8817e4Smiod 				     xrealloc (info->vars.vars,
2133*3d8817e4Smiod 					       (alloc
2134*3d8817e4Smiod 						* sizeof *info->vars.vars)));
2135*3d8817e4Smiod 		  memset (info->vars.vars + info->vars.alloc, 0,
2136*3d8817e4Smiod 			  ((alloc - info->vars.alloc)
2137*3d8817e4Smiod 			   * sizeof *info->vars.vars));
2138*3d8817e4Smiod 		  info->vars.alloc = alloc;
2139*3d8817e4Smiod 		}
2140*3d8817e4Smiod 
2141*3d8817e4Smiod 	      pvar = info->vars.vars + varindx;
2142*3d8817e4Smiod 	      pvar->name = "";
2143*3d8817e4Smiod 	      pvar->namlen = 0;
2144*3d8817e4Smiod 	    }
2145*3d8817e4Smiod 	  else
2146*3d8817e4Smiod 	    {
2147*3d8817e4Smiod 	      ieee_error (info, atn_start, _("undefined variable in ATN"));
2148*3d8817e4Smiod 	      return FALSE;
2149*3d8817e4Smiod 	    }
2150*3d8817e4Smiod 	}
2151*3d8817e4Smiod 
2152*3d8817e4Smiod       pvar = info->vars.vars + varindx;
2153*3d8817e4Smiod 
2154*3d8817e4Smiod       pvar->type = type;
2155*3d8817e4Smiod 
2156*3d8817e4Smiod       name = pvar->name;
2157*3d8817e4Smiod       namlen = pvar->namlen;
2158*3d8817e4Smiod     }
2159*3d8817e4Smiod 
2160*3d8817e4Smiod   dhandle = info->dhandle;
2161*3d8817e4Smiod 
2162*3d8817e4Smiod   /* If we are going to call debug_record_variable with a pointer
2163*3d8817e4Smiod      type, change the type to an indirect type so that we can later
2164*3d8817e4Smiod      change it to a reference type if we encounter a C++ pmisc 'R'
2165*3d8817e4Smiod      record.  */
2166*3d8817e4Smiod   if (pvar != NULL
2167*3d8817e4Smiod       && type != DEBUG_TYPE_NULL
2168*3d8817e4Smiod       && debug_get_type_kind (dhandle, type) == DEBUG_KIND_POINTER)
2169*3d8817e4Smiod     {
2170*3d8817e4Smiod       switch (atn_code)
2171*3d8817e4Smiod 	{
2172*3d8817e4Smiod 	case 1:
2173*3d8817e4Smiod 	case 2:
2174*3d8817e4Smiod 	case 3:
2175*3d8817e4Smiod 	case 5:
2176*3d8817e4Smiod 	case 8:
2177*3d8817e4Smiod 	case 10:
2178*3d8817e4Smiod 	  pvar->pslot = (debug_type *) xmalloc (sizeof *pvar->pslot);
2179*3d8817e4Smiod 	  *pvar->pslot = type;
2180*3d8817e4Smiod 	  type = debug_make_indirect_type (dhandle, pvar->pslot,
2181*3d8817e4Smiod 					   (const char *) NULL);
2182*3d8817e4Smiod 	  pvar->type = type;
2183*3d8817e4Smiod 	  break;
2184*3d8817e4Smiod 	}
2185*3d8817e4Smiod     }
2186*3d8817e4Smiod 
2187*3d8817e4Smiod   switch (atn_code)
2188*3d8817e4Smiod     {
2189*3d8817e4Smiod     default:
2190*3d8817e4Smiod       ieee_error (info, atn_code_start, _("unknown ATN type"));
2191*3d8817e4Smiod       return FALSE;
2192*3d8817e4Smiod 
2193*3d8817e4Smiod     case 1:
2194*3d8817e4Smiod       /* Automatic variable.  */
2195*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v))
2196*3d8817e4Smiod 	return FALSE;
2197*3d8817e4Smiod       namcopy = savestring (name, namlen);
2198*3d8817e4Smiod       if (type == NULL)
2199*3d8817e4Smiod 	type = debug_make_void_type (dhandle);
2200*3d8817e4Smiod       if (pvar != NULL)
2201*3d8817e4Smiod 	pvar->kind = IEEE_LOCAL;
2202*3d8817e4Smiod       return debug_record_variable (dhandle, namcopy, type, DEBUG_LOCAL, v);
2203*3d8817e4Smiod 
2204*3d8817e4Smiod     case 2:
2205*3d8817e4Smiod       /* Register variable.  */
2206*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v))
2207*3d8817e4Smiod 	return FALSE;
2208*3d8817e4Smiod       namcopy = savestring (name, namlen);
2209*3d8817e4Smiod       if (type == NULL)
2210*3d8817e4Smiod 	type = debug_make_void_type (dhandle);
2211*3d8817e4Smiod       if (pvar != NULL)
2212*3d8817e4Smiod 	pvar->kind = IEEE_LOCAL;
2213*3d8817e4Smiod       return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER,
2214*3d8817e4Smiod 				    ieee_regno_to_genreg (info->abfd, v));
2215*3d8817e4Smiod 
2216*3d8817e4Smiod     case 3:
2217*3d8817e4Smiod       /* Static variable.  */
2218*3d8817e4Smiod       if (! ieee_require_asn (info, pp, &v))
2219*3d8817e4Smiod 	return FALSE;
2220*3d8817e4Smiod       namcopy = savestring (name, namlen);
2221*3d8817e4Smiod       if (type == NULL)
2222*3d8817e4Smiod 	type = debug_make_void_type (dhandle);
2223*3d8817e4Smiod       if (info->blockstack.bsp <= info->blockstack.stack)
2224*3d8817e4Smiod 	blocktype = 0;
2225*3d8817e4Smiod       else
2226*3d8817e4Smiod 	blocktype = info->blockstack.bsp[-1].kind;
2227*3d8817e4Smiod       if (pvar != NULL)
2228*3d8817e4Smiod 	{
2229*3d8817e4Smiod 	  if (blocktype == 4 || blocktype == 6)
2230*3d8817e4Smiod 	    pvar->kind = IEEE_LOCAL;
2231*3d8817e4Smiod 	  else
2232*3d8817e4Smiod 	    pvar->kind = IEEE_STATIC;
2233*3d8817e4Smiod 	}
2234*3d8817e4Smiod       return debug_record_variable (dhandle, namcopy, type,
2235*3d8817e4Smiod 				    (blocktype == 4 || blocktype == 6
2236*3d8817e4Smiod 				     ? DEBUG_LOCAL_STATIC
2237*3d8817e4Smiod 				     : DEBUG_STATIC),
2238*3d8817e4Smiod 				    v);
2239*3d8817e4Smiod 
2240*3d8817e4Smiod     case 4:
2241*3d8817e4Smiod       /* External function.  We don't currently record these.  FIXME.  */
2242*3d8817e4Smiod       if (pvar != NULL)
2243*3d8817e4Smiod 	pvar->kind = IEEE_EXTERNAL;
2244*3d8817e4Smiod       return TRUE;
2245*3d8817e4Smiod 
2246*3d8817e4Smiod     case 5:
2247*3d8817e4Smiod       /* External variable.  We don't currently record these.  FIXME.  */
2248*3d8817e4Smiod       if (pvar != NULL)
2249*3d8817e4Smiod 	pvar->kind = IEEE_EXTERNAL;
2250*3d8817e4Smiod       return TRUE;
2251*3d8817e4Smiod 
2252*3d8817e4Smiod     case 7:
2253*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v)
2254*3d8817e4Smiod 	  || ! ieee_read_number (info, pp, &v2)
2255*3d8817e4Smiod 	  || ! ieee_read_optional_number (info, pp, &v3, &present))
2256*3d8817e4Smiod 	return FALSE;
2257*3d8817e4Smiod       if (present)
2258*3d8817e4Smiod 	{
2259*3d8817e4Smiod 	  if (! ieee_read_optional_number (info, pp, &v4, &present))
2260*3d8817e4Smiod 	    return FALSE;
2261*3d8817e4Smiod 	}
2262*3d8817e4Smiod 
2263*3d8817e4Smiod       /* We just ignore the two optional fields in v3 and v4, since
2264*3d8817e4Smiod          they are not defined.  */
2265*3d8817e4Smiod 
2266*3d8817e4Smiod       if (! ieee_require_asn (info, pp, &v3))
2267*3d8817e4Smiod 	return FALSE;
2268*3d8817e4Smiod 
2269*3d8817e4Smiod       /* We have no way to record the column number.  FIXME.  */
2270*3d8817e4Smiod 
2271*3d8817e4Smiod       return debug_record_line (dhandle, v, v3);
2272*3d8817e4Smiod 
2273*3d8817e4Smiod     case 8:
2274*3d8817e4Smiod       /* Global variable.  */
2275*3d8817e4Smiod       if (! ieee_require_asn (info, pp, &v))
2276*3d8817e4Smiod 	return FALSE;
2277*3d8817e4Smiod       namcopy = savestring (name, namlen);
2278*3d8817e4Smiod       if (type == NULL)
2279*3d8817e4Smiod 	type = debug_make_void_type (dhandle);
2280*3d8817e4Smiod       if (pvar != NULL)
2281*3d8817e4Smiod 	pvar->kind = IEEE_GLOBAL;
2282*3d8817e4Smiod       return debug_record_variable (dhandle, namcopy, type, DEBUG_GLOBAL, v);
2283*3d8817e4Smiod 
2284*3d8817e4Smiod     case 9:
2285*3d8817e4Smiod       /* Variable lifetime information.  */
2286*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v))
2287*3d8817e4Smiod 	return FALSE;
2288*3d8817e4Smiod 
2289*3d8817e4Smiod       /* We have no way to record this information.  FIXME.  */
2290*3d8817e4Smiod       return TRUE;
2291*3d8817e4Smiod 
2292*3d8817e4Smiod     case 10:
2293*3d8817e4Smiod       /* Locked register.  The spec says that there are two required
2294*3d8817e4Smiod          fields, but at least on occasion the MRI compiler only emits
2295*3d8817e4Smiod          one.  */
2296*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v)
2297*3d8817e4Smiod 	  || ! ieee_read_optional_number (info, pp, &v2, &present))
2298*3d8817e4Smiod 	return FALSE;
2299*3d8817e4Smiod 
2300*3d8817e4Smiod       /* I think this means a variable that is both in a register and
2301*3d8817e4Smiod          a frame slot.  We ignore the frame slot.  FIXME.  */
2302*3d8817e4Smiod 
2303*3d8817e4Smiod       namcopy = savestring (name, namlen);
2304*3d8817e4Smiod       if (type == NULL)
2305*3d8817e4Smiod 	type = debug_make_void_type (dhandle);
2306*3d8817e4Smiod       if (pvar != NULL)
2307*3d8817e4Smiod 	pvar->kind = IEEE_LOCAL;
2308*3d8817e4Smiod       return debug_record_variable (dhandle, namcopy, type, DEBUG_REGISTER, v);
2309*3d8817e4Smiod 
2310*3d8817e4Smiod     case 11:
2311*3d8817e4Smiod       /* Reserved for FORTRAN common.  */
2312*3d8817e4Smiod       ieee_error (info, atn_code_start, _("unsupported ATN11"));
2313*3d8817e4Smiod 
2314*3d8817e4Smiod       /* Return TRUE to keep going.  */
2315*3d8817e4Smiod       return TRUE;
2316*3d8817e4Smiod 
2317*3d8817e4Smiod     case 12:
2318*3d8817e4Smiod       /* Based variable.  */
2319*3d8817e4Smiod       v3 = 0;
2320*3d8817e4Smiod       v4 = 0x80;
2321*3d8817e4Smiod       v5 = 0;
2322*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v)
2323*3d8817e4Smiod 	  || ! ieee_read_number (info, pp, &v2)
2324*3d8817e4Smiod 	  || ! ieee_read_optional_number (info, pp, &v3, &present))
2325*3d8817e4Smiod 	return FALSE;
2326*3d8817e4Smiod       if (present)
2327*3d8817e4Smiod 	{
2328*3d8817e4Smiod 	  if (! ieee_read_optional_number (info, pp, &v4, &present))
2329*3d8817e4Smiod 	    return FALSE;
2330*3d8817e4Smiod 	  if (present)
2331*3d8817e4Smiod 	    {
2332*3d8817e4Smiod 	      if (! ieee_read_optional_number (info, pp, &v5, &present))
2333*3d8817e4Smiod 		return FALSE;
2334*3d8817e4Smiod 	    }
2335*3d8817e4Smiod 	}
2336*3d8817e4Smiod 
2337*3d8817e4Smiod       /* We have no way to record this information.  FIXME.  */
2338*3d8817e4Smiod 
2339*3d8817e4Smiod       ieee_error (info, atn_code_start, _("unsupported ATN12"));
2340*3d8817e4Smiod 
2341*3d8817e4Smiod       /* Return TRUE to keep going.  */
2342*3d8817e4Smiod       return TRUE;
2343*3d8817e4Smiod 
2344*3d8817e4Smiod     case 16:
2345*3d8817e4Smiod       /* Constant.  The description of this that I have is ambiguous,
2346*3d8817e4Smiod          so I'm not going to try to implement it.  */
2347*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v)
2348*3d8817e4Smiod 	  || ! ieee_read_optional_number (info, pp, &v2, &present))
2349*3d8817e4Smiod 	return FALSE;
2350*3d8817e4Smiod       if (present)
2351*3d8817e4Smiod 	{
2352*3d8817e4Smiod 	  if (! ieee_read_optional_number (info, pp, &v2, &present))
2353*3d8817e4Smiod 	    return FALSE;
2354*3d8817e4Smiod 	  if (present)
2355*3d8817e4Smiod 	    {
2356*3d8817e4Smiod 	      if (! ieee_read_optional_id (info, pp, &name, &namlen, &present))
2357*3d8817e4Smiod 		return FALSE;
2358*3d8817e4Smiod 	    }
2359*3d8817e4Smiod 	}
2360*3d8817e4Smiod 
2361*3d8817e4Smiod       if ((ieee_record_enum_type) **pp == ieee_e2_first_byte_enum)
2362*3d8817e4Smiod 	{
2363*3d8817e4Smiod 	  if (! ieee_require_asn (info, pp, &v3))
2364*3d8817e4Smiod 	    return FALSE;
2365*3d8817e4Smiod 	}
2366*3d8817e4Smiod 
2367*3d8817e4Smiod       return TRUE;
2368*3d8817e4Smiod 
2369*3d8817e4Smiod     case 19:
2370*3d8817e4Smiod       /* Static variable from assembler.  */
2371*3d8817e4Smiod       v2 = 0;
2372*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v)
2373*3d8817e4Smiod 	  || ! ieee_read_optional_number (info, pp, &v2, &present)
2374*3d8817e4Smiod 	  || ! ieee_require_asn (info, pp, &v3))
2375*3d8817e4Smiod 	return FALSE;
2376*3d8817e4Smiod       namcopy = savestring (name, namlen);
2377*3d8817e4Smiod       /* We don't really handle this correctly.  FIXME.  */
2378*3d8817e4Smiod       return debug_record_variable (dhandle, namcopy,
2379*3d8817e4Smiod 				    debug_make_void_type (dhandle),
2380*3d8817e4Smiod 				    v2 != 0 ? DEBUG_GLOBAL : DEBUG_STATIC,
2381*3d8817e4Smiod 				    v3);
2382*3d8817e4Smiod 
2383*3d8817e4Smiod     case 62:
2384*3d8817e4Smiod       /* Procedure miscellaneous information.  */
2385*3d8817e4Smiod     case 63:
2386*3d8817e4Smiod       /* Variable miscellaneous information.  */
2387*3d8817e4Smiod     case 64:
2388*3d8817e4Smiod       /* Module miscellaneous information.  */
2389*3d8817e4Smiod       if (! ieee_read_number (info, pp, &v)
2390*3d8817e4Smiod 	  || ! ieee_read_number (info, pp, &v2)
2391*3d8817e4Smiod 	  || ! ieee_read_optional_id (info, pp, &name, &namlen, &present))
2392*3d8817e4Smiod 	return FALSE;
2393*3d8817e4Smiod 
2394*3d8817e4Smiod       if (atn_code == 62 && v == 80)
2395*3d8817e4Smiod 	{
2396*3d8817e4Smiod 	  if (present)
2397*3d8817e4Smiod 	    {
2398*3d8817e4Smiod 	      ieee_error (info, atn_code_start,
2399*3d8817e4Smiod 			  _("unexpected string in C++ misc"));
2400*3d8817e4Smiod 	      return FALSE;
2401*3d8817e4Smiod 	    }
2402*3d8817e4Smiod 	  return ieee_read_cxx_misc (info, pp, v2);
2403*3d8817e4Smiod 	}
2404*3d8817e4Smiod 
2405*3d8817e4Smiod       /* We just ignore all of this stuff.  FIXME.  */
2406*3d8817e4Smiod 
2407*3d8817e4Smiod       for (; v2 > 0; --v2)
2408*3d8817e4Smiod 	{
2409*3d8817e4Smiod 	  switch ((ieee_record_enum_type) **pp)
2410*3d8817e4Smiod 	    {
2411*3d8817e4Smiod 	    default:
2412*3d8817e4Smiod 	      ieee_error (info, *pp, _("bad misc record"));
2413*3d8817e4Smiod 	      return FALSE;
2414*3d8817e4Smiod 
2415*3d8817e4Smiod 	    case ieee_at_record_enum:
2416*3d8817e4Smiod 	      if (! ieee_require_atn65 (info, pp, &name, &namlen))
2417*3d8817e4Smiod 		return FALSE;
2418*3d8817e4Smiod 	      break;
2419*3d8817e4Smiod 
2420*3d8817e4Smiod 	    case ieee_e2_first_byte_enum:
2421*3d8817e4Smiod 	      if (! ieee_require_asn (info, pp, &v3))
2422*3d8817e4Smiod 		return FALSE;
2423*3d8817e4Smiod 	      break;
2424*3d8817e4Smiod 	    }
2425*3d8817e4Smiod 	}
2426*3d8817e4Smiod 
2427*3d8817e4Smiod       return TRUE;
2428*3d8817e4Smiod     }
2429*3d8817e4Smiod 
2430*3d8817e4Smiod   /*NOTREACHED*/
2431*3d8817e4Smiod }
2432*3d8817e4Smiod 
2433*3d8817e4Smiod /* Handle C++ debugging miscellaneous records.  This is called for
2434*3d8817e4Smiod    procedure miscellaneous records of type 80.  */
2435*3d8817e4Smiod 
2436*3d8817e4Smiod static bfd_boolean
ieee_read_cxx_misc(struct ieee_info * info,const bfd_byte ** pp,unsigned long count)2437*3d8817e4Smiod ieee_read_cxx_misc (struct ieee_info *info, const bfd_byte **pp,
2438*3d8817e4Smiod 		    unsigned long count)
2439*3d8817e4Smiod {
2440*3d8817e4Smiod   const bfd_byte *start;
2441*3d8817e4Smiod   bfd_vma category;
2442*3d8817e4Smiod 
2443*3d8817e4Smiod   start = *pp;
2444*3d8817e4Smiod 
2445*3d8817e4Smiod   /* Get the category of C++ misc record.  */
2446*3d8817e4Smiod   if (! ieee_require_asn (info, pp, &category))
2447*3d8817e4Smiod     return FALSE;
2448*3d8817e4Smiod   --count;
2449*3d8817e4Smiod 
2450*3d8817e4Smiod   switch (category)
2451*3d8817e4Smiod     {
2452*3d8817e4Smiod     default:
2453*3d8817e4Smiod       ieee_error (info, start, _("unrecognized C++ misc record"));
2454*3d8817e4Smiod       return FALSE;
2455*3d8817e4Smiod 
2456*3d8817e4Smiod     case 'T':
2457*3d8817e4Smiod       if (! ieee_read_cxx_class (info, pp, count))
2458*3d8817e4Smiod 	return FALSE;
2459*3d8817e4Smiod       break;
2460*3d8817e4Smiod 
2461*3d8817e4Smiod     case 'M':
2462*3d8817e4Smiod       {
2463*3d8817e4Smiod 	bfd_vma flags;
2464*3d8817e4Smiod 	const char *name;
2465*3d8817e4Smiod 	unsigned long namlen;
2466*3d8817e4Smiod 
2467*3d8817e4Smiod 	/* The IEEE spec indicates that the 'M' record only has a
2468*3d8817e4Smiod            flags field.  The MRI compiler also emits the name of the
2469*3d8817e4Smiod            function.  */
2470*3d8817e4Smiod 
2471*3d8817e4Smiod 	if (! ieee_require_asn (info, pp, &flags))
2472*3d8817e4Smiod 	  return FALSE;
2473*3d8817e4Smiod 	if (*pp < info->pend
2474*3d8817e4Smiod 	    && (ieee_record_enum_type) **pp == ieee_at_record_enum)
2475*3d8817e4Smiod 	  {
2476*3d8817e4Smiod 	    if (! ieee_require_atn65 (info, pp, &name, &namlen))
2477*3d8817e4Smiod 	      return FALSE;
2478*3d8817e4Smiod 	  }
2479*3d8817e4Smiod 
2480*3d8817e4Smiod 	/* This is emitted for method functions, but I don't think we
2481*3d8817e4Smiod            care very much.  It might help if it told us useful
2482*3d8817e4Smiod            information like the class with which this function is
2483*3d8817e4Smiod            associated, but it doesn't, so it isn't helpful.  */
2484*3d8817e4Smiod       }
2485*3d8817e4Smiod       break;
2486*3d8817e4Smiod 
2487*3d8817e4Smiod     case 'B':
2488*3d8817e4Smiod       if (! ieee_read_cxx_defaults (info, pp, count))
2489*3d8817e4Smiod 	return FALSE;
2490*3d8817e4Smiod       break;
2491*3d8817e4Smiod 
2492*3d8817e4Smiod     case 'z':
2493*3d8817e4Smiod       {
2494*3d8817e4Smiod 	const char *name, *mangled, *class;
2495*3d8817e4Smiod 	unsigned long namlen, mangledlen, classlen;
2496*3d8817e4Smiod 	bfd_vma control;
2497*3d8817e4Smiod 
2498*3d8817e4Smiod 	/* Pointer to member.  */
2499*3d8817e4Smiod 
2500*3d8817e4Smiod 	if (! ieee_require_atn65 (info, pp, &name, &namlen)
2501*3d8817e4Smiod 	    || ! ieee_require_atn65 (info, pp, &mangled, &mangledlen)
2502*3d8817e4Smiod 	    || ! ieee_require_atn65 (info, pp, &class, &classlen)
2503*3d8817e4Smiod 	    || ! ieee_require_asn (info, pp, &control))
2504*3d8817e4Smiod 	  return FALSE;
2505*3d8817e4Smiod 
2506*3d8817e4Smiod 	/* FIXME: We should now track down name and change its type.  */
2507*3d8817e4Smiod       }
2508*3d8817e4Smiod       break;
2509*3d8817e4Smiod 
2510*3d8817e4Smiod     case 'R':
2511*3d8817e4Smiod       if (! ieee_read_reference (info, pp))
2512*3d8817e4Smiod 	return FALSE;
2513*3d8817e4Smiod       break;
2514*3d8817e4Smiod     }
2515*3d8817e4Smiod 
2516*3d8817e4Smiod   return TRUE;
2517*3d8817e4Smiod }
2518*3d8817e4Smiod 
2519*3d8817e4Smiod /* Read a C++ class definition.  This is a pmisc type 80 record of
2520*3d8817e4Smiod    category 'T'.  */
2521*3d8817e4Smiod 
2522*3d8817e4Smiod static bfd_boolean
ieee_read_cxx_class(struct ieee_info * info,const bfd_byte ** pp,unsigned long count)2523*3d8817e4Smiod ieee_read_cxx_class (struct ieee_info *info, const bfd_byte **pp,
2524*3d8817e4Smiod 		     unsigned long count)
2525*3d8817e4Smiod {
2526*3d8817e4Smiod   const bfd_byte *start;
2527*3d8817e4Smiod   bfd_vma class;
2528*3d8817e4Smiod   const char *tag;
2529*3d8817e4Smiod   unsigned long taglen;
2530*3d8817e4Smiod   struct ieee_tag *it;
2531*3d8817e4Smiod   void *dhandle;
2532*3d8817e4Smiod   debug_field *fields;
2533*3d8817e4Smiod   unsigned int field_count, field_alloc;
2534*3d8817e4Smiod   debug_baseclass *baseclasses;
2535*3d8817e4Smiod   unsigned int baseclasses_count, baseclasses_alloc;
2536*3d8817e4Smiod   const debug_field *structfields;
2537*3d8817e4Smiod   struct ieee_method
2538*3d8817e4Smiod     {
2539*3d8817e4Smiod       const char *name;
2540*3d8817e4Smiod       unsigned long namlen;
2541*3d8817e4Smiod       debug_method_variant *variants;
2542*3d8817e4Smiod       unsigned count;
2543*3d8817e4Smiod       unsigned int alloc;
2544*3d8817e4Smiod     } *methods;
2545*3d8817e4Smiod   unsigned int methods_count, methods_alloc;
2546*3d8817e4Smiod   debug_type vptrbase;
2547*3d8817e4Smiod   bfd_boolean ownvptr;
2548*3d8817e4Smiod   debug_method *dmethods;
2549*3d8817e4Smiod 
2550*3d8817e4Smiod   start = *pp;
2551*3d8817e4Smiod 
2552*3d8817e4Smiod   if (! ieee_require_asn (info, pp, &class))
2553*3d8817e4Smiod     return FALSE;
2554*3d8817e4Smiod   --count;
2555*3d8817e4Smiod 
2556*3d8817e4Smiod   if (! ieee_require_atn65 (info, pp, &tag, &taglen))
2557*3d8817e4Smiod     return FALSE;
2558*3d8817e4Smiod   --count;
2559*3d8817e4Smiod 
2560*3d8817e4Smiod   /* Find the C struct with this name.  */
2561*3d8817e4Smiod   for (it = info->tags; it != NULL; it = it->next)
2562*3d8817e4Smiod     if (it->name[0] == tag[0]
2563*3d8817e4Smiod 	&& strncmp (it->name, tag, taglen) == 0
2564*3d8817e4Smiod 	&& strlen (it->name) == taglen)
2565*3d8817e4Smiod       break;
2566*3d8817e4Smiod   if (it == NULL)
2567*3d8817e4Smiod     {
2568*3d8817e4Smiod       ieee_error (info, start, _("undefined C++ object"));
2569*3d8817e4Smiod       return FALSE;
2570*3d8817e4Smiod     }
2571*3d8817e4Smiod 
2572*3d8817e4Smiod   dhandle = info->dhandle;
2573*3d8817e4Smiod 
2574*3d8817e4Smiod   fields = NULL;
2575*3d8817e4Smiod   field_count = 0;
2576*3d8817e4Smiod   field_alloc = 0;
2577*3d8817e4Smiod   baseclasses = NULL;
2578*3d8817e4Smiod   baseclasses_count = 0;
2579*3d8817e4Smiod   baseclasses_alloc = 0;
2580*3d8817e4Smiod   methods = NULL;
2581*3d8817e4Smiod   methods_count = 0;
2582*3d8817e4Smiod   methods_alloc = 0;
2583*3d8817e4Smiod   vptrbase = DEBUG_TYPE_NULL;
2584*3d8817e4Smiod   ownvptr = FALSE;
2585*3d8817e4Smiod 
2586*3d8817e4Smiod   structfields = debug_get_fields (dhandle, it->type);
2587*3d8817e4Smiod 
2588*3d8817e4Smiod   while (count > 0)
2589*3d8817e4Smiod     {
2590*3d8817e4Smiod       bfd_vma id;
2591*3d8817e4Smiod       const bfd_byte *spec_start;
2592*3d8817e4Smiod 
2593*3d8817e4Smiod       spec_start = *pp;
2594*3d8817e4Smiod 
2595*3d8817e4Smiod       if (! ieee_require_asn (info, pp, &id))
2596*3d8817e4Smiod 	return FALSE;
2597*3d8817e4Smiod       --count;
2598*3d8817e4Smiod 
2599*3d8817e4Smiod       switch (id)
2600*3d8817e4Smiod 	{
2601*3d8817e4Smiod 	default:
2602*3d8817e4Smiod 	  ieee_error (info, spec_start, _("unrecognized C++ object spec"));
2603*3d8817e4Smiod 	  return FALSE;
2604*3d8817e4Smiod 
2605*3d8817e4Smiod 	case 'b':
2606*3d8817e4Smiod 	  {
2607*3d8817e4Smiod 	    bfd_vma flags, cinline;
2608*3d8817e4Smiod 	    const char *basename, *fieldname;
2609*3d8817e4Smiod 	    unsigned long baselen, fieldlen;
2610*3d8817e4Smiod 	    char *basecopy;
2611*3d8817e4Smiod 	    debug_type basetype;
2612*3d8817e4Smiod 	    bfd_vma bitpos;
2613*3d8817e4Smiod 	    bfd_boolean virtualp;
2614*3d8817e4Smiod 	    enum debug_visibility visibility;
2615*3d8817e4Smiod 	    debug_baseclass baseclass;
2616*3d8817e4Smiod 
2617*3d8817e4Smiod 	    /* This represents a base or friend class.  */
2618*3d8817e4Smiod 
2619*3d8817e4Smiod 	    if (! ieee_require_asn (info, pp, &flags)
2620*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &basename, &baselen)
2621*3d8817e4Smiod 		|| ! ieee_require_asn (info, pp, &cinline)
2622*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen))
2623*3d8817e4Smiod 	      return FALSE;
2624*3d8817e4Smiod 	    count -= 4;
2625*3d8817e4Smiod 
2626*3d8817e4Smiod 	    /* We have no way of recording friend information, so we
2627*3d8817e4Smiod                just ignore it.  */
2628*3d8817e4Smiod 	    if ((flags & BASEFLAGS_FRIEND) != 0)
2629*3d8817e4Smiod 	      break;
2630*3d8817e4Smiod 
2631*3d8817e4Smiod 	    /* I assume that either all of the members of the
2632*3d8817e4Smiod                baseclass are included in the object, starting at the
2633*3d8817e4Smiod                beginning of the object, or that none of them are
2634*3d8817e4Smiod                included.  */
2635*3d8817e4Smiod 
2636*3d8817e4Smiod 	    if ((fieldlen == 0) == (cinline == 0))
2637*3d8817e4Smiod 	      {
2638*3d8817e4Smiod 		ieee_error (info, start, _("unsupported C++ object type"));
2639*3d8817e4Smiod 		return FALSE;
2640*3d8817e4Smiod 	      }
2641*3d8817e4Smiod 
2642*3d8817e4Smiod 	    basecopy = savestring (basename, baselen);
2643*3d8817e4Smiod 	    basetype = debug_find_tagged_type (dhandle, basecopy,
2644*3d8817e4Smiod 					       DEBUG_KIND_ILLEGAL);
2645*3d8817e4Smiod 	    free (basecopy);
2646*3d8817e4Smiod 	    if (basetype == DEBUG_TYPE_NULL)
2647*3d8817e4Smiod 	      {
2648*3d8817e4Smiod 		ieee_error (info, start, _("C++ base class not defined"));
2649*3d8817e4Smiod 		return FALSE;
2650*3d8817e4Smiod 	      }
2651*3d8817e4Smiod 
2652*3d8817e4Smiod 	    if (fieldlen == 0)
2653*3d8817e4Smiod 	      bitpos = 0;
2654*3d8817e4Smiod 	    else
2655*3d8817e4Smiod 	      {
2656*3d8817e4Smiod 		const debug_field *pf;
2657*3d8817e4Smiod 
2658*3d8817e4Smiod 		if (structfields == NULL)
2659*3d8817e4Smiod 		  {
2660*3d8817e4Smiod 		    ieee_error (info, start, _("C++ object has no fields"));
2661*3d8817e4Smiod 		    return FALSE;
2662*3d8817e4Smiod 		  }
2663*3d8817e4Smiod 
2664*3d8817e4Smiod 		for (pf = structfields; *pf != DEBUG_FIELD_NULL; pf++)
2665*3d8817e4Smiod 		  {
2666*3d8817e4Smiod 		    const char *fname;
2667*3d8817e4Smiod 
2668*3d8817e4Smiod 		    fname = debug_get_field_name (dhandle, *pf);
2669*3d8817e4Smiod 		    if (fname == NULL)
2670*3d8817e4Smiod 		      return FALSE;
2671*3d8817e4Smiod 		    if (fname[0] == fieldname[0]
2672*3d8817e4Smiod 			&& strncmp (fname, fieldname, fieldlen) == 0
2673*3d8817e4Smiod 			&& strlen (fname) == fieldlen)
2674*3d8817e4Smiod 		      break;
2675*3d8817e4Smiod 		  }
2676*3d8817e4Smiod 		if (*pf == DEBUG_FIELD_NULL)
2677*3d8817e4Smiod 		  {
2678*3d8817e4Smiod 		    ieee_error (info, start,
2679*3d8817e4Smiod 				_("C++ base class not found in container"));
2680*3d8817e4Smiod 		    return FALSE;
2681*3d8817e4Smiod 		  }
2682*3d8817e4Smiod 
2683*3d8817e4Smiod 		bitpos = debug_get_field_bitpos (dhandle, *pf);
2684*3d8817e4Smiod 	      }
2685*3d8817e4Smiod 
2686*3d8817e4Smiod 	    if ((flags & BASEFLAGS_VIRTUAL) != 0)
2687*3d8817e4Smiod 	      virtualp = TRUE;
2688*3d8817e4Smiod 	    else
2689*3d8817e4Smiod 	      virtualp = FALSE;
2690*3d8817e4Smiod 	    if ((flags & BASEFLAGS_PRIVATE) != 0)
2691*3d8817e4Smiod 	      visibility = DEBUG_VISIBILITY_PRIVATE;
2692*3d8817e4Smiod 	    else
2693*3d8817e4Smiod 	      visibility = DEBUG_VISIBILITY_PUBLIC;
2694*3d8817e4Smiod 
2695*3d8817e4Smiod 	    baseclass = debug_make_baseclass (dhandle, basetype, bitpos,
2696*3d8817e4Smiod 					      virtualp, visibility);
2697*3d8817e4Smiod 	    if (baseclass == DEBUG_BASECLASS_NULL)
2698*3d8817e4Smiod 	      return FALSE;
2699*3d8817e4Smiod 
2700*3d8817e4Smiod 	    if (baseclasses_count + 1 >= baseclasses_alloc)
2701*3d8817e4Smiod 	      {
2702*3d8817e4Smiod 		baseclasses_alloc += 10;
2703*3d8817e4Smiod 		baseclasses = ((debug_baseclass *)
2704*3d8817e4Smiod 			       xrealloc (baseclasses,
2705*3d8817e4Smiod 					 (baseclasses_alloc
2706*3d8817e4Smiod 					  * sizeof *baseclasses)));
2707*3d8817e4Smiod 	      }
2708*3d8817e4Smiod 
2709*3d8817e4Smiod 	    baseclasses[baseclasses_count] = baseclass;
2710*3d8817e4Smiod 	    ++baseclasses_count;
2711*3d8817e4Smiod 	    baseclasses[baseclasses_count] = DEBUG_BASECLASS_NULL;
2712*3d8817e4Smiod 	  }
2713*3d8817e4Smiod 	  break;
2714*3d8817e4Smiod 
2715*3d8817e4Smiod 	case 'd':
2716*3d8817e4Smiod 	  {
2717*3d8817e4Smiod 	    bfd_vma flags;
2718*3d8817e4Smiod 	    const char *fieldname, *mangledname;
2719*3d8817e4Smiod 	    unsigned long fieldlen, mangledlen;
2720*3d8817e4Smiod 	    char *fieldcopy;
2721*3d8817e4Smiod 	    bfd_boolean staticp;
2722*3d8817e4Smiod 	    debug_type ftype;
2723*3d8817e4Smiod 	    const debug_field *pf = NULL;
2724*3d8817e4Smiod 	    enum debug_visibility visibility;
2725*3d8817e4Smiod 	    debug_field field;
2726*3d8817e4Smiod 
2727*3d8817e4Smiod 	    /* This represents a data member.  */
2728*3d8817e4Smiod 
2729*3d8817e4Smiod 	    if (! ieee_require_asn (info, pp, &flags)
2730*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &fieldname, &fieldlen)
2731*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &mangledname, &mangledlen))
2732*3d8817e4Smiod 	      return FALSE;
2733*3d8817e4Smiod 	    count -= 3;
2734*3d8817e4Smiod 
2735*3d8817e4Smiod 	    fieldcopy = savestring (fieldname, fieldlen);
2736*3d8817e4Smiod 
2737*3d8817e4Smiod 	    staticp = (flags & CXXFLAGS_STATIC) != 0 ? TRUE : FALSE;
2738*3d8817e4Smiod 
2739*3d8817e4Smiod 	    if (staticp)
2740*3d8817e4Smiod 	      {
2741*3d8817e4Smiod 		struct ieee_var *pv, *pvend;
2742*3d8817e4Smiod 
2743*3d8817e4Smiod 		/* See if we can find a definition for this variable.  */
2744*3d8817e4Smiod 		pv = info->vars.vars;
2745*3d8817e4Smiod 		pvend = pv + info->vars.alloc;
2746*3d8817e4Smiod 		for (; pv < pvend; pv++)
2747*3d8817e4Smiod 		  if (pv->namlen == mangledlen
2748*3d8817e4Smiod 		      && strncmp (pv->name, mangledname, mangledlen) == 0)
2749*3d8817e4Smiod 		    break;
2750*3d8817e4Smiod 		if (pv < pvend)
2751*3d8817e4Smiod 		  ftype = pv->type;
2752*3d8817e4Smiod 		else
2753*3d8817e4Smiod 		  {
2754*3d8817e4Smiod 		    /* This can happen if the variable is never used.  */
2755*3d8817e4Smiod 		    ftype = ieee_builtin_type (info, start,
2756*3d8817e4Smiod 					       (unsigned int) builtin_void);
2757*3d8817e4Smiod 		  }
2758*3d8817e4Smiod 	      }
2759*3d8817e4Smiod 	    else
2760*3d8817e4Smiod 	      {
2761*3d8817e4Smiod 		unsigned int findx;
2762*3d8817e4Smiod 
2763*3d8817e4Smiod 		if (structfields == NULL)
2764*3d8817e4Smiod 		  {
2765*3d8817e4Smiod 		    ieee_error (info, start, _("C++ object has no fields"));
2766*3d8817e4Smiod 		    return FALSE;
2767*3d8817e4Smiod 		  }
2768*3d8817e4Smiod 
2769*3d8817e4Smiod 		for (pf = structfields, findx = 0;
2770*3d8817e4Smiod 		     *pf != DEBUG_FIELD_NULL;
2771*3d8817e4Smiod 		     pf++, findx++)
2772*3d8817e4Smiod 		  {
2773*3d8817e4Smiod 		    const char *fname;
2774*3d8817e4Smiod 
2775*3d8817e4Smiod 		    fname = debug_get_field_name (dhandle, *pf);
2776*3d8817e4Smiod 		    if (fname == NULL)
2777*3d8817e4Smiod 		      return FALSE;
2778*3d8817e4Smiod 		    if (fname[0] == mangledname[0]
2779*3d8817e4Smiod 			&& strncmp (fname, mangledname, mangledlen) == 0
2780*3d8817e4Smiod 			&& strlen (fname) == mangledlen)
2781*3d8817e4Smiod 		      break;
2782*3d8817e4Smiod 		  }
2783*3d8817e4Smiod 		if (*pf == DEBUG_FIELD_NULL)
2784*3d8817e4Smiod 		  {
2785*3d8817e4Smiod 		    ieee_error (info, start,
2786*3d8817e4Smiod 				_("C++ data member not found in container"));
2787*3d8817e4Smiod 		    return FALSE;
2788*3d8817e4Smiod 		  }
2789*3d8817e4Smiod 
2790*3d8817e4Smiod 		ftype = debug_get_field_type (dhandle, *pf);
2791*3d8817e4Smiod 
2792*3d8817e4Smiod 		if (debug_get_type_kind (dhandle, ftype) == DEBUG_KIND_POINTER)
2793*3d8817e4Smiod 		  {
2794*3d8817e4Smiod 		    /* We might need to convert this field into a
2795*3d8817e4Smiod                        reference type later on, so make it an indirect
2796*3d8817e4Smiod                        type.  */
2797*3d8817e4Smiod 		    if (it->fslots == NULL)
2798*3d8817e4Smiod 		      {
2799*3d8817e4Smiod 			unsigned int fcnt;
2800*3d8817e4Smiod 			const debug_field *pfcnt;
2801*3d8817e4Smiod 
2802*3d8817e4Smiod 			fcnt = 0;
2803*3d8817e4Smiod 			for (pfcnt = structfields;
2804*3d8817e4Smiod 			     *pfcnt != DEBUG_FIELD_NULL;
2805*3d8817e4Smiod 			     pfcnt++)
2806*3d8817e4Smiod 			  ++fcnt;
2807*3d8817e4Smiod 			it->fslots = ((debug_type *)
2808*3d8817e4Smiod 				      xmalloc (fcnt * sizeof *it->fslots));
2809*3d8817e4Smiod 			memset (it->fslots, 0,
2810*3d8817e4Smiod 				fcnt * sizeof *it->fslots);
2811*3d8817e4Smiod 		      }
2812*3d8817e4Smiod 
2813*3d8817e4Smiod 		    if (ftype == DEBUG_TYPE_NULL)
2814*3d8817e4Smiod 		      return FALSE;
2815*3d8817e4Smiod 		    it->fslots[findx] = ftype;
2816*3d8817e4Smiod 		    ftype = debug_make_indirect_type (dhandle,
2817*3d8817e4Smiod 						      it->fslots + findx,
2818*3d8817e4Smiod 						      (const char *) NULL);
2819*3d8817e4Smiod 		  }
2820*3d8817e4Smiod 	      }
2821*3d8817e4Smiod 	    if (ftype == DEBUG_TYPE_NULL)
2822*3d8817e4Smiod 	      return FALSE;
2823*3d8817e4Smiod 
2824*3d8817e4Smiod 	    switch (flags & CXXFLAGS_VISIBILITY)
2825*3d8817e4Smiod 	      {
2826*3d8817e4Smiod 	      default:
2827*3d8817e4Smiod 		ieee_error (info, start, _("unknown C++ visibility"));
2828*3d8817e4Smiod 		return FALSE;
2829*3d8817e4Smiod 
2830*3d8817e4Smiod 	      case CXXFLAGS_VISIBILITY_PUBLIC:
2831*3d8817e4Smiod 		visibility = DEBUG_VISIBILITY_PUBLIC;
2832*3d8817e4Smiod 		break;
2833*3d8817e4Smiod 
2834*3d8817e4Smiod 	      case CXXFLAGS_VISIBILITY_PRIVATE:
2835*3d8817e4Smiod 		visibility = DEBUG_VISIBILITY_PRIVATE;
2836*3d8817e4Smiod 		break;
2837*3d8817e4Smiod 
2838*3d8817e4Smiod 	      case CXXFLAGS_VISIBILITY_PROTECTED:
2839*3d8817e4Smiod 		visibility = DEBUG_VISIBILITY_PROTECTED;
2840*3d8817e4Smiod 		break;
2841*3d8817e4Smiod 	      }
2842*3d8817e4Smiod 
2843*3d8817e4Smiod 	    if (staticp)
2844*3d8817e4Smiod 	      {
2845*3d8817e4Smiod 		char *mangledcopy;
2846*3d8817e4Smiod 
2847*3d8817e4Smiod 		mangledcopy = savestring (mangledname, mangledlen);
2848*3d8817e4Smiod 
2849*3d8817e4Smiod 		field = debug_make_static_member (dhandle, fieldcopy,
2850*3d8817e4Smiod 						  ftype, mangledcopy,
2851*3d8817e4Smiod 						  visibility);
2852*3d8817e4Smiod 	      }
2853*3d8817e4Smiod 	    else
2854*3d8817e4Smiod 	      {
2855*3d8817e4Smiod 		bfd_vma bitpos, bitsize;
2856*3d8817e4Smiod 
2857*3d8817e4Smiod 		bitpos = debug_get_field_bitpos (dhandle, *pf);
2858*3d8817e4Smiod 		bitsize = debug_get_field_bitsize (dhandle, *pf);
2859*3d8817e4Smiod 		if (bitpos == (bfd_vma) -1 || bitsize == (bfd_vma) -1)
2860*3d8817e4Smiod 		  {
2861*3d8817e4Smiod 		    ieee_error (info, start, _("bad C++ field bit pos or size"));
2862*3d8817e4Smiod 		    return FALSE;
2863*3d8817e4Smiod 		  }
2864*3d8817e4Smiod 		field = debug_make_field (dhandle, fieldcopy, ftype, bitpos,
2865*3d8817e4Smiod 					  bitsize, visibility);
2866*3d8817e4Smiod 	      }
2867*3d8817e4Smiod 
2868*3d8817e4Smiod 	    if (field == DEBUG_FIELD_NULL)
2869*3d8817e4Smiod 	      return FALSE;
2870*3d8817e4Smiod 
2871*3d8817e4Smiod 	    if (field_count + 1 >= field_alloc)
2872*3d8817e4Smiod 	      {
2873*3d8817e4Smiod 		field_alloc += 10;
2874*3d8817e4Smiod 		fields = ((debug_field *)
2875*3d8817e4Smiod 			  xrealloc (fields, field_alloc * sizeof *fields));
2876*3d8817e4Smiod 	      }
2877*3d8817e4Smiod 
2878*3d8817e4Smiod 	    fields[field_count] = field;
2879*3d8817e4Smiod 	    ++field_count;
2880*3d8817e4Smiod 	    fields[field_count] = DEBUG_FIELD_NULL;
2881*3d8817e4Smiod 	  }
2882*3d8817e4Smiod 	  break;
2883*3d8817e4Smiod 
2884*3d8817e4Smiod 	case 'm':
2885*3d8817e4Smiod 	case 'v':
2886*3d8817e4Smiod 	  {
2887*3d8817e4Smiod 	    bfd_vma flags, voffset, control;
2888*3d8817e4Smiod 	    const char *name, *mangled;
2889*3d8817e4Smiod 	    unsigned long namlen, mangledlen;
2890*3d8817e4Smiod 	    struct ieee_var *pv, *pvend;
2891*3d8817e4Smiod 	    debug_type type;
2892*3d8817e4Smiod 	    enum debug_visibility visibility;
2893*3d8817e4Smiod 	    bfd_boolean constp, volatilep;
2894*3d8817e4Smiod 	    char *mangledcopy;
2895*3d8817e4Smiod 	    debug_method_variant mv;
2896*3d8817e4Smiod 	    struct ieee_method *meth;
2897*3d8817e4Smiod 	    unsigned int im;
2898*3d8817e4Smiod 
2899*3d8817e4Smiod 	    if (! ieee_require_asn (info, pp, &flags)
2900*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &name, &namlen)
2901*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
2902*3d8817e4Smiod 	      return FALSE;
2903*3d8817e4Smiod 	    count -= 3;
2904*3d8817e4Smiod 	    if (id != 'v')
2905*3d8817e4Smiod 	      voffset = 0;
2906*3d8817e4Smiod 	    else
2907*3d8817e4Smiod 	      {
2908*3d8817e4Smiod 		if (! ieee_require_asn (info, pp, &voffset))
2909*3d8817e4Smiod 		  return FALSE;
2910*3d8817e4Smiod 		--count;
2911*3d8817e4Smiod 	      }
2912*3d8817e4Smiod 	    if (! ieee_require_asn (info, pp, &control))
2913*3d8817e4Smiod 	      return FALSE;
2914*3d8817e4Smiod 	    --count;
2915*3d8817e4Smiod 
2916*3d8817e4Smiod 	    /* We just ignore the control information.  */
2917*3d8817e4Smiod 
2918*3d8817e4Smiod 	    /* We have no way to represent friend information, so we
2919*3d8817e4Smiod                just ignore it.  */
2920*3d8817e4Smiod 	    if ((flags & CXXFLAGS_FRIEND) != 0)
2921*3d8817e4Smiod 	      break;
2922*3d8817e4Smiod 
2923*3d8817e4Smiod 	    /* We should already have seen a type for the function.  */
2924*3d8817e4Smiod 	    pv = info->vars.vars;
2925*3d8817e4Smiod 	    pvend = pv + info->vars.alloc;
2926*3d8817e4Smiod 	    for (; pv < pvend; pv++)
2927*3d8817e4Smiod 	      if (pv->namlen == mangledlen
2928*3d8817e4Smiod 		  && strncmp (pv->name, mangled, mangledlen) == 0)
2929*3d8817e4Smiod 		break;
2930*3d8817e4Smiod 
2931*3d8817e4Smiod 	    if (pv >= pvend)
2932*3d8817e4Smiod 	      {
2933*3d8817e4Smiod 		/* We won't have type information for this function if
2934*3d8817e4Smiod 		   it is not included in this file.  We don't try to
2935*3d8817e4Smiod 		   handle this case.  FIXME.  */
2936*3d8817e4Smiod 		type = (debug_make_function_type
2937*3d8817e4Smiod 			(dhandle,
2938*3d8817e4Smiod 			 ieee_builtin_type (info, start,
2939*3d8817e4Smiod 					    (unsigned int) builtin_void),
2940*3d8817e4Smiod 			 (debug_type *) NULL,
2941*3d8817e4Smiod 			 FALSE));
2942*3d8817e4Smiod 	      }
2943*3d8817e4Smiod 	    else
2944*3d8817e4Smiod 	      {
2945*3d8817e4Smiod 		debug_type return_type;
2946*3d8817e4Smiod 		const debug_type *arg_types;
2947*3d8817e4Smiod 		bfd_boolean varargs;
2948*3d8817e4Smiod 
2949*3d8817e4Smiod 		if (debug_get_type_kind (dhandle, pv->type)
2950*3d8817e4Smiod 		    != DEBUG_KIND_FUNCTION)
2951*3d8817e4Smiod 		  {
2952*3d8817e4Smiod 		    ieee_error (info, start,
2953*3d8817e4Smiod 				_("bad type for C++ method function"));
2954*3d8817e4Smiod 		    return FALSE;
2955*3d8817e4Smiod 		  }
2956*3d8817e4Smiod 
2957*3d8817e4Smiod 		return_type = debug_get_return_type (dhandle, pv->type);
2958*3d8817e4Smiod 		arg_types = debug_get_parameter_types (dhandle, pv->type,
2959*3d8817e4Smiod 						       &varargs);
2960*3d8817e4Smiod 		if (return_type == DEBUG_TYPE_NULL || arg_types == NULL)
2961*3d8817e4Smiod 		  {
2962*3d8817e4Smiod 		    ieee_error (info, start,
2963*3d8817e4Smiod 				_("no type information for C++ method function"));
2964*3d8817e4Smiod 		    return FALSE;
2965*3d8817e4Smiod 		  }
2966*3d8817e4Smiod 
2967*3d8817e4Smiod 		type = debug_make_method_type (dhandle, return_type, it->type,
2968*3d8817e4Smiod 					       (debug_type *) arg_types,
2969*3d8817e4Smiod 					       varargs);
2970*3d8817e4Smiod 	      }
2971*3d8817e4Smiod 	    if (type == DEBUG_TYPE_NULL)
2972*3d8817e4Smiod 	      return FALSE;
2973*3d8817e4Smiod 
2974*3d8817e4Smiod 	    switch (flags & CXXFLAGS_VISIBILITY)
2975*3d8817e4Smiod 	      {
2976*3d8817e4Smiod 	      default:
2977*3d8817e4Smiod 		ieee_error (info, start, _("unknown C++ visibility"));
2978*3d8817e4Smiod 		return FALSE;
2979*3d8817e4Smiod 
2980*3d8817e4Smiod 	      case CXXFLAGS_VISIBILITY_PUBLIC:
2981*3d8817e4Smiod 		visibility = DEBUG_VISIBILITY_PUBLIC;
2982*3d8817e4Smiod 		break;
2983*3d8817e4Smiod 
2984*3d8817e4Smiod 	      case CXXFLAGS_VISIBILITY_PRIVATE:
2985*3d8817e4Smiod 		visibility = DEBUG_VISIBILITY_PRIVATE;
2986*3d8817e4Smiod 		break;
2987*3d8817e4Smiod 
2988*3d8817e4Smiod 	      case CXXFLAGS_VISIBILITY_PROTECTED:
2989*3d8817e4Smiod 		visibility = DEBUG_VISIBILITY_PROTECTED;
2990*3d8817e4Smiod 		break;
2991*3d8817e4Smiod 	      }
2992*3d8817e4Smiod 
2993*3d8817e4Smiod 	    constp = (flags & CXXFLAGS_CONST) != 0 ? TRUE : FALSE;
2994*3d8817e4Smiod 	    volatilep = (flags & CXXFLAGS_VOLATILE) != 0 ? TRUE : FALSE;
2995*3d8817e4Smiod 
2996*3d8817e4Smiod 	    mangledcopy = savestring (mangled, mangledlen);
2997*3d8817e4Smiod 
2998*3d8817e4Smiod 	    if ((flags & CXXFLAGS_STATIC) != 0)
2999*3d8817e4Smiod 	      {
3000*3d8817e4Smiod 		if (id == 'v')
3001*3d8817e4Smiod 		  {
3002*3d8817e4Smiod 		    ieee_error (info, start, _("C++ static virtual method"));
3003*3d8817e4Smiod 		    return FALSE;
3004*3d8817e4Smiod 		  }
3005*3d8817e4Smiod 		mv = debug_make_static_method_variant (dhandle, mangledcopy,
3006*3d8817e4Smiod 						       type, visibility,
3007*3d8817e4Smiod 						       constp, volatilep);
3008*3d8817e4Smiod 	      }
3009*3d8817e4Smiod 	    else
3010*3d8817e4Smiod 	      {
3011*3d8817e4Smiod 		debug_type vcontext;
3012*3d8817e4Smiod 
3013*3d8817e4Smiod 		if (id != 'v')
3014*3d8817e4Smiod 		  vcontext = DEBUG_TYPE_NULL;
3015*3d8817e4Smiod 		else
3016*3d8817e4Smiod 		  {
3017*3d8817e4Smiod 		    /* FIXME: How can we calculate this correctly?  */
3018*3d8817e4Smiod 		    vcontext = it->type;
3019*3d8817e4Smiod 		  }
3020*3d8817e4Smiod 		mv = debug_make_method_variant (dhandle, mangledcopy, type,
3021*3d8817e4Smiod 						visibility, constp,
3022*3d8817e4Smiod 						volatilep, voffset,
3023*3d8817e4Smiod 						vcontext);
3024*3d8817e4Smiod 	      }
3025*3d8817e4Smiod 	    if (mv == DEBUG_METHOD_VARIANT_NULL)
3026*3d8817e4Smiod 	      return FALSE;
3027*3d8817e4Smiod 
3028*3d8817e4Smiod 	    for (meth = methods, im = 0; im < methods_count; meth++, im++)
3029*3d8817e4Smiod 	      if (meth->namlen == namlen
3030*3d8817e4Smiod 		  && strncmp (meth->name, name, namlen) == 0)
3031*3d8817e4Smiod 		break;
3032*3d8817e4Smiod 	    if (im >= methods_count)
3033*3d8817e4Smiod 	      {
3034*3d8817e4Smiod 		if (methods_count >= methods_alloc)
3035*3d8817e4Smiod 		  {
3036*3d8817e4Smiod 		    methods_alloc += 10;
3037*3d8817e4Smiod 		    methods = ((struct ieee_method *)
3038*3d8817e4Smiod 			       xrealloc (methods,
3039*3d8817e4Smiod 					 methods_alloc * sizeof *methods));
3040*3d8817e4Smiod 		  }
3041*3d8817e4Smiod 		methods[methods_count].name = name;
3042*3d8817e4Smiod 		methods[methods_count].namlen = namlen;
3043*3d8817e4Smiod 		methods[methods_count].variants = NULL;
3044*3d8817e4Smiod 		methods[methods_count].count = 0;
3045*3d8817e4Smiod 		methods[methods_count].alloc = 0;
3046*3d8817e4Smiod 		meth = methods + methods_count;
3047*3d8817e4Smiod 		++methods_count;
3048*3d8817e4Smiod 	      }
3049*3d8817e4Smiod 
3050*3d8817e4Smiod 	    if (meth->count + 1 >= meth->alloc)
3051*3d8817e4Smiod 	      {
3052*3d8817e4Smiod 		meth->alloc += 10;
3053*3d8817e4Smiod 		meth->variants = ((debug_method_variant *)
3054*3d8817e4Smiod 				  xrealloc (meth->variants,
3055*3d8817e4Smiod 					    (meth->alloc
3056*3d8817e4Smiod 					     * sizeof *meth->variants)));
3057*3d8817e4Smiod 	      }
3058*3d8817e4Smiod 
3059*3d8817e4Smiod 	    meth->variants[meth->count] = mv;
3060*3d8817e4Smiod 	    ++meth->count;
3061*3d8817e4Smiod 	    meth->variants[meth->count] = DEBUG_METHOD_VARIANT_NULL;
3062*3d8817e4Smiod 	  }
3063*3d8817e4Smiod 	  break;
3064*3d8817e4Smiod 
3065*3d8817e4Smiod 	case 'o':
3066*3d8817e4Smiod 	  {
3067*3d8817e4Smiod 	    bfd_vma spec;
3068*3d8817e4Smiod 
3069*3d8817e4Smiod 	    /* We have no way to store this information, so we just
3070*3d8817e4Smiod 	       ignore it.  */
3071*3d8817e4Smiod 	    if (! ieee_require_asn (info, pp, &spec))
3072*3d8817e4Smiod 	      return FALSE;
3073*3d8817e4Smiod 	    --count;
3074*3d8817e4Smiod 	    if ((spec & 4) != 0)
3075*3d8817e4Smiod 	      {
3076*3d8817e4Smiod 		const char *filename;
3077*3d8817e4Smiod 		unsigned long filenamlen;
3078*3d8817e4Smiod 		bfd_vma lineno;
3079*3d8817e4Smiod 
3080*3d8817e4Smiod 		if (! ieee_require_atn65 (info, pp, &filename, &filenamlen)
3081*3d8817e4Smiod 		    || ! ieee_require_asn (info, pp, &lineno))
3082*3d8817e4Smiod 		  return FALSE;
3083*3d8817e4Smiod 		count -= 2;
3084*3d8817e4Smiod 	      }
3085*3d8817e4Smiod 	    else if ((spec & 8) != 0)
3086*3d8817e4Smiod 	      {
3087*3d8817e4Smiod 		const char *mangled;
3088*3d8817e4Smiod 		unsigned long mangledlen;
3089*3d8817e4Smiod 
3090*3d8817e4Smiod 		if (! ieee_require_atn65 (info, pp, &mangled, &mangledlen))
3091*3d8817e4Smiod 		  return FALSE;
3092*3d8817e4Smiod 		--count;
3093*3d8817e4Smiod 	      }
3094*3d8817e4Smiod 	    else
3095*3d8817e4Smiod 	      {
3096*3d8817e4Smiod 		ieee_error (info, start,
3097*3d8817e4Smiod 			    _("unrecognized C++ object overhead spec"));
3098*3d8817e4Smiod 		return FALSE;
3099*3d8817e4Smiod 	      }
3100*3d8817e4Smiod 	  }
3101*3d8817e4Smiod 	  break;
3102*3d8817e4Smiod 
3103*3d8817e4Smiod 	case 'z':
3104*3d8817e4Smiod 	  {
3105*3d8817e4Smiod 	    const char *vname, *basename;
3106*3d8817e4Smiod 	    unsigned long vnamelen, baselen;
3107*3d8817e4Smiod 	    bfd_vma vsize, control;
3108*3d8817e4Smiod 
3109*3d8817e4Smiod 	    /* A virtual table pointer.  */
3110*3d8817e4Smiod 
3111*3d8817e4Smiod 	    if (! ieee_require_atn65 (info, pp, &vname, &vnamelen)
3112*3d8817e4Smiod 		|| ! ieee_require_asn (info, pp, &vsize)
3113*3d8817e4Smiod 		|| ! ieee_require_atn65 (info, pp, &basename, &baselen)
3114*3d8817e4Smiod 		|| ! ieee_require_asn (info, pp, &control))
3115*3d8817e4Smiod 	      return FALSE;
3116*3d8817e4Smiod 	    count -= 4;
3117*3d8817e4Smiod 
3118*3d8817e4Smiod 	    /* We just ignore the control number.  We don't care what
3119*3d8817e4Smiod 	       the virtual table name is.  We have no way to store the
3120*3d8817e4Smiod 	       virtual table size, and I don't think we care anyhow.  */
3121*3d8817e4Smiod 
3122*3d8817e4Smiod 	    /* FIXME: We can't handle multiple virtual table pointers.  */
3123*3d8817e4Smiod 
3124*3d8817e4Smiod 	    if (baselen == 0)
3125*3d8817e4Smiod 	      ownvptr = TRUE;
3126*3d8817e4Smiod 	    else
3127*3d8817e4Smiod 	      {
3128*3d8817e4Smiod 		char *basecopy;
3129*3d8817e4Smiod 
3130*3d8817e4Smiod 		basecopy = savestring (basename, baselen);
3131*3d8817e4Smiod 		vptrbase = debug_find_tagged_type (dhandle, basecopy,
3132*3d8817e4Smiod 						   DEBUG_KIND_ILLEGAL);
3133*3d8817e4Smiod 		free (basecopy);
3134*3d8817e4Smiod 		if (vptrbase == DEBUG_TYPE_NULL)
3135*3d8817e4Smiod 		  {
3136*3d8817e4Smiod 		    ieee_error (info, start, _("undefined C++ vtable"));
3137*3d8817e4Smiod 		    return FALSE;
3138*3d8817e4Smiod 		  }
3139*3d8817e4Smiod 	      }
3140*3d8817e4Smiod 	  }
3141*3d8817e4Smiod 	  break;
3142*3d8817e4Smiod 	}
3143*3d8817e4Smiod     }
3144*3d8817e4Smiod 
3145*3d8817e4Smiod   /* Now that we have seen all the method variants, we can call
3146*3d8817e4Smiod      debug_make_method for each one.  */
3147*3d8817e4Smiod 
3148*3d8817e4Smiod   if (methods_count == 0)
3149*3d8817e4Smiod     dmethods = NULL;
3150*3d8817e4Smiod   else
3151*3d8817e4Smiod     {
3152*3d8817e4Smiod       unsigned int i;
3153*3d8817e4Smiod 
3154*3d8817e4Smiod       dmethods = ((debug_method *)
3155*3d8817e4Smiod 		  xmalloc ((methods_count + 1) * sizeof *dmethods));
3156*3d8817e4Smiod       for (i = 0; i < methods_count; i++)
3157*3d8817e4Smiod 	{
3158*3d8817e4Smiod 	  char *namcopy;
3159*3d8817e4Smiod 
3160*3d8817e4Smiod 	  namcopy = savestring (methods[i].name, methods[i].namlen);
3161*3d8817e4Smiod 	  dmethods[i] = debug_make_method (dhandle, namcopy,
3162*3d8817e4Smiod 					   methods[i].variants);
3163*3d8817e4Smiod 	  if (dmethods[i] == DEBUG_METHOD_NULL)
3164*3d8817e4Smiod 	    return FALSE;
3165*3d8817e4Smiod 	}
3166*3d8817e4Smiod       dmethods[i] = DEBUG_METHOD_NULL;
3167*3d8817e4Smiod       free (methods);
3168*3d8817e4Smiod     }
3169*3d8817e4Smiod 
3170*3d8817e4Smiod   /* The struct type was created as an indirect type pointing at
3171*3d8817e4Smiod      it->slot.  We update it->slot to automatically update all
3172*3d8817e4Smiod      references to this struct.  */
3173*3d8817e4Smiod   it->slot = debug_make_object_type (dhandle,
3174*3d8817e4Smiod 				     class != 'u',
3175*3d8817e4Smiod 				     debug_get_type_size (dhandle,
3176*3d8817e4Smiod 							  it->slot),
3177*3d8817e4Smiod 				     fields, baseclasses, dmethods,
3178*3d8817e4Smiod 				     vptrbase, ownvptr);
3179*3d8817e4Smiod   if (it->slot == DEBUG_TYPE_NULL)
3180*3d8817e4Smiod     return FALSE;
3181*3d8817e4Smiod 
3182*3d8817e4Smiod   return TRUE;
3183*3d8817e4Smiod }
3184*3d8817e4Smiod 
3185*3d8817e4Smiod /* Read C++ default argument value and reference type information.  */
3186*3d8817e4Smiod 
3187*3d8817e4Smiod static bfd_boolean
ieee_read_cxx_defaults(struct ieee_info * info,const bfd_byte ** pp,unsigned long count)3188*3d8817e4Smiod ieee_read_cxx_defaults (struct ieee_info *info, const bfd_byte **pp,
3189*3d8817e4Smiod 			unsigned long count)
3190*3d8817e4Smiod {
3191*3d8817e4Smiod   const bfd_byte *start;
3192*3d8817e4Smiod   const char *fnname;
3193*3d8817e4Smiod   unsigned long fnlen;
3194*3d8817e4Smiod   bfd_vma defcount;
3195*3d8817e4Smiod 
3196*3d8817e4Smiod   start = *pp;
3197*3d8817e4Smiod 
3198*3d8817e4Smiod   /* Giving the function name before the argument count is an addendum
3199*3d8817e4Smiod      to the spec.  The function name is demangled, though, so this
3200*3d8817e4Smiod      record must always refer to the current function.  */
3201*3d8817e4Smiod 
3202*3d8817e4Smiod   if (info->blockstack.bsp <= info->blockstack.stack
3203*3d8817e4Smiod       || info->blockstack.bsp[-1].fnindx == (unsigned int) -1)
3204*3d8817e4Smiod     {
3205*3d8817e4Smiod       ieee_error (info, start, _("C++ default values not in a function"));
3206*3d8817e4Smiod       return FALSE;
3207*3d8817e4Smiod     }
3208*3d8817e4Smiod 
3209*3d8817e4Smiod   if (! ieee_require_atn65 (info, pp, &fnname, &fnlen)
3210*3d8817e4Smiod       || ! ieee_require_asn (info, pp, &defcount))
3211*3d8817e4Smiod     return FALSE;
3212*3d8817e4Smiod   count -= 2;
3213*3d8817e4Smiod 
3214*3d8817e4Smiod   while (defcount-- > 0)
3215*3d8817e4Smiod     {
3216*3d8817e4Smiod       bfd_vma type, val;
3217*3d8817e4Smiod       const char *strval;
3218*3d8817e4Smiod       unsigned long strvallen;
3219*3d8817e4Smiod 
3220*3d8817e4Smiod       if (! ieee_require_asn (info, pp, &type))
3221*3d8817e4Smiod 	return FALSE;
3222*3d8817e4Smiod       --count;
3223*3d8817e4Smiod 
3224*3d8817e4Smiod       switch (type)
3225*3d8817e4Smiod 	{
3226*3d8817e4Smiod 	case 0:
3227*3d8817e4Smiod 	case 4:
3228*3d8817e4Smiod 	  break;
3229*3d8817e4Smiod 
3230*3d8817e4Smiod 	case 1:
3231*3d8817e4Smiod 	case 2:
3232*3d8817e4Smiod 	  if (! ieee_require_asn (info, pp, &val))
3233*3d8817e4Smiod 	    return FALSE;
3234*3d8817e4Smiod 	  --count;
3235*3d8817e4Smiod 	  break;
3236*3d8817e4Smiod 
3237*3d8817e4Smiod 	case 3:
3238*3d8817e4Smiod 	case 7:
3239*3d8817e4Smiod 	  if (! ieee_require_atn65 (info, pp, &strval, &strvallen))
3240*3d8817e4Smiod 	    return FALSE;
3241*3d8817e4Smiod 	  --count;
3242*3d8817e4Smiod 	  break;
3243*3d8817e4Smiod 
3244*3d8817e4Smiod 	default:
3245*3d8817e4Smiod 	  ieee_error (info, start, _("unrecognized C++ default type"));
3246*3d8817e4Smiod 	  return FALSE;
3247*3d8817e4Smiod 	}
3248*3d8817e4Smiod 
3249*3d8817e4Smiod       /* We have no way to record the default argument values, so we
3250*3d8817e4Smiod          just ignore them.  FIXME.  */
3251*3d8817e4Smiod     }
3252*3d8817e4Smiod 
3253*3d8817e4Smiod   /* Any remaining arguments are indices of parameters that are really
3254*3d8817e4Smiod      reference type.  */
3255*3d8817e4Smiod   if (count > 0)
3256*3d8817e4Smiod     {
3257*3d8817e4Smiod       void *dhandle;
3258*3d8817e4Smiod       debug_type *arg_slots;
3259*3d8817e4Smiod 
3260*3d8817e4Smiod       dhandle = info->dhandle;
3261*3d8817e4Smiod       arg_slots = info->types.types[info->blockstack.bsp[-1].fnindx].arg_slots;
3262*3d8817e4Smiod       while (count-- > 0)
3263*3d8817e4Smiod 	{
3264*3d8817e4Smiod 	  bfd_vma indx;
3265*3d8817e4Smiod 	  debug_type target;
3266*3d8817e4Smiod 
3267*3d8817e4Smiod 	  if (! ieee_require_asn (info, pp, &indx))
3268*3d8817e4Smiod 	    return FALSE;
3269*3d8817e4Smiod 	  /* The index is 1 based.  */
3270*3d8817e4Smiod 	  --indx;
3271*3d8817e4Smiod 	  if (arg_slots == NULL
3272*3d8817e4Smiod 	      || arg_slots[indx] == DEBUG_TYPE_NULL
3273*3d8817e4Smiod 	      || (debug_get_type_kind (dhandle, arg_slots[indx])
3274*3d8817e4Smiod 		  != DEBUG_KIND_POINTER))
3275*3d8817e4Smiod 	    {
3276*3d8817e4Smiod 	      ieee_error (info, start, _("reference parameter is not a pointer"));
3277*3d8817e4Smiod 	      return FALSE;
3278*3d8817e4Smiod 	    }
3279*3d8817e4Smiod 
3280*3d8817e4Smiod 	  target = debug_get_target_type (dhandle, arg_slots[indx]);
3281*3d8817e4Smiod 	  arg_slots[indx] = debug_make_reference_type (dhandle, target);
3282*3d8817e4Smiod 	  if (arg_slots[indx] == DEBUG_TYPE_NULL)
3283*3d8817e4Smiod 	    return FALSE;
3284*3d8817e4Smiod 	}
3285*3d8817e4Smiod     }
3286*3d8817e4Smiod 
3287*3d8817e4Smiod   return TRUE;
3288*3d8817e4Smiod }
3289*3d8817e4Smiod 
3290*3d8817e4Smiod /* Read a C++ reference definition.  */
3291*3d8817e4Smiod 
3292*3d8817e4Smiod static bfd_boolean
ieee_read_reference(struct ieee_info * info,const bfd_byte ** pp)3293*3d8817e4Smiod ieee_read_reference (struct ieee_info *info, const bfd_byte **pp)
3294*3d8817e4Smiod {
3295*3d8817e4Smiod   const bfd_byte *start;
3296*3d8817e4Smiod   bfd_vma flags;
3297*3d8817e4Smiod   const char *class, *name;
3298*3d8817e4Smiod   unsigned long classlen, namlen;
3299*3d8817e4Smiod   debug_type *pslot;
3300*3d8817e4Smiod   debug_type target;
3301*3d8817e4Smiod 
3302*3d8817e4Smiod   start = *pp;
3303*3d8817e4Smiod 
3304*3d8817e4Smiod   if (! ieee_require_asn (info, pp, &flags))
3305*3d8817e4Smiod     return FALSE;
3306*3d8817e4Smiod 
3307*3d8817e4Smiod   /* Giving the class name before the member name is in an addendum to
3308*3d8817e4Smiod      the spec.  */
3309*3d8817e4Smiod   if (flags == 3)
3310*3d8817e4Smiod     {
3311*3d8817e4Smiod       if (! ieee_require_atn65 (info, pp, &class, &classlen))
3312*3d8817e4Smiod 	return FALSE;
3313*3d8817e4Smiod     }
3314*3d8817e4Smiod 
3315*3d8817e4Smiod   if (! ieee_require_atn65 (info, pp, &name, &namlen))
3316*3d8817e4Smiod     return FALSE;
3317*3d8817e4Smiod 
3318*3d8817e4Smiod   pslot = NULL;
3319*3d8817e4Smiod   if (flags != 3)
3320*3d8817e4Smiod     {
3321*3d8817e4Smiod       int pass;
3322*3d8817e4Smiod 
3323*3d8817e4Smiod       /* We search from the last variable indices to the first in
3324*3d8817e4Smiod 	 hopes of finding local variables correctly.  We search the
3325*3d8817e4Smiod 	 local variables on the first pass, and the global variables
3326*3d8817e4Smiod 	 on the second.  FIXME: This probably won't work in all cases.
3327*3d8817e4Smiod 	 On the other hand, I don't know what will.  */
3328*3d8817e4Smiod       for (pass = 0; pass < 2; pass++)
3329*3d8817e4Smiod 	{
3330*3d8817e4Smiod 	  struct ieee_vars *vars;
3331*3d8817e4Smiod 	  int i;
3332*3d8817e4Smiod 	  struct ieee_var *pv = NULL;
3333*3d8817e4Smiod 
3334*3d8817e4Smiod 	  if (pass == 0)
3335*3d8817e4Smiod 	    vars = &info->vars;
3336*3d8817e4Smiod 	  else
3337*3d8817e4Smiod 	    {
3338*3d8817e4Smiod 	      vars = info->global_vars;
3339*3d8817e4Smiod 	      if (vars == NULL)
3340*3d8817e4Smiod 		break;
3341*3d8817e4Smiod 	    }
3342*3d8817e4Smiod 
3343*3d8817e4Smiod 	  for (i = (int) vars->alloc - 1; i >= 0; i--)
3344*3d8817e4Smiod 	    {
3345*3d8817e4Smiod 	      bfd_boolean found;
3346*3d8817e4Smiod 
3347*3d8817e4Smiod 	      pv = vars->vars + i;
3348*3d8817e4Smiod 
3349*3d8817e4Smiod 	      if (pv->pslot == NULL
3350*3d8817e4Smiod 		  || pv->namlen != namlen
3351*3d8817e4Smiod 		  || strncmp (pv->name, name, namlen) != 0)
3352*3d8817e4Smiod 		continue;
3353*3d8817e4Smiod 
3354*3d8817e4Smiod 	      found = FALSE;
3355*3d8817e4Smiod 	      switch (flags)
3356*3d8817e4Smiod 		{
3357*3d8817e4Smiod 		default:
3358*3d8817e4Smiod 		  ieee_error (info, start,
3359*3d8817e4Smiod 			      _("unrecognized C++ reference type"));
3360*3d8817e4Smiod 		  return FALSE;
3361*3d8817e4Smiod 
3362*3d8817e4Smiod 		case 0:
3363*3d8817e4Smiod 		  /* Global variable or function.  */
3364*3d8817e4Smiod 		  if (pv->kind == IEEE_GLOBAL
3365*3d8817e4Smiod 		      || pv->kind == IEEE_EXTERNAL
3366*3d8817e4Smiod 		      || pv->kind == IEEE_FUNCTION)
3367*3d8817e4Smiod 		    found = TRUE;
3368*3d8817e4Smiod 		  break;
3369*3d8817e4Smiod 
3370*3d8817e4Smiod 		case 1:
3371*3d8817e4Smiod 		  /* Global static variable or function.  */
3372*3d8817e4Smiod 		  if (pv->kind == IEEE_STATIC
3373*3d8817e4Smiod 		      || pv->kind == IEEE_FUNCTION)
3374*3d8817e4Smiod 		    found = TRUE;
3375*3d8817e4Smiod 		  break;
3376*3d8817e4Smiod 
3377*3d8817e4Smiod 		case 2:
3378*3d8817e4Smiod 		  /* Local variable.  */
3379*3d8817e4Smiod 		  if (pv->kind == IEEE_LOCAL)
3380*3d8817e4Smiod 		    found = TRUE;
3381*3d8817e4Smiod 		  break;
3382*3d8817e4Smiod 		}
3383*3d8817e4Smiod 
3384*3d8817e4Smiod 	      if (found)
3385*3d8817e4Smiod 		break;
3386*3d8817e4Smiod 	    }
3387*3d8817e4Smiod 
3388*3d8817e4Smiod 	  if (i >= 0)
3389*3d8817e4Smiod 	    {
3390*3d8817e4Smiod 	      pslot = pv->pslot;
3391*3d8817e4Smiod 	      break;
3392*3d8817e4Smiod 	    }
3393*3d8817e4Smiod 	}
3394*3d8817e4Smiod     }
3395*3d8817e4Smiod   else
3396*3d8817e4Smiod     {
3397*3d8817e4Smiod       struct ieee_tag *it;
3398*3d8817e4Smiod 
3399*3d8817e4Smiod       for (it = info->tags; it != NULL; it = it->next)
3400*3d8817e4Smiod 	{
3401*3d8817e4Smiod 	  if (it->name[0] == class[0]
3402*3d8817e4Smiod 	      && strncmp (it->name, class, classlen) == 0
3403*3d8817e4Smiod 	      && strlen (it->name) == classlen)
3404*3d8817e4Smiod 	    {
3405*3d8817e4Smiod 	      if (it->fslots != NULL)
3406*3d8817e4Smiod 		{
3407*3d8817e4Smiod 		  const debug_field *pf;
3408*3d8817e4Smiod 		  unsigned int findx;
3409*3d8817e4Smiod 
3410*3d8817e4Smiod 		  pf = debug_get_fields (info->dhandle, it->type);
3411*3d8817e4Smiod 		  if (pf == NULL)
3412*3d8817e4Smiod 		    {
3413*3d8817e4Smiod 		      ieee_error (info, start,
3414*3d8817e4Smiod 				  "C++ reference in class with no fields");
3415*3d8817e4Smiod 		      return FALSE;
3416*3d8817e4Smiod 		    }
3417*3d8817e4Smiod 
3418*3d8817e4Smiod 		  for (findx = 0; *pf != DEBUG_FIELD_NULL; pf++, findx++)
3419*3d8817e4Smiod 		    {
3420*3d8817e4Smiod 		      const char *fname;
3421*3d8817e4Smiod 
3422*3d8817e4Smiod 		      fname = debug_get_field_name (info->dhandle, *pf);
3423*3d8817e4Smiod 		      if (fname == NULL)
3424*3d8817e4Smiod 			return FALSE;
3425*3d8817e4Smiod 		      if (strncmp (fname, name, namlen) == 0
3426*3d8817e4Smiod 			  && strlen (fname) == namlen)
3427*3d8817e4Smiod 			{
3428*3d8817e4Smiod 			  pslot = it->fslots + findx;
3429*3d8817e4Smiod 			  break;
3430*3d8817e4Smiod 			}
3431*3d8817e4Smiod 		    }
3432*3d8817e4Smiod 		}
3433*3d8817e4Smiod 
3434*3d8817e4Smiod 	      break;
3435*3d8817e4Smiod 	    }
3436*3d8817e4Smiod 	}
3437*3d8817e4Smiod     }
3438*3d8817e4Smiod 
3439*3d8817e4Smiod   if (pslot == NULL)
3440*3d8817e4Smiod     {
3441*3d8817e4Smiod       ieee_error (info, start, _("C++ reference not found"));
3442*3d8817e4Smiod       return FALSE;
3443*3d8817e4Smiod     }
3444*3d8817e4Smiod 
3445*3d8817e4Smiod   /* We allocated the type of the object as an indirect type pointing
3446*3d8817e4Smiod      to *pslot, which we can now update to be a reference type.  */
3447*3d8817e4Smiod   if (debug_get_type_kind (info->dhandle, *pslot) != DEBUG_KIND_POINTER)
3448*3d8817e4Smiod     {
3449*3d8817e4Smiod       ieee_error (info, start, _("C++ reference is not pointer"));
3450*3d8817e4Smiod       return FALSE;
3451*3d8817e4Smiod     }
3452*3d8817e4Smiod 
3453*3d8817e4Smiod   target = debug_get_target_type (info->dhandle, *pslot);
3454*3d8817e4Smiod   *pslot = debug_make_reference_type (info->dhandle, target);
3455*3d8817e4Smiod   if (*pslot == DEBUG_TYPE_NULL)
3456*3d8817e4Smiod     return FALSE;
3457*3d8817e4Smiod 
3458*3d8817e4Smiod   return TRUE;
3459*3d8817e4Smiod }
3460*3d8817e4Smiod 
3461*3d8817e4Smiod /* Require an ASN record.  */
3462*3d8817e4Smiod 
3463*3d8817e4Smiod static bfd_boolean
ieee_require_asn(struct ieee_info * info,const bfd_byte ** pp,bfd_vma * pv)3464*3d8817e4Smiod ieee_require_asn (struct ieee_info *info, const bfd_byte **pp, bfd_vma *pv)
3465*3d8817e4Smiod {
3466*3d8817e4Smiod   const bfd_byte *start;
3467*3d8817e4Smiod   ieee_record_enum_type c;
3468*3d8817e4Smiod   bfd_vma varindx;
3469*3d8817e4Smiod 
3470*3d8817e4Smiod   start = *pp;
3471*3d8817e4Smiod 
3472*3d8817e4Smiod   c = (ieee_record_enum_type) **pp;
3473*3d8817e4Smiod   if (c != ieee_e2_first_byte_enum)
3474*3d8817e4Smiod     {
3475*3d8817e4Smiod       ieee_error (info, start, _("missing required ASN"));
3476*3d8817e4Smiod       return FALSE;
3477*3d8817e4Smiod     }
3478*3d8817e4Smiod   ++*pp;
3479*3d8817e4Smiod 
3480*3d8817e4Smiod   c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
3481*3d8817e4Smiod   if (c != ieee_asn_record_enum)
3482*3d8817e4Smiod     {
3483*3d8817e4Smiod       ieee_error (info, start, _("missing required ASN"));
3484*3d8817e4Smiod       return FALSE;
3485*3d8817e4Smiod     }
3486*3d8817e4Smiod   ++*pp;
3487*3d8817e4Smiod 
3488*3d8817e4Smiod   /* Just ignore the variable index.  */
3489*3d8817e4Smiod   if (! ieee_read_number (info, pp, &varindx))
3490*3d8817e4Smiod     return FALSE;
3491*3d8817e4Smiod 
3492*3d8817e4Smiod   return ieee_read_expression (info, pp, pv);
3493*3d8817e4Smiod }
3494*3d8817e4Smiod 
3495*3d8817e4Smiod /* Require an ATN65 record.  */
3496*3d8817e4Smiod 
3497*3d8817e4Smiod static bfd_boolean
ieee_require_atn65(struct ieee_info * info,const bfd_byte ** pp,const char ** pname,unsigned long * pnamlen)3498*3d8817e4Smiod ieee_require_atn65 (struct ieee_info *info, const bfd_byte **pp,
3499*3d8817e4Smiod 		    const char **pname, unsigned long *pnamlen)
3500*3d8817e4Smiod {
3501*3d8817e4Smiod   const bfd_byte *start;
3502*3d8817e4Smiod   ieee_record_enum_type c;
3503*3d8817e4Smiod   bfd_vma name_indx, type_indx, atn_code;
3504*3d8817e4Smiod 
3505*3d8817e4Smiod   start = *pp;
3506*3d8817e4Smiod 
3507*3d8817e4Smiod   c = (ieee_record_enum_type) **pp;
3508*3d8817e4Smiod   if (c != ieee_at_record_enum)
3509*3d8817e4Smiod     {
3510*3d8817e4Smiod       ieee_error (info, start, _("missing required ATN65"));
3511*3d8817e4Smiod       return FALSE;
3512*3d8817e4Smiod     }
3513*3d8817e4Smiod   ++*pp;
3514*3d8817e4Smiod 
3515*3d8817e4Smiod   c = (ieee_record_enum_type) (((unsigned int) c << 8) | **pp);
3516*3d8817e4Smiod   if (c != ieee_atn_record_enum)
3517*3d8817e4Smiod     {
3518*3d8817e4Smiod       ieee_error (info, start, _("missing required ATN65"));
3519*3d8817e4Smiod       return FALSE;
3520*3d8817e4Smiod     }
3521*3d8817e4Smiod   ++*pp;
3522*3d8817e4Smiod 
3523*3d8817e4Smiod   if (! ieee_read_number (info, pp, &name_indx)
3524*3d8817e4Smiod       || ! ieee_read_number (info, pp, &type_indx)
3525*3d8817e4Smiod       || ! ieee_read_number (info, pp, &atn_code))
3526*3d8817e4Smiod     return FALSE;
3527*3d8817e4Smiod 
3528*3d8817e4Smiod   /* Just ignore name_indx.  */
3529*3d8817e4Smiod 
3530*3d8817e4Smiod   if (type_indx != 0 || atn_code != 65)
3531*3d8817e4Smiod     {
3532*3d8817e4Smiod       ieee_error (info, start, _("bad ATN65 record"));
3533*3d8817e4Smiod       return FALSE;
3534*3d8817e4Smiod     }
3535*3d8817e4Smiod 
3536*3d8817e4Smiod   return ieee_read_id (info, pp, pname, pnamlen);
3537*3d8817e4Smiod }
3538*3d8817e4Smiod 
3539*3d8817e4Smiod /* Convert a register number in IEEE debugging information into a
3540*3d8817e4Smiod    generic register number.  */
3541*3d8817e4Smiod 
3542*3d8817e4Smiod static int
ieee_regno_to_genreg(bfd * abfd,int r)3543*3d8817e4Smiod ieee_regno_to_genreg (bfd *abfd, int r)
3544*3d8817e4Smiod {
3545*3d8817e4Smiod   switch (bfd_get_arch (abfd))
3546*3d8817e4Smiod     {
3547*3d8817e4Smiod     case bfd_arch_m68k:
3548*3d8817e4Smiod       /* For some reasons stabs adds 2 to the floating point register
3549*3d8817e4Smiod          numbers.  */
3550*3d8817e4Smiod       if (r >= 16)
3551*3d8817e4Smiod 	r += 2;
3552*3d8817e4Smiod       break;
3553*3d8817e4Smiod 
3554*3d8817e4Smiod     case bfd_arch_i960:
3555*3d8817e4Smiod       /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
3556*3d8817e4Smiod          32 to 35 for fp0 to fp3.  */
3557*3d8817e4Smiod       --r;
3558*3d8817e4Smiod       break;
3559*3d8817e4Smiod 
3560*3d8817e4Smiod     default:
3561*3d8817e4Smiod       break;
3562*3d8817e4Smiod     }
3563*3d8817e4Smiod 
3564*3d8817e4Smiod   return r;
3565*3d8817e4Smiod }
3566*3d8817e4Smiod 
3567*3d8817e4Smiod /* Convert a generic register number to an IEEE specific one.  */
3568*3d8817e4Smiod 
3569*3d8817e4Smiod static int
ieee_genreg_to_regno(bfd * abfd,int r)3570*3d8817e4Smiod ieee_genreg_to_regno (bfd *abfd, int r)
3571*3d8817e4Smiod {
3572*3d8817e4Smiod   switch (bfd_get_arch (abfd))
3573*3d8817e4Smiod     {
3574*3d8817e4Smiod     case bfd_arch_m68k:
3575*3d8817e4Smiod       /* For some reason stabs add 2 to the floating point register
3576*3d8817e4Smiod          numbers.  */
3577*3d8817e4Smiod       if (r >= 18)
3578*3d8817e4Smiod 	r -= 2;
3579*3d8817e4Smiod       break;
3580*3d8817e4Smiod 
3581*3d8817e4Smiod     case bfd_arch_i960:
3582*3d8817e4Smiod       /* Stabs uses 0 to 15 for r0 to r15, 16 to 31 for g0 to g15, and
3583*3d8817e4Smiod          32 to 35 for fp0 to fp3.  */
3584*3d8817e4Smiod       ++r;
3585*3d8817e4Smiod       break;
3586*3d8817e4Smiod 
3587*3d8817e4Smiod     default:
3588*3d8817e4Smiod       break;
3589*3d8817e4Smiod     }
3590*3d8817e4Smiod 
3591*3d8817e4Smiod   return r;
3592*3d8817e4Smiod }
3593*3d8817e4Smiod 
3594*3d8817e4Smiod /* These routines build IEEE debugging information out of the generic
3595*3d8817e4Smiod    debugging information.  */
3596*3d8817e4Smiod 
3597*3d8817e4Smiod /* We build the IEEE debugging information byte by byte.  Rather than
3598*3d8817e4Smiod    waste time copying data around, we use a linked list of buffers to
3599*3d8817e4Smiod    hold the data.  */
3600*3d8817e4Smiod 
3601*3d8817e4Smiod #define IEEE_BUFSIZE (490)
3602*3d8817e4Smiod 
3603*3d8817e4Smiod struct ieee_buf
3604*3d8817e4Smiod {
3605*3d8817e4Smiod   /* Next buffer.  */
3606*3d8817e4Smiod   struct ieee_buf *next;
3607*3d8817e4Smiod   /* Number of data bytes in this buffer.  */
3608*3d8817e4Smiod   unsigned int c;
3609*3d8817e4Smiod   /* Bytes.  */
3610*3d8817e4Smiod   bfd_byte buf[IEEE_BUFSIZE];
3611*3d8817e4Smiod };
3612*3d8817e4Smiod 
3613*3d8817e4Smiod /* A list of buffers.  */
3614*3d8817e4Smiod 
3615*3d8817e4Smiod struct ieee_buflist
3616*3d8817e4Smiod {
3617*3d8817e4Smiod   /* Head of list.  */
3618*3d8817e4Smiod   struct ieee_buf *head;
3619*3d8817e4Smiod   /* Tail--last buffer on list.  */
3620*3d8817e4Smiod   struct ieee_buf *tail;
3621*3d8817e4Smiod };
3622*3d8817e4Smiod 
3623*3d8817e4Smiod /* In order to generate the BB11 blocks required by the HP emulator,
3624*3d8817e4Smiod    we keep track of ranges of addresses which correspond to a given
3625*3d8817e4Smiod    compilation unit.  */
3626*3d8817e4Smiod 
3627*3d8817e4Smiod struct ieee_range
3628*3d8817e4Smiod {
3629*3d8817e4Smiod   /* Next range.  */
3630*3d8817e4Smiod   struct ieee_range *next;
3631*3d8817e4Smiod   /* Low address.  */
3632*3d8817e4Smiod   bfd_vma low;
3633*3d8817e4Smiod   /* High address.  */
3634*3d8817e4Smiod   bfd_vma high;
3635*3d8817e4Smiod };
3636*3d8817e4Smiod 
3637*3d8817e4Smiod /* This structure holds information for a class on the type stack.  */
3638*3d8817e4Smiod 
3639*3d8817e4Smiod struct ieee_type_class
3640*3d8817e4Smiod {
3641*3d8817e4Smiod   /* The name index in the debugging information.  */
3642*3d8817e4Smiod   unsigned int indx;
3643*3d8817e4Smiod   /* The pmisc records for the class.  */
3644*3d8817e4Smiod   struct ieee_buflist pmiscbuf;
3645*3d8817e4Smiod   /* The number of pmisc records.  */
3646*3d8817e4Smiod   unsigned int pmisccount;
3647*3d8817e4Smiod   /* The name of the class holding the virtual table, if not this
3648*3d8817e4Smiod      class.  */
3649*3d8817e4Smiod   const char *vclass;
3650*3d8817e4Smiod   /* Whether this class holds its own virtual table.  */
3651*3d8817e4Smiod   bfd_boolean ownvptr;
3652*3d8817e4Smiod   /* The largest virtual table offset seen so far.  */
3653*3d8817e4Smiod   bfd_vma voffset;
3654*3d8817e4Smiod   /* The current method.  */
3655*3d8817e4Smiod   const char *method;
3656*3d8817e4Smiod   /* Additional pmisc records used to record fields of reference type.  */
3657*3d8817e4Smiod   struct ieee_buflist refs;
3658*3d8817e4Smiod };
3659*3d8817e4Smiod 
3660*3d8817e4Smiod /* This is how we store types for the writing routines.  Most types
3661*3d8817e4Smiod    are simply represented by a type index.  */
3662*3d8817e4Smiod 
3663*3d8817e4Smiod struct ieee_write_type
3664*3d8817e4Smiod {
3665*3d8817e4Smiod   /* Type index.  */
3666*3d8817e4Smiod   unsigned int indx;
3667*3d8817e4Smiod   /* The size of the type, if known.  */
3668*3d8817e4Smiod   unsigned int size;
3669*3d8817e4Smiod   /* The name of the type, if any.  */
3670*3d8817e4Smiod   const char *name;
3671*3d8817e4Smiod   /* If this is a function or method type, we build the type here, and
3672*3d8817e4Smiod      only add it to the output buffers if we need it.  */
3673*3d8817e4Smiod   struct ieee_buflist fndef;
3674*3d8817e4Smiod   /* If this is a struct, this is where the struct definition is
3675*3d8817e4Smiod      built.  */
3676*3d8817e4Smiod   struct ieee_buflist strdef;
3677*3d8817e4Smiod   /* If this is a class, this is where the class information is built.  */
3678*3d8817e4Smiod   struct ieee_type_class *classdef;
3679*3d8817e4Smiod   /* Whether the type is unsigned.  */
3680*3d8817e4Smiod   unsigned int unsignedp : 1;
3681*3d8817e4Smiod   /* Whether this is a reference type.  */
3682*3d8817e4Smiod   unsigned int referencep : 1;
3683*3d8817e4Smiod   /* Whether this is in the local type block.  */
3684*3d8817e4Smiod   unsigned int localp : 1;
3685*3d8817e4Smiod   /* Whether this is a duplicate struct definition which we are
3686*3d8817e4Smiod      ignoring.  */
3687*3d8817e4Smiod   unsigned int ignorep : 1;
3688*3d8817e4Smiod };
3689*3d8817e4Smiod 
3690*3d8817e4Smiod /* This is the type stack used by the debug writing routines.  FIXME:
3691*3d8817e4Smiod    We could generate more efficient output if we remembered when we
3692*3d8817e4Smiod    have output a particular type before.  */
3693*3d8817e4Smiod 
3694*3d8817e4Smiod struct ieee_type_stack
3695*3d8817e4Smiod {
3696*3d8817e4Smiod   /* Next entry on stack.  */
3697*3d8817e4Smiod   struct ieee_type_stack *next;
3698*3d8817e4Smiod   /* Type information.  */
3699*3d8817e4Smiod   struct ieee_write_type type;
3700*3d8817e4Smiod };
3701*3d8817e4Smiod 
3702*3d8817e4Smiod /* This is a list of associations between a name and some types.
3703*3d8817e4Smiod    These are used for typedefs and tags.  */
3704*3d8817e4Smiod 
3705*3d8817e4Smiod struct ieee_name_type
3706*3d8817e4Smiod {
3707*3d8817e4Smiod   /* Next type for this name.  */
3708*3d8817e4Smiod   struct ieee_name_type *next;
3709*3d8817e4Smiod   /* ID number.  For a typedef, this is the index of the type to which
3710*3d8817e4Smiod      this name is typedefed.  */
3711*3d8817e4Smiod   unsigned int id;
3712*3d8817e4Smiod   /* Type.  */
3713*3d8817e4Smiod   struct ieee_write_type type;
3714*3d8817e4Smiod   /* If this is a tag which has not yet been defined, this is the
3715*3d8817e4Smiod      kind.  If the tag has been defined, this is DEBUG_KIND_ILLEGAL.  */
3716*3d8817e4Smiod   enum debug_type_kind kind;
3717*3d8817e4Smiod };
3718*3d8817e4Smiod 
3719*3d8817e4Smiod /* We use a hash table to associate names and types.  */
3720*3d8817e4Smiod 
3721*3d8817e4Smiod struct ieee_name_type_hash_table
3722*3d8817e4Smiod {
3723*3d8817e4Smiod   struct bfd_hash_table root;
3724*3d8817e4Smiod };
3725*3d8817e4Smiod 
3726*3d8817e4Smiod struct ieee_name_type_hash_entry
3727*3d8817e4Smiod {
3728*3d8817e4Smiod   struct bfd_hash_entry root;
3729*3d8817e4Smiod   /* Information for this name.  */
3730*3d8817e4Smiod   struct ieee_name_type *types;
3731*3d8817e4Smiod };
3732*3d8817e4Smiod 
3733*3d8817e4Smiod /* This is a list of enums.  */
3734*3d8817e4Smiod 
3735*3d8817e4Smiod struct ieee_defined_enum
3736*3d8817e4Smiod {
3737*3d8817e4Smiod   /* Next enum.  */
3738*3d8817e4Smiod   struct ieee_defined_enum *next;
3739*3d8817e4Smiod   /* Type index.  */
3740*3d8817e4Smiod   unsigned int indx;
3741*3d8817e4Smiod   /* Whether this enum has been defined.  */
3742*3d8817e4Smiod   bfd_boolean defined;
3743*3d8817e4Smiod   /* Tag.  */
3744*3d8817e4Smiod   const char *tag;
3745*3d8817e4Smiod   /* Names.  */
3746*3d8817e4Smiod   const char **names;
3747*3d8817e4Smiod   /* Values.  */
3748*3d8817e4Smiod   bfd_signed_vma *vals;
3749*3d8817e4Smiod };
3750*3d8817e4Smiod 
3751*3d8817e4Smiod /* We keep a list of modified versions of types, so that we don't
3752*3d8817e4Smiod    output them more than once.  */
3753*3d8817e4Smiod 
3754*3d8817e4Smiod struct ieee_modified_type
3755*3d8817e4Smiod {
3756*3d8817e4Smiod   /* Pointer to this type.  */
3757*3d8817e4Smiod   unsigned int pointer;
3758*3d8817e4Smiod   /* Function with unknown arguments returning this type.  */
3759*3d8817e4Smiod   unsigned int function;
3760*3d8817e4Smiod   /* Const version of this type.  */
3761*3d8817e4Smiod   unsigned int const_qualified;
3762*3d8817e4Smiod   /* Volatile version of this type.  */
3763*3d8817e4Smiod   unsigned int volatile_qualified;
3764*3d8817e4Smiod   /* List of arrays of this type of various bounds.  */
3765*3d8817e4Smiod   struct ieee_modified_array_type *arrays;
3766*3d8817e4Smiod };
3767*3d8817e4Smiod 
3768*3d8817e4Smiod /* A list of arrays bounds.  */
3769*3d8817e4Smiod 
3770*3d8817e4Smiod struct ieee_modified_array_type
3771*3d8817e4Smiod {
3772*3d8817e4Smiod   /* Next array bounds.  */
3773*3d8817e4Smiod   struct ieee_modified_array_type *next;
3774*3d8817e4Smiod   /* Type index with these bounds.  */
3775*3d8817e4Smiod   unsigned int indx;
3776*3d8817e4Smiod   /* Low bound.  */
3777*3d8817e4Smiod   bfd_signed_vma low;
3778*3d8817e4Smiod   /* High bound.  */
3779*3d8817e4Smiod   bfd_signed_vma high;
3780*3d8817e4Smiod };
3781*3d8817e4Smiod 
3782*3d8817e4Smiod /* This is a list of pending function parameter information.  We don't
3783*3d8817e4Smiod    output them until we see the first block.  */
3784*3d8817e4Smiod 
3785*3d8817e4Smiod struct ieee_pending_parm
3786*3d8817e4Smiod {
3787*3d8817e4Smiod   /* Next pending parameter.  */
3788*3d8817e4Smiod   struct ieee_pending_parm *next;
3789*3d8817e4Smiod   /* Name.  */
3790*3d8817e4Smiod   const char *name;
3791*3d8817e4Smiod   /* Type index.  */
3792*3d8817e4Smiod   unsigned int type;
3793*3d8817e4Smiod   /* Whether the type is a reference.  */
3794*3d8817e4Smiod   bfd_boolean referencep;
3795*3d8817e4Smiod   /* Kind.  */
3796*3d8817e4Smiod   enum debug_parm_kind kind;
3797*3d8817e4Smiod   /* Value.  */
3798*3d8817e4Smiod   bfd_vma val;
3799*3d8817e4Smiod };
3800*3d8817e4Smiod 
3801*3d8817e4Smiod /* This is the handle passed down by debug_write.  */
3802*3d8817e4Smiod 
3803*3d8817e4Smiod struct ieee_handle
3804*3d8817e4Smiod {
3805*3d8817e4Smiod   /* BFD we are writing to.  */
3806*3d8817e4Smiod   bfd *abfd;
3807*3d8817e4Smiod   /* Whether we got an error in a subroutine called via traverse or
3808*3d8817e4Smiod      map_over_sections.  */
3809*3d8817e4Smiod   bfd_boolean error;
3810*3d8817e4Smiod   /* Current data buffer list.  */
3811*3d8817e4Smiod   struct ieee_buflist *current;
3812*3d8817e4Smiod   /* Current data buffer.  */
3813*3d8817e4Smiod   struct ieee_buf *curbuf;
3814*3d8817e4Smiod   /* Filename of current compilation unit.  */
3815*3d8817e4Smiod   const char *filename;
3816*3d8817e4Smiod   /* Module name of current compilation unit.  */
3817*3d8817e4Smiod   const char *modname;
3818*3d8817e4Smiod   /* List of buffer for global types.  */
3819*3d8817e4Smiod   struct ieee_buflist global_types;
3820*3d8817e4Smiod   /* List of finished data buffers.  */
3821*3d8817e4Smiod   struct ieee_buflist data;
3822*3d8817e4Smiod   /* List of buffers for typedefs in the current compilation unit.  */
3823*3d8817e4Smiod   struct ieee_buflist types;
3824*3d8817e4Smiod   /* List of buffers for variables and functions in the current
3825*3d8817e4Smiod      compilation unit.  */
3826*3d8817e4Smiod   struct ieee_buflist vars;
3827*3d8817e4Smiod   /* List of buffers for C++ class definitions in the current
3828*3d8817e4Smiod      compilation unit.  */
3829*3d8817e4Smiod   struct ieee_buflist cxx;
3830*3d8817e4Smiod   /* List of buffers for line numbers in the current compilation unit.  */
3831*3d8817e4Smiod   struct ieee_buflist linenos;
3832*3d8817e4Smiod   /* Ranges for the current compilation unit.  */
3833*3d8817e4Smiod   struct ieee_range *ranges;
3834*3d8817e4Smiod   /* Ranges for all debugging information.  */
3835*3d8817e4Smiod   struct ieee_range *global_ranges;
3836*3d8817e4Smiod   /* Nested pending ranges.  */
3837*3d8817e4Smiod   struct ieee_range *pending_ranges;
3838*3d8817e4Smiod   /* Type stack.  */
3839*3d8817e4Smiod   struct ieee_type_stack *type_stack;
3840*3d8817e4Smiod   /* Next unallocated type index.  */
3841*3d8817e4Smiod   unsigned int type_indx;
3842*3d8817e4Smiod   /* Next unallocated name index.  */
3843*3d8817e4Smiod   unsigned int name_indx;
3844*3d8817e4Smiod   /* Typedefs.  */
3845*3d8817e4Smiod   struct ieee_name_type_hash_table typedefs;
3846*3d8817e4Smiod   /* Tags.  */
3847*3d8817e4Smiod   struct ieee_name_type_hash_table tags;
3848*3d8817e4Smiod   /* Enums.  */
3849*3d8817e4Smiod   struct ieee_defined_enum *enums;
3850*3d8817e4Smiod   /* Modified versions of types.  */
3851*3d8817e4Smiod   struct ieee_modified_type *modified;
3852*3d8817e4Smiod   /* Number of entries allocated in modified.  */
3853*3d8817e4Smiod   unsigned int modified_alloc;
3854*3d8817e4Smiod   /* 4 byte complex type.  */
3855*3d8817e4Smiod   unsigned int complex_float_index;
3856*3d8817e4Smiod   /* 8 byte complex type.  */
3857*3d8817e4Smiod   unsigned int complex_double_index;
3858*3d8817e4Smiod   /* The depth of block nesting.  This is 0 outside a function, and 1
3859*3d8817e4Smiod      just after start_function is called.  */
3860*3d8817e4Smiod   unsigned int block_depth;
3861*3d8817e4Smiod   /* The name of the current function.  */
3862*3d8817e4Smiod   const char *fnname;
3863*3d8817e4Smiod   /* List of buffers for the type of the function we are currently
3864*3d8817e4Smiod      writing out.  */
3865*3d8817e4Smiod   struct ieee_buflist fntype;
3866*3d8817e4Smiod   /* List of buffers for the parameters of the function we are
3867*3d8817e4Smiod      currently writing out.  */
3868*3d8817e4Smiod   struct ieee_buflist fnargs;
3869*3d8817e4Smiod   /* Number of arguments written to fnargs.  */
3870*3d8817e4Smiod   unsigned int fnargcount;
3871*3d8817e4Smiod   /* Pending function parameters.  */
3872*3d8817e4Smiod   struct ieee_pending_parm *pending_parms;
3873*3d8817e4Smiod   /* Current line number filename.  */
3874*3d8817e4Smiod   const char *lineno_filename;
3875*3d8817e4Smiod   /* Line number name index.  */
3876*3d8817e4Smiod   unsigned int lineno_name_indx;
3877*3d8817e4Smiod   /* Filename of pending line number.  */
3878*3d8817e4Smiod   const char *pending_lineno_filename;
3879*3d8817e4Smiod   /* Pending line number.  */
3880*3d8817e4Smiod   unsigned long pending_lineno;
3881*3d8817e4Smiod   /* Address of pending line number.  */
3882*3d8817e4Smiod   bfd_vma pending_lineno_addr;
3883*3d8817e4Smiod   /* Highest address seen at end of procedure.  */
3884*3d8817e4Smiod   bfd_vma highaddr;
3885*3d8817e4Smiod };
3886*3d8817e4Smiod 
3887*3d8817e4Smiod static bfd_boolean ieee_init_buffer
3888*3d8817e4Smiod   (struct ieee_handle *, struct ieee_buflist *);
3889*3d8817e4Smiod static bfd_boolean ieee_change_buffer
3890*3d8817e4Smiod   (struct ieee_handle *, struct ieee_buflist *);
3891*3d8817e4Smiod static bfd_boolean ieee_append_buffer
3892*3d8817e4Smiod   (struct ieee_handle *, struct ieee_buflist *, struct ieee_buflist *);
3893*3d8817e4Smiod static bfd_boolean ieee_real_write_byte (struct ieee_handle *, int);
3894*3d8817e4Smiod static bfd_boolean ieee_write_2bytes (struct ieee_handle *, int);
3895*3d8817e4Smiod static bfd_boolean ieee_write_number (struct ieee_handle *, bfd_vma);
3896*3d8817e4Smiod static bfd_boolean ieee_write_id (struct ieee_handle *, const char *);
3897*3d8817e4Smiod static bfd_boolean ieee_write_asn
3898*3d8817e4Smiod   (struct ieee_handle *, unsigned int, bfd_vma);
3899*3d8817e4Smiod static bfd_boolean ieee_write_atn65
3900*3d8817e4Smiod   (struct ieee_handle *, unsigned int, const char *);
3901*3d8817e4Smiod static bfd_boolean ieee_push_type
3902*3d8817e4Smiod   (struct ieee_handle *, unsigned int, unsigned int, bfd_boolean,
3903*3d8817e4Smiod    bfd_boolean);
3904*3d8817e4Smiod static unsigned int ieee_pop_type (struct ieee_handle *);
3905*3d8817e4Smiod static void ieee_pop_unused_type (struct ieee_handle *);
3906*3d8817e4Smiod static unsigned int ieee_pop_type_used (struct ieee_handle *, bfd_boolean);
3907*3d8817e4Smiod static bfd_boolean ieee_add_range
3908*3d8817e4Smiod   (struct ieee_handle *, bfd_boolean, bfd_vma, bfd_vma);
3909*3d8817e4Smiod static bfd_boolean ieee_start_range (struct ieee_handle *, bfd_vma);
3910*3d8817e4Smiod static bfd_boolean ieee_end_range (struct ieee_handle *, bfd_vma);
3911*3d8817e4Smiod static bfd_boolean ieee_define_type
3912*3d8817e4Smiod   (struct ieee_handle *, unsigned int, bfd_boolean, bfd_boolean);
3913*3d8817e4Smiod static bfd_boolean ieee_define_named_type
3914*3d8817e4Smiod   (struct ieee_handle *, const char *, unsigned int, unsigned int,
3915*3d8817e4Smiod    bfd_boolean, bfd_boolean, struct ieee_buflist *);
3916*3d8817e4Smiod static struct ieee_modified_type *ieee_get_modified_info
3917*3d8817e4Smiod   (struct ieee_handle *, unsigned int);
3918*3d8817e4Smiod static struct bfd_hash_entry *ieee_name_type_newfunc
3919*3d8817e4Smiod   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
3920*3d8817e4Smiod static bfd_boolean ieee_write_undefined_tag
3921*3d8817e4Smiod   (struct ieee_name_type_hash_entry *, void *);
3922*3d8817e4Smiod static bfd_boolean ieee_finish_compilation_unit (struct ieee_handle *);
3923*3d8817e4Smiod static void ieee_add_bb11_blocks (bfd *, asection *, void *);
3924*3d8817e4Smiod static bfd_boolean ieee_add_bb11
3925*3d8817e4Smiod   (struct ieee_handle *, asection *, bfd_vma, bfd_vma);
3926*3d8817e4Smiod static bfd_boolean ieee_output_pending_parms (struct ieee_handle *);
3927*3d8817e4Smiod static unsigned int ieee_vis_to_flags (enum debug_visibility);
3928*3d8817e4Smiod static bfd_boolean ieee_class_method_var
3929*3d8817e4Smiod   (struct ieee_handle *, const char *, enum debug_visibility, bfd_boolean,
3930*3d8817e4Smiod    bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean);
3931*3d8817e4Smiod 
3932*3d8817e4Smiod static bfd_boolean ieee_start_compilation_unit (void *, const char *);
3933*3d8817e4Smiod static bfd_boolean ieee_start_source (void *, const char *);
3934*3d8817e4Smiod static bfd_boolean ieee_empty_type (void *);
3935*3d8817e4Smiod static bfd_boolean ieee_void_type (void *);
3936*3d8817e4Smiod static bfd_boolean ieee_int_type (void *, unsigned int, bfd_boolean);
3937*3d8817e4Smiod static bfd_boolean ieee_float_type (void *, unsigned int);
3938*3d8817e4Smiod static bfd_boolean ieee_complex_type (void *, unsigned int);
3939*3d8817e4Smiod static bfd_boolean ieee_bool_type (void *, unsigned int);
3940*3d8817e4Smiod static bfd_boolean ieee_enum_type
3941*3d8817e4Smiod   (void *, const char *, const char **, bfd_signed_vma *);
3942*3d8817e4Smiod static bfd_boolean ieee_pointer_type (void *);
3943*3d8817e4Smiod static bfd_boolean ieee_function_type (void *, int, bfd_boolean);
3944*3d8817e4Smiod static bfd_boolean ieee_reference_type (void *);
3945*3d8817e4Smiod static bfd_boolean ieee_range_type (void *, bfd_signed_vma, bfd_signed_vma);
3946*3d8817e4Smiod static bfd_boolean ieee_array_type
3947*3d8817e4Smiod   (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean);
3948*3d8817e4Smiod static bfd_boolean ieee_set_type (void *, bfd_boolean);
3949*3d8817e4Smiod static bfd_boolean ieee_offset_type (void *);
3950*3d8817e4Smiod static bfd_boolean ieee_method_type (void *, bfd_boolean, int, bfd_boolean);
3951*3d8817e4Smiod static bfd_boolean ieee_const_type (void *);
3952*3d8817e4Smiod static bfd_boolean ieee_volatile_type (void *);
3953*3d8817e4Smiod static bfd_boolean ieee_start_struct_type
3954*3d8817e4Smiod   (void *, const char *, unsigned int, bfd_boolean, unsigned int);
3955*3d8817e4Smiod static bfd_boolean ieee_struct_field
3956*3d8817e4Smiod   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
3957*3d8817e4Smiod static bfd_boolean ieee_end_struct_type (void *);
3958*3d8817e4Smiod static bfd_boolean ieee_start_class_type
3959*3d8817e4Smiod   (void *, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean,
3960*3d8817e4Smiod    bfd_boolean);
3961*3d8817e4Smiod static bfd_boolean ieee_class_static_member
3962*3d8817e4Smiod   (void *, const char *, const char *, enum debug_visibility);
3963*3d8817e4Smiod static bfd_boolean ieee_class_baseclass
3964*3d8817e4Smiod   (void *, bfd_vma, bfd_boolean, enum debug_visibility);
3965*3d8817e4Smiod static bfd_boolean ieee_class_start_method (void *, const char *);
3966*3d8817e4Smiod static bfd_boolean ieee_class_method_variant
3967*3d8817e4Smiod   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
3968*3d8817e4Smiod    bfd_vma, bfd_boolean);
3969*3d8817e4Smiod static bfd_boolean ieee_class_static_method_variant
3970*3d8817e4Smiod   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean);
3971*3d8817e4Smiod static bfd_boolean ieee_class_end_method (void *);
3972*3d8817e4Smiod static bfd_boolean ieee_end_class_type (void *);
3973*3d8817e4Smiod static bfd_boolean ieee_typedef_type (void *, const char *);
3974*3d8817e4Smiod static bfd_boolean ieee_tag_type
3975*3d8817e4Smiod   (void *, const char *, unsigned int, enum debug_type_kind);
3976*3d8817e4Smiod static bfd_boolean ieee_typdef (void *, const char *);
3977*3d8817e4Smiod static bfd_boolean ieee_tag (void *, const char *);
3978*3d8817e4Smiod static bfd_boolean ieee_int_constant (void *, const char *, bfd_vma);
3979*3d8817e4Smiod static bfd_boolean ieee_float_constant (void *, const char *, double);
3980*3d8817e4Smiod static bfd_boolean ieee_typed_constant (void *, const char *, bfd_vma);
3981*3d8817e4Smiod static bfd_boolean ieee_variable
3982*3d8817e4Smiod   (void *, const char *, enum debug_var_kind, bfd_vma);
3983*3d8817e4Smiod static bfd_boolean ieee_start_function (void *, const char *, bfd_boolean);
3984*3d8817e4Smiod static bfd_boolean ieee_function_parameter
3985*3d8817e4Smiod   (void *, const char *, enum debug_parm_kind, bfd_vma);
3986*3d8817e4Smiod static bfd_boolean ieee_start_block (void *, bfd_vma);
3987*3d8817e4Smiod static bfd_boolean ieee_end_block (void *, bfd_vma);
3988*3d8817e4Smiod static bfd_boolean ieee_end_function (void *);
3989*3d8817e4Smiod static bfd_boolean ieee_lineno (void *, const char *, unsigned long, bfd_vma);
3990*3d8817e4Smiod 
3991*3d8817e4Smiod static const struct debug_write_fns ieee_fns =
3992*3d8817e4Smiod {
3993*3d8817e4Smiod   ieee_start_compilation_unit,
3994*3d8817e4Smiod   ieee_start_source,
3995*3d8817e4Smiod   ieee_empty_type,
3996*3d8817e4Smiod   ieee_void_type,
3997*3d8817e4Smiod   ieee_int_type,
3998*3d8817e4Smiod   ieee_float_type,
3999*3d8817e4Smiod   ieee_complex_type,
4000*3d8817e4Smiod   ieee_bool_type,
4001*3d8817e4Smiod   ieee_enum_type,
4002*3d8817e4Smiod   ieee_pointer_type,
4003*3d8817e4Smiod   ieee_function_type,
4004*3d8817e4Smiod   ieee_reference_type,
4005*3d8817e4Smiod   ieee_range_type,
4006*3d8817e4Smiod   ieee_array_type,
4007*3d8817e4Smiod   ieee_set_type,
4008*3d8817e4Smiod   ieee_offset_type,
4009*3d8817e4Smiod   ieee_method_type,
4010*3d8817e4Smiod   ieee_const_type,
4011*3d8817e4Smiod   ieee_volatile_type,
4012*3d8817e4Smiod   ieee_start_struct_type,
4013*3d8817e4Smiod   ieee_struct_field,
4014*3d8817e4Smiod   ieee_end_struct_type,
4015*3d8817e4Smiod   ieee_start_class_type,
4016*3d8817e4Smiod   ieee_class_static_member,
4017*3d8817e4Smiod   ieee_class_baseclass,
4018*3d8817e4Smiod   ieee_class_start_method,
4019*3d8817e4Smiod   ieee_class_method_variant,
4020*3d8817e4Smiod   ieee_class_static_method_variant,
4021*3d8817e4Smiod   ieee_class_end_method,
4022*3d8817e4Smiod   ieee_end_class_type,
4023*3d8817e4Smiod   ieee_typedef_type,
4024*3d8817e4Smiod   ieee_tag_type,
4025*3d8817e4Smiod   ieee_typdef,
4026*3d8817e4Smiod   ieee_tag,
4027*3d8817e4Smiod   ieee_int_constant,
4028*3d8817e4Smiod   ieee_float_constant,
4029*3d8817e4Smiod   ieee_typed_constant,
4030*3d8817e4Smiod   ieee_variable,
4031*3d8817e4Smiod   ieee_start_function,
4032*3d8817e4Smiod   ieee_function_parameter,
4033*3d8817e4Smiod   ieee_start_block,
4034*3d8817e4Smiod   ieee_end_block,
4035*3d8817e4Smiod   ieee_end_function,
4036*3d8817e4Smiod   ieee_lineno
4037*3d8817e4Smiod };
4038*3d8817e4Smiod 
4039*3d8817e4Smiod /* Initialize a buffer to be empty.  */
4040*3d8817e4Smiod 
4041*3d8817e4Smiod static bfd_boolean
ieee_init_buffer(struct ieee_handle * info ATTRIBUTE_UNUSED,struct ieee_buflist * buflist)4042*3d8817e4Smiod ieee_init_buffer (struct ieee_handle *info ATTRIBUTE_UNUSED,
4043*3d8817e4Smiod 		  struct ieee_buflist *buflist)
4044*3d8817e4Smiod {
4045*3d8817e4Smiod   buflist->head = NULL;
4046*3d8817e4Smiod   buflist->tail = NULL;
4047*3d8817e4Smiod   return TRUE;
4048*3d8817e4Smiod }
4049*3d8817e4Smiod 
4050*3d8817e4Smiod /* See whether a buffer list has any data.  */
4051*3d8817e4Smiod 
4052*3d8817e4Smiod #define ieee_buffer_emptyp(buflist) ((buflist)->head == NULL)
4053*3d8817e4Smiod 
4054*3d8817e4Smiod /* Change the current buffer to a specified buffer chain.  */
4055*3d8817e4Smiod 
4056*3d8817e4Smiod static bfd_boolean
ieee_change_buffer(struct ieee_handle * info,struct ieee_buflist * buflist)4057*3d8817e4Smiod ieee_change_buffer (struct ieee_handle *info, struct ieee_buflist *buflist)
4058*3d8817e4Smiod {
4059*3d8817e4Smiod   if (buflist->head == NULL)
4060*3d8817e4Smiod     {
4061*3d8817e4Smiod       struct ieee_buf *buf;
4062*3d8817e4Smiod 
4063*3d8817e4Smiod       buf = (struct ieee_buf *) xmalloc (sizeof *buf);
4064*3d8817e4Smiod       buf->next = NULL;
4065*3d8817e4Smiod       buf->c = 0;
4066*3d8817e4Smiod       buflist->head = buf;
4067*3d8817e4Smiod       buflist->tail = buf;
4068*3d8817e4Smiod     }
4069*3d8817e4Smiod 
4070*3d8817e4Smiod   info->current = buflist;
4071*3d8817e4Smiod   info->curbuf = buflist->tail;
4072*3d8817e4Smiod 
4073*3d8817e4Smiod   return TRUE;
4074*3d8817e4Smiod }
4075*3d8817e4Smiod 
4076*3d8817e4Smiod /* Append a buffer chain.  */
4077*3d8817e4Smiod 
4078*3d8817e4Smiod static bfd_boolean
ieee_append_buffer(struct ieee_handle * info ATTRIBUTE_UNUSED,struct ieee_buflist * mainbuf,struct ieee_buflist * newbuf)4079*3d8817e4Smiod ieee_append_buffer (struct ieee_handle *info ATTRIBUTE_UNUSED,
4080*3d8817e4Smiod 		    struct ieee_buflist *mainbuf,
4081*3d8817e4Smiod 		    struct ieee_buflist *newbuf)
4082*3d8817e4Smiod {
4083*3d8817e4Smiod   if (newbuf->head != NULL)
4084*3d8817e4Smiod     {
4085*3d8817e4Smiod       if (mainbuf->head == NULL)
4086*3d8817e4Smiod 	mainbuf->head = newbuf->head;
4087*3d8817e4Smiod       else
4088*3d8817e4Smiod 	mainbuf->tail->next = newbuf->head;
4089*3d8817e4Smiod       mainbuf->tail = newbuf->tail;
4090*3d8817e4Smiod     }
4091*3d8817e4Smiod   return TRUE;
4092*3d8817e4Smiod }
4093*3d8817e4Smiod 
4094*3d8817e4Smiod /* Write a byte into the buffer.  We use a macro for speed and a
4095*3d8817e4Smiod    function for the complex cases.  */
4096*3d8817e4Smiod 
4097*3d8817e4Smiod #define ieee_write_byte(info, b)				\
4098*3d8817e4Smiod   ((info)->curbuf->c < IEEE_BUFSIZE				\
4099*3d8817e4Smiod    ? ((info)->curbuf->buf[(info)->curbuf->c++] = (b), TRUE)	\
4100*3d8817e4Smiod    : ieee_real_write_byte ((info), (b)))
4101*3d8817e4Smiod 
4102*3d8817e4Smiod static bfd_boolean
ieee_real_write_byte(struct ieee_handle * info,int b)4103*3d8817e4Smiod ieee_real_write_byte (struct ieee_handle *info, int b)
4104*3d8817e4Smiod {
4105*3d8817e4Smiod   if (info->curbuf->c >= IEEE_BUFSIZE)
4106*3d8817e4Smiod     {
4107*3d8817e4Smiod       struct ieee_buf *n;
4108*3d8817e4Smiod 
4109*3d8817e4Smiod       n = (struct ieee_buf *) xmalloc (sizeof *n);
4110*3d8817e4Smiod       n->next = NULL;
4111*3d8817e4Smiod       n->c = 0;
4112*3d8817e4Smiod       if (info->current->head == NULL)
4113*3d8817e4Smiod 	info->current->head = n;
4114*3d8817e4Smiod       else
4115*3d8817e4Smiod 	info->current->tail->next = n;
4116*3d8817e4Smiod       info->current->tail = n;
4117*3d8817e4Smiod       info->curbuf = n;
4118*3d8817e4Smiod     }
4119*3d8817e4Smiod 
4120*3d8817e4Smiod   info->curbuf->buf[info->curbuf->c] = b;
4121*3d8817e4Smiod   ++info->curbuf->c;
4122*3d8817e4Smiod 
4123*3d8817e4Smiod   return TRUE;
4124*3d8817e4Smiod }
4125*3d8817e4Smiod 
4126*3d8817e4Smiod /* Write out two bytes.  */
4127*3d8817e4Smiod 
4128*3d8817e4Smiod static bfd_boolean
ieee_write_2bytes(struct ieee_handle * info,int i)4129*3d8817e4Smiod ieee_write_2bytes (struct ieee_handle *info, int i)
4130*3d8817e4Smiod {
4131*3d8817e4Smiod   return (ieee_write_byte (info, i >> 8)
4132*3d8817e4Smiod 	  && ieee_write_byte (info, i & 0xff));
4133*3d8817e4Smiod }
4134*3d8817e4Smiod 
4135*3d8817e4Smiod /* Write out an integer.  */
4136*3d8817e4Smiod 
4137*3d8817e4Smiod static bfd_boolean
ieee_write_number(struct ieee_handle * info,bfd_vma v)4138*3d8817e4Smiod ieee_write_number (struct ieee_handle *info, bfd_vma v)
4139*3d8817e4Smiod {
4140*3d8817e4Smiod   bfd_vma t;
4141*3d8817e4Smiod   bfd_byte ab[20];
4142*3d8817e4Smiod   bfd_byte *p;
4143*3d8817e4Smiod   unsigned int c;
4144*3d8817e4Smiod 
4145*3d8817e4Smiod   if (v <= (bfd_vma) ieee_number_end_enum)
4146*3d8817e4Smiod     return ieee_write_byte (info, (int) v);
4147*3d8817e4Smiod 
4148*3d8817e4Smiod   t = v;
4149*3d8817e4Smiod   p = ab + sizeof ab;
4150*3d8817e4Smiod   while (t != 0)
4151*3d8817e4Smiod     {
4152*3d8817e4Smiod       *--p = t & 0xff;
4153*3d8817e4Smiod       t >>= 8;
4154*3d8817e4Smiod     }
4155*3d8817e4Smiod   c = (ab + 20) - p;
4156*3d8817e4Smiod 
4157*3d8817e4Smiod   if (c > (unsigned int) (ieee_number_repeat_end_enum
4158*3d8817e4Smiod 			  - ieee_number_repeat_start_enum))
4159*3d8817e4Smiod     {
4160*3d8817e4Smiod       fprintf (stderr, _("IEEE numeric overflow: 0x"));
4161*3d8817e4Smiod       fprintf_vma (stderr, v);
4162*3d8817e4Smiod       fprintf (stderr, "\n");
4163*3d8817e4Smiod       return FALSE;
4164*3d8817e4Smiod     }
4165*3d8817e4Smiod 
4166*3d8817e4Smiod   if (! ieee_write_byte (info, (int) ieee_number_repeat_start_enum + c))
4167*3d8817e4Smiod     return FALSE;
4168*3d8817e4Smiod   for (; c > 0; --c, ++p)
4169*3d8817e4Smiod     {
4170*3d8817e4Smiod       if (! ieee_write_byte (info, *p))
4171*3d8817e4Smiod 	return FALSE;
4172*3d8817e4Smiod     }
4173*3d8817e4Smiod 
4174*3d8817e4Smiod   return TRUE;
4175*3d8817e4Smiod }
4176*3d8817e4Smiod 
4177*3d8817e4Smiod /* Write out a string.  */
4178*3d8817e4Smiod 
4179*3d8817e4Smiod static bfd_boolean
ieee_write_id(struct ieee_handle * info,const char * s)4180*3d8817e4Smiod ieee_write_id (struct ieee_handle *info, const char *s)
4181*3d8817e4Smiod {
4182*3d8817e4Smiod   unsigned int len;
4183*3d8817e4Smiod 
4184*3d8817e4Smiod   len = strlen (s);
4185*3d8817e4Smiod   if (len <= 0x7f)
4186*3d8817e4Smiod     {
4187*3d8817e4Smiod       if (! ieee_write_byte (info, len))
4188*3d8817e4Smiod 	return FALSE;
4189*3d8817e4Smiod     }
4190*3d8817e4Smiod   else if (len <= 0xff)
4191*3d8817e4Smiod     {
4192*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_extension_length_1_enum)
4193*3d8817e4Smiod 	  || ! ieee_write_byte (info, len))
4194*3d8817e4Smiod 	return FALSE;
4195*3d8817e4Smiod     }
4196*3d8817e4Smiod   else if (len <= 0xffff)
4197*3d8817e4Smiod     {
4198*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_extension_length_2_enum)
4199*3d8817e4Smiod 	  || ! ieee_write_2bytes (info, len))
4200*3d8817e4Smiod 	return FALSE;
4201*3d8817e4Smiod     }
4202*3d8817e4Smiod   else
4203*3d8817e4Smiod     {
4204*3d8817e4Smiod       fprintf (stderr, _("IEEE string length overflow: %u\n"), len);
4205*3d8817e4Smiod       return FALSE;
4206*3d8817e4Smiod     }
4207*3d8817e4Smiod 
4208*3d8817e4Smiod   for (; *s != '\0'; s++)
4209*3d8817e4Smiod     if (! ieee_write_byte (info, *s))
4210*3d8817e4Smiod       return FALSE;
4211*3d8817e4Smiod 
4212*3d8817e4Smiod   return TRUE;
4213*3d8817e4Smiod }
4214*3d8817e4Smiod 
4215*3d8817e4Smiod /* Write out an ASN record.  */
4216*3d8817e4Smiod 
4217*3d8817e4Smiod static bfd_boolean
ieee_write_asn(struct ieee_handle * info,unsigned int indx,bfd_vma val)4218*3d8817e4Smiod ieee_write_asn (struct ieee_handle *info, unsigned int indx, bfd_vma val)
4219*3d8817e4Smiod {
4220*3d8817e4Smiod   return (ieee_write_2bytes (info, (int) ieee_asn_record_enum)
4221*3d8817e4Smiod 	  && ieee_write_number (info, indx)
4222*3d8817e4Smiod 	  && ieee_write_number (info, val));
4223*3d8817e4Smiod }
4224*3d8817e4Smiod 
4225*3d8817e4Smiod /* Write out an ATN65 record.  */
4226*3d8817e4Smiod 
4227*3d8817e4Smiod static bfd_boolean
ieee_write_atn65(struct ieee_handle * info,unsigned int indx,const char * s)4228*3d8817e4Smiod ieee_write_atn65 (struct ieee_handle *info, unsigned int indx, const char *s)
4229*3d8817e4Smiod {
4230*3d8817e4Smiod   return (ieee_write_2bytes (info, (int) ieee_atn_record_enum)
4231*3d8817e4Smiod 	  && ieee_write_number (info, indx)
4232*3d8817e4Smiod 	  && ieee_write_number (info, 0)
4233*3d8817e4Smiod 	  && ieee_write_number (info, 65)
4234*3d8817e4Smiod 	  && ieee_write_id (info, s));
4235*3d8817e4Smiod }
4236*3d8817e4Smiod 
4237*3d8817e4Smiod /* Push a type index onto the type stack.  */
4238*3d8817e4Smiod 
4239*3d8817e4Smiod static bfd_boolean
ieee_push_type(struct ieee_handle * info,unsigned int indx,unsigned int size,bfd_boolean unsignedp,bfd_boolean localp)4240*3d8817e4Smiod ieee_push_type (struct ieee_handle *info, unsigned int indx,
4241*3d8817e4Smiod 		unsigned int size, bfd_boolean unsignedp, bfd_boolean localp)
4242*3d8817e4Smiod {
4243*3d8817e4Smiod   struct ieee_type_stack *ts;
4244*3d8817e4Smiod 
4245*3d8817e4Smiod   ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
4246*3d8817e4Smiod   memset (ts, 0, sizeof *ts);
4247*3d8817e4Smiod 
4248*3d8817e4Smiod   ts->type.indx = indx;
4249*3d8817e4Smiod   ts->type.size = size;
4250*3d8817e4Smiod   ts->type.unsignedp = unsignedp;
4251*3d8817e4Smiod   ts->type.localp = localp;
4252*3d8817e4Smiod 
4253*3d8817e4Smiod   ts->next = info->type_stack;
4254*3d8817e4Smiod   info->type_stack = ts;
4255*3d8817e4Smiod 
4256*3d8817e4Smiod   return TRUE;
4257*3d8817e4Smiod }
4258*3d8817e4Smiod 
4259*3d8817e4Smiod /* Pop a type index off the type stack.  */
4260*3d8817e4Smiod 
4261*3d8817e4Smiod static unsigned int
ieee_pop_type(struct ieee_handle * info)4262*3d8817e4Smiod ieee_pop_type (struct ieee_handle *info)
4263*3d8817e4Smiod {
4264*3d8817e4Smiod   return ieee_pop_type_used (info, TRUE);
4265*3d8817e4Smiod }
4266*3d8817e4Smiod 
4267*3d8817e4Smiod /* Pop an unused type index off the type stack.  */
4268*3d8817e4Smiod 
4269*3d8817e4Smiod static void
ieee_pop_unused_type(struct ieee_handle * info)4270*3d8817e4Smiod ieee_pop_unused_type (struct ieee_handle *info)
4271*3d8817e4Smiod {
4272*3d8817e4Smiod   (void) ieee_pop_type_used (info, FALSE);
4273*3d8817e4Smiod }
4274*3d8817e4Smiod 
4275*3d8817e4Smiod /* Pop a used or unused type index off the type stack.  */
4276*3d8817e4Smiod 
4277*3d8817e4Smiod static unsigned int
ieee_pop_type_used(struct ieee_handle * info,bfd_boolean used)4278*3d8817e4Smiod ieee_pop_type_used (struct ieee_handle *info, bfd_boolean used)
4279*3d8817e4Smiod {
4280*3d8817e4Smiod   struct ieee_type_stack *ts;
4281*3d8817e4Smiod   unsigned int ret;
4282*3d8817e4Smiod 
4283*3d8817e4Smiod   ts = info->type_stack;
4284*3d8817e4Smiod   assert (ts != NULL);
4285*3d8817e4Smiod 
4286*3d8817e4Smiod   /* If this is a function type, and we need it, we need to append the
4287*3d8817e4Smiod      actual definition to the typedef block now.  */
4288*3d8817e4Smiod   if (used && ! ieee_buffer_emptyp (&ts->type.fndef))
4289*3d8817e4Smiod     {
4290*3d8817e4Smiod       struct ieee_buflist *buflist;
4291*3d8817e4Smiod 
4292*3d8817e4Smiod       if (ts->type.localp)
4293*3d8817e4Smiod 	{
4294*3d8817e4Smiod 	  /* Make sure we have started the types block.  */
4295*3d8817e4Smiod 	  if (ieee_buffer_emptyp (&info->types))
4296*3d8817e4Smiod 	    {
4297*3d8817e4Smiod 	      if (! ieee_change_buffer (info, &info->types)
4298*3d8817e4Smiod 		  || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4299*3d8817e4Smiod 		  || ! ieee_write_byte (info, 1)
4300*3d8817e4Smiod 		  || ! ieee_write_number (info, 0)
4301*3d8817e4Smiod 		  || ! ieee_write_id (info, info->modname))
4302*3d8817e4Smiod 		return FALSE;
4303*3d8817e4Smiod 	    }
4304*3d8817e4Smiod 	  buflist = &info->types;
4305*3d8817e4Smiod 	}
4306*3d8817e4Smiod       else
4307*3d8817e4Smiod 	{
4308*3d8817e4Smiod 	  /* Make sure we started the global type block.  */
4309*3d8817e4Smiod 	  if (ieee_buffer_emptyp (&info->global_types))
4310*3d8817e4Smiod 	    {
4311*3d8817e4Smiod 	      if (! ieee_change_buffer (info, &info->global_types)
4312*3d8817e4Smiod 		  || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4313*3d8817e4Smiod 		  || ! ieee_write_byte (info, 2)
4314*3d8817e4Smiod 		  || ! ieee_write_number (info, 0)
4315*3d8817e4Smiod 		  || ! ieee_write_id (info, ""))
4316*3d8817e4Smiod 		return FALSE;
4317*3d8817e4Smiod 	    }
4318*3d8817e4Smiod 	  buflist = &info->global_types;
4319*3d8817e4Smiod 	}
4320*3d8817e4Smiod 
4321*3d8817e4Smiod       if (! ieee_append_buffer (info, buflist, &ts->type.fndef))
4322*3d8817e4Smiod 	return FALSE;
4323*3d8817e4Smiod     }
4324*3d8817e4Smiod 
4325*3d8817e4Smiod   ret = ts->type.indx;
4326*3d8817e4Smiod   info->type_stack = ts->next;
4327*3d8817e4Smiod   free (ts);
4328*3d8817e4Smiod   return ret;
4329*3d8817e4Smiod }
4330*3d8817e4Smiod 
4331*3d8817e4Smiod /* Add a range of bytes included in the current compilation unit.  */
4332*3d8817e4Smiod 
4333*3d8817e4Smiod static bfd_boolean
ieee_add_range(struct ieee_handle * info,bfd_boolean global,bfd_vma low,bfd_vma high)4334*3d8817e4Smiod ieee_add_range (struct ieee_handle *info, bfd_boolean global, bfd_vma low,
4335*3d8817e4Smiod 		bfd_vma high)
4336*3d8817e4Smiod {
4337*3d8817e4Smiod   struct ieee_range **plist, *r, **pr;
4338*3d8817e4Smiod 
4339*3d8817e4Smiod   if (low == (bfd_vma) -1 || high == (bfd_vma) -1 || low == high)
4340*3d8817e4Smiod     return TRUE;
4341*3d8817e4Smiod 
4342*3d8817e4Smiod   if (global)
4343*3d8817e4Smiod     plist = &info->global_ranges;
4344*3d8817e4Smiod   else
4345*3d8817e4Smiod     plist = &info->ranges;
4346*3d8817e4Smiod 
4347*3d8817e4Smiod   for (r = *plist; r != NULL; r = r->next)
4348*3d8817e4Smiod     {
4349*3d8817e4Smiod       if (high >= r->low && low <= r->high)
4350*3d8817e4Smiod 	{
4351*3d8817e4Smiod 	  /* The new range overlaps r.  */
4352*3d8817e4Smiod 	  if (low < r->low)
4353*3d8817e4Smiod 	    r->low = low;
4354*3d8817e4Smiod 	  if (high > r->high)
4355*3d8817e4Smiod 	    r->high = high;
4356*3d8817e4Smiod 	  pr = &r->next;
4357*3d8817e4Smiod 	  while (*pr != NULL && (*pr)->low <= r->high)
4358*3d8817e4Smiod 	    {
4359*3d8817e4Smiod 	      struct ieee_range *n;
4360*3d8817e4Smiod 
4361*3d8817e4Smiod 	      if ((*pr)->high > r->high)
4362*3d8817e4Smiod 		r->high = (*pr)->high;
4363*3d8817e4Smiod 	      n = (*pr)->next;
4364*3d8817e4Smiod 	      free (*pr);
4365*3d8817e4Smiod 	      *pr = n;
4366*3d8817e4Smiod 	    }
4367*3d8817e4Smiod 	  return TRUE;
4368*3d8817e4Smiod 	}
4369*3d8817e4Smiod     }
4370*3d8817e4Smiod 
4371*3d8817e4Smiod   r = (struct ieee_range *) xmalloc (sizeof *r);
4372*3d8817e4Smiod   memset (r, 0, sizeof *r);
4373*3d8817e4Smiod 
4374*3d8817e4Smiod   r->low = low;
4375*3d8817e4Smiod   r->high = high;
4376*3d8817e4Smiod 
4377*3d8817e4Smiod   /* Store the ranges sorted by address.  */
4378*3d8817e4Smiod   for (pr = plist; *pr != NULL; pr = &(*pr)->next)
4379*3d8817e4Smiod     if ((*pr)->low > high)
4380*3d8817e4Smiod       break;
4381*3d8817e4Smiod   r->next = *pr;
4382*3d8817e4Smiod   *pr = r;
4383*3d8817e4Smiod 
4384*3d8817e4Smiod   return TRUE;
4385*3d8817e4Smiod }
4386*3d8817e4Smiod 
4387*3d8817e4Smiod /* Start a new range for which we only have the low address.  */
4388*3d8817e4Smiod 
4389*3d8817e4Smiod static bfd_boolean
ieee_start_range(struct ieee_handle * info,bfd_vma low)4390*3d8817e4Smiod ieee_start_range (struct ieee_handle *info, bfd_vma low)
4391*3d8817e4Smiod {
4392*3d8817e4Smiod   struct ieee_range *r;
4393*3d8817e4Smiod 
4394*3d8817e4Smiod   r = (struct ieee_range *) xmalloc (sizeof *r);
4395*3d8817e4Smiod   memset (r, 0, sizeof *r);
4396*3d8817e4Smiod   r->low = low;
4397*3d8817e4Smiod   r->next = info->pending_ranges;
4398*3d8817e4Smiod   info->pending_ranges = r;
4399*3d8817e4Smiod   return TRUE;
4400*3d8817e4Smiod }
4401*3d8817e4Smiod 
4402*3d8817e4Smiod /* Finish a range started by ieee_start_range.  */
4403*3d8817e4Smiod 
4404*3d8817e4Smiod static bfd_boolean
ieee_end_range(struct ieee_handle * info,bfd_vma high)4405*3d8817e4Smiod ieee_end_range (struct ieee_handle *info, bfd_vma high)
4406*3d8817e4Smiod {
4407*3d8817e4Smiod   struct ieee_range *r;
4408*3d8817e4Smiod   bfd_vma low;
4409*3d8817e4Smiod 
4410*3d8817e4Smiod   assert (info->pending_ranges != NULL);
4411*3d8817e4Smiod   r = info->pending_ranges;
4412*3d8817e4Smiod   low = r->low;
4413*3d8817e4Smiod   info->pending_ranges = r->next;
4414*3d8817e4Smiod   free (r);
4415*3d8817e4Smiod   return ieee_add_range (info, FALSE, low, high);
4416*3d8817e4Smiod }
4417*3d8817e4Smiod 
4418*3d8817e4Smiod /* Start defining a type.  */
4419*3d8817e4Smiod 
4420*3d8817e4Smiod static bfd_boolean
ieee_define_type(struct ieee_handle * info,unsigned int size,bfd_boolean unsignedp,bfd_boolean localp)4421*3d8817e4Smiod ieee_define_type (struct ieee_handle *info, unsigned int size,
4422*3d8817e4Smiod 		  bfd_boolean unsignedp, bfd_boolean localp)
4423*3d8817e4Smiod {
4424*3d8817e4Smiod   return ieee_define_named_type (info, (const char *) NULL,
4425*3d8817e4Smiod 				 (unsigned int) -1, size, unsignedp,
4426*3d8817e4Smiod 				 localp, (struct ieee_buflist *) NULL);
4427*3d8817e4Smiod }
4428*3d8817e4Smiod 
4429*3d8817e4Smiod /* Start defining a named type.  */
4430*3d8817e4Smiod 
4431*3d8817e4Smiod static bfd_boolean
ieee_define_named_type(struct ieee_handle * info,const char * name,unsigned int indx,unsigned int size,bfd_boolean unsignedp,bfd_boolean localp,struct ieee_buflist * buflist)4432*3d8817e4Smiod ieee_define_named_type (struct ieee_handle *info, const char *name,
4433*3d8817e4Smiod 			unsigned int indx, unsigned int size,
4434*3d8817e4Smiod 			bfd_boolean unsignedp, bfd_boolean localp,
4435*3d8817e4Smiod 			struct ieee_buflist *buflist)
4436*3d8817e4Smiod {
4437*3d8817e4Smiod   unsigned int type_indx;
4438*3d8817e4Smiod   unsigned int name_indx;
4439*3d8817e4Smiod 
4440*3d8817e4Smiod   if (indx != (unsigned int) -1)
4441*3d8817e4Smiod     type_indx = indx;
4442*3d8817e4Smiod   else
4443*3d8817e4Smiod     {
4444*3d8817e4Smiod       type_indx = info->type_indx;
4445*3d8817e4Smiod       ++info->type_indx;
4446*3d8817e4Smiod     }
4447*3d8817e4Smiod 
4448*3d8817e4Smiod   name_indx = info->name_indx;
4449*3d8817e4Smiod   ++info->name_indx;
4450*3d8817e4Smiod 
4451*3d8817e4Smiod   if (name == NULL)
4452*3d8817e4Smiod     name = "";
4453*3d8817e4Smiod 
4454*3d8817e4Smiod   /* If we were given a buffer, use it; otherwise, use either the
4455*3d8817e4Smiod      local or the global type information, and make sure that the type
4456*3d8817e4Smiod      block is started.  */
4457*3d8817e4Smiod   if (buflist != NULL)
4458*3d8817e4Smiod     {
4459*3d8817e4Smiod       if (! ieee_change_buffer (info, buflist))
4460*3d8817e4Smiod 	return FALSE;
4461*3d8817e4Smiod     }
4462*3d8817e4Smiod   else if (localp)
4463*3d8817e4Smiod     {
4464*3d8817e4Smiod       if (! ieee_buffer_emptyp (&info->types))
4465*3d8817e4Smiod 	{
4466*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->types))
4467*3d8817e4Smiod 	    return FALSE;
4468*3d8817e4Smiod 	}
4469*3d8817e4Smiod       else
4470*3d8817e4Smiod 	{
4471*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->types)
4472*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4473*3d8817e4Smiod 	      || ! ieee_write_byte (info, 1)
4474*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
4475*3d8817e4Smiod 	      || ! ieee_write_id (info, info->modname))
4476*3d8817e4Smiod 	    return FALSE;
4477*3d8817e4Smiod 	}
4478*3d8817e4Smiod     }
4479*3d8817e4Smiod   else
4480*3d8817e4Smiod     {
4481*3d8817e4Smiod       if (! ieee_buffer_emptyp (&info->global_types))
4482*3d8817e4Smiod 	{
4483*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->global_types))
4484*3d8817e4Smiod 	    return FALSE;
4485*3d8817e4Smiod 	}
4486*3d8817e4Smiod       else
4487*3d8817e4Smiod 	{
4488*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->global_types)
4489*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4490*3d8817e4Smiod 	      || ! ieee_write_byte (info, 2)
4491*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
4492*3d8817e4Smiod 	      || ! ieee_write_id (info, ""))
4493*3d8817e4Smiod 	    return FALSE;
4494*3d8817e4Smiod 	}
4495*3d8817e4Smiod     }
4496*3d8817e4Smiod 
4497*3d8817e4Smiod   /* Push the new type on the type stack, write out an NN record, and
4498*3d8817e4Smiod      write out the start of a TY record.  The caller will then finish
4499*3d8817e4Smiod      the TY record.  */
4500*3d8817e4Smiod   if (! ieee_push_type (info, type_indx, size, unsignedp, localp))
4501*3d8817e4Smiod     return FALSE;
4502*3d8817e4Smiod 
4503*3d8817e4Smiod   return (ieee_write_byte (info, (int) ieee_nn_record)
4504*3d8817e4Smiod 	  && ieee_write_number (info, name_indx)
4505*3d8817e4Smiod 	  && ieee_write_id (info, name)
4506*3d8817e4Smiod 	  && ieee_write_byte (info, (int) ieee_ty_record_enum)
4507*3d8817e4Smiod 	  && ieee_write_number (info, type_indx)
4508*3d8817e4Smiod 	  && ieee_write_byte (info, 0xce)
4509*3d8817e4Smiod 	  && ieee_write_number (info, name_indx));
4510*3d8817e4Smiod }
4511*3d8817e4Smiod 
4512*3d8817e4Smiod /* Get an entry to the list of modified versions of a type.  */
4513*3d8817e4Smiod 
4514*3d8817e4Smiod static struct ieee_modified_type *
ieee_get_modified_info(struct ieee_handle * info,unsigned int indx)4515*3d8817e4Smiod ieee_get_modified_info (struct ieee_handle *info, unsigned int indx)
4516*3d8817e4Smiod {
4517*3d8817e4Smiod   if (indx >= info->modified_alloc)
4518*3d8817e4Smiod     {
4519*3d8817e4Smiod       unsigned int nalloc;
4520*3d8817e4Smiod 
4521*3d8817e4Smiod       nalloc = info->modified_alloc;
4522*3d8817e4Smiod       if (nalloc == 0)
4523*3d8817e4Smiod 	nalloc = 16;
4524*3d8817e4Smiod       while (indx >= nalloc)
4525*3d8817e4Smiod 	nalloc *= 2;
4526*3d8817e4Smiod       info->modified = ((struct ieee_modified_type *)
4527*3d8817e4Smiod 			xrealloc (info->modified,
4528*3d8817e4Smiod 				  nalloc * sizeof *info->modified));
4529*3d8817e4Smiod       memset (info->modified + info->modified_alloc, 0,
4530*3d8817e4Smiod 	      (nalloc - info->modified_alloc) * sizeof *info->modified);
4531*3d8817e4Smiod       info->modified_alloc = nalloc;
4532*3d8817e4Smiod     }
4533*3d8817e4Smiod 
4534*3d8817e4Smiod   return info->modified + indx;
4535*3d8817e4Smiod }
4536*3d8817e4Smiod 
4537*3d8817e4Smiod /* Routines for the hash table mapping names to types.  */
4538*3d8817e4Smiod 
4539*3d8817e4Smiod /* Initialize an entry in the hash table.  */
4540*3d8817e4Smiod 
4541*3d8817e4Smiod static struct bfd_hash_entry *
ieee_name_type_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)4542*3d8817e4Smiod ieee_name_type_newfunc (struct bfd_hash_entry *entry,
4543*3d8817e4Smiod 			struct bfd_hash_table *table, const char *string)
4544*3d8817e4Smiod {
4545*3d8817e4Smiod   struct ieee_name_type_hash_entry *ret =
4546*3d8817e4Smiod     (struct ieee_name_type_hash_entry *) entry;
4547*3d8817e4Smiod 
4548*3d8817e4Smiod   /* Allocate the structure if it has not already been allocated by a
4549*3d8817e4Smiod      subclass.  */
4550*3d8817e4Smiod   if (ret == NULL)
4551*3d8817e4Smiod     ret = ((struct ieee_name_type_hash_entry *)
4552*3d8817e4Smiod 	   bfd_hash_allocate (table, sizeof *ret));
4553*3d8817e4Smiod   if (ret == NULL)
4554*3d8817e4Smiod     return NULL;
4555*3d8817e4Smiod 
4556*3d8817e4Smiod   /* Call the allocation method of the superclass.  */
4557*3d8817e4Smiod   ret = ((struct ieee_name_type_hash_entry *)
4558*3d8817e4Smiod 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
4559*3d8817e4Smiod   if (ret)
4560*3d8817e4Smiod     {
4561*3d8817e4Smiod       /* Set local fields.  */
4562*3d8817e4Smiod       ret->types = NULL;
4563*3d8817e4Smiod     }
4564*3d8817e4Smiod 
4565*3d8817e4Smiod   return (struct bfd_hash_entry *) ret;
4566*3d8817e4Smiod }
4567*3d8817e4Smiod 
4568*3d8817e4Smiod /* Look up an entry in the hash table.  */
4569*3d8817e4Smiod 
4570*3d8817e4Smiod #define ieee_name_type_hash_lookup(table, string, create, copy) \
4571*3d8817e4Smiod   ((struct ieee_name_type_hash_entry *) \
4572*3d8817e4Smiod    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
4573*3d8817e4Smiod 
4574*3d8817e4Smiod /* Traverse the hash table.  */
4575*3d8817e4Smiod 
4576*3d8817e4Smiod #define ieee_name_type_hash_traverse(table, func, info)			\
4577*3d8817e4Smiod   (bfd_hash_traverse							\
4578*3d8817e4Smiod    (&(table)->root,							\
4579*3d8817e4Smiod     (bfd_boolean (*) (struct bfd_hash_entry *, void *)) (func),		\
4580*3d8817e4Smiod     (info)))
4581*3d8817e4Smiod 
4582*3d8817e4Smiod /* The general routine to write out IEEE debugging information.  */
4583*3d8817e4Smiod 
4584*3d8817e4Smiod bfd_boolean
write_ieee_debugging_info(bfd * abfd,void * dhandle)4585*3d8817e4Smiod write_ieee_debugging_info (bfd *abfd, void *dhandle)
4586*3d8817e4Smiod {
4587*3d8817e4Smiod   struct ieee_handle info;
4588*3d8817e4Smiod   asection *s;
4589*3d8817e4Smiod   const char *err;
4590*3d8817e4Smiod   struct ieee_buf *b;
4591*3d8817e4Smiod 
4592*3d8817e4Smiod   memset (&info, 0, sizeof info);
4593*3d8817e4Smiod   info.abfd = abfd;
4594*3d8817e4Smiod   info.type_indx = 256;
4595*3d8817e4Smiod   info.name_indx = 32;
4596*3d8817e4Smiod 
4597*3d8817e4Smiod   if (!bfd_hash_table_init (&info.typedefs.root, ieee_name_type_newfunc,
4598*3d8817e4Smiod 			    sizeof (struct ieee_name_type_hash_entry))
4599*3d8817e4Smiod       || !bfd_hash_table_init (&info.tags.root, ieee_name_type_newfunc,
4600*3d8817e4Smiod 			       sizeof (struct ieee_name_type_hash_entry)))
4601*3d8817e4Smiod     return FALSE;
4602*3d8817e4Smiod 
4603*3d8817e4Smiod   if (! ieee_init_buffer (&info, &info.global_types)
4604*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.data)
4605*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.types)
4606*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.vars)
4607*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.cxx)
4608*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.linenos)
4609*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.fntype)
4610*3d8817e4Smiod       || ! ieee_init_buffer (&info, &info.fnargs))
4611*3d8817e4Smiod     return FALSE;
4612*3d8817e4Smiod 
4613*3d8817e4Smiod   if (! debug_write (dhandle, &ieee_fns, (void *) &info))
4614*3d8817e4Smiod     return FALSE;
4615*3d8817e4Smiod 
4616*3d8817e4Smiod   if (info.filename != NULL)
4617*3d8817e4Smiod     {
4618*3d8817e4Smiod       if (! ieee_finish_compilation_unit (&info))
4619*3d8817e4Smiod 	return FALSE;
4620*3d8817e4Smiod     }
4621*3d8817e4Smiod 
4622*3d8817e4Smiod   /* Put any undefined tags in the global typedef information.  */
4623*3d8817e4Smiod   info.error = FALSE;
4624*3d8817e4Smiod   ieee_name_type_hash_traverse (&info.tags,
4625*3d8817e4Smiod 				ieee_write_undefined_tag,
4626*3d8817e4Smiod 				(void *) &info);
4627*3d8817e4Smiod   if (info.error)
4628*3d8817e4Smiod     return FALSE;
4629*3d8817e4Smiod 
4630*3d8817e4Smiod   /* Prepend the global typedef information to the other data.  */
4631*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info.global_types))
4632*3d8817e4Smiod     {
4633*3d8817e4Smiod       /* The HP debugger seems to have a bug in which it ignores the
4634*3d8817e4Smiod          last entry in the global types, so we add a dummy entry.  */
4635*3d8817e4Smiod       if (! ieee_change_buffer (&info, &info.global_types)
4636*3d8817e4Smiod 	  || ! ieee_write_byte (&info, (int) ieee_nn_record)
4637*3d8817e4Smiod 	  || ! ieee_write_number (&info, info.name_indx)
4638*3d8817e4Smiod 	  || ! ieee_write_id (&info, "")
4639*3d8817e4Smiod 	  || ! ieee_write_byte (&info, (int) ieee_ty_record_enum)
4640*3d8817e4Smiod 	  || ! ieee_write_number (&info, info.type_indx)
4641*3d8817e4Smiod 	  || ! ieee_write_byte (&info, 0xce)
4642*3d8817e4Smiod 	  || ! ieee_write_number (&info, info.name_indx)
4643*3d8817e4Smiod 	  || ! ieee_write_number (&info, 'P')
4644*3d8817e4Smiod 	  || ! ieee_write_number (&info, (int) builtin_void + 32)
4645*3d8817e4Smiod 	  || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
4646*3d8817e4Smiod 	return FALSE;
4647*3d8817e4Smiod 
4648*3d8817e4Smiod       if (! ieee_append_buffer (&info, &info.global_types, &info.data))
4649*3d8817e4Smiod 	return FALSE;
4650*3d8817e4Smiod       info.data = info.global_types;
4651*3d8817e4Smiod     }
4652*3d8817e4Smiod 
4653*3d8817e4Smiod   /* Make sure that we have declare BB11 blocks for each range in the
4654*3d8817e4Smiod      file.  They are added to info->vars.  */
4655*3d8817e4Smiod   info.error = FALSE;
4656*3d8817e4Smiod   if (! ieee_init_buffer (&info, &info.vars))
4657*3d8817e4Smiod     return FALSE;
4658*3d8817e4Smiod   bfd_map_over_sections (abfd, ieee_add_bb11_blocks, (void *) &info);
4659*3d8817e4Smiod   if (info.error)
4660*3d8817e4Smiod     return FALSE;
4661*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info.vars))
4662*3d8817e4Smiod     {
4663*3d8817e4Smiod       if (! ieee_change_buffer (&info, &info.vars)
4664*3d8817e4Smiod 	  || ! ieee_write_byte (&info, (int) ieee_be_record_enum))
4665*3d8817e4Smiod 	return FALSE;
4666*3d8817e4Smiod 
4667*3d8817e4Smiod       if (! ieee_append_buffer (&info, &info.data, &info.vars))
4668*3d8817e4Smiod 	return FALSE;
4669*3d8817e4Smiod     }
4670*3d8817e4Smiod 
4671*3d8817e4Smiod   /* Now all the data is in info.data.  Write it out to the BFD.  We
4672*3d8817e4Smiod      normally would need to worry about whether all the other sections
4673*3d8817e4Smiod      are set up yet, but the IEEE backend will handle this particular
4674*3d8817e4Smiod      case correctly regardless.  */
4675*3d8817e4Smiod   if (ieee_buffer_emptyp (&info.data))
4676*3d8817e4Smiod     {
4677*3d8817e4Smiod       /* There is no debugging information.  */
4678*3d8817e4Smiod       return TRUE;
4679*3d8817e4Smiod     }
4680*3d8817e4Smiod   err = NULL;
4681*3d8817e4Smiod   s = bfd_make_section (abfd, ".debug");
4682*3d8817e4Smiod   if (s == NULL)
4683*3d8817e4Smiod     err = "bfd_make_section";
4684*3d8817e4Smiod   if (err == NULL)
4685*3d8817e4Smiod     {
4686*3d8817e4Smiod       if (! bfd_set_section_flags (abfd, s, SEC_DEBUGGING | SEC_HAS_CONTENTS))
4687*3d8817e4Smiod 	err = "bfd_set_section_flags";
4688*3d8817e4Smiod     }
4689*3d8817e4Smiod   if (err == NULL)
4690*3d8817e4Smiod     {
4691*3d8817e4Smiod       bfd_size_type size;
4692*3d8817e4Smiod 
4693*3d8817e4Smiod       size = 0;
4694*3d8817e4Smiod       for (b = info.data.head; b != NULL; b = b->next)
4695*3d8817e4Smiod 	size += b->c;
4696*3d8817e4Smiod       if (! bfd_set_section_size (abfd, s, size))
4697*3d8817e4Smiod 	err = "bfd_set_section_size";
4698*3d8817e4Smiod     }
4699*3d8817e4Smiod   if (err == NULL)
4700*3d8817e4Smiod     {
4701*3d8817e4Smiod       file_ptr offset;
4702*3d8817e4Smiod 
4703*3d8817e4Smiod       offset = 0;
4704*3d8817e4Smiod       for (b = info.data.head; b != NULL; b = b->next)
4705*3d8817e4Smiod 	{
4706*3d8817e4Smiod 	  if (! bfd_set_section_contents (abfd, s, b->buf, offset, b->c))
4707*3d8817e4Smiod 	    {
4708*3d8817e4Smiod 	      err = "bfd_set_section_contents";
4709*3d8817e4Smiod 	      break;
4710*3d8817e4Smiod 	    }
4711*3d8817e4Smiod 	  offset += b->c;
4712*3d8817e4Smiod 	}
4713*3d8817e4Smiod     }
4714*3d8817e4Smiod 
4715*3d8817e4Smiod   if (err != NULL)
4716*3d8817e4Smiod     {
4717*3d8817e4Smiod       fprintf (stderr, "%s: %s: %s\n", bfd_get_filename (abfd), err,
4718*3d8817e4Smiod 	       bfd_errmsg (bfd_get_error ()));
4719*3d8817e4Smiod       return FALSE;
4720*3d8817e4Smiod     }
4721*3d8817e4Smiod 
4722*3d8817e4Smiod   bfd_hash_table_free (&info.typedefs.root);
4723*3d8817e4Smiod   bfd_hash_table_free (&info.tags.root);
4724*3d8817e4Smiod 
4725*3d8817e4Smiod   return TRUE;
4726*3d8817e4Smiod }
4727*3d8817e4Smiod 
4728*3d8817e4Smiod /* Write out information for an undefined tag.  This is called via
4729*3d8817e4Smiod    ieee_name_type_hash_traverse.  */
4730*3d8817e4Smiod 
4731*3d8817e4Smiod static bfd_boolean
ieee_write_undefined_tag(struct ieee_name_type_hash_entry * h,void * p)4732*3d8817e4Smiod ieee_write_undefined_tag (struct ieee_name_type_hash_entry *h, void *p)
4733*3d8817e4Smiod {
4734*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
4735*3d8817e4Smiod   struct ieee_name_type *nt;
4736*3d8817e4Smiod 
4737*3d8817e4Smiod   for (nt = h->types; nt != NULL; nt = nt->next)
4738*3d8817e4Smiod     {
4739*3d8817e4Smiod       unsigned int name_indx;
4740*3d8817e4Smiod       char code;
4741*3d8817e4Smiod 
4742*3d8817e4Smiod       if (nt->kind == DEBUG_KIND_ILLEGAL)
4743*3d8817e4Smiod 	continue;
4744*3d8817e4Smiod 
4745*3d8817e4Smiod       if (ieee_buffer_emptyp (&info->global_types))
4746*3d8817e4Smiod 	{
4747*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->global_types)
4748*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4749*3d8817e4Smiod 	      || ! ieee_write_byte (info, 2)
4750*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
4751*3d8817e4Smiod 	      || ! ieee_write_id (info, ""))
4752*3d8817e4Smiod 	    {
4753*3d8817e4Smiod 	      info->error = TRUE;
4754*3d8817e4Smiod 	      return FALSE;
4755*3d8817e4Smiod 	    }
4756*3d8817e4Smiod 	}
4757*3d8817e4Smiod       else
4758*3d8817e4Smiod 	{
4759*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->global_types))
4760*3d8817e4Smiod 	    {
4761*3d8817e4Smiod 	      info->error = TRUE;
4762*3d8817e4Smiod 	      return FALSE;
4763*3d8817e4Smiod 	    }
4764*3d8817e4Smiod 	}
4765*3d8817e4Smiod 
4766*3d8817e4Smiod       name_indx = info->name_indx;
4767*3d8817e4Smiod       ++info->name_indx;
4768*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_nn_record)
4769*3d8817e4Smiod 	  || ! ieee_write_number (info, name_indx)
4770*3d8817e4Smiod 	  || ! ieee_write_id (info, nt->type.name)
4771*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_ty_record_enum)
4772*3d8817e4Smiod 	  || ! ieee_write_number (info, nt->type.indx)
4773*3d8817e4Smiod 	  || ! ieee_write_byte (info, 0xce)
4774*3d8817e4Smiod 	  || ! ieee_write_number (info, name_indx))
4775*3d8817e4Smiod 	{
4776*3d8817e4Smiod 	  info->error = TRUE;
4777*3d8817e4Smiod 	  return FALSE;
4778*3d8817e4Smiod 	}
4779*3d8817e4Smiod 
4780*3d8817e4Smiod       switch (nt->kind)
4781*3d8817e4Smiod 	{
4782*3d8817e4Smiod 	default:
4783*3d8817e4Smiod 	  abort ();
4784*3d8817e4Smiod 	  info->error = TRUE;
4785*3d8817e4Smiod 	  return FALSE;
4786*3d8817e4Smiod 	case DEBUG_KIND_STRUCT:
4787*3d8817e4Smiod 	case DEBUG_KIND_CLASS:
4788*3d8817e4Smiod 	  code = 'S';
4789*3d8817e4Smiod 	  break;
4790*3d8817e4Smiod 	case DEBUG_KIND_UNION:
4791*3d8817e4Smiod 	case DEBUG_KIND_UNION_CLASS:
4792*3d8817e4Smiod 	  code = 'U';
4793*3d8817e4Smiod 	  break;
4794*3d8817e4Smiod 	case DEBUG_KIND_ENUM:
4795*3d8817e4Smiod 	  code = 'E';
4796*3d8817e4Smiod 	  break;
4797*3d8817e4Smiod 	}
4798*3d8817e4Smiod       if (! ieee_write_number (info, code)
4799*3d8817e4Smiod 	  || ! ieee_write_number (info, 0))
4800*3d8817e4Smiod 	{
4801*3d8817e4Smiod 	  info->error = TRUE;
4802*3d8817e4Smiod 	  return FALSE;
4803*3d8817e4Smiod 	}
4804*3d8817e4Smiod     }
4805*3d8817e4Smiod 
4806*3d8817e4Smiod   return TRUE;
4807*3d8817e4Smiod }
4808*3d8817e4Smiod 
4809*3d8817e4Smiod /* Start writing out information for a compilation unit.  */
4810*3d8817e4Smiod 
4811*3d8817e4Smiod static bfd_boolean
ieee_start_compilation_unit(void * p,const char * filename)4812*3d8817e4Smiod ieee_start_compilation_unit (void *p, const char *filename)
4813*3d8817e4Smiod {
4814*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
4815*3d8817e4Smiod   const char *modname;
4816*3d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4817*3d8817e4Smiod   const char *backslash;
4818*3d8817e4Smiod #endif
4819*3d8817e4Smiod   char *c, *s;
4820*3d8817e4Smiod   unsigned int nindx;
4821*3d8817e4Smiod 
4822*3d8817e4Smiod   if (info->filename != NULL)
4823*3d8817e4Smiod     {
4824*3d8817e4Smiod       if (! ieee_finish_compilation_unit (info))
4825*3d8817e4Smiod 	return FALSE;
4826*3d8817e4Smiod     }
4827*3d8817e4Smiod 
4828*3d8817e4Smiod   info->filename = filename;
4829*3d8817e4Smiod   modname = strrchr (filename, '/');
4830*3d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4831*3d8817e4Smiod   /* We could have a mixed forward/back slash case.  */
4832*3d8817e4Smiod   backslash = strrchr (filename, '\\');
4833*3d8817e4Smiod   if (modname == NULL || (backslash != NULL && backslash > modname))
4834*3d8817e4Smiod     modname = backslash;
4835*3d8817e4Smiod #endif
4836*3d8817e4Smiod 
4837*3d8817e4Smiod   if (modname != NULL)
4838*3d8817e4Smiod     ++modname;
4839*3d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
4840*3d8817e4Smiod   else if (filename[0] && filename[1] == ':')
4841*3d8817e4Smiod     modname = filename + 2;
4842*3d8817e4Smiod #endif
4843*3d8817e4Smiod   else
4844*3d8817e4Smiod     modname = filename;
4845*3d8817e4Smiod 
4846*3d8817e4Smiod   c = xstrdup (modname);
4847*3d8817e4Smiod   s = strrchr (c, '.');
4848*3d8817e4Smiod   if (s != NULL)
4849*3d8817e4Smiod     *s = '\0';
4850*3d8817e4Smiod   info->modname = c;
4851*3d8817e4Smiod 
4852*3d8817e4Smiod   if (! ieee_init_buffer (info, &info->types)
4853*3d8817e4Smiod       || ! ieee_init_buffer (info, &info->vars)
4854*3d8817e4Smiod       || ! ieee_init_buffer (info, &info->cxx)
4855*3d8817e4Smiod       || ! ieee_init_buffer (info, &info->linenos))
4856*3d8817e4Smiod     return FALSE;
4857*3d8817e4Smiod   info->ranges = NULL;
4858*3d8817e4Smiod 
4859*3d8817e4Smiod   /* Always include a BB1 and a BB3 block.  That is what the output of
4860*3d8817e4Smiod      the MRI linker seems to look like.  */
4861*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->types)
4862*3d8817e4Smiod       || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4863*3d8817e4Smiod       || ! ieee_write_byte (info, 1)
4864*3d8817e4Smiod       || ! ieee_write_number (info, 0)
4865*3d8817e4Smiod       || ! ieee_write_id (info, info->modname))
4866*3d8817e4Smiod     return FALSE;
4867*3d8817e4Smiod 
4868*3d8817e4Smiod   nindx = info->name_indx;
4869*3d8817e4Smiod   ++info->name_indx;
4870*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->vars)
4871*3d8817e4Smiod       || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
4872*3d8817e4Smiod       || ! ieee_write_byte (info, 3)
4873*3d8817e4Smiod       || ! ieee_write_number (info, 0)
4874*3d8817e4Smiod       || ! ieee_write_id (info, info->modname))
4875*3d8817e4Smiod     return FALSE;
4876*3d8817e4Smiod 
4877*3d8817e4Smiod   return TRUE;
4878*3d8817e4Smiod }
4879*3d8817e4Smiod 
4880*3d8817e4Smiod /* Finish up a compilation unit.  */
4881*3d8817e4Smiod 
4882*3d8817e4Smiod static bfd_boolean
ieee_finish_compilation_unit(struct ieee_handle * info)4883*3d8817e4Smiod ieee_finish_compilation_unit (struct ieee_handle *info)
4884*3d8817e4Smiod {
4885*3d8817e4Smiod   struct ieee_range *r;
4886*3d8817e4Smiod 
4887*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->types))
4888*3d8817e4Smiod     {
4889*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->types)
4890*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_be_record_enum))
4891*3d8817e4Smiod 	return FALSE;
4892*3d8817e4Smiod     }
4893*3d8817e4Smiod 
4894*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->cxx))
4895*3d8817e4Smiod     {
4896*3d8817e4Smiod       /* Append any C++ information to the global function and
4897*3d8817e4Smiod          variable information.  */
4898*3d8817e4Smiod       assert (! ieee_buffer_emptyp (&info->vars));
4899*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->vars))
4900*3d8817e4Smiod 	return FALSE;
4901*3d8817e4Smiod 
4902*3d8817e4Smiod       /* We put the pmisc records in a dummy procedure, just as the
4903*3d8817e4Smiod          MRI compiler does.  */
4904*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
4905*3d8817e4Smiod 	  || ! ieee_write_byte (info, 6)
4906*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
4907*3d8817e4Smiod 	  || ! ieee_write_id (info, "__XRYCPP")
4908*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
4909*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
4910*3d8817e4Smiod 	  || ! ieee_write_number (info, info->highaddr - 1)
4911*3d8817e4Smiod 	  || ! ieee_append_buffer (info, &info->vars, &info->cxx)
4912*3d8817e4Smiod 	  || ! ieee_change_buffer (info, &info->vars)
4913*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_be_record_enum)
4914*3d8817e4Smiod 	  || ! ieee_write_number (info, info->highaddr - 1))
4915*3d8817e4Smiod 	return FALSE;
4916*3d8817e4Smiod     }
4917*3d8817e4Smiod 
4918*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->vars))
4919*3d8817e4Smiod     {
4920*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->vars)
4921*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_be_record_enum))
4922*3d8817e4Smiod 	return FALSE;
4923*3d8817e4Smiod     }
4924*3d8817e4Smiod 
4925*3d8817e4Smiod   if (info->pending_lineno_filename != NULL)
4926*3d8817e4Smiod     {
4927*3d8817e4Smiod       /* Force out the pending line number.  */
4928*3d8817e4Smiod       if (! ieee_lineno ((void *) info, (const char *) NULL, 0, (bfd_vma) -1))
4929*3d8817e4Smiod 	return FALSE;
4930*3d8817e4Smiod     }
4931*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->linenos))
4932*3d8817e4Smiod     {
4933*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->linenos)
4934*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_be_record_enum))
4935*3d8817e4Smiod 	return FALSE;
4936*3d8817e4Smiod       if (strcmp (info->filename, info->lineno_filename) != 0)
4937*3d8817e4Smiod 	{
4938*3d8817e4Smiod 	  /* We were not in the main file.  We just closed the
4939*3d8817e4Smiod              included line number block, and now we must close the
4940*3d8817e4Smiod              main line number block.  */
4941*3d8817e4Smiod 	  if (! ieee_write_byte (info, (int) ieee_be_record_enum))
4942*3d8817e4Smiod 	    return FALSE;
4943*3d8817e4Smiod 	}
4944*3d8817e4Smiod     }
4945*3d8817e4Smiod 
4946*3d8817e4Smiod   if (! ieee_append_buffer (info, &info->data, &info->types)
4947*3d8817e4Smiod       || ! ieee_append_buffer (info, &info->data, &info->vars)
4948*3d8817e4Smiod       || ! ieee_append_buffer (info, &info->data, &info->linenos))
4949*3d8817e4Smiod     return FALSE;
4950*3d8817e4Smiod 
4951*3d8817e4Smiod   /* Build BB10/BB11 blocks based on the ranges we recorded.  */
4952*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->data))
4953*3d8817e4Smiod     return FALSE;
4954*3d8817e4Smiod 
4955*3d8817e4Smiod   if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
4956*3d8817e4Smiod       || ! ieee_write_byte (info, 10)
4957*3d8817e4Smiod       || ! ieee_write_number (info, 0)
4958*3d8817e4Smiod       || ! ieee_write_id (info, info->modname)
4959*3d8817e4Smiod       || ! ieee_write_id (info, "")
4960*3d8817e4Smiod       || ! ieee_write_number (info, 0)
4961*3d8817e4Smiod       || ! ieee_write_id (info, "GNU objcopy"))
4962*3d8817e4Smiod     return FALSE;
4963*3d8817e4Smiod 
4964*3d8817e4Smiod   for (r = info->ranges; r != NULL; r = r->next)
4965*3d8817e4Smiod     {
4966*3d8817e4Smiod       bfd_vma low, high;
4967*3d8817e4Smiod       asection *s;
4968*3d8817e4Smiod       int kind;
4969*3d8817e4Smiod 
4970*3d8817e4Smiod       low = r->low;
4971*3d8817e4Smiod       high = r->high;
4972*3d8817e4Smiod 
4973*3d8817e4Smiod       /* Find the section corresponding to this range.  */
4974*3d8817e4Smiod       for (s = info->abfd->sections; s != NULL; s = s->next)
4975*3d8817e4Smiod 	{
4976*3d8817e4Smiod 	  if (bfd_get_section_vma (info->abfd, s) <= low
4977*3d8817e4Smiod 	      && high <= (bfd_get_section_vma (info->abfd, s)
4978*3d8817e4Smiod 			  + bfd_section_size (info->abfd, s)))
4979*3d8817e4Smiod 	    break;
4980*3d8817e4Smiod 	}
4981*3d8817e4Smiod 
4982*3d8817e4Smiod       if (s == NULL)
4983*3d8817e4Smiod 	{
4984*3d8817e4Smiod 	  /* Just ignore this range.  */
4985*3d8817e4Smiod 	  continue;
4986*3d8817e4Smiod 	}
4987*3d8817e4Smiod 
4988*3d8817e4Smiod       /* Coalesce ranges if it seems reasonable.  */
4989*3d8817e4Smiod       while (r->next != NULL
4990*3d8817e4Smiod 	     && high + 0x1000 >= r->next->low
4991*3d8817e4Smiod 	     && (r->next->high
4992*3d8817e4Smiod 		 <= (bfd_get_section_vma (info->abfd, s)
4993*3d8817e4Smiod 		     + bfd_section_size (info->abfd, s))))
4994*3d8817e4Smiod 	{
4995*3d8817e4Smiod 	  r = r->next;
4996*3d8817e4Smiod 	  high = r->high;
4997*3d8817e4Smiod 	}
4998*3d8817e4Smiod 
4999*3d8817e4Smiod       if ((s->flags & SEC_CODE) != 0)
5000*3d8817e4Smiod 	kind = 1;
5001*3d8817e4Smiod       else if ((s->flags & SEC_READONLY) != 0)
5002*3d8817e4Smiod 	kind = 3;
5003*3d8817e4Smiod       else
5004*3d8817e4Smiod 	kind = 2;
5005*3d8817e4Smiod 
5006*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
5007*3d8817e4Smiod 	  || ! ieee_write_byte (info, 11)
5008*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
5009*3d8817e4Smiod 	  || ! ieee_write_id (info, "")
5010*3d8817e4Smiod 	  || ! ieee_write_number (info, kind)
5011*3d8817e4Smiod 	  || ! ieee_write_number (info, s->index + IEEE_SECTION_NUMBER_BASE)
5012*3d8817e4Smiod 	  || ! ieee_write_number (info, low)
5013*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_be_record_enum)
5014*3d8817e4Smiod 	  || ! ieee_write_number (info, high - low))
5015*3d8817e4Smiod 	return FALSE;
5016*3d8817e4Smiod 
5017*3d8817e4Smiod       /* Add this range to the list of global ranges.  */
5018*3d8817e4Smiod       if (! ieee_add_range (info, TRUE, low, high))
5019*3d8817e4Smiod 	return FALSE;
5020*3d8817e4Smiod     }
5021*3d8817e4Smiod 
5022*3d8817e4Smiod   if (! ieee_write_byte (info, (int) ieee_be_record_enum))
5023*3d8817e4Smiod     return FALSE;
5024*3d8817e4Smiod 
5025*3d8817e4Smiod   return TRUE;
5026*3d8817e4Smiod }
5027*3d8817e4Smiod 
5028*3d8817e4Smiod /* Add BB11 blocks describing each range that we have not already
5029*3d8817e4Smiod    described.  */
5030*3d8817e4Smiod 
5031*3d8817e4Smiod static void
ieee_add_bb11_blocks(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,void * data)5032*3d8817e4Smiod ieee_add_bb11_blocks (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *data)
5033*3d8817e4Smiod {
5034*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) data;
5035*3d8817e4Smiod   bfd_vma low, high;
5036*3d8817e4Smiod   struct ieee_range *r;
5037*3d8817e4Smiod 
5038*3d8817e4Smiod   low = bfd_get_section_vma (abfd, sec);
5039*3d8817e4Smiod   high = low + bfd_section_size (abfd, sec);
5040*3d8817e4Smiod 
5041*3d8817e4Smiod   /* Find the first range at or after this section.  The ranges are
5042*3d8817e4Smiod      sorted by address.  */
5043*3d8817e4Smiod   for (r = info->global_ranges; r != NULL; r = r->next)
5044*3d8817e4Smiod     if (r->high > low)
5045*3d8817e4Smiod       break;
5046*3d8817e4Smiod 
5047*3d8817e4Smiod   while (low < high)
5048*3d8817e4Smiod     {
5049*3d8817e4Smiod       if (r == NULL || r->low >= high)
5050*3d8817e4Smiod 	{
5051*3d8817e4Smiod 	  if (! ieee_add_bb11 (info, sec, low, high))
5052*3d8817e4Smiod 	    info->error = TRUE;
5053*3d8817e4Smiod 	  return;
5054*3d8817e4Smiod 	}
5055*3d8817e4Smiod 
5056*3d8817e4Smiod       if (low < r->low
5057*3d8817e4Smiod 	  && r->low - low > 0x100)
5058*3d8817e4Smiod 	{
5059*3d8817e4Smiod 	  if (! ieee_add_bb11 (info, sec, low, r->low))
5060*3d8817e4Smiod 	    {
5061*3d8817e4Smiod 	      info->error = TRUE;
5062*3d8817e4Smiod 	      return;
5063*3d8817e4Smiod 	    }
5064*3d8817e4Smiod 	}
5065*3d8817e4Smiod       low = r->high;
5066*3d8817e4Smiod 
5067*3d8817e4Smiod       r = r->next;
5068*3d8817e4Smiod     }
5069*3d8817e4Smiod }
5070*3d8817e4Smiod 
5071*3d8817e4Smiod /* Add a single BB11 block for a range.  We add it to info->vars.  */
5072*3d8817e4Smiod 
5073*3d8817e4Smiod static bfd_boolean
ieee_add_bb11(struct ieee_handle * info,asection * sec,bfd_vma low,bfd_vma high)5074*3d8817e4Smiod ieee_add_bb11 (struct ieee_handle *info, asection *sec, bfd_vma low,
5075*3d8817e4Smiod 	       bfd_vma high)
5076*3d8817e4Smiod {
5077*3d8817e4Smiod   int kind;
5078*3d8817e4Smiod 
5079*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->vars))
5080*3d8817e4Smiod     {
5081*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->vars))
5082*3d8817e4Smiod 	return FALSE;
5083*3d8817e4Smiod     }
5084*3d8817e4Smiod   else
5085*3d8817e4Smiod     {
5086*3d8817e4Smiod       const char *filename, *modname;
5087*3d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
5088*3d8817e4Smiod       const char *backslash;
5089*3d8817e4Smiod #endif
5090*3d8817e4Smiod       char *c, *s;
5091*3d8817e4Smiod 
5092*3d8817e4Smiod       /* Start the enclosing BB10 block.  */
5093*3d8817e4Smiod       filename = bfd_get_filename (info->abfd);
5094*3d8817e4Smiod       modname = strrchr (filename, '/');
5095*3d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
5096*3d8817e4Smiod       backslash = strrchr (filename, '\\');
5097*3d8817e4Smiod       if (modname == NULL || (backslash != NULL && backslash > modname))
5098*3d8817e4Smiod 	modname = backslash;
5099*3d8817e4Smiod #endif
5100*3d8817e4Smiod 
5101*3d8817e4Smiod       if (modname != NULL)
5102*3d8817e4Smiod 	++modname;
5103*3d8817e4Smiod #ifdef HAVE_DOS_BASED_FILE_SYSTEM
5104*3d8817e4Smiod       else if (filename[0] && filename[1] == ':')
5105*3d8817e4Smiod 	modname = filename + 2;
5106*3d8817e4Smiod #endif
5107*3d8817e4Smiod       else
5108*3d8817e4Smiod 	modname = filename;
5109*3d8817e4Smiod 
5110*3d8817e4Smiod       c = xstrdup (modname);
5111*3d8817e4Smiod       s = strrchr (c, '.');
5112*3d8817e4Smiod       if (s != NULL)
5113*3d8817e4Smiod 	*s = '\0';
5114*3d8817e4Smiod 
5115*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->vars)
5116*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
5117*3d8817e4Smiod 	  || ! ieee_write_byte (info, 10)
5118*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
5119*3d8817e4Smiod 	  || ! ieee_write_id (info, c)
5120*3d8817e4Smiod 	  || ! ieee_write_id (info, "")
5121*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
5122*3d8817e4Smiod 	  || ! ieee_write_id (info, "GNU objcopy"))
5123*3d8817e4Smiod 	return FALSE;
5124*3d8817e4Smiod 
5125*3d8817e4Smiod       free (c);
5126*3d8817e4Smiod     }
5127*3d8817e4Smiod 
5128*3d8817e4Smiod   if ((sec->flags & SEC_CODE) != 0)
5129*3d8817e4Smiod     kind = 1;
5130*3d8817e4Smiod   else if ((sec->flags & SEC_READONLY) != 0)
5131*3d8817e4Smiod     kind = 3;
5132*3d8817e4Smiod   else
5133*3d8817e4Smiod     kind = 2;
5134*3d8817e4Smiod 
5135*3d8817e4Smiod   if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
5136*3d8817e4Smiod       || ! ieee_write_byte (info, 11)
5137*3d8817e4Smiod       || ! ieee_write_number (info, 0)
5138*3d8817e4Smiod       || ! ieee_write_id (info, "")
5139*3d8817e4Smiod       || ! ieee_write_number (info, kind)
5140*3d8817e4Smiod       || ! ieee_write_number (info, sec->index + IEEE_SECTION_NUMBER_BASE)
5141*3d8817e4Smiod       || ! ieee_write_number (info, low)
5142*3d8817e4Smiod       || ! ieee_write_byte (info, (int) ieee_be_record_enum)
5143*3d8817e4Smiod       || ! ieee_write_number (info, high - low))
5144*3d8817e4Smiod     return FALSE;
5145*3d8817e4Smiod 
5146*3d8817e4Smiod   return TRUE;
5147*3d8817e4Smiod }
5148*3d8817e4Smiod 
5149*3d8817e4Smiod /* Start recording information from a particular source file.  This is
5150*3d8817e4Smiod    used to record which file defined which types, variables, etc.  It
5151*3d8817e4Smiod    is not used for line numbers, since the lineno entry point passes
5152*3d8817e4Smiod    down the file name anyhow.  IEEE debugging information doesn't seem
5153*3d8817e4Smiod    to store this information anywhere.  */
5154*3d8817e4Smiod 
5155*3d8817e4Smiod static bfd_boolean
ieee_start_source(void * p ATTRIBUTE_UNUSED,const char * filename ATTRIBUTE_UNUSED)5156*3d8817e4Smiod ieee_start_source (void *p ATTRIBUTE_UNUSED,
5157*3d8817e4Smiod 		   const char *filename ATTRIBUTE_UNUSED)
5158*3d8817e4Smiod {
5159*3d8817e4Smiod   return TRUE;
5160*3d8817e4Smiod }
5161*3d8817e4Smiod 
5162*3d8817e4Smiod /* Make an empty type.  */
5163*3d8817e4Smiod 
5164*3d8817e4Smiod static bfd_boolean
ieee_empty_type(void * p)5165*3d8817e4Smiod ieee_empty_type (void *p)
5166*3d8817e4Smiod {
5167*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5168*3d8817e4Smiod 
5169*3d8817e4Smiod   return ieee_push_type (info, (int) builtin_unknown, 0, FALSE, FALSE);
5170*3d8817e4Smiod }
5171*3d8817e4Smiod 
5172*3d8817e4Smiod /* Make a void type.  */
5173*3d8817e4Smiod 
5174*3d8817e4Smiod static bfd_boolean
ieee_void_type(void * p)5175*3d8817e4Smiod ieee_void_type (void *p)
5176*3d8817e4Smiod {
5177*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5178*3d8817e4Smiod 
5179*3d8817e4Smiod   return ieee_push_type (info, (int) builtin_void, 0, FALSE, FALSE);
5180*3d8817e4Smiod }
5181*3d8817e4Smiod 
5182*3d8817e4Smiod /* Make an integer type.  */
5183*3d8817e4Smiod 
5184*3d8817e4Smiod static bfd_boolean
ieee_int_type(void * p,unsigned int size,bfd_boolean unsignedp)5185*3d8817e4Smiod ieee_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
5186*3d8817e4Smiod {
5187*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5188*3d8817e4Smiod   unsigned int indx;
5189*3d8817e4Smiod 
5190*3d8817e4Smiod   switch (size)
5191*3d8817e4Smiod     {
5192*3d8817e4Smiod     case 1:
5193*3d8817e4Smiod       indx = (int) builtin_signed_char;
5194*3d8817e4Smiod       break;
5195*3d8817e4Smiod     case 2:
5196*3d8817e4Smiod       indx = (int) builtin_signed_short_int;
5197*3d8817e4Smiod       break;
5198*3d8817e4Smiod     case 4:
5199*3d8817e4Smiod       indx = (int) builtin_signed_long;
5200*3d8817e4Smiod       break;
5201*3d8817e4Smiod     case 8:
5202*3d8817e4Smiod       indx = (int) builtin_signed_long_long;
5203*3d8817e4Smiod       break;
5204*3d8817e4Smiod     default:
5205*3d8817e4Smiod       fprintf (stderr, _("IEEE unsupported integer type size %u\n"), size);
5206*3d8817e4Smiod       return FALSE;
5207*3d8817e4Smiod     }
5208*3d8817e4Smiod 
5209*3d8817e4Smiod   if (unsignedp)
5210*3d8817e4Smiod     ++indx;
5211*3d8817e4Smiod 
5212*3d8817e4Smiod   return ieee_push_type (info, indx, size, unsignedp, FALSE);
5213*3d8817e4Smiod }
5214*3d8817e4Smiod 
5215*3d8817e4Smiod /* Make a floating point type.  */
5216*3d8817e4Smiod 
5217*3d8817e4Smiod static bfd_boolean
ieee_float_type(void * p,unsigned int size)5218*3d8817e4Smiod ieee_float_type (void *p, unsigned int size)
5219*3d8817e4Smiod {
5220*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5221*3d8817e4Smiod   unsigned int indx;
5222*3d8817e4Smiod 
5223*3d8817e4Smiod   switch (size)
5224*3d8817e4Smiod     {
5225*3d8817e4Smiod     case 4:
5226*3d8817e4Smiod       indx = (int) builtin_float;
5227*3d8817e4Smiod       break;
5228*3d8817e4Smiod     case 8:
5229*3d8817e4Smiod       indx = (int) builtin_double;
5230*3d8817e4Smiod       break;
5231*3d8817e4Smiod     case 12:
5232*3d8817e4Smiod       /* FIXME: This size really depends upon the processor.  */
5233*3d8817e4Smiod       indx = (int) builtin_long_double;
5234*3d8817e4Smiod       break;
5235*3d8817e4Smiod     case 16:
5236*3d8817e4Smiod       indx = (int) builtin_long_long_double;
5237*3d8817e4Smiod       break;
5238*3d8817e4Smiod     default:
5239*3d8817e4Smiod       fprintf (stderr, _("IEEE unsupported float type size %u\n"), size);
5240*3d8817e4Smiod       return FALSE;
5241*3d8817e4Smiod     }
5242*3d8817e4Smiod 
5243*3d8817e4Smiod   return ieee_push_type (info, indx, size, FALSE, FALSE);
5244*3d8817e4Smiod }
5245*3d8817e4Smiod 
5246*3d8817e4Smiod /* Make a complex type.  */
5247*3d8817e4Smiod 
5248*3d8817e4Smiod static bfd_boolean
ieee_complex_type(void * p,unsigned int size)5249*3d8817e4Smiod ieee_complex_type (void *p, unsigned int size)
5250*3d8817e4Smiod {
5251*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5252*3d8817e4Smiod   char code;
5253*3d8817e4Smiod 
5254*3d8817e4Smiod   switch (size)
5255*3d8817e4Smiod     {
5256*3d8817e4Smiod     case 4:
5257*3d8817e4Smiod       if (info->complex_float_index != 0)
5258*3d8817e4Smiod 	return ieee_push_type (info, info->complex_float_index, size * 2,
5259*3d8817e4Smiod 			       FALSE, FALSE);
5260*3d8817e4Smiod       code = 'c';
5261*3d8817e4Smiod       break;
5262*3d8817e4Smiod     case 12:
5263*3d8817e4Smiod     case 16:
5264*3d8817e4Smiod       /* These cases can be output by gcc -gstabs.  Outputting the
5265*3d8817e4Smiod          wrong type is better than crashing.  */
5266*3d8817e4Smiod     case 8:
5267*3d8817e4Smiod       if (info->complex_double_index != 0)
5268*3d8817e4Smiod 	return ieee_push_type (info, info->complex_double_index, size * 2,
5269*3d8817e4Smiod 			       FALSE, FALSE);
5270*3d8817e4Smiod       code = 'd';
5271*3d8817e4Smiod       break;
5272*3d8817e4Smiod     default:
5273*3d8817e4Smiod       fprintf (stderr, _("IEEE unsupported complex type size %u\n"), size);
5274*3d8817e4Smiod       return FALSE;
5275*3d8817e4Smiod     }
5276*3d8817e4Smiod 
5277*3d8817e4Smiod   /* FIXME: I don't know what the string is for.  */
5278*3d8817e4Smiod   if (! ieee_define_type (info, size * 2, FALSE, FALSE)
5279*3d8817e4Smiod       || ! ieee_write_number (info, code)
5280*3d8817e4Smiod       || ! ieee_write_id (info, ""))
5281*3d8817e4Smiod     return FALSE;
5282*3d8817e4Smiod 
5283*3d8817e4Smiod   if (size == 4)
5284*3d8817e4Smiod     info->complex_float_index = info->type_stack->type.indx;
5285*3d8817e4Smiod   else
5286*3d8817e4Smiod     info->complex_double_index = info->type_stack->type.indx;
5287*3d8817e4Smiod 
5288*3d8817e4Smiod   return TRUE;
5289*3d8817e4Smiod }
5290*3d8817e4Smiod 
5291*3d8817e4Smiod /* Make a boolean type.  IEEE doesn't support these, so we just make
5292*3d8817e4Smiod    an integer type instead.  */
5293*3d8817e4Smiod 
5294*3d8817e4Smiod static bfd_boolean
ieee_bool_type(void * p,unsigned int size)5295*3d8817e4Smiod ieee_bool_type (void *p, unsigned int size)
5296*3d8817e4Smiod {
5297*3d8817e4Smiod   return ieee_int_type (p, size, TRUE);
5298*3d8817e4Smiod }
5299*3d8817e4Smiod 
5300*3d8817e4Smiod /* Make an enumeration.  */
5301*3d8817e4Smiod 
5302*3d8817e4Smiod static bfd_boolean
ieee_enum_type(void * p,const char * tag,const char ** names,bfd_signed_vma * vals)5303*3d8817e4Smiod ieee_enum_type (void *p, const char *tag, const char **names,
5304*3d8817e4Smiod 		bfd_signed_vma *vals)
5305*3d8817e4Smiod {
5306*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5307*3d8817e4Smiod   struct ieee_defined_enum *e;
5308*3d8817e4Smiod   bfd_boolean localp, simple;
5309*3d8817e4Smiod   unsigned int indx;
5310*3d8817e4Smiod   int i = 0;
5311*3d8817e4Smiod 
5312*3d8817e4Smiod   localp = FALSE;
5313*3d8817e4Smiod   indx = (unsigned int) -1;
5314*3d8817e4Smiod   for (e = info->enums; e != NULL; e = e->next)
5315*3d8817e4Smiod     {
5316*3d8817e4Smiod       if (tag == NULL)
5317*3d8817e4Smiod 	{
5318*3d8817e4Smiod 	  if (e->tag != NULL)
5319*3d8817e4Smiod 	    continue;
5320*3d8817e4Smiod 	}
5321*3d8817e4Smiod       else
5322*3d8817e4Smiod 	{
5323*3d8817e4Smiod 	  if (e->tag == NULL
5324*3d8817e4Smiod 	      || tag[0] != e->tag[0]
5325*3d8817e4Smiod 	      || strcmp (tag, e->tag) != 0)
5326*3d8817e4Smiod 	    continue;
5327*3d8817e4Smiod 	}
5328*3d8817e4Smiod 
5329*3d8817e4Smiod       if (! e->defined)
5330*3d8817e4Smiod 	{
5331*3d8817e4Smiod 	  /* This enum tag has been seen but not defined.  */
5332*3d8817e4Smiod 	  indx = e->indx;
5333*3d8817e4Smiod 	  break;
5334*3d8817e4Smiod 	}
5335*3d8817e4Smiod 
5336*3d8817e4Smiod       if (names != NULL && e->names != NULL)
5337*3d8817e4Smiod 	{
5338*3d8817e4Smiod 	  for (i = 0; names[i] != NULL && e->names[i] != NULL; i++)
5339*3d8817e4Smiod 	    {
5340*3d8817e4Smiod 	      if (names[i][0] != e->names[i][0]
5341*3d8817e4Smiod 		  || vals[i] != e->vals[i]
5342*3d8817e4Smiod 		  || strcmp (names[i], e->names[i]) != 0)
5343*3d8817e4Smiod 		break;
5344*3d8817e4Smiod 	    }
5345*3d8817e4Smiod 	}
5346*3d8817e4Smiod 
5347*3d8817e4Smiod       if ((names == NULL && e->names == NULL)
5348*3d8817e4Smiod 	  || (names != NULL
5349*3d8817e4Smiod 	      && e->names != NULL
5350*3d8817e4Smiod 	      && names[i] == NULL
5351*3d8817e4Smiod 	      && e->names[i] == NULL))
5352*3d8817e4Smiod 	{
5353*3d8817e4Smiod 	  /* We've seen this enum before.  */
5354*3d8817e4Smiod 	  return ieee_push_type (info, e->indx, 0, TRUE, FALSE);
5355*3d8817e4Smiod 	}
5356*3d8817e4Smiod 
5357*3d8817e4Smiod       if (tag != NULL)
5358*3d8817e4Smiod 	{
5359*3d8817e4Smiod 	  /* We've already seen an enum of the same name, so we must make
5360*3d8817e4Smiod 	     sure to output this one locally.  */
5361*3d8817e4Smiod 	  localp = TRUE;
5362*3d8817e4Smiod 	  break;
5363*3d8817e4Smiod 	}
5364*3d8817e4Smiod     }
5365*3d8817e4Smiod 
5366*3d8817e4Smiod   /* If this is a simple enumeration, in which the values start at 0
5367*3d8817e4Smiod      and always increment by 1, we can use type E.  Otherwise we must
5368*3d8817e4Smiod      use type N.  */
5369*3d8817e4Smiod 
5370*3d8817e4Smiod   simple = TRUE;
5371*3d8817e4Smiod   if (names != NULL)
5372*3d8817e4Smiod     {
5373*3d8817e4Smiod       for (i = 0; names[i] != NULL; i++)
5374*3d8817e4Smiod 	{
5375*3d8817e4Smiod 	  if (vals[i] != i)
5376*3d8817e4Smiod 	    {
5377*3d8817e4Smiod 	      simple = FALSE;
5378*3d8817e4Smiod 	      break;
5379*3d8817e4Smiod 	    }
5380*3d8817e4Smiod 	}
5381*3d8817e4Smiod     }
5382*3d8817e4Smiod 
5383*3d8817e4Smiod   if (! ieee_define_named_type (info, tag, indx, 0, TRUE, localp,
5384*3d8817e4Smiod 				(struct ieee_buflist *) NULL)
5385*3d8817e4Smiod       || ! ieee_write_number (info, simple ? 'E' : 'N'))
5386*3d8817e4Smiod     return FALSE;
5387*3d8817e4Smiod   if (simple)
5388*3d8817e4Smiod     {
5389*3d8817e4Smiod       /* FIXME: This is supposed to be the enumeration size, but we
5390*3d8817e4Smiod          don't store that.  */
5391*3d8817e4Smiod       if (! ieee_write_number (info, 4))
5392*3d8817e4Smiod 	return FALSE;
5393*3d8817e4Smiod     }
5394*3d8817e4Smiod   if (names != NULL)
5395*3d8817e4Smiod     {
5396*3d8817e4Smiod       for (i = 0; names[i] != NULL; i++)
5397*3d8817e4Smiod 	{
5398*3d8817e4Smiod 	  if (! ieee_write_id (info, names[i]))
5399*3d8817e4Smiod 	    return FALSE;
5400*3d8817e4Smiod 	  if (! simple)
5401*3d8817e4Smiod 	    {
5402*3d8817e4Smiod 	      if (! ieee_write_number (info, vals[i]))
5403*3d8817e4Smiod 		return FALSE;
5404*3d8817e4Smiod 	    }
5405*3d8817e4Smiod 	}
5406*3d8817e4Smiod     }
5407*3d8817e4Smiod 
5408*3d8817e4Smiod   if (! localp)
5409*3d8817e4Smiod     {
5410*3d8817e4Smiod       if (indx == (unsigned int) -1)
5411*3d8817e4Smiod 	{
5412*3d8817e4Smiod 	  e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
5413*3d8817e4Smiod 	  memset (e, 0, sizeof *e);
5414*3d8817e4Smiod 	  e->indx = info->type_stack->type.indx;
5415*3d8817e4Smiod 	  e->tag = tag;
5416*3d8817e4Smiod 
5417*3d8817e4Smiod 	  e->next = info->enums;
5418*3d8817e4Smiod 	  info->enums = e;
5419*3d8817e4Smiod 	}
5420*3d8817e4Smiod 
5421*3d8817e4Smiod       e->names = names;
5422*3d8817e4Smiod       e->vals = vals;
5423*3d8817e4Smiod       e->defined = TRUE;
5424*3d8817e4Smiod     }
5425*3d8817e4Smiod 
5426*3d8817e4Smiod   return TRUE;
5427*3d8817e4Smiod }
5428*3d8817e4Smiod 
5429*3d8817e4Smiod /* Make a pointer type.  */
5430*3d8817e4Smiod 
5431*3d8817e4Smiod static bfd_boolean
ieee_pointer_type(void * p)5432*3d8817e4Smiod ieee_pointer_type (void *p)
5433*3d8817e4Smiod {
5434*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5435*3d8817e4Smiod   bfd_boolean localp;
5436*3d8817e4Smiod   unsigned int indx;
5437*3d8817e4Smiod   struct ieee_modified_type *m = NULL;
5438*3d8817e4Smiod 
5439*3d8817e4Smiod   localp = info->type_stack->type.localp;
5440*3d8817e4Smiod   indx = ieee_pop_type (info);
5441*3d8817e4Smiod 
5442*3d8817e4Smiod   /* A pointer to a simple builtin type can be obtained by adding 32.
5443*3d8817e4Smiod      FIXME: Will this be a short pointer, and will that matter?  */
5444*3d8817e4Smiod   if (indx < 32)
5445*3d8817e4Smiod     return ieee_push_type (info, indx + 32, 0, TRUE, FALSE);
5446*3d8817e4Smiod 
5447*3d8817e4Smiod   if (! localp)
5448*3d8817e4Smiod     {
5449*3d8817e4Smiod       m = ieee_get_modified_info (p, indx);
5450*3d8817e4Smiod       if (m == NULL)
5451*3d8817e4Smiod 	return FALSE;
5452*3d8817e4Smiod 
5453*3d8817e4Smiod       /* FIXME: The size should depend upon the architecture.  */
5454*3d8817e4Smiod       if (m->pointer > 0)
5455*3d8817e4Smiod 	return ieee_push_type (info, m->pointer, 4, TRUE, FALSE);
5456*3d8817e4Smiod     }
5457*3d8817e4Smiod 
5458*3d8817e4Smiod   if (! ieee_define_type (info, 4, TRUE, localp)
5459*3d8817e4Smiod       || ! ieee_write_number (info, 'P')
5460*3d8817e4Smiod       || ! ieee_write_number (info, indx))
5461*3d8817e4Smiod     return FALSE;
5462*3d8817e4Smiod 
5463*3d8817e4Smiod   if (! localp)
5464*3d8817e4Smiod     m->pointer = info->type_stack->type.indx;
5465*3d8817e4Smiod 
5466*3d8817e4Smiod   return TRUE;
5467*3d8817e4Smiod }
5468*3d8817e4Smiod 
5469*3d8817e4Smiod /* Make a function type.  This will be called for a method, but we
5470*3d8817e4Smiod    don't want to actually add it to the type table in that case.  We
5471*3d8817e4Smiod    handle this by defining the type in a private buffer, and only
5472*3d8817e4Smiod    adding that buffer to the typedef block if we are going to use it.  */
5473*3d8817e4Smiod 
5474*3d8817e4Smiod static bfd_boolean
ieee_function_type(void * p,int argcount,bfd_boolean varargs)5475*3d8817e4Smiod ieee_function_type (void *p, int argcount, bfd_boolean varargs)
5476*3d8817e4Smiod {
5477*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5478*3d8817e4Smiod   bfd_boolean localp;
5479*3d8817e4Smiod   unsigned int *args = NULL;
5480*3d8817e4Smiod   int i;
5481*3d8817e4Smiod   unsigned int retindx;
5482*3d8817e4Smiod   struct ieee_buflist fndef;
5483*3d8817e4Smiod   struct ieee_modified_type *m;
5484*3d8817e4Smiod 
5485*3d8817e4Smiod   localp = FALSE;
5486*3d8817e4Smiod 
5487*3d8817e4Smiod   if (argcount > 0)
5488*3d8817e4Smiod     {
5489*3d8817e4Smiod       args = (unsigned int *) xmalloc (argcount * sizeof *args);
5490*3d8817e4Smiod       for (i = argcount - 1; i >= 0; i--)
5491*3d8817e4Smiod 	{
5492*3d8817e4Smiod 	  if (info->type_stack->type.localp)
5493*3d8817e4Smiod 	    localp = TRUE;
5494*3d8817e4Smiod 	  args[i] = ieee_pop_type (info);
5495*3d8817e4Smiod 	}
5496*3d8817e4Smiod     }
5497*3d8817e4Smiod   else if (argcount < 0)
5498*3d8817e4Smiod     varargs = FALSE;
5499*3d8817e4Smiod 
5500*3d8817e4Smiod   if (info->type_stack->type.localp)
5501*3d8817e4Smiod     localp = TRUE;
5502*3d8817e4Smiod   retindx = ieee_pop_type (info);
5503*3d8817e4Smiod 
5504*3d8817e4Smiod   m = NULL;
5505*3d8817e4Smiod   if (argcount < 0 && ! localp)
5506*3d8817e4Smiod     {
5507*3d8817e4Smiod       m = ieee_get_modified_info (p, retindx);
5508*3d8817e4Smiod       if (m == NULL)
5509*3d8817e4Smiod 	return FALSE;
5510*3d8817e4Smiod 
5511*3d8817e4Smiod       if (m->function > 0)
5512*3d8817e4Smiod 	return ieee_push_type (info, m->function, 0, TRUE, FALSE);
5513*3d8817e4Smiod     }
5514*3d8817e4Smiod 
5515*3d8817e4Smiod   /* An attribute of 0x41 means that the frame and push mask are
5516*3d8817e4Smiod      unknown.  */
5517*3d8817e4Smiod   if (! ieee_init_buffer (info, &fndef)
5518*3d8817e4Smiod       || ! ieee_define_named_type (info, (const char *) NULL,
5519*3d8817e4Smiod 				   (unsigned int) -1, 0, TRUE, localp,
5520*3d8817e4Smiod 				   &fndef)
5521*3d8817e4Smiod       || ! ieee_write_number (info, 'x')
5522*3d8817e4Smiod       || ! ieee_write_number (info, 0x41)
5523*3d8817e4Smiod       || ! ieee_write_number (info, 0)
5524*3d8817e4Smiod       || ! ieee_write_number (info, 0)
5525*3d8817e4Smiod       || ! ieee_write_number (info, retindx)
5526*3d8817e4Smiod       || ! ieee_write_number (info, (bfd_vma) argcount + (varargs ? 1 : 0)))
5527*3d8817e4Smiod     return FALSE;
5528*3d8817e4Smiod   if (argcount > 0)
5529*3d8817e4Smiod     {
5530*3d8817e4Smiod       for (i = 0; i < argcount; i++)
5531*3d8817e4Smiod 	if (! ieee_write_number (info, args[i]))
5532*3d8817e4Smiod 	  return FALSE;
5533*3d8817e4Smiod       free (args);
5534*3d8817e4Smiod     }
5535*3d8817e4Smiod   if (varargs)
5536*3d8817e4Smiod     {
5537*3d8817e4Smiod       /* A varargs function is represented by writing out the last
5538*3d8817e4Smiod          argument as type void *, although this makes little sense.  */
5539*3d8817e4Smiod       if (! ieee_write_number (info, (bfd_vma) builtin_void + 32))
5540*3d8817e4Smiod 	return FALSE;
5541*3d8817e4Smiod     }
5542*3d8817e4Smiod 
5543*3d8817e4Smiod   if (! ieee_write_number (info, 0))
5544*3d8817e4Smiod     return FALSE;
5545*3d8817e4Smiod 
5546*3d8817e4Smiod   /* We wrote the information into fndef, in case we don't need it.
5547*3d8817e4Smiod      It will be appended to info->types by ieee_pop_type.  */
5548*3d8817e4Smiod   info->type_stack->type.fndef = fndef;
5549*3d8817e4Smiod 
5550*3d8817e4Smiod   if (m != NULL)
5551*3d8817e4Smiod     m->function = info->type_stack->type.indx;
5552*3d8817e4Smiod 
5553*3d8817e4Smiod   return TRUE;
5554*3d8817e4Smiod }
5555*3d8817e4Smiod 
5556*3d8817e4Smiod /* Make a reference type.  */
5557*3d8817e4Smiod 
5558*3d8817e4Smiod static bfd_boolean
ieee_reference_type(void * p)5559*3d8817e4Smiod ieee_reference_type (void *p)
5560*3d8817e4Smiod {
5561*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5562*3d8817e4Smiod 
5563*3d8817e4Smiod   /* IEEE appears to record a normal pointer type, and then use a
5564*3d8817e4Smiod      pmisc record to indicate that it is really a reference.  */
5565*3d8817e4Smiod 
5566*3d8817e4Smiod   if (! ieee_pointer_type (p))
5567*3d8817e4Smiod     return FALSE;
5568*3d8817e4Smiod   info->type_stack->type.referencep = TRUE;
5569*3d8817e4Smiod   return TRUE;
5570*3d8817e4Smiod }
5571*3d8817e4Smiod 
5572*3d8817e4Smiod /* Make a range type.  */
5573*3d8817e4Smiod 
5574*3d8817e4Smiod static bfd_boolean
ieee_range_type(void * p,bfd_signed_vma low,bfd_signed_vma high)5575*3d8817e4Smiod ieee_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high)
5576*3d8817e4Smiod {
5577*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5578*3d8817e4Smiod   unsigned int size;
5579*3d8817e4Smiod   bfd_boolean unsignedp, localp;
5580*3d8817e4Smiod 
5581*3d8817e4Smiod   size = info->type_stack->type.size;
5582*3d8817e4Smiod   unsignedp = info->type_stack->type.unsignedp;
5583*3d8817e4Smiod   localp = info->type_stack->type.localp;
5584*3d8817e4Smiod   ieee_pop_unused_type (info);
5585*3d8817e4Smiod   return (ieee_define_type (info, size, unsignedp, localp)
5586*3d8817e4Smiod 	  && ieee_write_number (info, 'R')
5587*3d8817e4Smiod 	  && ieee_write_number (info, (bfd_vma) low)
5588*3d8817e4Smiod 	  && ieee_write_number (info, (bfd_vma) high)
5589*3d8817e4Smiod 	  && ieee_write_number (info, unsignedp ? 0 : 1)
5590*3d8817e4Smiod 	  && ieee_write_number (info, size));
5591*3d8817e4Smiod }
5592*3d8817e4Smiod 
5593*3d8817e4Smiod /* Make an array type.  */
5594*3d8817e4Smiod 
5595*3d8817e4Smiod static bfd_boolean
ieee_array_type(void * p,bfd_signed_vma low,bfd_signed_vma high,bfd_boolean stringp ATTRIBUTE_UNUSED)5596*3d8817e4Smiod ieee_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high,
5597*3d8817e4Smiod 		 bfd_boolean stringp ATTRIBUTE_UNUSED)
5598*3d8817e4Smiod {
5599*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5600*3d8817e4Smiod   unsigned int eleindx;
5601*3d8817e4Smiod   bfd_boolean localp;
5602*3d8817e4Smiod   unsigned int size;
5603*3d8817e4Smiod   struct ieee_modified_type *m = NULL;
5604*3d8817e4Smiod   struct ieee_modified_array_type *a;
5605*3d8817e4Smiod 
5606*3d8817e4Smiod   /* IEEE does not store the range, so we just ignore it.  */
5607*3d8817e4Smiod   ieee_pop_unused_type (info);
5608*3d8817e4Smiod   localp = info->type_stack->type.localp;
5609*3d8817e4Smiod   size = info->type_stack->type.size;
5610*3d8817e4Smiod   eleindx = ieee_pop_type (info);
5611*3d8817e4Smiod 
5612*3d8817e4Smiod   /* If we don't know the range, treat the size as exactly one
5613*3d8817e4Smiod      element.  */
5614*3d8817e4Smiod   if (low < high)
5615*3d8817e4Smiod     size *= (high - low) + 1;
5616*3d8817e4Smiod 
5617*3d8817e4Smiod   if (! localp)
5618*3d8817e4Smiod     {
5619*3d8817e4Smiod       m = ieee_get_modified_info (info, eleindx);
5620*3d8817e4Smiod       if (m == NULL)
5621*3d8817e4Smiod 	return FALSE;
5622*3d8817e4Smiod 
5623*3d8817e4Smiod       for (a = m->arrays; a != NULL; a = a->next)
5624*3d8817e4Smiod 	{
5625*3d8817e4Smiod 	  if (a->low == low && a->high == high)
5626*3d8817e4Smiod 	    return ieee_push_type (info, a->indx, size, FALSE, FALSE);
5627*3d8817e4Smiod 	}
5628*3d8817e4Smiod     }
5629*3d8817e4Smiod 
5630*3d8817e4Smiod   if (! ieee_define_type (info, size, FALSE, localp)
5631*3d8817e4Smiod       || ! ieee_write_number (info, low == 0 ? 'Z' : 'C')
5632*3d8817e4Smiod       || ! ieee_write_number (info, eleindx))
5633*3d8817e4Smiod     return FALSE;
5634*3d8817e4Smiod   if (low != 0)
5635*3d8817e4Smiod     {
5636*3d8817e4Smiod       if (! ieee_write_number (info, low))
5637*3d8817e4Smiod 	return FALSE;
5638*3d8817e4Smiod     }
5639*3d8817e4Smiod 
5640*3d8817e4Smiod   if (! ieee_write_number (info, high + 1))
5641*3d8817e4Smiod     return FALSE;
5642*3d8817e4Smiod 
5643*3d8817e4Smiod   if (! localp)
5644*3d8817e4Smiod     {
5645*3d8817e4Smiod       a = (struct ieee_modified_array_type *) xmalloc (sizeof *a);
5646*3d8817e4Smiod       memset (a, 0, sizeof *a);
5647*3d8817e4Smiod 
5648*3d8817e4Smiod       a->indx = info->type_stack->type.indx;
5649*3d8817e4Smiod       a->low = low;
5650*3d8817e4Smiod       a->high = high;
5651*3d8817e4Smiod 
5652*3d8817e4Smiod       a->next = m->arrays;
5653*3d8817e4Smiod       m->arrays = a;
5654*3d8817e4Smiod     }
5655*3d8817e4Smiod 
5656*3d8817e4Smiod   return TRUE;
5657*3d8817e4Smiod }
5658*3d8817e4Smiod 
5659*3d8817e4Smiod /* Make a set type.  */
5660*3d8817e4Smiod 
5661*3d8817e4Smiod static bfd_boolean
ieee_set_type(void * p,bfd_boolean bitstringp ATTRIBUTE_UNUSED)5662*3d8817e4Smiod ieee_set_type (void *p, bfd_boolean bitstringp ATTRIBUTE_UNUSED)
5663*3d8817e4Smiod {
5664*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5665*3d8817e4Smiod   bfd_boolean localp;
5666*3d8817e4Smiod   unsigned int eleindx;
5667*3d8817e4Smiod 
5668*3d8817e4Smiod   localp = info->type_stack->type.localp;
5669*3d8817e4Smiod   eleindx = ieee_pop_type (info);
5670*3d8817e4Smiod 
5671*3d8817e4Smiod   /* FIXME: We don't know the size, so we just use 4.  */
5672*3d8817e4Smiod 
5673*3d8817e4Smiod   return (ieee_define_type (info, 0, TRUE, localp)
5674*3d8817e4Smiod 	  && ieee_write_number (info, 's')
5675*3d8817e4Smiod 	  && ieee_write_number (info, 4)
5676*3d8817e4Smiod 	  && ieee_write_number (info, eleindx));
5677*3d8817e4Smiod }
5678*3d8817e4Smiod 
5679*3d8817e4Smiod /* Make an offset type.  */
5680*3d8817e4Smiod 
5681*3d8817e4Smiod static bfd_boolean
ieee_offset_type(void * p)5682*3d8817e4Smiod ieee_offset_type (void *p)
5683*3d8817e4Smiod {
5684*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5685*3d8817e4Smiod   unsigned int targetindx, baseindx;
5686*3d8817e4Smiod 
5687*3d8817e4Smiod   targetindx = ieee_pop_type (info);
5688*3d8817e4Smiod   baseindx = ieee_pop_type (info);
5689*3d8817e4Smiod 
5690*3d8817e4Smiod   /* FIXME: The MRI C++ compiler does not appear to generate any
5691*3d8817e4Smiod      useful type information about an offset type.  It just records a
5692*3d8817e4Smiod      pointer to member as an integer.  The MRI/HP IEEE spec does
5693*3d8817e4Smiod      describe a pmisc record which can be used for a pointer to
5694*3d8817e4Smiod      member.  Unfortunately, it does not describe the target type,
5695*3d8817e4Smiod      which seems pretty important.  I'm going to punt this for now.  */
5696*3d8817e4Smiod 
5697*3d8817e4Smiod   return ieee_int_type (p, 4, TRUE);
5698*3d8817e4Smiod }
5699*3d8817e4Smiod 
5700*3d8817e4Smiod /* Make a method type.  */
5701*3d8817e4Smiod 
5702*3d8817e4Smiod static bfd_boolean
ieee_method_type(void * p,bfd_boolean domain,int argcount,bfd_boolean varargs)5703*3d8817e4Smiod ieee_method_type (void *p, bfd_boolean domain, int argcount,
5704*3d8817e4Smiod 		  bfd_boolean varargs)
5705*3d8817e4Smiod {
5706*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5707*3d8817e4Smiod 
5708*3d8817e4Smiod   /* FIXME: The MRI/HP IEEE spec defines a pmisc record to use for a
5709*3d8817e4Smiod      method, but the definition is incomplete.  We just output an 'x'
5710*3d8817e4Smiod      type.  */
5711*3d8817e4Smiod 
5712*3d8817e4Smiod   if (domain)
5713*3d8817e4Smiod     ieee_pop_unused_type (info);
5714*3d8817e4Smiod 
5715*3d8817e4Smiod   return ieee_function_type (p, argcount, varargs);
5716*3d8817e4Smiod }
5717*3d8817e4Smiod 
5718*3d8817e4Smiod /* Make a const qualified type.  */
5719*3d8817e4Smiod 
5720*3d8817e4Smiod static bfd_boolean
ieee_const_type(void * p)5721*3d8817e4Smiod ieee_const_type (void *p)
5722*3d8817e4Smiod {
5723*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5724*3d8817e4Smiod   unsigned int size;
5725*3d8817e4Smiod   bfd_boolean unsignedp, localp;
5726*3d8817e4Smiod   unsigned int indx;
5727*3d8817e4Smiod   struct ieee_modified_type *m = NULL;
5728*3d8817e4Smiod 
5729*3d8817e4Smiod   size = info->type_stack->type.size;
5730*3d8817e4Smiod   unsignedp = info->type_stack->type.unsignedp;
5731*3d8817e4Smiod   localp = info->type_stack->type.localp;
5732*3d8817e4Smiod   indx = ieee_pop_type (info);
5733*3d8817e4Smiod 
5734*3d8817e4Smiod   if (! localp)
5735*3d8817e4Smiod     {
5736*3d8817e4Smiod       m = ieee_get_modified_info (info, indx);
5737*3d8817e4Smiod       if (m == NULL)
5738*3d8817e4Smiod 	return FALSE;
5739*3d8817e4Smiod 
5740*3d8817e4Smiod       if (m->const_qualified > 0)
5741*3d8817e4Smiod 	return ieee_push_type (info, m->const_qualified, size, unsignedp,
5742*3d8817e4Smiod 			       FALSE);
5743*3d8817e4Smiod     }
5744*3d8817e4Smiod 
5745*3d8817e4Smiod   if (! ieee_define_type (info, size, unsignedp, localp)
5746*3d8817e4Smiod       || ! ieee_write_number (info, 'n')
5747*3d8817e4Smiod       || ! ieee_write_number (info, 1)
5748*3d8817e4Smiod       || ! ieee_write_number (info, indx))
5749*3d8817e4Smiod     return FALSE;
5750*3d8817e4Smiod 
5751*3d8817e4Smiod   if (! localp)
5752*3d8817e4Smiod     m->const_qualified = info->type_stack->type.indx;
5753*3d8817e4Smiod 
5754*3d8817e4Smiod   return TRUE;
5755*3d8817e4Smiod }
5756*3d8817e4Smiod 
5757*3d8817e4Smiod /* Make a volatile qualified type.  */
5758*3d8817e4Smiod 
5759*3d8817e4Smiod static bfd_boolean
ieee_volatile_type(void * p)5760*3d8817e4Smiod ieee_volatile_type (void *p)
5761*3d8817e4Smiod {
5762*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5763*3d8817e4Smiod   unsigned int size;
5764*3d8817e4Smiod   bfd_boolean unsignedp, localp;
5765*3d8817e4Smiod   unsigned int indx;
5766*3d8817e4Smiod   struct ieee_modified_type *m = NULL;
5767*3d8817e4Smiod 
5768*3d8817e4Smiod   size = info->type_stack->type.size;
5769*3d8817e4Smiod   unsignedp = info->type_stack->type.unsignedp;
5770*3d8817e4Smiod   localp = info->type_stack->type.localp;
5771*3d8817e4Smiod   indx = ieee_pop_type (info);
5772*3d8817e4Smiod 
5773*3d8817e4Smiod   if (! localp)
5774*3d8817e4Smiod     {
5775*3d8817e4Smiod       m = ieee_get_modified_info (info, indx);
5776*3d8817e4Smiod       if (m == NULL)
5777*3d8817e4Smiod 	return FALSE;
5778*3d8817e4Smiod 
5779*3d8817e4Smiod       if (m->volatile_qualified > 0)
5780*3d8817e4Smiod 	return ieee_push_type (info, m->volatile_qualified, size, unsignedp,
5781*3d8817e4Smiod 			       FALSE);
5782*3d8817e4Smiod     }
5783*3d8817e4Smiod 
5784*3d8817e4Smiod   if (! ieee_define_type (info, size, unsignedp, localp)
5785*3d8817e4Smiod       || ! ieee_write_number (info, 'n')
5786*3d8817e4Smiod       || ! ieee_write_number (info, 2)
5787*3d8817e4Smiod       || ! ieee_write_number (info, indx))
5788*3d8817e4Smiod     return FALSE;
5789*3d8817e4Smiod 
5790*3d8817e4Smiod   if (! localp)
5791*3d8817e4Smiod     m->volatile_qualified = info->type_stack->type.indx;
5792*3d8817e4Smiod 
5793*3d8817e4Smiod   return TRUE;
5794*3d8817e4Smiod }
5795*3d8817e4Smiod 
5796*3d8817e4Smiod /* Convert an enum debug_visibility into a CXXFLAGS value.  */
5797*3d8817e4Smiod 
5798*3d8817e4Smiod static unsigned int
ieee_vis_to_flags(enum debug_visibility visibility)5799*3d8817e4Smiod ieee_vis_to_flags (enum debug_visibility visibility)
5800*3d8817e4Smiod {
5801*3d8817e4Smiod   switch (visibility)
5802*3d8817e4Smiod     {
5803*3d8817e4Smiod     default:
5804*3d8817e4Smiod       abort ();
5805*3d8817e4Smiod     case DEBUG_VISIBILITY_PUBLIC:
5806*3d8817e4Smiod       return CXXFLAGS_VISIBILITY_PUBLIC;
5807*3d8817e4Smiod     case DEBUG_VISIBILITY_PRIVATE:
5808*3d8817e4Smiod       return CXXFLAGS_VISIBILITY_PRIVATE;
5809*3d8817e4Smiod     case DEBUG_VISIBILITY_PROTECTED:
5810*3d8817e4Smiod       return CXXFLAGS_VISIBILITY_PROTECTED;
5811*3d8817e4Smiod     }
5812*3d8817e4Smiod   /*NOTREACHED*/
5813*3d8817e4Smiod }
5814*3d8817e4Smiod 
5815*3d8817e4Smiod /* Start defining a struct type.  We build it in the strdef field on
5816*3d8817e4Smiod    the stack, to avoid confusing type definitions required by the
5817*3d8817e4Smiod    fields with the struct type itself.  */
5818*3d8817e4Smiod 
5819*3d8817e4Smiod static bfd_boolean
ieee_start_struct_type(void * p,const char * tag,unsigned int id,bfd_boolean structp,unsigned int size)5820*3d8817e4Smiod ieee_start_struct_type (void *p, const char *tag, unsigned int id,
5821*3d8817e4Smiod 			bfd_boolean structp, unsigned int size)
5822*3d8817e4Smiod {
5823*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5824*3d8817e4Smiod   bfd_boolean localp, ignorep;
5825*3d8817e4Smiod   bfd_boolean copy;
5826*3d8817e4Smiod   char ab[20];
5827*3d8817e4Smiod   const char *look;
5828*3d8817e4Smiod   struct ieee_name_type_hash_entry *h;
5829*3d8817e4Smiod   struct ieee_name_type *nt, *ntlook;
5830*3d8817e4Smiod   struct ieee_buflist strdef;
5831*3d8817e4Smiod 
5832*3d8817e4Smiod   localp = FALSE;
5833*3d8817e4Smiod   ignorep = FALSE;
5834*3d8817e4Smiod 
5835*3d8817e4Smiod   /* We need to create a tag for internal use even if we don't want
5836*3d8817e4Smiod      one for external use.  This will let us refer to an anonymous
5837*3d8817e4Smiod      struct.  */
5838*3d8817e4Smiod   if (tag != NULL)
5839*3d8817e4Smiod     {
5840*3d8817e4Smiod       look = tag;
5841*3d8817e4Smiod       copy = FALSE;
5842*3d8817e4Smiod     }
5843*3d8817e4Smiod   else
5844*3d8817e4Smiod     {
5845*3d8817e4Smiod       sprintf (ab, "__anon%u", id);
5846*3d8817e4Smiod       look = ab;
5847*3d8817e4Smiod       copy = TRUE;
5848*3d8817e4Smiod     }
5849*3d8817e4Smiod 
5850*3d8817e4Smiod   /* If we already have references to the tag, we must use the
5851*3d8817e4Smiod      existing type index.  */
5852*3d8817e4Smiod   h = ieee_name_type_hash_lookup (&info->tags, look, TRUE, copy);
5853*3d8817e4Smiod   if (h == NULL)
5854*3d8817e4Smiod     return FALSE;
5855*3d8817e4Smiod 
5856*3d8817e4Smiod   nt = NULL;
5857*3d8817e4Smiod   for (ntlook = h->types; ntlook != NULL; ntlook = ntlook->next)
5858*3d8817e4Smiod     {
5859*3d8817e4Smiod       if (ntlook->id == id)
5860*3d8817e4Smiod 	nt = ntlook;
5861*3d8817e4Smiod       else if (! ntlook->type.localp)
5862*3d8817e4Smiod 	{
5863*3d8817e4Smiod 	  /* We are creating a duplicate definition of a globally
5864*3d8817e4Smiod 	     defined tag.  Force it to be local to avoid
5865*3d8817e4Smiod 	     confusion.  */
5866*3d8817e4Smiod 	  localp = TRUE;
5867*3d8817e4Smiod 	}
5868*3d8817e4Smiod     }
5869*3d8817e4Smiod 
5870*3d8817e4Smiod   if (nt != NULL)
5871*3d8817e4Smiod     {
5872*3d8817e4Smiod       assert (localp == nt->type.localp);
5873*3d8817e4Smiod       if (nt->kind == DEBUG_KIND_ILLEGAL && ! localp)
5874*3d8817e4Smiod 	{
5875*3d8817e4Smiod 	  /* We've already seen a global definition of the type.
5876*3d8817e4Smiod              Ignore this new definition.  */
5877*3d8817e4Smiod 	  ignorep = TRUE;
5878*3d8817e4Smiod 	}
5879*3d8817e4Smiod     }
5880*3d8817e4Smiod   else
5881*3d8817e4Smiod     {
5882*3d8817e4Smiod       nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
5883*3d8817e4Smiod       memset (nt, 0, sizeof *nt);
5884*3d8817e4Smiod       nt->id = id;
5885*3d8817e4Smiod       nt->type.name = h->root.string;
5886*3d8817e4Smiod       nt->next = h->types;
5887*3d8817e4Smiod       h->types = nt;
5888*3d8817e4Smiod       nt->type.indx = info->type_indx;
5889*3d8817e4Smiod       ++info->type_indx;
5890*3d8817e4Smiod     }
5891*3d8817e4Smiod 
5892*3d8817e4Smiod   nt->kind = DEBUG_KIND_ILLEGAL;
5893*3d8817e4Smiod 
5894*3d8817e4Smiod   if (! ieee_init_buffer (info, &strdef)
5895*3d8817e4Smiod       || ! ieee_define_named_type (info, tag, nt->type.indx, size, TRUE,
5896*3d8817e4Smiod 				   localp, &strdef)
5897*3d8817e4Smiod       || ! ieee_write_number (info, structp ? 'S' : 'U')
5898*3d8817e4Smiod       || ! ieee_write_number (info, size))
5899*3d8817e4Smiod     return FALSE;
5900*3d8817e4Smiod 
5901*3d8817e4Smiod   if (! ignorep)
5902*3d8817e4Smiod     {
5903*3d8817e4Smiod       const char *hold;
5904*3d8817e4Smiod 
5905*3d8817e4Smiod       /* We never want nt->type.name to be NULL.  We want the rest of
5906*3d8817e4Smiod 	 the type to be the object set up on the type stack; it will
5907*3d8817e4Smiod 	 have a NULL name if tag is NULL.  */
5908*3d8817e4Smiod       hold = nt->type.name;
5909*3d8817e4Smiod       nt->type = info->type_stack->type;
5910*3d8817e4Smiod       nt->type.name = hold;
5911*3d8817e4Smiod     }
5912*3d8817e4Smiod 
5913*3d8817e4Smiod   info->type_stack->type.name = tag;
5914*3d8817e4Smiod   info->type_stack->type.strdef = strdef;
5915*3d8817e4Smiod   info->type_stack->type.ignorep = ignorep;
5916*3d8817e4Smiod 
5917*3d8817e4Smiod   return TRUE;
5918*3d8817e4Smiod }
5919*3d8817e4Smiod 
5920*3d8817e4Smiod /* Add a field to a struct.  */
5921*3d8817e4Smiod 
5922*3d8817e4Smiod static bfd_boolean
ieee_struct_field(void * p,const char * name,bfd_vma bitpos,bfd_vma bitsize,enum debug_visibility visibility)5923*3d8817e4Smiod ieee_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize,
5924*3d8817e4Smiod 		   enum debug_visibility visibility)
5925*3d8817e4Smiod {
5926*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
5927*3d8817e4Smiod   unsigned int size;
5928*3d8817e4Smiod   bfd_boolean unsignedp;
5929*3d8817e4Smiod   bfd_boolean referencep;
5930*3d8817e4Smiod   bfd_boolean localp;
5931*3d8817e4Smiod   unsigned int indx;
5932*3d8817e4Smiod   bfd_vma offset;
5933*3d8817e4Smiod 
5934*3d8817e4Smiod   assert (info->type_stack != NULL
5935*3d8817e4Smiod 	  && info->type_stack->next != NULL
5936*3d8817e4Smiod 	  && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
5937*3d8817e4Smiod 
5938*3d8817e4Smiod   /* If we are ignoring this struct definition, just pop and ignore
5939*3d8817e4Smiod      the type.  */
5940*3d8817e4Smiod   if (info->type_stack->next->type.ignorep)
5941*3d8817e4Smiod     {
5942*3d8817e4Smiod       ieee_pop_unused_type (info);
5943*3d8817e4Smiod       return TRUE;
5944*3d8817e4Smiod     }
5945*3d8817e4Smiod 
5946*3d8817e4Smiod   size = info->type_stack->type.size;
5947*3d8817e4Smiod   unsignedp = info->type_stack->type.unsignedp;
5948*3d8817e4Smiod   referencep = info->type_stack->type.referencep;
5949*3d8817e4Smiod   localp = info->type_stack->type.localp;
5950*3d8817e4Smiod   indx = ieee_pop_type (info);
5951*3d8817e4Smiod 
5952*3d8817e4Smiod   if (localp)
5953*3d8817e4Smiod     info->type_stack->type.localp = TRUE;
5954*3d8817e4Smiod 
5955*3d8817e4Smiod   if (info->type_stack->type.classdef != NULL)
5956*3d8817e4Smiod     {
5957*3d8817e4Smiod       unsigned int flags;
5958*3d8817e4Smiod       unsigned int nindx;
5959*3d8817e4Smiod 
5960*3d8817e4Smiod       /* This is a class.  We must add a description of this field to
5961*3d8817e4Smiod          the class records we are building.  */
5962*3d8817e4Smiod 
5963*3d8817e4Smiod       flags = ieee_vis_to_flags (visibility);
5964*3d8817e4Smiod       nindx = info->type_stack->type.classdef->indx;
5965*3d8817e4Smiod       if (! ieee_change_buffer (info,
5966*3d8817e4Smiod 				&info->type_stack->type.classdef->pmiscbuf)
5967*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, 'd')
5968*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, flags)
5969*3d8817e4Smiod 	  || ! ieee_write_atn65 (info, nindx, name)
5970*3d8817e4Smiod 	  || ! ieee_write_atn65 (info, nindx, name))
5971*3d8817e4Smiod 	return FALSE;
5972*3d8817e4Smiod       info->type_stack->type.classdef->pmisccount += 4;
5973*3d8817e4Smiod 
5974*3d8817e4Smiod       if (referencep)
5975*3d8817e4Smiod 	{
5976*3d8817e4Smiod 	  unsigned int nindx;
5977*3d8817e4Smiod 
5978*3d8817e4Smiod 	  /* We need to output a record recording that this field is
5979*3d8817e4Smiod              really of reference type.  We put this on the refs field
5980*3d8817e4Smiod              of classdef, so that it can be appended to the C++
5981*3d8817e4Smiod              records after the class is defined.  */
5982*3d8817e4Smiod 
5983*3d8817e4Smiod 	  nindx = info->name_indx;
5984*3d8817e4Smiod 	  ++info->name_indx;
5985*3d8817e4Smiod 
5986*3d8817e4Smiod 	  if (! ieee_change_buffer (info,
5987*3d8817e4Smiod 				    &info->type_stack->type.classdef->refs)
5988*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_nn_record)
5989*3d8817e4Smiod 	      || ! ieee_write_number (info, nindx)
5990*3d8817e4Smiod 	      || ! ieee_write_id (info, "")
5991*3d8817e4Smiod 	      || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
5992*3d8817e4Smiod 	      || ! ieee_write_number (info, nindx)
5993*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
5994*3d8817e4Smiod 	      || ! ieee_write_number (info, 62)
5995*3d8817e4Smiod 	      || ! ieee_write_number (info, 80)
5996*3d8817e4Smiod 	      || ! ieee_write_number (info, 4)
5997*3d8817e4Smiod 	      || ! ieee_write_asn (info, nindx, 'R')
5998*3d8817e4Smiod 	      || ! ieee_write_asn (info, nindx, 3)
5999*3d8817e4Smiod 	      || ! ieee_write_atn65 (info, nindx, info->type_stack->type.name)
6000*3d8817e4Smiod 	      || ! ieee_write_atn65 (info, nindx, name))
6001*3d8817e4Smiod 	    return FALSE;
6002*3d8817e4Smiod 	}
6003*3d8817e4Smiod     }
6004*3d8817e4Smiod 
6005*3d8817e4Smiod   /* If the bitsize doesn't match the expected size, we need to output
6006*3d8817e4Smiod      a bitfield type.  */
6007*3d8817e4Smiod   if (size == 0 || bitsize == 0 || bitsize == size * 8)
6008*3d8817e4Smiod     offset = bitpos / 8;
6009*3d8817e4Smiod   else
6010*3d8817e4Smiod     {
6011*3d8817e4Smiod       if (! ieee_define_type (info, 0, unsignedp,
6012*3d8817e4Smiod 			      info->type_stack->type.localp)
6013*3d8817e4Smiod 	  || ! ieee_write_number (info, 'g')
6014*3d8817e4Smiod 	  || ! ieee_write_number (info, unsignedp ? 0 : 1)
6015*3d8817e4Smiod 	  || ! ieee_write_number (info, bitsize)
6016*3d8817e4Smiod 	  || ! ieee_write_number (info, indx))
6017*3d8817e4Smiod 	return FALSE;
6018*3d8817e4Smiod       indx = ieee_pop_type (info);
6019*3d8817e4Smiod       offset = bitpos;
6020*3d8817e4Smiod     }
6021*3d8817e4Smiod 
6022*3d8817e4Smiod   /* Switch to the struct we are building in order to output this
6023*3d8817e4Smiod      field definition.  */
6024*3d8817e4Smiod   return (ieee_change_buffer (info, &info->type_stack->type.strdef)
6025*3d8817e4Smiod 	  && ieee_write_id (info, name)
6026*3d8817e4Smiod 	  && ieee_write_number (info, indx)
6027*3d8817e4Smiod 	  && ieee_write_number (info, offset));
6028*3d8817e4Smiod }
6029*3d8817e4Smiod 
6030*3d8817e4Smiod /* Finish up a struct type.  */
6031*3d8817e4Smiod 
6032*3d8817e4Smiod static bfd_boolean
ieee_end_struct_type(void * p)6033*3d8817e4Smiod ieee_end_struct_type (void *p)
6034*3d8817e4Smiod {
6035*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6036*3d8817e4Smiod   struct ieee_buflist *pb;
6037*3d8817e4Smiod 
6038*3d8817e4Smiod   assert (info->type_stack != NULL
6039*3d8817e4Smiod 	  && ! ieee_buffer_emptyp (&info->type_stack->type.strdef));
6040*3d8817e4Smiod 
6041*3d8817e4Smiod   /* If we were ignoring this struct definition because it was a
6042*3d8817e4Smiod      duplicate definition, just through away whatever bytes we have
6043*3d8817e4Smiod      accumulated.  Leave the type on the stack.  */
6044*3d8817e4Smiod   if (info->type_stack->type.ignorep)
6045*3d8817e4Smiod     return TRUE;
6046*3d8817e4Smiod 
6047*3d8817e4Smiod   /* If this is not a duplicate definition of this tag, then localp
6048*3d8817e4Smiod      will be FALSE, and we can put it in the global type block.
6049*3d8817e4Smiod      FIXME: We should avoid outputting duplicate definitions which are
6050*3d8817e4Smiod      the same.  */
6051*3d8817e4Smiod   if (! info->type_stack->type.localp)
6052*3d8817e4Smiod     {
6053*3d8817e4Smiod       /* Make sure we have started the global type block.  */
6054*3d8817e4Smiod       if (ieee_buffer_emptyp (&info->global_types))
6055*3d8817e4Smiod 	{
6056*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->global_types)
6057*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
6058*3d8817e4Smiod 	      || ! ieee_write_byte (info, 2)
6059*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
6060*3d8817e4Smiod 	      || ! ieee_write_id (info, ""))
6061*3d8817e4Smiod 	    return FALSE;
6062*3d8817e4Smiod 	}
6063*3d8817e4Smiod       pb = &info->global_types;
6064*3d8817e4Smiod     }
6065*3d8817e4Smiod   else
6066*3d8817e4Smiod     {
6067*3d8817e4Smiod       /* Make sure we have started the types block.  */
6068*3d8817e4Smiod       if (ieee_buffer_emptyp (&info->types))
6069*3d8817e4Smiod 	{
6070*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->types)
6071*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
6072*3d8817e4Smiod 	      || ! ieee_write_byte (info, 1)
6073*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
6074*3d8817e4Smiod 	      || ! ieee_write_id (info, info->modname))
6075*3d8817e4Smiod 	    return FALSE;
6076*3d8817e4Smiod 	}
6077*3d8817e4Smiod       pb = &info->types;
6078*3d8817e4Smiod     }
6079*3d8817e4Smiod 
6080*3d8817e4Smiod   /* Append the struct definition to the types.  */
6081*3d8817e4Smiod   if (! ieee_append_buffer (info, pb, &info->type_stack->type.strdef)
6082*3d8817e4Smiod       || ! ieee_init_buffer (info, &info->type_stack->type.strdef))
6083*3d8817e4Smiod     return FALSE;
6084*3d8817e4Smiod 
6085*3d8817e4Smiod   /* Leave the struct on the type stack.  */
6086*3d8817e4Smiod 
6087*3d8817e4Smiod   return TRUE;
6088*3d8817e4Smiod }
6089*3d8817e4Smiod 
6090*3d8817e4Smiod /* Start a class type.  */
6091*3d8817e4Smiod 
6092*3d8817e4Smiod static bfd_boolean
ieee_start_class_type(void * p,const char * tag,unsigned int id,bfd_boolean structp,unsigned int size,bfd_boolean vptr,bfd_boolean ownvptr)6093*3d8817e4Smiod ieee_start_class_type (void *p, const char *tag, unsigned int id,
6094*3d8817e4Smiod 		       bfd_boolean structp, unsigned int size,
6095*3d8817e4Smiod 		       bfd_boolean vptr, bfd_boolean ownvptr)
6096*3d8817e4Smiod {
6097*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6098*3d8817e4Smiod   const char *vclass;
6099*3d8817e4Smiod   struct ieee_buflist pmiscbuf;
6100*3d8817e4Smiod   unsigned int indx;
6101*3d8817e4Smiod   struct ieee_type_class *classdef;
6102*3d8817e4Smiod 
6103*3d8817e4Smiod   /* A C++ class is output as a C++ struct along with a set of pmisc
6104*3d8817e4Smiod      records describing the class.  */
6105*3d8817e4Smiod 
6106*3d8817e4Smiod   /* We need to have a name so that we can associate the struct and
6107*3d8817e4Smiod      the class.  */
6108*3d8817e4Smiod   if (tag == NULL)
6109*3d8817e4Smiod     {
6110*3d8817e4Smiod       char *t;
6111*3d8817e4Smiod 
6112*3d8817e4Smiod       t = (char *) xmalloc (20);
6113*3d8817e4Smiod       sprintf (t, "__anon%u", id);
6114*3d8817e4Smiod       tag = t;
6115*3d8817e4Smiod     }
6116*3d8817e4Smiod 
6117*3d8817e4Smiod   /* We can't write out the virtual table information until we have
6118*3d8817e4Smiod      finished the class, because we don't know the virtual table size.
6119*3d8817e4Smiod      We get the size from the largest voffset we see.  */
6120*3d8817e4Smiod   vclass = NULL;
6121*3d8817e4Smiod   if (vptr && ! ownvptr)
6122*3d8817e4Smiod     {
6123*3d8817e4Smiod       vclass = info->type_stack->type.name;
6124*3d8817e4Smiod       assert (vclass != NULL);
6125*3d8817e4Smiod       /* We don't call ieee_pop_unused_type, since the class should
6126*3d8817e4Smiod          get defined.  */
6127*3d8817e4Smiod       (void) ieee_pop_type (info);
6128*3d8817e4Smiod     }
6129*3d8817e4Smiod 
6130*3d8817e4Smiod   if (! ieee_start_struct_type (p, tag, id, structp, size))
6131*3d8817e4Smiod     return FALSE;
6132*3d8817e4Smiod 
6133*3d8817e4Smiod   indx = info->name_indx;
6134*3d8817e4Smiod   ++info->name_indx;
6135*3d8817e4Smiod 
6136*3d8817e4Smiod   /* We write out pmisc records into the classdef field.  We will
6137*3d8817e4Smiod      write out the pmisc start after we know the number of records we
6138*3d8817e4Smiod      need.  */
6139*3d8817e4Smiod   if (! ieee_init_buffer (info, &pmiscbuf)
6140*3d8817e4Smiod       || ! ieee_change_buffer (info, &pmiscbuf)
6141*3d8817e4Smiod       || ! ieee_write_asn (info, indx, 'T')
6142*3d8817e4Smiod       || ! ieee_write_asn (info, indx, structp ? 'o' : 'u')
6143*3d8817e4Smiod       || ! ieee_write_atn65 (info, indx, tag))
6144*3d8817e4Smiod     return FALSE;
6145*3d8817e4Smiod 
6146*3d8817e4Smiod   classdef = (struct ieee_type_class *) xmalloc (sizeof *classdef);
6147*3d8817e4Smiod   memset (classdef, 0, sizeof *classdef);
6148*3d8817e4Smiod 
6149*3d8817e4Smiod   classdef->indx = indx;
6150*3d8817e4Smiod   classdef->pmiscbuf = pmiscbuf;
6151*3d8817e4Smiod   classdef->pmisccount = 3;
6152*3d8817e4Smiod   classdef->vclass = vclass;
6153*3d8817e4Smiod   classdef->ownvptr = ownvptr;
6154*3d8817e4Smiod 
6155*3d8817e4Smiod   info->type_stack->type.classdef = classdef;
6156*3d8817e4Smiod 
6157*3d8817e4Smiod   return TRUE;
6158*3d8817e4Smiod }
6159*3d8817e4Smiod 
6160*3d8817e4Smiod /* Add a static member to a class.  */
6161*3d8817e4Smiod 
6162*3d8817e4Smiod static bfd_boolean
ieee_class_static_member(void * p,const char * name,const char * physname,enum debug_visibility visibility)6163*3d8817e4Smiod ieee_class_static_member (void *p, const char *name, const char *physname,
6164*3d8817e4Smiod 			  enum debug_visibility visibility)
6165*3d8817e4Smiod {
6166*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6167*3d8817e4Smiod   unsigned int flags;
6168*3d8817e4Smiod   unsigned int nindx;
6169*3d8817e4Smiod 
6170*3d8817e4Smiod   /* We don't care about the type.  Hopefully there will be a call to
6171*3d8817e4Smiod      ieee_variable declaring the physical name and the type, since
6172*3d8817e4Smiod      that is where an IEEE consumer must get the type.  */
6173*3d8817e4Smiod   ieee_pop_unused_type (info);
6174*3d8817e4Smiod 
6175*3d8817e4Smiod   assert (info->type_stack != NULL
6176*3d8817e4Smiod 	  && info->type_stack->type.classdef != NULL);
6177*3d8817e4Smiod 
6178*3d8817e4Smiod   flags = ieee_vis_to_flags (visibility);
6179*3d8817e4Smiod   flags |= CXXFLAGS_STATIC;
6180*3d8817e4Smiod 
6181*3d8817e4Smiod   nindx = info->type_stack->type.classdef->indx;
6182*3d8817e4Smiod 
6183*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
6184*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, 'd')
6185*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, flags)
6186*3d8817e4Smiod       || ! ieee_write_atn65 (info, nindx, name)
6187*3d8817e4Smiod       || ! ieee_write_atn65 (info, nindx, physname))
6188*3d8817e4Smiod     return FALSE;
6189*3d8817e4Smiod   info->type_stack->type.classdef->pmisccount += 4;
6190*3d8817e4Smiod 
6191*3d8817e4Smiod   return TRUE;
6192*3d8817e4Smiod }
6193*3d8817e4Smiod 
6194*3d8817e4Smiod /* Add a base class to a class.  */
6195*3d8817e4Smiod 
6196*3d8817e4Smiod static bfd_boolean
ieee_class_baseclass(void * p,bfd_vma bitpos,bfd_boolean virtual,enum debug_visibility visibility)6197*3d8817e4Smiod ieee_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
6198*3d8817e4Smiod 		      enum debug_visibility visibility)
6199*3d8817e4Smiod {
6200*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6201*3d8817e4Smiod   const char *bname;
6202*3d8817e4Smiod   bfd_boolean localp;
6203*3d8817e4Smiod   unsigned int bindx;
6204*3d8817e4Smiod   char *fname;
6205*3d8817e4Smiod   unsigned int flags;
6206*3d8817e4Smiod   unsigned int nindx;
6207*3d8817e4Smiod 
6208*3d8817e4Smiod   assert (info->type_stack != NULL
6209*3d8817e4Smiod 	  && info->type_stack->type.name != NULL
6210*3d8817e4Smiod 	  && info->type_stack->next != NULL
6211*3d8817e4Smiod 	  && info->type_stack->next->type.classdef != NULL
6212*3d8817e4Smiod 	  && ! ieee_buffer_emptyp (&info->type_stack->next->type.strdef));
6213*3d8817e4Smiod 
6214*3d8817e4Smiod   bname = info->type_stack->type.name;
6215*3d8817e4Smiod   localp = info->type_stack->type.localp;
6216*3d8817e4Smiod   bindx = ieee_pop_type (info);
6217*3d8817e4Smiod 
6218*3d8817e4Smiod   /* We are currently defining both a struct and a class.  We must
6219*3d8817e4Smiod      write out a field definition in the struct which holds the base
6220*3d8817e4Smiod      class.  The stabs debugging reader will create a field named
6221*3d8817e4Smiod      _vb$CLASS for a virtual base class, so we just use that.  FIXME:
6222*3d8817e4Smiod      we should not depend upon a detail of stabs debugging.  */
6223*3d8817e4Smiod   if (virtual)
6224*3d8817e4Smiod     {
6225*3d8817e4Smiod       fname = (char *) xmalloc (strlen (bname) + sizeof "_vb$");
6226*3d8817e4Smiod       sprintf (fname, "_vb$%s", bname);
6227*3d8817e4Smiod       flags = BASEFLAGS_VIRTUAL;
6228*3d8817e4Smiod     }
6229*3d8817e4Smiod   else
6230*3d8817e4Smiod     {
6231*3d8817e4Smiod       if (localp)
6232*3d8817e4Smiod 	info->type_stack->type.localp = TRUE;
6233*3d8817e4Smiod 
6234*3d8817e4Smiod       fname = (char *) xmalloc (strlen (bname) + sizeof "_b$");
6235*3d8817e4Smiod       sprintf (fname, "_b$%s", bname);
6236*3d8817e4Smiod 
6237*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->type_stack->type.strdef)
6238*3d8817e4Smiod 	  || ! ieee_write_id (info, fname)
6239*3d8817e4Smiod 	  || ! ieee_write_number (info, bindx)
6240*3d8817e4Smiod 	  || ! ieee_write_number (info, bitpos / 8))
6241*3d8817e4Smiod 	return FALSE;
6242*3d8817e4Smiod       flags = 0;
6243*3d8817e4Smiod     }
6244*3d8817e4Smiod 
6245*3d8817e4Smiod   if (visibility == DEBUG_VISIBILITY_PRIVATE)
6246*3d8817e4Smiod     flags |= BASEFLAGS_PRIVATE;
6247*3d8817e4Smiod 
6248*3d8817e4Smiod   nindx = info->type_stack->type.classdef->indx;
6249*3d8817e4Smiod 
6250*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->type_stack->type.classdef->pmiscbuf)
6251*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, 'b')
6252*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, flags)
6253*3d8817e4Smiod       || ! ieee_write_atn65 (info, nindx, bname)
6254*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, 0)
6255*3d8817e4Smiod       || ! ieee_write_atn65 (info, nindx, fname))
6256*3d8817e4Smiod     return FALSE;
6257*3d8817e4Smiod   info->type_stack->type.classdef->pmisccount += 5;
6258*3d8817e4Smiod 
6259*3d8817e4Smiod   free (fname);
6260*3d8817e4Smiod 
6261*3d8817e4Smiod   return TRUE;
6262*3d8817e4Smiod }
6263*3d8817e4Smiod 
6264*3d8817e4Smiod /* Start building a method for a class.  */
6265*3d8817e4Smiod 
6266*3d8817e4Smiod static bfd_boolean
ieee_class_start_method(void * p,const char * name)6267*3d8817e4Smiod ieee_class_start_method (void *p, const char *name)
6268*3d8817e4Smiod {
6269*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6270*3d8817e4Smiod 
6271*3d8817e4Smiod   assert (info->type_stack != NULL
6272*3d8817e4Smiod 	  && info->type_stack->type.classdef != NULL
6273*3d8817e4Smiod 	  && info->type_stack->type.classdef->method == NULL);
6274*3d8817e4Smiod 
6275*3d8817e4Smiod   info->type_stack->type.classdef->method = name;
6276*3d8817e4Smiod 
6277*3d8817e4Smiod   return TRUE;
6278*3d8817e4Smiod }
6279*3d8817e4Smiod 
6280*3d8817e4Smiod /* Define a new method variant, either static or not.  */
6281*3d8817e4Smiod 
6282*3d8817e4Smiod static bfd_boolean
ieee_class_method_var(struct ieee_handle * info,const char * physname,enum debug_visibility visibility,bfd_boolean staticp,bfd_boolean constp,bfd_boolean volatilep,bfd_vma voffset,bfd_boolean context)6283*3d8817e4Smiod ieee_class_method_var (struct ieee_handle *info, const char *physname,
6284*3d8817e4Smiod 		       enum debug_visibility visibility,
6285*3d8817e4Smiod 		       bfd_boolean staticp, bfd_boolean constp,
6286*3d8817e4Smiod 		       bfd_boolean volatilep, bfd_vma voffset,
6287*3d8817e4Smiod 		       bfd_boolean context)
6288*3d8817e4Smiod {
6289*3d8817e4Smiod   unsigned int flags;
6290*3d8817e4Smiod   unsigned int nindx;
6291*3d8817e4Smiod   bfd_boolean virtual;
6292*3d8817e4Smiod 
6293*3d8817e4Smiod   /* We don't need the type of the method.  An IEEE consumer which
6294*3d8817e4Smiod      wants the type must track down the function by the physical name
6295*3d8817e4Smiod      and get the type from that.  */
6296*3d8817e4Smiod   ieee_pop_unused_type (info);
6297*3d8817e4Smiod 
6298*3d8817e4Smiod   /* We don't use the context.  FIXME: We probably ought to use it to
6299*3d8817e4Smiod      adjust the voffset somehow, but I don't really know how.  */
6300*3d8817e4Smiod   if (context)
6301*3d8817e4Smiod     ieee_pop_unused_type (info);
6302*3d8817e4Smiod 
6303*3d8817e4Smiod   assert (info->type_stack != NULL
6304*3d8817e4Smiod 	  && info->type_stack->type.classdef != NULL
6305*3d8817e4Smiod 	  && info->type_stack->type.classdef->method != NULL);
6306*3d8817e4Smiod 
6307*3d8817e4Smiod   flags = ieee_vis_to_flags (visibility);
6308*3d8817e4Smiod 
6309*3d8817e4Smiod   /* FIXME: We never set CXXFLAGS_OVERRIDE, CXXFLAGS_OPERATOR,
6310*3d8817e4Smiod      CXXFLAGS_CTORDTOR, CXXFLAGS_CTOR, or CXXFLAGS_INLINE.  */
6311*3d8817e4Smiod 
6312*3d8817e4Smiod   if (staticp)
6313*3d8817e4Smiod     flags |= CXXFLAGS_STATIC;
6314*3d8817e4Smiod   if (constp)
6315*3d8817e4Smiod     flags |= CXXFLAGS_CONST;
6316*3d8817e4Smiod   if (volatilep)
6317*3d8817e4Smiod     flags |= CXXFLAGS_VOLATILE;
6318*3d8817e4Smiod 
6319*3d8817e4Smiod   nindx = info->type_stack->type.classdef->indx;
6320*3d8817e4Smiod 
6321*3d8817e4Smiod   virtual = context || voffset > 0;
6322*3d8817e4Smiod 
6323*3d8817e4Smiod   if (! ieee_change_buffer (info,
6324*3d8817e4Smiod 			    &info->type_stack->type.classdef->pmiscbuf)
6325*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, virtual ? 'v' : 'm')
6326*3d8817e4Smiod       || ! ieee_write_asn (info, nindx, flags)
6327*3d8817e4Smiod       || ! ieee_write_atn65 (info, nindx,
6328*3d8817e4Smiod 			     info->type_stack->type.classdef->method)
6329*3d8817e4Smiod       || ! ieee_write_atn65 (info, nindx, physname))
6330*3d8817e4Smiod     return FALSE;
6331*3d8817e4Smiod 
6332*3d8817e4Smiod   if (virtual)
6333*3d8817e4Smiod     {
6334*3d8817e4Smiod       if (voffset > info->type_stack->type.classdef->voffset)
6335*3d8817e4Smiod 	info->type_stack->type.classdef->voffset = voffset;
6336*3d8817e4Smiod       if (! ieee_write_asn (info, nindx, voffset))
6337*3d8817e4Smiod 	return FALSE;
6338*3d8817e4Smiod       ++info->type_stack->type.classdef->pmisccount;
6339*3d8817e4Smiod     }
6340*3d8817e4Smiod 
6341*3d8817e4Smiod   if (! ieee_write_asn (info, nindx, 0))
6342*3d8817e4Smiod     return FALSE;
6343*3d8817e4Smiod 
6344*3d8817e4Smiod   info->type_stack->type.classdef->pmisccount += 5;
6345*3d8817e4Smiod 
6346*3d8817e4Smiod   return TRUE;
6347*3d8817e4Smiod }
6348*3d8817e4Smiod 
6349*3d8817e4Smiod /* Define a new method variant.  */
6350*3d8817e4Smiod 
6351*3d8817e4Smiod static bfd_boolean
ieee_class_method_variant(void * p,const char * physname,enum debug_visibility visibility,bfd_boolean constp,bfd_boolean volatilep,bfd_vma voffset,bfd_boolean context)6352*3d8817e4Smiod ieee_class_method_variant (void *p, const char *physname,
6353*3d8817e4Smiod 			   enum debug_visibility visibility,
6354*3d8817e4Smiod 			   bfd_boolean constp, bfd_boolean volatilep,
6355*3d8817e4Smiod 			   bfd_vma voffset, bfd_boolean context)
6356*3d8817e4Smiod {
6357*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6358*3d8817e4Smiod 
6359*3d8817e4Smiod   return ieee_class_method_var (info, physname, visibility, FALSE, constp,
6360*3d8817e4Smiod 				volatilep, voffset, context);
6361*3d8817e4Smiod }
6362*3d8817e4Smiod 
6363*3d8817e4Smiod /* Define a new static method variant.  */
6364*3d8817e4Smiod 
6365*3d8817e4Smiod static bfd_boolean
ieee_class_static_method_variant(void * p,const char * physname,enum debug_visibility visibility,bfd_boolean constp,bfd_boolean volatilep)6366*3d8817e4Smiod ieee_class_static_method_variant (void *p, const char *physname,
6367*3d8817e4Smiod 				  enum debug_visibility visibility,
6368*3d8817e4Smiod 				  bfd_boolean constp, bfd_boolean volatilep)
6369*3d8817e4Smiod {
6370*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6371*3d8817e4Smiod 
6372*3d8817e4Smiod   return ieee_class_method_var (info, physname, visibility, TRUE, constp,
6373*3d8817e4Smiod 				volatilep, 0, FALSE);
6374*3d8817e4Smiod }
6375*3d8817e4Smiod 
6376*3d8817e4Smiod /* Finish up a method.  */
6377*3d8817e4Smiod 
6378*3d8817e4Smiod static bfd_boolean
ieee_class_end_method(void * p)6379*3d8817e4Smiod ieee_class_end_method (void *p)
6380*3d8817e4Smiod {
6381*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6382*3d8817e4Smiod 
6383*3d8817e4Smiod   assert (info->type_stack != NULL
6384*3d8817e4Smiod 	  && info->type_stack->type.classdef != NULL
6385*3d8817e4Smiod 	  && info->type_stack->type.classdef->method != NULL);
6386*3d8817e4Smiod 
6387*3d8817e4Smiod   info->type_stack->type.classdef->method = NULL;
6388*3d8817e4Smiod 
6389*3d8817e4Smiod   return TRUE;
6390*3d8817e4Smiod }
6391*3d8817e4Smiod 
6392*3d8817e4Smiod /* Finish up a class.  */
6393*3d8817e4Smiod 
6394*3d8817e4Smiod static bfd_boolean
ieee_end_class_type(void * p)6395*3d8817e4Smiod ieee_end_class_type (void *p)
6396*3d8817e4Smiod {
6397*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6398*3d8817e4Smiod   unsigned int nindx;
6399*3d8817e4Smiod 
6400*3d8817e4Smiod   assert (info->type_stack != NULL
6401*3d8817e4Smiod 	  && info->type_stack->type.classdef != NULL);
6402*3d8817e4Smiod 
6403*3d8817e4Smiod   /* If we were ignoring this class definition because it was a
6404*3d8817e4Smiod      duplicate definition, just through away whatever bytes we have
6405*3d8817e4Smiod      accumulated.  Leave the type on the stack.  */
6406*3d8817e4Smiod   if (info->type_stack->type.ignorep)
6407*3d8817e4Smiod     return TRUE;
6408*3d8817e4Smiod 
6409*3d8817e4Smiod   nindx = info->type_stack->type.classdef->indx;
6410*3d8817e4Smiod 
6411*3d8817e4Smiod   /* If we have a virtual table, we can write out the information now.  */
6412*3d8817e4Smiod   if (info->type_stack->type.classdef->vclass != NULL
6413*3d8817e4Smiod       || info->type_stack->type.classdef->ownvptr)
6414*3d8817e4Smiod     {
6415*3d8817e4Smiod       if (! ieee_change_buffer (info,
6416*3d8817e4Smiod 				&info->type_stack->type.classdef->pmiscbuf)
6417*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, 'z')
6418*3d8817e4Smiod 	  || ! ieee_write_atn65 (info, nindx, "")
6419*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx,
6420*3d8817e4Smiod 			       info->type_stack->type.classdef->voffset))
6421*3d8817e4Smiod 	return FALSE;
6422*3d8817e4Smiod       if (info->type_stack->type.classdef->ownvptr)
6423*3d8817e4Smiod 	{
6424*3d8817e4Smiod 	  if (! ieee_write_atn65 (info, nindx, ""))
6425*3d8817e4Smiod 	    return FALSE;
6426*3d8817e4Smiod 	}
6427*3d8817e4Smiod       else
6428*3d8817e4Smiod 	{
6429*3d8817e4Smiod 	  if (! ieee_write_atn65 (info, nindx,
6430*3d8817e4Smiod 				  info->type_stack->type.classdef->vclass))
6431*3d8817e4Smiod 	    return FALSE;
6432*3d8817e4Smiod 	}
6433*3d8817e4Smiod       if (! ieee_write_asn (info, nindx, 0))
6434*3d8817e4Smiod 	return FALSE;
6435*3d8817e4Smiod       info->type_stack->type.classdef->pmisccount += 5;
6436*3d8817e4Smiod     }
6437*3d8817e4Smiod 
6438*3d8817e4Smiod   /* Now that we know the number of pmisc records, we can write out
6439*3d8817e4Smiod      the atn62 which starts the pmisc records, and append them to the
6440*3d8817e4Smiod      C++ buffers.  */
6441*3d8817e4Smiod 
6442*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->cxx)
6443*3d8817e4Smiod       || ! ieee_write_byte (info, (int) ieee_nn_record)
6444*3d8817e4Smiod       || ! ieee_write_number (info, nindx)
6445*3d8817e4Smiod       || ! ieee_write_id (info, "")
6446*3d8817e4Smiod       || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
6447*3d8817e4Smiod       || ! ieee_write_number (info, nindx)
6448*3d8817e4Smiod       || ! ieee_write_number (info, 0)
6449*3d8817e4Smiod       || ! ieee_write_number (info, 62)
6450*3d8817e4Smiod       || ! ieee_write_number (info, 80)
6451*3d8817e4Smiod       || ! ieee_write_number (info,
6452*3d8817e4Smiod 			      info->type_stack->type.classdef->pmisccount))
6453*3d8817e4Smiod     return FALSE;
6454*3d8817e4Smiod 
6455*3d8817e4Smiod   if (! ieee_append_buffer (info, &info->cxx,
6456*3d8817e4Smiod 			    &info->type_stack->type.classdef->pmiscbuf))
6457*3d8817e4Smiod     return FALSE;
6458*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->type_stack->type.classdef->refs))
6459*3d8817e4Smiod     {
6460*3d8817e4Smiod       if (! ieee_append_buffer (info, &info->cxx,
6461*3d8817e4Smiod 				&info->type_stack->type.classdef->refs))
6462*3d8817e4Smiod 	return FALSE;
6463*3d8817e4Smiod     }
6464*3d8817e4Smiod 
6465*3d8817e4Smiod   return ieee_end_struct_type (p);
6466*3d8817e4Smiod }
6467*3d8817e4Smiod 
6468*3d8817e4Smiod /* Push a previously seen typedef onto the type stack.  */
6469*3d8817e4Smiod 
6470*3d8817e4Smiod static bfd_boolean
ieee_typedef_type(void * p,const char * name)6471*3d8817e4Smiod ieee_typedef_type (void *p, const char *name)
6472*3d8817e4Smiod {
6473*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6474*3d8817e4Smiod   struct ieee_name_type_hash_entry *h;
6475*3d8817e4Smiod   struct ieee_name_type *nt;
6476*3d8817e4Smiod 
6477*3d8817e4Smiod   h = ieee_name_type_hash_lookup (&info->typedefs, name, FALSE, FALSE);
6478*3d8817e4Smiod 
6479*3d8817e4Smiod   /* h should never be NULL, since that would imply that the generic
6480*3d8817e4Smiod      debugging code has asked for a typedef which it has not yet
6481*3d8817e4Smiod      defined.  */
6482*3d8817e4Smiod   assert (h != NULL);
6483*3d8817e4Smiod 
6484*3d8817e4Smiod   /* We always use the most recently defined type for this name, which
6485*3d8817e4Smiod      will be the first one on the list.  */
6486*3d8817e4Smiod 
6487*3d8817e4Smiod   nt = h->types;
6488*3d8817e4Smiod   if (! ieee_push_type (info, nt->type.indx, nt->type.size,
6489*3d8817e4Smiod 			nt->type.unsignedp, nt->type.localp))
6490*3d8817e4Smiod     return FALSE;
6491*3d8817e4Smiod 
6492*3d8817e4Smiod   /* Copy over any other type information we may have.  */
6493*3d8817e4Smiod   info->type_stack->type = nt->type;
6494*3d8817e4Smiod 
6495*3d8817e4Smiod   return TRUE;
6496*3d8817e4Smiod }
6497*3d8817e4Smiod 
6498*3d8817e4Smiod /* Push a tagged type onto the type stack.  */
6499*3d8817e4Smiod 
6500*3d8817e4Smiod static bfd_boolean
ieee_tag_type(void * p,const char * name,unsigned int id,enum debug_type_kind kind)6501*3d8817e4Smiod ieee_tag_type (void *p, const char *name, unsigned int id,
6502*3d8817e4Smiod 	       enum debug_type_kind kind)
6503*3d8817e4Smiod {
6504*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6505*3d8817e4Smiod   bfd_boolean localp;
6506*3d8817e4Smiod   bfd_boolean copy;
6507*3d8817e4Smiod   char ab[20];
6508*3d8817e4Smiod   struct ieee_name_type_hash_entry *h;
6509*3d8817e4Smiod   struct ieee_name_type *nt;
6510*3d8817e4Smiod 
6511*3d8817e4Smiod   if (kind == DEBUG_KIND_ENUM)
6512*3d8817e4Smiod     {
6513*3d8817e4Smiod       struct ieee_defined_enum *e;
6514*3d8817e4Smiod 
6515*3d8817e4Smiod       if (name == NULL)
6516*3d8817e4Smiod 	abort ();
6517*3d8817e4Smiod       for (e = info->enums; e != NULL; e = e->next)
6518*3d8817e4Smiod 	if (e->tag != NULL && strcmp (e->tag, name) == 0)
6519*3d8817e4Smiod 	  return ieee_push_type (info, e->indx, 0, TRUE, FALSE);
6520*3d8817e4Smiod 
6521*3d8817e4Smiod       e = (struct ieee_defined_enum *) xmalloc (sizeof *e);
6522*3d8817e4Smiod       memset (e, 0, sizeof *e);
6523*3d8817e4Smiod 
6524*3d8817e4Smiod       e->indx = info->type_indx;
6525*3d8817e4Smiod       ++info->type_indx;
6526*3d8817e4Smiod       e->tag = name;
6527*3d8817e4Smiod       e->defined = FALSE;
6528*3d8817e4Smiod 
6529*3d8817e4Smiod       e->next = info->enums;
6530*3d8817e4Smiod       info->enums = e;
6531*3d8817e4Smiod 
6532*3d8817e4Smiod       return ieee_push_type (info, e->indx, 0, TRUE, FALSE);
6533*3d8817e4Smiod     }
6534*3d8817e4Smiod 
6535*3d8817e4Smiod   localp = FALSE;
6536*3d8817e4Smiod 
6537*3d8817e4Smiod   copy = FALSE;
6538*3d8817e4Smiod   if (name == NULL)
6539*3d8817e4Smiod     {
6540*3d8817e4Smiod       sprintf (ab, "__anon%u", id);
6541*3d8817e4Smiod       name = ab;
6542*3d8817e4Smiod       copy = TRUE;
6543*3d8817e4Smiod     }
6544*3d8817e4Smiod 
6545*3d8817e4Smiod   h = ieee_name_type_hash_lookup (&info->tags, name, TRUE, copy);
6546*3d8817e4Smiod   if (h == NULL)
6547*3d8817e4Smiod     return FALSE;
6548*3d8817e4Smiod 
6549*3d8817e4Smiod   for (nt = h->types; nt != NULL; nt = nt->next)
6550*3d8817e4Smiod     {
6551*3d8817e4Smiod       if (nt->id == id)
6552*3d8817e4Smiod 	{
6553*3d8817e4Smiod 	  if (! ieee_push_type (info, nt->type.indx, nt->type.size,
6554*3d8817e4Smiod 				nt->type.unsignedp, nt->type.localp))
6555*3d8817e4Smiod 	    return FALSE;
6556*3d8817e4Smiod 	  /* Copy over any other type information we may have.  */
6557*3d8817e4Smiod 	  info->type_stack->type = nt->type;
6558*3d8817e4Smiod 	  return TRUE;
6559*3d8817e4Smiod 	}
6560*3d8817e4Smiod 
6561*3d8817e4Smiod       if (! nt->type.localp)
6562*3d8817e4Smiod 	{
6563*3d8817e4Smiod 	  /* This is a duplicate of a global type, so it must be
6564*3d8817e4Smiod              local.  */
6565*3d8817e4Smiod 	  localp = TRUE;
6566*3d8817e4Smiod 	}
6567*3d8817e4Smiod     }
6568*3d8817e4Smiod 
6569*3d8817e4Smiod   nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
6570*3d8817e4Smiod   memset (nt, 0, sizeof *nt);
6571*3d8817e4Smiod 
6572*3d8817e4Smiod   nt->id = id;
6573*3d8817e4Smiod   nt->type.name = h->root.string;
6574*3d8817e4Smiod   nt->type.indx = info->type_indx;
6575*3d8817e4Smiod   nt->type.localp = localp;
6576*3d8817e4Smiod   ++info->type_indx;
6577*3d8817e4Smiod   nt->kind = kind;
6578*3d8817e4Smiod 
6579*3d8817e4Smiod   nt->next = h->types;
6580*3d8817e4Smiod   h->types = nt;
6581*3d8817e4Smiod 
6582*3d8817e4Smiod   if (! ieee_push_type (info, nt->type.indx, 0, FALSE, localp))
6583*3d8817e4Smiod     return FALSE;
6584*3d8817e4Smiod 
6585*3d8817e4Smiod   info->type_stack->type.name = h->root.string;
6586*3d8817e4Smiod 
6587*3d8817e4Smiod   return TRUE;
6588*3d8817e4Smiod }
6589*3d8817e4Smiod 
6590*3d8817e4Smiod /* Output a typedef.  */
6591*3d8817e4Smiod 
6592*3d8817e4Smiod static bfd_boolean
ieee_typdef(void * p,const char * name)6593*3d8817e4Smiod ieee_typdef (void *p, const char *name)
6594*3d8817e4Smiod {
6595*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6596*3d8817e4Smiod   struct ieee_write_type type;
6597*3d8817e4Smiod   unsigned int indx;
6598*3d8817e4Smiod   bfd_boolean found;
6599*3d8817e4Smiod   bfd_boolean localp;
6600*3d8817e4Smiod   struct ieee_name_type_hash_entry *h;
6601*3d8817e4Smiod   struct ieee_name_type *nt;
6602*3d8817e4Smiod 
6603*3d8817e4Smiod   type = info->type_stack->type;
6604*3d8817e4Smiod   indx = type.indx;
6605*3d8817e4Smiod 
6606*3d8817e4Smiod   /* If this is a simple builtin type using a builtin name, we don't
6607*3d8817e4Smiod      want to output the typedef itself.  We also want to change the
6608*3d8817e4Smiod      type index to correspond to the name being used.  We recognize
6609*3d8817e4Smiod      names used in stabs debugging output even if they don't exactly
6610*3d8817e4Smiod      correspond to the names used for the IEEE builtin types.  */
6611*3d8817e4Smiod   found = FALSE;
6612*3d8817e4Smiod   if (indx <= (unsigned int) builtin_bcd_float)
6613*3d8817e4Smiod     {
6614*3d8817e4Smiod       switch ((enum builtin_types) indx)
6615*3d8817e4Smiod 	{
6616*3d8817e4Smiod 	default:
6617*3d8817e4Smiod 	  break;
6618*3d8817e4Smiod 
6619*3d8817e4Smiod 	case builtin_void:
6620*3d8817e4Smiod 	  if (strcmp (name, "void") == 0)
6621*3d8817e4Smiod 	    found = TRUE;
6622*3d8817e4Smiod 	  break;
6623*3d8817e4Smiod 
6624*3d8817e4Smiod 	case builtin_signed_char:
6625*3d8817e4Smiod 	case builtin_char:
6626*3d8817e4Smiod 	  if (strcmp (name, "signed char") == 0)
6627*3d8817e4Smiod 	    {
6628*3d8817e4Smiod 	      indx = (unsigned int) builtin_signed_char;
6629*3d8817e4Smiod 	      found = TRUE;
6630*3d8817e4Smiod 	    }
6631*3d8817e4Smiod 	  else if (strcmp (name, "char") == 0)
6632*3d8817e4Smiod 	    {
6633*3d8817e4Smiod 	      indx = (unsigned int) builtin_char;
6634*3d8817e4Smiod 	      found = TRUE;
6635*3d8817e4Smiod 	    }
6636*3d8817e4Smiod 	  break;
6637*3d8817e4Smiod 
6638*3d8817e4Smiod 	case builtin_unsigned_char:
6639*3d8817e4Smiod 	  if (strcmp (name, "unsigned char") == 0)
6640*3d8817e4Smiod 	    found = TRUE;
6641*3d8817e4Smiod 	  break;
6642*3d8817e4Smiod 
6643*3d8817e4Smiod 	case builtin_signed_short_int:
6644*3d8817e4Smiod 	case builtin_short:
6645*3d8817e4Smiod 	case builtin_short_int:
6646*3d8817e4Smiod 	case builtin_signed_short:
6647*3d8817e4Smiod 	  if (strcmp (name, "signed short int") == 0)
6648*3d8817e4Smiod 	    {
6649*3d8817e4Smiod 	      indx = (unsigned int) builtin_signed_short_int;
6650*3d8817e4Smiod 	      found = TRUE;
6651*3d8817e4Smiod 	    }
6652*3d8817e4Smiod 	  else if (strcmp (name, "short") == 0)
6653*3d8817e4Smiod 	    {
6654*3d8817e4Smiod 	      indx = (unsigned int) builtin_short;
6655*3d8817e4Smiod 	      found = TRUE;
6656*3d8817e4Smiod 	    }
6657*3d8817e4Smiod 	  else if (strcmp (name, "short int") == 0)
6658*3d8817e4Smiod 	    {
6659*3d8817e4Smiod 	      indx = (unsigned int) builtin_short_int;
6660*3d8817e4Smiod 	      found = TRUE;
6661*3d8817e4Smiod 	    }
6662*3d8817e4Smiod 	  else if (strcmp (name, "signed short") == 0)
6663*3d8817e4Smiod 	    {
6664*3d8817e4Smiod 	      indx = (unsigned int) builtin_signed_short;
6665*3d8817e4Smiod 	      found = TRUE;
6666*3d8817e4Smiod 	    }
6667*3d8817e4Smiod 	  break;
6668*3d8817e4Smiod 
6669*3d8817e4Smiod 	case builtin_unsigned_short_int:
6670*3d8817e4Smiod 	case builtin_unsigned_short:
6671*3d8817e4Smiod 	  if (strcmp (name, "unsigned short int") == 0
6672*3d8817e4Smiod 	      || strcmp (name, "short unsigned int") == 0)
6673*3d8817e4Smiod 	    {
6674*3d8817e4Smiod 	      indx = builtin_unsigned_short_int;
6675*3d8817e4Smiod 	      found = TRUE;
6676*3d8817e4Smiod 	    }
6677*3d8817e4Smiod 	  else if (strcmp (name, "unsigned short") == 0)
6678*3d8817e4Smiod 	    {
6679*3d8817e4Smiod 	      indx = builtin_unsigned_short;
6680*3d8817e4Smiod 	      found = TRUE;
6681*3d8817e4Smiod 	    }
6682*3d8817e4Smiod 	  break;
6683*3d8817e4Smiod 
6684*3d8817e4Smiod 	case builtin_signed_long:
6685*3d8817e4Smiod 	case builtin_int: /* FIXME: Size depends upon architecture.  */
6686*3d8817e4Smiod 	case builtin_long:
6687*3d8817e4Smiod 	  if (strcmp (name, "signed long") == 0)
6688*3d8817e4Smiod 	    {
6689*3d8817e4Smiod 	      indx = builtin_signed_long;
6690*3d8817e4Smiod 	      found = TRUE;
6691*3d8817e4Smiod 	    }
6692*3d8817e4Smiod 	  else if (strcmp (name, "int") == 0)
6693*3d8817e4Smiod 	    {
6694*3d8817e4Smiod 	      indx = builtin_int;
6695*3d8817e4Smiod 	      found = TRUE;
6696*3d8817e4Smiod 	    }
6697*3d8817e4Smiod 	  else if (strcmp (name, "long") == 0
6698*3d8817e4Smiod 		   || strcmp (name, "long int") == 0)
6699*3d8817e4Smiod 	    {
6700*3d8817e4Smiod 	      indx = builtin_long;
6701*3d8817e4Smiod 	      found = TRUE;
6702*3d8817e4Smiod 	    }
6703*3d8817e4Smiod 	  break;
6704*3d8817e4Smiod 
6705*3d8817e4Smiod 	case builtin_unsigned_long:
6706*3d8817e4Smiod 	case builtin_unsigned: /* FIXME: Size depends upon architecture.  */
6707*3d8817e4Smiod 	case builtin_unsigned_int: /* FIXME: Like builtin_unsigned.  */
6708*3d8817e4Smiod 	  if (strcmp (name, "unsigned long") == 0
6709*3d8817e4Smiod 	      || strcmp (name, "long unsigned int") == 0)
6710*3d8817e4Smiod 	    {
6711*3d8817e4Smiod 	      indx = builtin_unsigned_long;
6712*3d8817e4Smiod 	      found = TRUE;
6713*3d8817e4Smiod 	    }
6714*3d8817e4Smiod 	  else if (strcmp (name, "unsigned") == 0)
6715*3d8817e4Smiod 	    {
6716*3d8817e4Smiod 	      indx = builtin_unsigned;
6717*3d8817e4Smiod 	      found = TRUE;
6718*3d8817e4Smiod 	    }
6719*3d8817e4Smiod 	  else if (strcmp (name, "unsigned int") == 0)
6720*3d8817e4Smiod 	    {
6721*3d8817e4Smiod 	      indx = builtin_unsigned_int;
6722*3d8817e4Smiod 	      found = TRUE;
6723*3d8817e4Smiod 	    }
6724*3d8817e4Smiod 	  break;
6725*3d8817e4Smiod 
6726*3d8817e4Smiod 	case builtin_signed_long_long:
6727*3d8817e4Smiod 	  if (strcmp (name, "signed long long") == 0
6728*3d8817e4Smiod 	      || strcmp (name, "long long int") == 0)
6729*3d8817e4Smiod 	    found = TRUE;
6730*3d8817e4Smiod 	  break;
6731*3d8817e4Smiod 
6732*3d8817e4Smiod 	case builtin_unsigned_long_long:
6733*3d8817e4Smiod 	  if (strcmp (name, "unsigned long long") == 0
6734*3d8817e4Smiod 	      || strcmp (name, "long long unsigned int") == 0)
6735*3d8817e4Smiod 	    found = TRUE;
6736*3d8817e4Smiod 	  break;
6737*3d8817e4Smiod 
6738*3d8817e4Smiod 	case builtin_float:
6739*3d8817e4Smiod 	  if (strcmp (name, "float") == 0)
6740*3d8817e4Smiod 	    found = TRUE;
6741*3d8817e4Smiod 	  break;
6742*3d8817e4Smiod 
6743*3d8817e4Smiod 	case builtin_double:
6744*3d8817e4Smiod 	  if (strcmp (name, "double") == 0)
6745*3d8817e4Smiod 	    found = TRUE;
6746*3d8817e4Smiod 	  break;
6747*3d8817e4Smiod 
6748*3d8817e4Smiod 	case builtin_long_double:
6749*3d8817e4Smiod 	  if (strcmp (name, "long double") == 0)
6750*3d8817e4Smiod 	    found = TRUE;
6751*3d8817e4Smiod 	  break;
6752*3d8817e4Smiod 
6753*3d8817e4Smiod 	case builtin_long_long_double:
6754*3d8817e4Smiod 	  if (strcmp (name, "long long double") == 0)
6755*3d8817e4Smiod 	    found = TRUE;
6756*3d8817e4Smiod 	  break;
6757*3d8817e4Smiod 	}
6758*3d8817e4Smiod 
6759*3d8817e4Smiod       if (found)
6760*3d8817e4Smiod 	type.indx = indx;
6761*3d8817e4Smiod     }
6762*3d8817e4Smiod 
6763*3d8817e4Smiod   h = ieee_name_type_hash_lookup (&info->typedefs, name, TRUE, FALSE);
6764*3d8817e4Smiod   if (h == NULL)
6765*3d8817e4Smiod     return FALSE;
6766*3d8817e4Smiod 
6767*3d8817e4Smiod   /* See if we have already defined this type with this name.  */
6768*3d8817e4Smiod   localp = type.localp;
6769*3d8817e4Smiod   for (nt = h->types; nt != NULL; nt = nt->next)
6770*3d8817e4Smiod     {
6771*3d8817e4Smiod       if (nt->id == indx)
6772*3d8817e4Smiod 	{
6773*3d8817e4Smiod 	  /* If this is a global definition, then we don't need to
6774*3d8817e4Smiod 	     do anything here.  */
6775*3d8817e4Smiod 	  if (! nt->type.localp)
6776*3d8817e4Smiod 	    {
6777*3d8817e4Smiod 	      ieee_pop_unused_type (info);
6778*3d8817e4Smiod 	      return TRUE;
6779*3d8817e4Smiod 	    }
6780*3d8817e4Smiod 	}
6781*3d8817e4Smiod       else
6782*3d8817e4Smiod 	{
6783*3d8817e4Smiod 	  /* This is a duplicate definition, so make this one local.  */
6784*3d8817e4Smiod 	  localp = TRUE;
6785*3d8817e4Smiod 	}
6786*3d8817e4Smiod     }
6787*3d8817e4Smiod 
6788*3d8817e4Smiod   /* We need to add a new typedef for this type.  */
6789*3d8817e4Smiod 
6790*3d8817e4Smiod   nt = (struct ieee_name_type *) xmalloc (sizeof *nt);
6791*3d8817e4Smiod   memset (nt, 0, sizeof *nt);
6792*3d8817e4Smiod   nt->id = indx;
6793*3d8817e4Smiod   nt->type = type;
6794*3d8817e4Smiod   nt->type.name = name;
6795*3d8817e4Smiod   nt->type.localp = localp;
6796*3d8817e4Smiod   nt->kind = DEBUG_KIND_ILLEGAL;
6797*3d8817e4Smiod 
6798*3d8817e4Smiod   nt->next = h->types;
6799*3d8817e4Smiod   h->types = nt;
6800*3d8817e4Smiod 
6801*3d8817e4Smiod   if (found)
6802*3d8817e4Smiod     {
6803*3d8817e4Smiod       /* This is one of the builtin typedefs, so we don't need to
6804*3d8817e4Smiod          actually define it.  */
6805*3d8817e4Smiod       ieee_pop_unused_type (info);
6806*3d8817e4Smiod       return TRUE;
6807*3d8817e4Smiod     }
6808*3d8817e4Smiod 
6809*3d8817e4Smiod   indx = ieee_pop_type (info);
6810*3d8817e4Smiod 
6811*3d8817e4Smiod   if (! ieee_define_named_type (info, name, (unsigned int) -1, type.size,
6812*3d8817e4Smiod 				type.unsignedp,	localp,
6813*3d8817e4Smiod 				(struct ieee_buflist *) NULL)
6814*3d8817e4Smiod       || ! ieee_write_number (info, 'T')
6815*3d8817e4Smiod       || ! ieee_write_number (info, indx))
6816*3d8817e4Smiod     return FALSE;
6817*3d8817e4Smiod 
6818*3d8817e4Smiod   /* Remove the type we just added to the type stack.  This should not
6819*3d8817e4Smiod      be ieee_pop_unused_type, since the type is used, we just don't
6820*3d8817e4Smiod      need it now.  */
6821*3d8817e4Smiod   (void) ieee_pop_type (info);
6822*3d8817e4Smiod 
6823*3d8817e4Smiod   return TRUE;
6824*3d8817e4Smiod }
6825*3d8817e4Smiod 
6826*3d8817e4Smiod /* Output a tag for a type.  We don't have to do anything here.  */
6827*3d8817e4Smiod 
6828*3d8817e4Smiod static bfd_boolean
ieee_tag(void * p,const char * name ATTRIBUTE_UNUSED)6829*3d8817e4Smiod ieee_tag (void *p, const char *name ATTRIBUTE_UNUSED)
6830*3d8817e4Smiod {
6831*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6832*3d8817e4Smiod 
6833*3d8817e4Smiod   /* This should not be ieee_pop_unused_type, since we want the type
6834*3d8817e4Smiod      to be defined.  */
6835*3d8817e4Smiod   (void) ieee_pop_type (info);
6836*3d8817e4Smiod   return TRUE;
6837*3d8817e4Smiod }
6838*3d8817e4Smiod 
6839*3d8817e4Smiod /* Output an integer constant.  */
6840*3d8817e4Smiod 
6841*3d8817e4Smiod static bfd_boolean
ieee_int_constant(void * p ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED,bfd_vma val ATTRIBUTE_UNUSED)6842*3d8817e4Smiod ieee_int_constant (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED,
6843*3d8817e4Smiod 		   bfd_vma val ATTRIBUTE_UNUSED)
6844*3d8817e4Smiod {
6845*3d8817e4Smiod   /* FIXME.  */
6846*3d8817e4Smiod   return TRUE;
6847*3d8817e4Smiod }
6848*3d8817e4Smiod 
6849*3d8817e4Smiod /* Output a floating point constant.  */
6850*3d8817e4Smiod 
6851*3d8817e4Smiod static bfd_boolean
ieee_float_constant(void * p ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED,double val ATTRIBUTE_UNUSED)6852*3d8817e4Smiod ieee_float_constant (void *p ATTRIBUTE_UNUSED,
6853*3d8817e4Smiod 		     const char *name ATTRIBUTE_UNUSED,
6854*3d8817e4Smiod 		     double val ATTRIBUTE_UNUSED)
6855*3d8817e4Smiod {
6856*3d8817e4Smiod   /* FIXME.  */
6857*3d8817e4Smiod   return TRUE;
6858*3d8817e4Smiod }
6859*3d8817e4Smiod 
6860*3d8817e4Smiod /* Output a typed constant.  */
6861*3d8817e4Smiod 
6862*3d8817e4Smiod static bfd_boolean
ieee_typed_constant(void * p,const char * name ATTRIBUTE_UNUSED,bfd_vma val ATTRIBUTE_UNUSED)6863*3d8817e4Smiod ieee_typed_constant (void *p, const char *name ATTRIBUTE_UNUSED,
6864*3d8817e4Smiod 		     bfd_vma val ATTRIBUTE_UNUSED)
6865*3d8817e4Smiod {
6866*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6867*3d8817e4Smiod 
6868*3d8817e4Smiod   /* FIXME.  */
6869*3d8817e4Smiod   ieee_pop_unused_type (info);
6870*3d8817e4Smiod   return TRUE;
6871*3d8817e4Smiod }
6872*3d8817e4Smiod 
6873*3d8817e4Smiod /* Output a variable.  */
6874*3d8817e4Smiod 
6875*3d8817e4Smiod static bfd_boolean
ieee_variable(void * p,const char * name,enum debug_var_kind kind,bfd_vma val)6876*3d8817e4Smiod ieee_variable (void *p, const char *name, enum debug_var_kind kind,
6877*3d8817e4Smiod 	       bfd_vma val)
6878*3d8817e4Smiod {
6879*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6880*3d8817e4Smiod   unsigned int name_indx;
6881*3d8817e4Smiod   unsigned int size;
6882*3d8817e4Smiod   bfd_boolean referencep;
6883*3d8817e4Smiod   unsigned int type_indx;
6884*3d8817e4Smiod   bfd_boolean asn;
6885*3d8817e4Smiod   int refflag;
6886*3d8817e4Smiod 
6887*3d8817e4Smiod   size = info->type_stack->type.size;
6888*3d8817e4Smiod   referencep = info->type_stack->type.referencep;
6889*3d8817e4Smiod   type_indx = ieee_pop_type (info);
6890*3d8817e4Smiod 
6891*3d8817e4Smiod   assert (! ieee_buffer_emptyp (&info->vars));
6892*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->vars))
6893*3d8817e4Smiod     return FALSE;
6894*3d8817e4Smiod 
6895*3d8817e4Smiod   name_indx = info->name_indx;
6896*3d8817e4Smiod   ++info->name_indx;
6897*3d8817e4Smiod 
6898*3d8817e4Smiod   /* Write out an NN and an ATN record for this variable.  */
6899*3d8817e4Smiod   if (! ieee_write_byte (info, (int) ieee_nn_record)
6900*3d8817e4Smiod       || ! ieee_write_number (info, name_indx)
6901*3d8817e4Smiod       || ! ieee_write_id (info, name)
6902*3d8817e4Smiod       || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
6903*3d8817e4Smiod       || ! ieee_write_number (info, name_indx)
6904*3d8817e4Smiod       || ! ieee_write_number (info, type_indx))
6905*3d8817e4Smiod     return FALSE;
6906*3d8817e4Smiod   switch (kind)
6907*3d8817e4Smiod     {
6908*3d8817e4Smiod     default:
6909*3d8817e4Smiod       abort ();
6910*3d8817e4Smiod       return FALSE;
6911*3d8817e4Smiod     case DEBUG_GLOBAL:
6912*3d8817e4Smiod       if (! ieee_write_number (info, 8)
6913*3d8817e4Smiod 	  || ! ieee_add_range (info, FALSE, val, val + size))
6914*3d8817e4Smiod 	return FALSE;
6915*3d8817e4Smiod       refflag = 0;
6916*3d8817e4Smiod       asn = TRUE;
6917*3d8817e4Smiod       break;
6918*3d8817e4Smiod     case DEBUG_STATIC:
6919*3d8817e4Smiod       if (! ieee_write_number (info, 3)
6920*3d8817e4Smiod 	  || ! ieee_add_range (info, FALSE, val, val + size))
6921*3d8817e4Smiod 	return FALSE;
6922*3d8817e4Smiod       refflag = 1;
6923*3d8817e4Smiod       asn = TRUE;
6924*3d8817e4Smiod       break;
6925*3d8817e4Smiod     case DEBUG_LOCAL_STATIC:
6926*3d8817e4Smiod       if (! ieee_write_number (info, 3)
6927*3d8817e4Smiod 	  || ! ieee_add_range (info, FALSE, val, val + size))
6928*3d8817e4Smiod 	return FALSE;
6929*3d8817e4Smiod       refflag = 2;
6930*3d8817e4Smiod       asn = TRUE;
6931*3d8817e4Smiod       break;
6932*3d8817e4Smiod     case DEBUG_LOCAL:
6933*3d8817e4Smiod       if (! ieee_write_number (info, 1)
6934*3d8817e4Smiod 	  || ! ieee_write_number (info, val))
6935*3d8817e4Smiod 	return FALSE;
6936*3d8817e4Smiod       refflag = 2;
6937*3d8817e4Smiod       asn = FALSE;
6938*3d8817e4Smiod       break;
6939*3d8817e4Smiod     case DEBUG_REGISTER:
6940*3d8817e4Smiod       if (! ieee_write_number (info, 2)
6941*3d8817e4Smiod 	  || ! ieee_write_number (info,
6942*3d8817e4Smiod 				  ieee_genreg_to_regno (info->abfd, val)))
6943*3d8817e4Smiod 	return FALSE;
6944*3d8817e4Smiod       refflag = 2;
6945*3d8817e4Smiod       asn = FALSE;
6946*3d8817e4Smiod       break;
6947*3d8817e4Smiod     }
6948*3d8817e4Smiod 
6949*3d8817e4Smiod   if (asn)
6950*3d8817e4Smiod     {
6951*3d8817e4Smiod       if (! ieee_write_asn (info, name_indx, val))
6952*3d8817e4Smiod 	return FALSE;
6953*3d8817e4Smiod     }
6954*3d8817e4Smiod 
6955*3d8817e4Smiod   /* If this is really a reference type, then we just output it with
6956*3d8817e4Smiod      pointer type, and must now output a C++ record indicating that it
6957*3d8817e4Smiod      is really reference type.  */
6958*3d8817e4Smiod   if (referencep)
6959*3d8817e4Smiod     {
6960*3d8817e4Smiod       unsigned int nindx;
6961*3d8817e4Smiod 
6962*3d8817e4Smiod       nindx = info->name_indx;
6963*3d8817e4Smiod       ++info->name_indx;
6964*3d8817e4Smiod 
6965*3d8817e4Smiod       /* If this is a global variable, we want to output the misc
6966*3d8817e4Smiod          record in the C++ misc record block.  Otherwise, we want to
6967*3d8817e4Smiod          output it just after the variable definition, which is where
6968*3d8817e4Smiod          the current buffer is.  */
6969*3d8817e4Smiod       if (refflag != 2)
6970*3d8817e4Smiod 	{
6971*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->cxx))
6972*3d8817e4Smiod 	    return FALSE;
6973*3d8817e4Smiod 	}
6974*3d8817e4Smiod 
6975*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_nn_record)
6976*3d8817e4Smiod 	  || ! ieee_write_number (info, nindx)
6977*3d8817e4Smiod 	  || ! ieee_write_id (info, "")
6978*3d8817e4Smiod 	  || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
6979*3d8817e4Smiod 	  || ! ieee_write_number (info, nindx)
6980*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
6981*3d8817e4Smiod 	  || ! ieee_write_number (info, 62)
6982*3d8817e4Smiod 	  || ! ieee_write_number (info, 80)
6983*3d8817e4Smiod 	  || ! ieee_write_number (info, 3)
6984*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, 'R')
6985*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, refflag)
6986*3d8817e4Smiod 	  || ! ieee_write_atn65 (info, nindx, name))
6987*3d8817e4Smiod 	return FALSE;
6988*3d8817e4Smiod     }
6989*3d8817e4Smiod 
6990*3d8817e4Smiod   return TRUE;
6991*3d8817e4Smiod }
6992*3d8817e4Smiod 
6993*3d8817e4Smiod /* Start outputting information for a function.  */
6994*3d8817e4Smiod 
6995*3d8817e4Smiod static bfd_boolean
ieee_start_function(void * p,const char * name,bfd_boolean global)6996*3d8817e4Smiod ieee_start_function (void *p, const char *name, bfd_boolean global)
6997*3d8817e4Smiod {
6998*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
6999*3d8817e4Smiod   bfd_boolean referencep;
7000*3d8817e4Smiod   unsigned int retindx, typeindx;
7001*3d8817e4Smiod 
7002*3d8817e4Smiod   referencep = info->type_stack->type.referencep;
7003*3d8817e4Smiod   retindx = ieee_pop_type (info);
7004*3d8817e4Smiod 
7005*3d8817e4Smiod   /* Besides recording a BB4 or BB6 block, we record the type of the
7006*3d8817e4Smiod      function in the BB1 typedef block.  We can't write out the full
7007*3d8817e4Smiod      type until we have seen all the parameters, so we accumulate it
7008*3d8817e4Smiod      in info->fntype and info->fnargs.  */
7009*3d8817e4Smiod   if (! ieee_buffer_emptyp (&info->fntype))
7010*3d8817e4Smiod     {
7011*3d8817e4Smiod       /* FIXME: This might happen someday if we support nested
7012*3d8817e4Smiod          functions.  */
7013*3d8817e4Smiod       abort ();
7014*3d8817e4Smiod     }
7015*3d8817e4Smiod 
7016*3d8817e4Smiod   info->fnname = name;
7017*3d8817e4Smiod 
7018*3d8817e4Smiod   /* An attribute of 0x40 means that the push mask is unknown.  */
7019*3d8817e4Smiod   if (! ieee_define_named_type (info, name, (unsigned int) -1, 0, FALSE, TRUE,
7020*3d8817e4Smiod 				&info->fntype)
7021*3d8817e4Smiod       || ! ieee_write_number (info, 'x')
7022*3d8817e4Smiod       || ! ieee_write_number (info, 0x40)
7023*3d8817e4Smiod       || ! ieee_write_number (info, 0)
7024*3d8817e4Smiod       || ! ieee_write_number (info, 0)
7025*3d8817e4Smiod       || ! ieee_write_number (info, retindx))
7026*3d8817e4Smiod     return FALSE;
7027*3d8817e4Smiod 
7028*3d8817e4Smiod   typeindx = ieee_pop_type (info);
7029*3d8817e4Smiod 
7030*3d8817e4Smiod   if (! ieee_init_buffer (info, &info->fnargs))
7031*3d8817e4Smiod     return FALSE;
7032*3d8817e4Smiod   info->fnargcount = 0;
7033*3d8817e4Smiod 
7034*3d8817e4Smiod   /* If the function return value is actually a reference type, we
7035*3d8817e4Smiod      must add a record indicating that.  */
7036*3d8817e4Smiod   if (referencep)
7037*3d8817e4Smiod     {
7038*3d8817e4Smiod       unsigned int nindx;
7039*3d8817e4Smiod 
7040*3d8817e4Smiod       nindx = info->name_indx;
7041*3d8817e4Smiod       ++info->name_indx;
7042*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->cxx)
7043*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_nn_record)
7044*3d8817e4Smiod 	  || ! ieee_write_number (info, nindx)
7045*3d8817e4Smiod 	  || ! ieee_write_id (info, "")
7046*3d8817e4Smiod 	  || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
7047*3d8817e4Smiod 	  || ! ieee_write_number (info, nindx)
7048*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7049*3d8817e4Smiod 	  || ! ieee_write_number (info, 62)
7050*3d8817e4Smiod 	  || ! ieee_write_number (info, 80)
7051*3d8817e4Smiod 	  || ! ieee_write_number (info, 3)
7052*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, 'R')
7053*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, global ? 0 : 1)
7054*3d8817e4Smiod 	  || ! ieee_write_atn65 (info, nindx, name))
7055*3d8817e4Smiod 	return FALSE;
7056*3d8817e4Smiod     }
7057*3d8817e4Smiod 
7058*3d8817e4Smiod   assert (! ieee_buffer_emptyp (&info->vars));
7059*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->vars))
7060*3d8817e4Smiod     return FALSE;
7061*3d8817e4Smiod 
7062*3d8817e4Smiod   /* The address is written out as the first block.  */
7063*3d8817e4Smiod 
7064*3d8817e4Smiod   ++info->block_depth;
7065*3d8817e4Smiod 
7066*3d8817e4Smiod   return (ieee_write_byte (info, (int) ieee_bb_record_enum)
7067*3d8817e4Smiod 	  && ieee_write_byte (info, global ? 4 : 6)
7068*3d8817e4Smiod 	  && ieee_write_number (info, 0)
7069*3d8817e4Smiod 	  && ieee_write_id (info, name)
7070*3d8817e4Smiod 	  && ieee_write_number (info, 0)
7071*3d8817e4Smiod 	  && ieee_write_number (info, typeindx));
7072*3d8817e4Smiod }
7073*3d8817e4Smiod 
7074*3d8817e4Smiod /* Add a function parameter.  This will normally be called before the
7075*3d8817e4Smiod    first block, so we postpone them until we see the block.  */
7076*3d8817e4Smiod 
7077*3d8817e4Smiod static bfd_boolean
ieee_function_parameter(void * p,const char * name,enum debug_parm_kind kind,bfd_vma val)7078*3d8817e4Smiod ieee_function_parameter (void *p, const char *name, enum debug_parm_kind kind,
7079*3d8817e4Smiod 			 bfd_vma val)
7080*3d8817e4Smiod {
7081*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
7082*3d8817e4Smiod   struct ieee_pending_parm *m, **pm;
7083*3d8817e4Smiod 
7084*3d8817e4Smiod   assert (info->block_depth == 1);
7085*3d8817e4Smiod 
7086*3d8817e4Smiod   m = (struct ieee_pending_parm *) xmalloc (sizeof *m);
7087*3d8817e4Smiod   memset (m, 0, sizeof *m);
7088*3d8817e4Smiod 
7089*3d8817e4Smiod   m->next = NULL;
7090*3d8817e4Smiod   m->name = name;
7091*3d8817e4Smiod   m->referencep = info->type_stack->type.referencep;
7092*3d8817e4Smiod   m->type = ieee_pop_type (info);
7093*3d8817e4Smiod   m->kind = kind;
7094*3d8817e4Smiod   m->val = val;
7095*3d8817e4Smiod 
7096*3d8817e4Smiod   for (pm = &info->pending_parms; *pm != NULL; pm = &(*pm)->next)
7097*3d8817e4Smiod     ;
7098*3d8817e4Smiod   *pm = m;
7099*3d8817e4Smiod 
7100*3d8817e4Smiod   /* Add the type to the fnargs list.  */
7101*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->fnargs)
7102*3d8817e4Smiod       || ! ieee_write_number (info, m->type))
7103*3d8817e4Smiod     return FALSE;
7104*3d8817e4Smiod   ++info->fnargcount;
7105*3d8817e4Smiod 
7106*3d8817e4Smiod   return TRUE;
7107*3d8817e4Smiod }
7108*3d8817e4Smiod 
7109*3d8817e4Smiod /* Output pending function parameters.  */
7110*3d8817e4Smiod 
7111*3d8817e4Smiod static bfd_boolean
ieee_output_pending_parms(struct ieee_handle * info)7112*3d8817e4Smiod ieee_output_pending_parms (struct ieee_handle *info)
7113*3d8817e4Smiod {
7114*3d8817e4Smiod   struct ieee_pending_parm *m;
7115*3d8817e4Smiod   unsigned int refcount;
7116*3d8817e4Smiod 
7117*3d8817e4Smiod   refcount = 0;
7118*3d8817e4Smiod   for (m = info->pending_parms; m != NULL; m = m->next)
7119*3d8817e4Smiod     {
7120*3d8817e4Smiod       enum debug_var_kind vkind;
7121*3d8817e4Smiod 
7122*3d8817e4Smiod       switch (m->kind)
7123*3d8817e4Smiod 	{
7124*3d8817e4Smiod 	default:
7125*3d8817e4Smiod 	  abort ();
7126*3d8817e4Smiod 	  return FALSE;
7127*3d8817e4Smiod 	case DEBUG_PARM_STACK:
7128*3d8817e4Smiod 	case DEBUG_PARM_REFERENCE:
7129*3d8817e4Smiod 	  vkind = DEBUG_LOCAL;
7130*3d8817e4Smiod 	  break;
7131*3d8817e4Smiod 	case DEBUG_PARM_REG:
7132*3d8817e4Smiod 	case DEBUG_PARM_REF_REG:
7133*3d8817e4Smiod 	  vkind = DEBUG_REGISTER;
7134*3d8817e4Smiod 	  break;
7135*3d8817e4Smiod 	}
7136*3d8817e4Smiod 
7137*3d8817e4Smiod       if (! ieee_push_type (info, m->type, 0, FALSE, FALSE))
7138*3d8817e4Smiod 	return FALSE;
7139*3d8817e4Smiod       info->type_stack->type.referencep = m->referencep;
7140*3d8817e4Smiod       if (m->referencep)
7141*3d8817e4Smiod 	++refcount;
7142*3d8817e4Smiod       if (! ieee_variable ((void *) info, m->name, vkind, m->val))
7143*3d8817e4Smiod 	return FALSE;
7144*3d8817e4Smiod     }
7145*3d8817e4Smiod 
7146*3d8817e4Smiod   /* If there are any reference parameters, we need to output a
7147*3d8817e4Smiod      miscellaneous record indicating them.  */
7148*3d8817e4Smiod   if (refcount > 0)
7149*3d8817e4Smiod     {
7150*3d8817e4Smiod       unsigned int nindx, varindx;
7151*3d8817e4Smiod 
7152*3d8817e4Smiod       /* FIXME: The MRI compiler outputs the demangled function name
7153*3d8817e4Smiod          here, but we are outputting the mangled name.  */
7154*3d8817e4Smiod       nindx = info->name_indx;
7155*3d8817e4Smiod       ++info->name_indx;
7156*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->vars)
7157*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_nn_record)
7158*3d8817e4Smiod 	  || ! ieee_write_number (info, nindx)
7159*3d8817e4Smiod 	  || ! ieee_write_id (info, "")
7160*3d8817e4Smiod 	  || ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
7161*3d8817e4Smiod 	  || ! ieee_write_number (info, nindx)
7162*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7163*3d8817e4Smiod 	  || ! ieee_write_number (info, 62)
7164*3d8817e4Smiod 	  || ! ieee_write_number (info, 80)
7165*3d8817e4Smiod 	  || ! ieee_write_number (info, refcount + 3)
7166*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, 'B')
7167*3d8817e4Smiod 	  || ! ieee_write_atn65 (info, nindx, info->fnname)
7168*3d8817e4Smiod 	  || ! ieee_write_asn (info, nindx, 0))
7169*3d8817e4Smiod 	return FALSE;
7170*3d8817e4Smiod       for (m = info->pending_parms, varindx = 1;
7171*3d8817e4Smiod 	   m != NULL;
7172*3d8817e4Smiod 	   m = m->next, varindx++)
7173*3d8817e4Smiod 	{
7174*3d8817e4Smiod 	  if (m->referencep)
7175*3d8817e4Smiod 	    {
7176*3d8817e4Smiod 	      if (! ieee_write_asn (info, nindx, varindx))
7177*3d8817e4Smiod 		return FALSE;
7178*3d8817e4Smiod 	    }
7179*3d8817e4Smiod 	}
7180*3d8817e4Smiod     }
7181*3d8817e4Smiod 
7182*3d8817e4Smiod   m = info->pending_parms;
7183*3d8817e4Smiod   while (m != NULL)
7184*3d8817e4Smiod     {
7185*3d8817e4Smiod       struct ieee_pending_parm *next;
7186*3d8817e4Smiod 
7187*3d8817e4Smiod       next = m->next;
7188*3d8817e4Smiod       free (m);
7189*3d8817e4Smiod       m = next;
7190*3d8817e4Smiod     }
7191*3d8817e4Smiod 
7192*3d8817e4Smiod   info->pending_parms = NULL;
7193*3d8817e4Smiod 
7194*3d8817e4Smiod   return TRUE;
7195*3d8817e4Smiod }
7196*3d8817e4Smiod 
7197*3d8817e4Smiod /* Start a block.  If this is the first block, we output the address
7198*3d8817e4Smiod    to finish the BB4 or BB6, and then output the function parameters.  */
7199*3d8817e4Smiod 
7200*3d8817e4Smiod static bfd_boolean
ieee_start_block(void * p,bfd_vma addr)7201*3d8817e4Smiod ieee_start_block (void *p, bfd_vma addr)
7202*3d8817e4Smiod {
7203*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
7204*3d8817e4Smiod 
7205*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->vars))
7206*3d8817e4Smiod     return FALSE;
7207*3d8817e4Smiod 
7208*3d8817e4Smiod   if (info->block_depth == 1)
7209*3d8817e4Smiod     {
7210*3d8817e4Smiod       if (! ieee_write_number (info, addr)
7211*3d8817e4Smiod 	  || ! ieee_output_pending_parms (info))
7212*3d8817e4Smiod 	return FALSE;
7213*3d8817e4Smiod     }
7214*3d8817e4Smiod   else
7215*3d8817e4Smiod     {
7216*3d8817e4Smiod       if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
7217*3d8817e4Smiod 	  || ! ieee_write_byte (info, 6)
7218*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7219*3d8817e4Smiod 	  || ! ieee_write_id (info, "")
7220*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7221*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7222*3d8817e4Smiod 	  || ! ieee_write_number (info, addr))
7223*3d8817e4Smiod 	return FALSE;
7224*3d8817e4Smiod     }
7225*3d8817e4Smiod 
7226*3d8817e4Smiod   if (! ieee_start_range (info, addr))
7227*3d8817e4Smiod     return FALSE;
7228*3d8817e4Smiod 
7229*3d8817e4Smiod   ++info->block_depth;
7230*3d8817e4Smiod 
7231*3d8817e4Smiod   return TRUE;
7232*3d8817e4Smiod }
7233*3d8817e4Smiod 
7234*3d8817e4Smiod /* End a block.  */
7235*3d8817e4Smiod 
7236*3d8817e4Smiod static bfd_boolean
ieee_end_block(void * p,bfd_vma addr)7237*3d8817e4Smiod ieee_end_block (void *p, bfd_vma addr)
7238*3d8817e4Smiod {
7239*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
7240*3d8817e4Smiod 
7241*3d8817e4Smiod   /* The address we are given is the end of the block, but IEEE seems
7242*3d8817e4Smiod      to want to the address of the last byte in the block, so we
7243*3d8817e4Smiod      subtract one.  */
7244*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->vars)
7245*3d8817e4Smiod       || ! ieee_write_byte (info, (int) ieee_be_record_enum)
7246*3d8817e4Smiod       || ! ieee_write_number (info, addr - 1))
7247*3d8817e4Smiod     return FALSE;
7248*3d8817e4Smiod 
7249*3d8817e4Smiod   if (! ieee_end_range (info, addr))
7250*3d8817e4Smiod     return FALSE;
7251*3d8817e4Smiod 
7252*3d8817e4Smiod   --info->block_depth;
7253*3d8817e4Smiod 
7254*3d8817e4Smiod   if (addr > info->highaddr)
7255*3d8817e4Smiod     info->highaddr = addr;
7256*3d8817e4Smiod 
7257*3d8817e4Smiod   return TRUE;
7258*3d8817e4Smiod }
7259*3d8817e4Smiod 
7260*3d8817e4Smiod /* End a function.  */
7261*3d8817e4Smiod 
7262*3d8817e4Smiod static bfd_boolean
ieee_end_function(void * p)7263*3d8817e4Smiod ieee_end_function (void *p)
7264*3d8817e4Smiod {
7265*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
7266*3d8817e4Smiod 
7267*3d8817e4Smiod   assert (info->block_depth == 1);
7268*3d8817e4Smiod 
7269*3d8817e4Smiod   --info->block_depth;
7270*3d8817e4Smiod 
7271*3d8817e4Smiod   /* Now we can finish up fntype, and add it to the typdef section.
7272*3d8817e4Smiod      At this point, fntype is the 'x' type up to the argument count,
7273*3d8817e4Smiod      and fnargs is the argument types.  We must add the argument
7274*3d8817e4Smiod      count, and we must add the level.  FIXME: We don't record varargs
7275*3d8817e4Smiod      functions correctly.  In fact, stabs debugging does not give us
7276*3d8817e4Smiod      enough information to do so.  */
7277*3d8817e4Smiod   if (! ieee_change_buffer (info, &info->fntype)
7278*3d8817e4Smiod       || ! ieee_write_number (info, info->fnargcount)
7279*3d8817e4Smiod       || ! ieee_change_buffer (info, &info->fnargs)
7280*3d8817e4Smiod       || ! ieee_write_number (info, 0))
7281*3d8817e4Smiod     return FALSE;
7282*3d8817e4Smiod 
7283*3d8817e4Smiod   /* Make sure the typdef block has been started.  */
7284*3d8817e4Smiod   if (ieee_buffer_emptyp (&info->types))
7285*3d8817e4Smiod     {
7286*3d8817e4Smiod       if (! ieee_change_buffer (info, &info->types)
7287*3d8817e4Smiod 	  || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
7288*3d8817e4Smiod 	  || ! ieee_write_byte (info, 1)
7289*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7290*3d8817e4Smiod 	  || ! ieee_write_id (info, info->modname))
7291*3d8817e4Smiod 	return FALSE;
7292*3d8817e4Smiod     }
7293*3d8817e4Smiod 
7294*3d8817e4Smiod   if (! ieee_append_buffer (info, &info->types, &info->fntype)
7295*3d8817e4Smiod       || ! ieee_append_buffer (info, &info->types, &info->fnargs))
7296*3d8817e4Smiod     return FALSE;
7297*3d8817e4Smiod 
7298*3d8817e4Smiod   info->fnname = NULL;
7299*3d8817e4Smiod   if (! ieee_init_buffer (info, &info->fntype)
7300*3d8817e4Smiod       || ! ieee_init_buffer (info, &info->fnargs))
7301*3d8817e4Smiod     return FALSE;
7302*3d8817e4Smiod   info->fnargcount = 0;
7303*3d8817e4Smiod 
7304*3d8817e4Smiod   return TRUE;
7305*3d8817e4Smiod }
7306*3d8817e4Smiod 
7307*3d8817e4Smiod /* Record line number information.  */
7308*3d8817e4Smiod 
7309*3d8817e4Smiod static bfd_boolean
ieee_lineno(void * p,const char * filename,unsigned long lineno,bfd_vma addr)7310*3d8817e4Smiod ieee_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr)
7311*3d8817e4Smiod {
7312*3d8817e4Smiod   struct ieee_handle *info = (struct ieee_handle *) p;
7313*3d8817e4Smiod 
7314*3d8817e4Smiod   assert (info->filename != NULL);
7315*3d8817e4Smiod 
7316*3d8817e4Smiod   /* The HP simulator seems to get confused when more than one line is
7317*3d8817e4Smiod      listed for the same address, at least if they are in different
7318*3d8817e4Smiod      files.  We handle this by always listing the last line for a
7319*3d8817e4Smiod      given address, since that seems to be the one that gdb uses.  */
7320*3d8817e4Smiod   if (info->pending_lineno_filename != NULL
7321*3d8817e4Smiod       && addr != info->pending_lineno_addr)
7322*3d8817e4Smiod     {
7323*3d8817e4Smiod       /* Make sure we have a line number block.  */
7324*3d8817e4Smiod       if (! ieee_buffer_emptyp (&info->linenos))
7325*3d8817e4Smiod 	{
7326*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->linenos))
7327*3d8817e4Smiod 	    return FALSE;
7328*3d8817e4Smiod 	}
7329*3d8817e4Smiod       else
7330*3d8817e4Smiod 	{
7331*3d8817e4Smiod 	  info->lineno_name_indx = info->name_indx;
7332*3d8817e4Smiod 	  ++info->name_indx;
7333*3d8817e4Smiod 	  if (! ieee_change_buffer (info, &info->linenos)
7334*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_bb_record_enum)
7335*3d8817e4Smiod 	      || ! ieee_write_byte (info, 5)
7336*3d8817e4Smiod 	      || ! ieee_write_number (info, 0)
7337*3d8817e4Smiod 	      || ! ieee_write_id (info, info->filename)
7338*3d8817e4Smiod 	      || ! ieee_write_byte (info, (int) ieee_nn_record)
7339*3d8817e4Smiod 	      || ! ieee_write_number (info, info->lineno_name_indx)
7340*3d8817e4Smiod 	      || ! ieee_write_id (info, ""))
7341*3d8817e4Smiod 	    return FALSE;
7342*3d8817e4Smiod 	  info->lineno_filename = info->filename;
7343*3d8817e4Smiod 	}
7344*3d8817e4Smiod 
7345*3d8817e4Smiod       if (strcmp (info->pending_lineno_filename, info->lineno_filename) != 0)
7346*3d8817e4Smiod 	{
7347*3d8817e4Smiod 	  if (strcmp (info->filename, info->lineno_filename) != 0)
7348*3d8817e4Smiod 	    {
7349*3d8817e4Smiod 	      /* We were not in the main file.  Close the block for the
7350*3d8817e4Smiod 		 included file.  */
7351*3d8817e4Smiod 	      if (! ieee_write_byte (info, (int) ieee_be_record_enum))
7352*3d8817e4Smiod 		return FALSE;
7353*3d8817e4Smiod 	      if (strcmp (info->filename, info->pending_lineno_filename) == 0)
7354*3d8817e4Smiod 		{
7355*3d8817e4Smiod 		  /* We need a new NN record, and we aren't about to
7356*3d8817e4Smiod 		     output one.  */
7357*3d8817e4Smiod 		  info->lineno_name_indx = info->name_indx;
7358*3d8817e4Smiod 		  ++info->name_indx;
7359*3d8817e4Smiod 		  if (! ieee_write_byte (info, (int) ieee_nn_record)
7360*3d8817e4Smiod 		      || ! ieee_write_number (info, info->lineno_name_indx)
7361*3d8817e4Smiod 		      || ! ieee_write_id (info, ""))
7362*3d8817e4Smiod 		    return FALSE;
7363*3d8817e4Smiod 		}
7364*3d8817e4Smiod 	    }
7365*3d8817e4Smiod 	  if (strcmp (info->filename, info->pending_lineno_filename) != 0)
7366*3d8817e4Smiod 	    {
7367*3d8817e4Smiod 	      /* We are not changing to the main file.  Open a block for
7368*3d8817e4Smiod 		 the new included file.  */
7369*3d8817e4Smiod 	      info->lineno_name_indx = info->name_indx;
7370*3d8817e4Smiod 	      ++info->name_indx;
7371*3d8817e4Smiod 	      if (! ieee_write_byte (info, (int) ieee_bb_record_enum)
7372*3d8817e4Smiod 		  || ! ieee_write_byte (info, 5)
7373*3d8817e4Smiod 		  || ! ieee_write_number (info, 0)
7374*3d8817e4Smiod 		  || ! ieee_write_id (info, info->pending_lineno_filename)
7375*3d8817e4Smiod 		  || ! ieee_write_byte (info, (int) ieee_nn_record)
7376*3d8817e4Smiod 		  || ! ieee_write_number (info, info->lineno_name_indx)
7377*3d8817e4Smiod 		  || ! ieee_write_id (info, ""))
7378*3d8817e4Smiod 		return FALSE;
7379*3d8817e4Smiod 	    }
7380*3d8817e4Smiod 	  info->lineno_filename = info->pending_lineno_filename;
7381*3d8817e4Smiod 	}
7382*3d8817e4Smiod 
7383*3d8817e4Smiod       if (! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
7384*3d8817e4Smiod 	  || ! ieee_write_number (info, info->lineno_name_indx)
7385*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7386*3d8817e4Smiod 	  || ! ieee_write_number (info, 7)
7387*3d8817e4Smiod 	  || ! ieee_write_number (info, info->pending_lineno)
7388*3d8817e4Smiod 	  || ! ieee_write_number (info, 0)
7389*3d8817e4Smiod 	  || ! ieee_write_asn (info, info->lineno_name_indx,
7390*3d8817e4Smiod 			       info->pending_lineno_addr))
7391*3d8817e4Smiod 	return FALSE;
7392*3d8817e4Smiod     }
7393*3d8817e4Smiod 
7394*3d8817e4Smiod   info->pending_lineno_filename = filename;
7395*3d8817e4Smiod   info->pending_lineno = lineno;
7396*3d8817e4Smiod   info->pending_lineno_addr = addr;
7397*3d8817e4Smiod 
7398*3d8817e4Smiod   return TRUE;
7399*3d8817e4Smiod }
7400