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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [gnu-v2-abi.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/* Abstraction of GNU v2 abi.
2
   Contributed by Daniel Berlin <dberlin@redhat.com>
3
   Copyright 2001 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or
8
   modify
9
   it under the terms of the GNU General Public License as published
10
   by
11
   the Free Software Foundation; either version 2 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 59 Temple Place - Suite 330,
22
   Boston, MA 02111-1307, USA.  */
23
 
24
#include "defs.h"
25
#include "gdb_string.h"
26
#include "symtab.h"
27
#include "gdbtypes.h"
28
#include "value.h"
29
#include "demangle.h"
30
#include "cp-abi.h"
31
 
32
#include <ctype.h>
33
 
34
struct cp_abi_ops gnu_v2_abi_ops;
35
 
36
static int vb_match (struct type *, int, struct type *);
37
 
38
static enum dtor_kinds
39
gnuv2_is_destructor_name (const char *name)
40
{
41
  if ((name[0] == '_' && is_cplus_marker (name[1]) && name[2] == '_')
42
      || strncmp (name, "__dt__", 6) == 0)
43
    return complete_object_dtor;
44
  else
45
    return 0;
46
}
47
 
48
static enum ctor_kinds
49
gnuv2_is_constructor_name (const char *name)
50
{
51
  if ((name[0] == '_' && name[1] == '_'
52
       && (isdigit (name[2]) || strchr ("Qt", name[2])))
53
      || strncmp (name, "__ct__", 6) == 0)
54
    return complete_object_ctor;
55
  else
56
    return 0;
57
}
58
 
59
static int
60
gnuv2_is_vtable_name (const char *name)
61
{
62
  return (((name)[0] == '_'
63
           && (((name)[1] == 'V' && (name)[2] == 'T')
64
               || ((name)[1] == 'v' && (name)[2] == 't'))
65
           && is_cplus_marker ((name)[3])) ||
66
          ((name)[0] == '_' && (name)[1] == '_'
67
           && (name)[2] == 'v' && (name)[3] == 't' && (name)[4] == '_'));
68
}
69
 
70
static int
71
gnuv2_is_operator_name (const char *name)
72
{
73
  return strncmp (name, "operator", 8) == 0;
74
}
75
 
76
 
77
/* Return a virtual function as a value.
78
   ARG1 is the object which provides the virtual function
79
   table pointer.  *ARG1P is side-effected in calling this function.
80
   F is the list of member functions which contains the desired virtual
81
   function.
82
   J is an index into F which provides the desired virtual function.
83
 
84
   TYPE is the type in which F is located.  */
85
static value_ptr
86
gnuv2_virtual_fn_field (value_ptr * arg1p, struct fn_field * f, int j,
87
                        struct type * type, int offset)
88
{
89
  value_ptr arg1 = *arg1p;
90
  struct type *type1 = check_typedef (VALUE_TYPE (arg1));
91
 
92
 
93
  struct type *entry_type;
94
  /* First, get the virtual function table pointer.  That comes
95
     with a strange type, so cast it to type `pointer to long' (which
96
     should serve just fine as a function type).  Then, index into
97
     the table, and convert final value to appropriate function type.  */
98
  value_ptr entry, vfn, vtbl;
99
  value_ptr vi = value_from_longest (builtin_type_int,
100
                                     (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
101
  struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);
102
  struct type *context;
103
  if (fcontext == NULL)
104
    /* We don't have an fcontext (e.g. the program was compiled with
105
       g++ version 1).  Try to get the vtbl from the TYPE_VPTR_BASETYPE.
106
       This won't work right for multiple inheritance, but at least we
107
       should do as well as GDB 3.x did.  */
108
    fcontext = TYPE_VPTR_BASETYPE (type);
109
  context = lookup_pointer_type (fcontext);
110
  /* Now context is a pointer to the basetype containing the vtbl.  */
111
  if (TYPE_TARGET_TYPE (context) != type1)
112
    {
113
      value_ptr tmp = value_cast (context, value_addr (arg1));
114
      arg1 = value_ind (tmp);
115
      type1 = check_typedef (VALUE_TYPE (arg1));
116
    }
117
 
118
  context = type1;
119
  /* Now context is the basetype containing the vtbl.  */
120
 
121
  /* This type may have been defined before its virtual function table
122
     was.  If so, fill in the virtual function table entry for the
123
     type now.  */
124
  if (TYPE_VPTR_FIELDNO (context) < 0)
125
    fill_in_vptr_fieldno (context);
126
 
127
  /* The virtual function table is now an array of structures
128
     which have the form { int16 offset, delta; void *pfn; }.  */
129
  vtbl = value_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
130
                                TYPE_VPTR_BASETYPE (context));
131
 
132
  /* With older versions of g++, the vtbl field pointed to an array
133
     of structures.  Nowadays it points directly to the structure. */
134
  if (TYPE_CODE (VALUE_TYPE (vtbl)) == TYPE_CODE_PTR
135
      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (vtbl))) == TYPE_CODE_ARRAY)
