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