OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [gnu-v2-abi.c] - Blame information for rev 853

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Abstraction of GNU v2 abi.
2
 
3
   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008
4
   Free Software Foundation, Inc.
5
 
6
   Contributed by Daniel Berlin <dberlin@redhat.com>
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
#include "defs.h"
24
#include "gdb_string.h"
25
#include "symtab.h"
26
#include "gdbtypes.h"
27
#include "value.h"
28
#include "demangle.h"
29
#include "cp-abi.h"
30
#include "cp-support.h"
31
#include "gnu-v2-abi.h"
32
 
33
#include <ctype.h>
34
 
35
struct cp_abi_ops gnu_v2_abi_ops;
36
 
37
static int vb_match (struct type *, int, struct type *);
38
 
39
static enum dtor_kinds
40
gnuv2_is_destructor_name (const char *name)
41
{
42
  if ((name[0] == '_' && is_cplus_marker (name[1]) && name[2] == '_')
43
      || strncmp (name, "__dt__", 6) == 0)
44
    return complete_object_dtor;
45
  else
46
    return 0;
47
}
48
 
49
static enum ctor_kinds
50
gnuv2_is_constructor_name (const char *name)
51
{
52
  if ((name[0] == '_' && name[1] == '_'
53
       && (isdigit (name[2]) || strchr ("Qt", name[2])))
54
      || strncmp (name, "__ct__", 6) == 0)
55
    return complete_object_ctor;
56
  else
57
    return 0;
58
}
59
 
60
static int
61
gnuv2_is_vtable_name (const char *name)
62
{
63
  return (((name)[0] == '_'
64
           && (((name)[1] == 'V' && (name)[2] == 'T')
65
               || ((name)[1] == 'v' && (name)[2] == 't'))
66
           && is_cplus_marker ((name)[3])) ||
67
          ((name)[0] == '_' && (name)[1] == '_'
68
           && (name)[2] == 'v' && (name)[3] == 't' && (name)[4] == '_'));
69
}
70
 
71
static int
72
gnuv2_is_operator_name (const char *name)
73
{
74
  return strncmp (name, "operator", 8) == 0;
75
}
76
 
77
 
78
/* Return a virtual function as a value.
79
   ARG1 is the object which provides the virtual function
80
   table pointer.  *ARG1P is side-effected in calling this function.
81
   F is the list of member functions which contains the desired virtual
82
   function.
83
   J is an index into F which provides the desired virtual function.
84
 
85
   TYPE is the type in which F is located.  */
86
static struct value *
87
gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
88
                        struct type * type, int offset)
89
{
90
  struct value *arg1 = *arg1p;
91
  struct type *type1 = check_typedef (value_type (arg1));
92
  struct type *entry_type;
93
  /* First, get the virtual function table pointer.  That comes
94
     with a strange type, so cast it to type `pointer to long' (which
95
     should serve just fine as a function type).  Then, index into
96
     the table, and convert final value to appropriate function type.  */
97
  struct value *entry;
98
  struct value *vfn;
99
  struct value *vtbl;
100
  struct value *vi = value_from_longest (builtin_type_int,
101
                                     (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
102
  struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
103
  struct type *context;
104
  struct type *context_vptr_basetype;
105
  int context_vptr_fieldno;
106
 
107
  if (fcontext == NULL)
108
    /* We don't have an fcontext (e.g. the program was compiled with
109
       g++ version 1).  Try to get the vtbl from the TYPE_VPTR_BASETYPE.
110
       This won't work right for multiple inheritance, but at least we
111
       should do as well as GDB 3.x did.  */
112
    fcontext = TYPE_VPTR_BASETYPE (type);
113
  context = lookup_pointer_type (fcontext);
114
  /* Now context is a pointer to the basetype containing the vtbl.  */
115
  if (TYPE_TARGET_TYPE (context) != type1)
116
    {
117
      struct value *tmp = value_cast (context, value_addr (arg1));
118
      arg1 = value_ind (tmp);
119
      type1 = check_typedef (value_type (arg1));
120
    }
121
 
122
  context = type1;
123
  /* Now context is the basetype containing the vtbl.  */
124
 
125
  /* This type may have been defined before its virtual function table
126
     was.  If so, fill in the virtual function table entry for the
127
     type now.  */
128
  context_vptr_fieldno = get_vptr_fieldno (context, &context_vptr_basetype);
129
  /* FIXME: What to do if vptr_fieldno is still -1?  */
130
 
131
  /* The virtual function table is now an array of structures
132
     which have the form { int16 offset, delta; void *pfn; }.  */
133
  vtbl = value_primitive_field (arg1, 0, context_vptr_fieldno,
134
                                context_vptr_basetype);
135
 
136
  /* With older versions of g++, the vtbl field pointed to an array
137
     of structures.  Nowadays it points directly to the structure. */
138
  if (TYPE_CODE (value_type (vtbl)) == TYPE_CODE_PTR
139
      && TYPE_CODE (TYPE_TARGET_TYPE (value_type (vtbl))) == TYPE_CODE_ARRAY)
140
    {
141
      /* Handle the case where the vtbl field points to an
142
         array of structures. */
143
      vtbl = value_ind (vtbl);
144
 
145
      /* Index into the virtual function table.  This is hard-coded because
146
         looking up a field is not cheap, and it may be important to save
147
         time, e.g. if the user has set a conditional breakpoint calling
148
         a virtual function.  */
149
      entry = value_subscript (vtbl, vi);
150
    }
151
  else
152
    {
153
      /* Handle the case where the vtbl field points directly to a structure. */
154
      vtbl = value_add (vtbl, vi);
155
      entry = value_ind (vtbl);
156
    }
157
 
158
  entry_type = check_typedef (value_type (entry));
159
 
160
  if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
161
    {
162
      /* Move the `this' pointer according to the virtual function table. */
163
      set_value_offset (arg1, value_offset (arg1) + value_as_long (value_field (entry, 0)));
164
 
165
      if (!value_lazy (arg1))
166
        {
167
          set_value_lazy (arg1, 1);
168
          value_fetch_lazy (arg1);
169
        }
170
 
171
      vfn = value_field (entry, 2);
172
    }
173
  else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
174
    vfn = entry;
175
  else
176
    error (_("I'm confused:  virtual function table has bad type"));
177
  /* Reinstantiate the function pointer with the correct type.  */
178
  deprecated_set_value_type (vfn, lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)));
179
 
180
  *arg1p = arg1;
181
  return vfn;
182
}
183
 