136
    {
137
      /* Handle the case where the vtbl field points to an
138
         array of structures. */
139
      vtbl = value_ind (vtbl);
140
 
141
      /* Index into the virtual function table.  This is hard-coded because
142
         looking up a field is not cheap, and it may be important to save
143
         time, e.g. if the user has set a conditional breakpoint calling
144
         a virtual function.  */
145
      entry = value_subscript (vtbl, vi);
146
    }
147
  else
148
    {
149
      /* Handle the case where the vtbl field points directly to a structure. */
150
      vtbl = value_add (vtbl, vi);
151
      entry = value_ind (vtbl);
152
    }
153
 
154
  entry_type = check_typedef (VALUE_TYPE (entry));
155
 
156
  if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
157
    {
158
      /* Move the `this' pointer according to the virtual function table. */
159
      VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0));
160
 
161
      if (!VALUE_LAZY (arg1))
162
        {
163
          VALUE_LAZY (arg1) = 1;
164
          value_fetch_lazy (arg1);
165
        }
166
 
167
      vfn = value_field (entry, 2);
168
    }
169
  else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
170
    vfn = entry;
171
  else
172
    error ("I'm confused:  virtual function table has bad type");
173
  /* Reinstantiate the function pointer with the correct type.  */
174
  VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
175
 
176
  *arg1p = arg1;
177
  return vfn;
178
}
179
 
180
 