184
 
185
static struct type *
186
gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
187
{
188
  struct type *known_type;
189
  struct type *rtti_type;
190
  CORE_ADDR coreptr;
191
  struct value *vp;
192
  long top_offset = 0;
193
  char rtti_type_name[256];
194
  CORE_ADDR vtbl;
195
  struct minimal_symbol *minsym;
196
  struct symbol *sym;
197
  char *demangled_name, *p;
198
  struct type *btype;
199
  struct type *known_type_vptr_basetype;
200
  int known_type_vptr_fieldno;
201
 
202
  if (full)
203
    *full = 0;
204
  if (top)
205
    *top = -1;
206
  if (using_enc)
207
    *using_enc = 0;
208
 
209
  /* Get declared type */
210
  known_type = value_type (v);
211
  CHECK_TYPEDEF (known_type);
212
  /* RTTI works only or class objects */
213
  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
214
    return NULL;
215
 
216
  /* Plan on this changing in the future as i get around to setting
217
     the vtables properly for G++ compiled stuff.  Also, I'll be using
218
     the type info functions, which are always right.  Deal with it
219
     until then.  */
220
 
221
  /* Try to get the vptr basetype, fieldno.  */
222
  known_type_vptr_fieldno = get_vptr_fieldno (known_type,
223
                                              &known_type_vptr_basetype);
224
 
225
  /* If we can't find it, give up.  */
226
  if (known_type_vptr_fieldno < 0)
227
    return NULL;
228
 
229
  /* Make sure our basetype and known type match, otherwise, cast
230
     so we can get at the vtable properly.
231
  */
232
  btype = known_type_vptr_basetype;
233
  CHECK_TYPEDEF (btype);
234
  if (btype != known_type )
235
    {
236
      v = value_cast (btype, v);
237
      if (using_enc)
238
        *using_enc=1;
239
    }
240
  /*
241
    We can't use value_ind here, because it would want to use RTTI, and
242
    we'd waste a bunch of time figuring out we already know the type.
243
    Besides, we don't care about the type, just the actual pointer
244
  */
245
  if (VALUE_ADDRESS (value_field (v, known_type_vptr_fieldno)) == 0)
246
    return NULL;
247
 
248
  vtbl = value_as_address (value_field (v, known_type_vptr_fieldno));
249
 
250
  /* Try to find a symbol that is the vtable */
251
  minsym=lookup_minimal_symbol_by_pc(vtbl);
252
  if (minsym==NULL
253
      || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL
254
      || !is_vtable_name (demangled_name))
255
    return NULL;
256
 
257
  /* If we just skip the prefix, we get screwed by namespaces */
258
  demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
259
  p = strchr (demangled_name, ' ');
260
  if (p)
261
    *p = '\0';
262
 
263
  /* Lookup the type for the name */
264
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465. */
265
  rtti_type = cp_lookup_rtti_type (demangled_name, NULL);
266
  if (rtti_type == NULL)
267
    return NULL;
268
 
269
  if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
270
    {
271
      if (top)
272
        *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
273
      if (top && ((*top) >0))
274
        {
275
          if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
276
            {
277
              if (full)
278
                *full=0;
279
            }
280
          else
281
            {
282
              if (full)
283
                *full=1;
284
            }
285
        }
286
    }
287
  else
288
    {
289
      if (full)
290
        *full=1;
291
    }
292
 
293
  return rtti_type;
294
}
295
 
296
/* Return true if the INDEXth field of TYPE is a virtual baseclass
297
   pointer which is for the base class whose type is BASECLASS.  */
298
 
299
static int
300
vb_match (struct type *type, int index, struct type *basetype)
301
{
302
  struct type *fieldtype;
303
  char *name = TYPE_FIELD_NAME (type, index);
304
  char *field_class_name = NULL;
305
 
306
  if (*name != '_')
307
    return 0;
308
  /* gcc 2.4 uses _vb$.  */
309
  if (name[1] == 'v' && name[2] == 'b' && is_cplus_marker (name[3]))
310
    field_class_name = name + 4;
311
  /* gcc 2.5 will use __vb_.  */
312
  if (name[1] == '_' && name[2] == 'v' && name[3] == 'b' && name[4] == '_')
313
    field_class_name = name + 5;
314
 
315
  if (field_class_name == NULL)
316
    /* This field is not a virtual base class pointer.  */
317
    return 0;
318
 
319
  /* It's a virtual baseclass pointer, now we just need to find out whether
320
     it is for this baseclass.  */
321
  fieldtype = TYPE_FIELD_TYPE (type, index);
322
  if (fieldtype == NULL
323
      || TYPE_CODE (fieldtype) != TYPE_CODE_PTR)
324
    /* "Can't happen".  */
325
    return 0;
326
 
327
  /* What we check for is that either the types are equal (needed for
328
     nameless types) or have the same name.  This is ugly, and a more
329
     elegant solution should be devised (which would probably just push
330
     the ugliness into symbol reading unless we change the stabs format).  */
331
  if (TYPE_TARGET_TYPE (fieldtype) == basetype)
332
    return 1;
333
 
334
  if (TYPE_NAME (basetype) != NULL
335
      && TYPE_NAME (TYPE_TARGET_TYPE (fieldtype)) != NULL
336
      && strcmp (TYPE_NAME (basetype),
337
                 TYPE_NAME (TYPE_TARGET_TYPE (fieldtype))) == 0)
338
    return 1;
339
  return 0;
340
}
341
 
342
/* Compute the offset of the baseclass which is
343
   the INDEXth baseclass of class TYPE,
344
   for value at VALADDR (in host) at ADDRESS (in target).
345
   The result is the offset of the baseclass value relative
346
   to (the address of)(ARG) + OFFSET.
347
 
348
   -1 is returned on error. */
349
 
350
int
351
gnuv2_baseclass_offset (struct type *type, int index,
352
                        const bfd_byte *valaddr, CORE_ADDR address)
353
{
354
  struct type *basetype = TYPE_BASECLASS (type, index);
355
 
356
  if (BASETYPE_VIA_VIRTUAL (type, index))
357
    {
358
      /* Must hunt for the pointer to this virtual baseclass.  */
359
      int i, len = TYPE_NFIELDS (type);
360
      int n_baseclasses = TYPE_N_BASECLASSES (type);
361
 
362
      /* First look for the virtual baseclass pointer
363
         in the fields.  */
364
      for (i = n_baseclasses; i < len; i++)
365
        {
366
          if (vb_match (type, i, basetype))
367
            {
368
              CORE_ADDR addr
369
              = unpack_pointer (TYPE_FIELD_TYPE (type, i),
370
                                valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
371
 
372
              return addr - (LONGEST) address;
373
            }
374
        }
375
      /* Not in the fields, so try looking through the baseclasses.  */
376
      for (i = index + 1; i < n_baseclasses; i++)
377
        {
378
          int boffset =
379
          baseclass_offset (type, i, valaddr, address);
380
          if (boffset)
381
            return boffset;
382
        }
383
      /* Not found.  */
384
      return -1;
385
    }
386
 
387
  /* Baseclass is easily computed.  */
388
  return TYPE_BASECLASS_BITPOS (type, index) / 8;
389
}
390
 
391
static void
392
init_gnuv2_ops (void)
393
{
394
  gnu_v2_abi_ops.shortname = "gnu-v2";
395
  gnu_v2_abi_ops.longname = "GNU G++ Version 2 ABI";
396
  gnu_v2_abi_ops.doc = "G++ Version 2 ABI";
397
  gnu_v2_abi_ops.is_destructor_name = gnuv2_is_destructor_name;
398
  gnu_v2_abi_ops.is_constructor_name = gnuv2_is_constructor_name;
399
  gnu_v2_abi_ops.is_vtable_name = gnuv2_is_vtable_name;
400
  gnu_v2_abi_ops.is_operator_name = gnuv2_is_operator_name;
401
  gnu_v2_abi_ops.virtual_fn_field = gnuv2_virtual_fn_field;
402
  gnu_v2_abi_ops.rtti_type = gnuv2_value_rtti_type;
403
  gnu_v2_abi_ops.baseclass_offset = gnuv2_baseclass_offset;
404
}
405
 
406
extern initialize_file_ftype _initialize_gnu_v2_abi; /* -Wmissing-prototypes */
407
 
408
void
409
_initialize_gnu_v2_abi (void)
410
{
411
  init_gnuv2_ops ();
412
  register_cp_abi (&gnu_v2_abi_ops);
413
  set_cp_abi_as_auto_default (gnu_v2_abi_ops.shortname);
414
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.