181
struct type *
182
gnuv2_value_rtti_type (value_ptr v, int *full, int *top, int *using_enc)
183
{
184
  struct type *known_type;
185
  struct type *rtti_type;
186
  CORE_ADDR coreptr;
187
  value_ptr vp;
188
  int using_enclosing = 0;
189
  long top_offset = 0;
190
  char rtti_type_name[256];
191
  CORE_ADDR vtbl;
192
  struct minimal_symbol *minsym;
193
  struct symbol *sym;
194
  char *demangled_name;
195
  struct type *btype;
196
 
197
  if (full)
198
    *full = 0;
199
  if (top)
200
    *top = -1;
201
  if (using_enc)
202
    *using_enc = 0;
203
 
204
  /* Get declared type */
205
  known_type = VALUE_TYPE (v);
206
  CHECK_TYPEDEF (known_type);
207
  /* RTTI works only or class objects */
208
  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
209
    return NULL;
210
 
211
  /* Plan on this changing in the future as i get around to setting
212
     the vtables properly for G++ compiled stuff.  Also, I'll be using
213
     the type info functions, which are always right.  Deal with it
214
     until then.  */
215
 
216
  /* If the type has no vptr fieldno, try to get it filled in */
217
  if (TYPE_VPTR_FIELDNO(known_type) < 0)
218
    fill_in_vptr_fieldno(known_type);
219
 
220
  /* If we still can't find one, give up */
221
  if (TYPE_VPTR_FIELDNO(known_type) < 0)
222
    return NULL;
223
 
224
  /* Make sure our basetype and known type match, otherwise, cast
225
     so we can get at the vtable properly.
226
  */
227
  btype = TYPE_VPTR_BASETYPE (known_type);
228
  CHECK_TYPEDEF (btype);
229
  if (btype != known_type )
230
    {
231
      v = value_cast (btype, v);
232
      if (using_enc)
233
        *using_enc=1;
234
    }
235
  /*
236
    We can't use value_ind here, because it would want to use RTTI, and
237
    we'd waste a bunch of time figuring out we already know the type.
238
    Besides, we don't care about the type, just the actual pointer
239
  */
240
  if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
241
    return NULL;
242
 
243
  /*
244
    If we are enclosed by something that isn't us, adjust the
245
    address properly and set using_enclosing.
246
  */
247
  if (VALUE_ENCLOSING_TYPE(v) != VALUE_TYPE(v))
248
    {
249
      value_ptr tempval;
250
      int bitpos = TYPE_BASECLASS_BITPOS (known_type,
251
                                          TYPE_VPTR_FIELDNO (known_type));
252
      tempval=value_field (v, TYPE_VPTR_FIELDNO(known_type));
253
      VALUE_ADDRESS(tempval) += bitpos / 8;
254
      vtbl=value_as_pointer (tempval);
255
      using_enclosing=1;
256
    }
257
  else
258
    {
259
      vtbl=value_as_pointer(value_field(v,TYPE_VPTR_FIELDNO(known_type)));
260
      using_enclosing=0;
261
    }
262
 
263
  /* Try to find a symbol that is the vtable */
264
  minsym=lookup_minimal_symbol_by_pc(vtbl);
265
  if (minsym==NULL
266
      || (demangled_name=SYMBOL_NAME(minsym))==NULL
267
      || !is_vtable_name (demangled_name))
268
    return NULL;
269
 
270
  /* If we just skip the prefix, we get screwed by namespaces */
271
  demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
272
  *(strchr(demangled_name,' '))=0;
273
 
274
  /* Lookup the type for the name */
275
  rtti_type=lookup_typename(demangled_name, (struct block *)0,1);
276
 
277
  if (rtti_type==NULL)
278
    return NULL;
279
 
280
  if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
281
    {
282
      if (top)
283
        *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
284
      if (top && ((*top) >0))
285
        {
286
          if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
287
            {
288
              if (full)
289
                *full=0;
290
            }
291
          else
292
            {
293
              if (full)
294
                *full=1;
295
            }
296
        }
297
    }
298
  else
299
    {
300
      if (full)
301
        *full=1;
302
    }
303
  if (using_enc)
304
    *using_enc=using_enclosing;
305
 
306
  return rtti_type;
307
}
308
 
309
 
310
static void
311
init_gnuv2_ops (void)
312
{
313
  gnu_v2_abi_ops.shortname = "gnu-v2";
314
  gnu_v2_abi_ops.longname = "GNU G++ Version 2 ABI";
315
  gnu_v2_abi_ops.doc = "G++ Version 2 ABI";
316
  gnu_v2_abi_ops.is_destructor_name = gnuv2_is_destructor_name;
317
  gnu_v2_abi_ops.is_constructor_name = gnuv2_is_constructor_name;
318
  gnu_v2_abi_ops.is_vtable_name = gnuv2_is_vtable_name;
319
  gnu_v2_abi_ops.is_operator_name = gnuv2_is_operator_name;
320
  gnu_v2_abi_ops.virtual_fn_field = gnuv2_virtual_fn_field;
321
  gnu_v2_abi_ops.rtti_type = gnuv2_value_rtti_type;
322
}
323
 
324
void
325
_initialize_gnu_v2_abi (void)
326
{
327
  init_gnuv2_ops ();
328
  register_cp_abi (gnu_v2_abi_ops);
329
  switch_to_cp_abi ("gnu-v2");
330
}

powered by: WebSVN 2.1.0

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