1 /* Abstraction of HP aCC ABI. 2 Contributed by Daniel Berlin <dberlin@redhat.com> 3 Most of the real code is from HP, i've just fiddled it to fit in 4 the C++ ABI abstraction framework. 5 6 Copyright 2001 Free Software Foundation, Inc. 7 8 This file is part of GDB. 9 10 This program is free software; you can redistribute it and/or 11 modify 12 it under the terms of the GNU General Public License as published 13 by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place - Suite 330, 25 Boston, MA 02111-1307, USA. */ 26 27 #include "defs.h" 28 #include "value.h" 29 #include "gdb_regex.h" 30 #include "gdb_string.h" 31 #include "gdbtypes.h" 32 #include "gdbcore.h" 33 #include "cp-abi.h" 34 35 struct cp_abi_ops hpacc_abi_ops; 36 37 /* It appears the is_*_name stuff is never used when we try the hpACC 38 * ABI. As such, I have no clue what the real answers are. Shouldn't 39 * have any more effect than it does now. */ 40 static regex_t constructor_pattern; 41 static regex_t destructor_pattern; 42 static regex_t operator_pattern; 43 44 static enum dtor_kinds 45 hpacc_is_destructor_name (const char *name) 46 { 47 if (regexec (&destructor_pattern, name, 0, 0, 0) == 0) 48 return complete_object_dtor; 49 else 50 return 0; 51 } 52 53 static enum ctor_kinds 54 hpacc_is_constructor_name (const char *name) 55 { 56 if (regexec (&constructor_pattern, name, 0, 0, 0) == 0) 57 return complete_object_ctor; 58 else 59 return 0; 60 } 61 62 static int 63 hpacc_is_operator_name (const char *name) 64 { 65 return regexec (&operator_pattern, name, 0, 0, 0) == 0; 66 } 67 68 static int 69 hpacc_is_vtable_name (const char *name) 70 { 71 return strcmp (name, 72 "This will never match anything, please fill it in") == 0; 73 } 74 75 /* Return a virtual function as a value. 76 ARG1 is the object which provides the virtual function 77 table pointer. *ARG1P is side-effected in calling this function. 78 F is the list of member functions which contains the desired virtual 79 function. 80 J is an index into F which provides the desired virtual function. 81 82 TYPE is the type in which F is located. */ 83 static struct value * 84 hpacc_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, 85 struct type * type, int offset) 86 { 87 struct value *arg1 = *arg1p; 88 struct type *type1 = check_typedef (VALUE_TYPE (arg1)); 89 90 /* Deal with HP/Taligent runtime model for virtual functions */ 91 struct value *vp; 92 struct value *argp; /* arg1 cast to base */ 93 CORE_ADDR coreptr; /* pointer to target address */ 94 int class_index; /* which class segment pointer to use */ 95 struct type *ftype = TYPE_FN_FIELD_TYPE (f, j); /* method type */ 96 97 argp = value_cast (type, *arg1p); 98 99 if (VALUE_ADDRESS (argp) == 0) 100 error ("Address of object is null; object may not have been created."); 101 102 /* pai: FIXME -- 32x64 possible problem? */ 103 /* First word (4 bytes) in object layout is the vtable pointer */ 104 coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (argp)); /* pai: (temp) */ 105 /* + offset + VALUE_EMBEDDED_OFFSET (argp)); */ 106 107 if (!coreptr) 108 error 109 ("Virtual table pointer is null for object; object may not have been created."); 110 111 /* pai/1997-05-09 112 * FIXME: The code here currently handles only 113 * the non-RRBC case of the Taligent/HP runtime spec; when RRBC 114 * is introduced, the condition for the "if" below will have to 115 * be changed to be a test for the RRBC case. */ 116 117 if (1) 118 { 119 /* Non-RRBC case; the virtual function pointers are stored at fixed 120 * offsets in the virtual table. */ 121 122 /* Retrieve the offset in the virtual table from the debug 123 * info. The offset of the vfunc's entry is in words from 124 * the beginning of the vtable; but first we have to adjust 125 * by HP_ACC_VFUNC_START to account for other entries */ 126 127 /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in 128 * which case the multiplier should be 8 and values should be long */ 129 vp = value_at (builtin_type_int, 130 coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) + 131 HP_ACC_VFUNC_START), NULL); 132 133 coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)); 134 /* coreptr now contains the address of the virtual function */ 135 /* (Actually, it contains the pointer to the plabel for the function. */ 136 } 137 else 138 { 139 /* RRBC case; the virtual function pointers are found by double 140 * indirection through the class segment tables. */ 141 142 /* Choose class segment depending on type we were passed */ 143 class_index = class_index_in_primary_list (type); 144 145 /* Find class segment pointer. These are in the vtable slots after 146 * some other entries, so adjust by HP_ACC_VFUNC_START for that. */ 147 /* pai: FIXME 32x64 problem here, if words are 8 bytes long 148 * the multiplier below has to be 8 and value should be long. */ 149 vp = value_at (builtin_type_int, 150 coreptr + 4 * (HP_ACC_VFUNC_START + class_index), NULL); 151 /* Indirect once more, offset by function index */ 152 /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */ 153 coreptr = 154 *(CORE_ADDR *) (VALUE_CONTENTS (vp) + 155 4 * TYPE_FN_FIELD_VOFFSET (f, j)); 156 vp = value_at (builtin_type_int, coreptr, NULL); 157 coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)); 158 159 /* coreptr now contains the address of the virtual function */ 160 /* (Actually, it contains the pointer to the plabel for the function.) */ 161 162 } 163 164 if (!coreptr) 165 error ("Address of virtual function is null; error in virtual table?"); 166 167 /* Wrap this addr in a value and return pointer */ 168 vp = allocate_value (ftype); 169 VALUE_TYPE (vp) = ftype; 170 VALUE_ADDRESS (vp) = coreptr; 171 172 /* pai: (temp) do we need the value_ind stuff in value_fn_field? */ 173 return vp; 174 } 175 176 177 static struct type * 178 hpacc_value_rtti_type (struct value *v, int *full, int *top, int *using_enc) 179 { 180 struct type *known_type; 181 struct type *rtti_type; 182 CORE_ADDR coreptr; 183 struct value *vp; 184 int using_enclosing = 0; 185 long top_offset = 0; 186 char rtti_type_name[256]; 187 188 if (full) 189 *full = 0; 190 if (top) 191 *top = -1; 192 if (using_enc) 193 *using_enc = 0; 194 195 /* Get declared type */ 196 known_type = VALUE_TYPE (v); 197 CHECK_TYPEDEF (known_type); 198 /* RTTI works only or class objects */ 199 if (TYPE_CODE (known_type) != TYPE_CODE_CLASS) 200 return NULL; 201 202 /* If neither the declared type nor the enclosing type of the 203 * value structure has a HP ANSI C++ style virtual table, 204 * we can't do anything. */ 205 if (!TYPE_HAS_VTABLE (known_type)) 206 { 207 known_type = VALUE_ENCLOSING_TYPE (v); 208 CHECK_TYPEDEF (known_type); 209 if ((TYPE_CODE (known_type) != TYPE_CODE_CLASS) || 210 !TYPE_HAS_VTABLE (known_type)) 211 return NULL; /* No RTTI, or not HP-compiled types */ 212 CHECK_TYPEDEF (known_type); 213 using_enclosing = 1; 214 } 215 216 if (using_enclosing && using_enc) 217 *using_enc = 1; 218 219 /* First get the virtual table address */ 220 coreptr = *(CORE_ADDR *) ((VALUE_CONTENTS_ALL (v)) 221 + VALUE_OFFSET (v) 222 + (using_enclosing 223 ? 0 224 : VALUE_EMBEDDED_OFFSET (v))); 225 if (coreptr == 0) 226 /* return silently -- maybe called on gdb-generated value */ 227 return NULL; 228 229 /* Fetch the top offset of the object */ 230 /* FIXME possible 32x64 problem with pointer size & arithmetic */ 231 vp = value_at (builtin_type_int, 232 coreptr + 4 * HP_ACC_TOP_OFFSET_OFFSET, 233 VALUE_BFD_SECTION (v)); 234 top_offset = value_as_long (vp); 235 if (top) 236 *top = top_offset; 237 238 /* Fetch the typeinfo pointer */ 239 /* FIXME possible 32x64 problem with pointer size & arithmetic */ 240 vp = value_at (builtin_type_int, coreptr + 4 * HP_ACC_TYPEINFO_OFFSET, 241 VALUE_BFD_SECTION (v)); 242 /* Indirect through the typeinfo pointer and retrieve the pointer 243 * to the string name */ 244 coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)); 245 if (!coreptr) 246 error ("Retrieved null typeinfo pointer in trying to determine " 247 "run-time type"); 248 /* 4 -> offset of name field */ 249 vp = value_at (builtin_type_int, coreptr + 4, VALUE_BFD_SECTION (v)); 250 /* FIXME possible 32x64 problem */ 251 252 coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)); 253 254 read_memory_string (coreptr, rtti_type_name, 256); 255 256 if (strlen (rtti_type_name) == 0) 257 error ("Retrieved null type name from typeinfo"); 258 259 /* search for type */ 260 rtti_type = lookup_typename (rtti_type_name, (struct block *) 0, 1); 261 262 if (!rtti_type) 263 error ("Could not find run-time type: invalid type name %s in typeinfo??", 264 rtti_type_name); 265 CHECK_TYPEDEF (rtti_type); 266 #if 0 267 printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type), 268 TYPE_TAG_NAME (rtti_type), full ? *full : -1); 269 #endif 270 /* Check whether we have the entire object */ 271 if (full /* Non-null pointer passed */ 272 && 273 /* Either we checked on the whole object in hand and found the 274 top offset to be zero */ 275 (((top_offset == 0) && 276 using_enclosing && 277 TYPE_LENGTH (known_type) == TYPE_LENGTH (rtti_type)) 278 || 279 /* Or we checked on the embedded object and top offset was the 280 same as the embedded offset */ 281 ((top_offset == VALUE_EMBEDDED_OFFSET (v)) && 282 !using_enclosing && 283 TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v)) == TYPE_LENGTH (rtti_type)))) 284 285 *full = 1; 286 287 return rtti_type; 288 } 289 290 extern int gnuv2_baseclass_offset (struct type *type, int index, 291 char *valaddr, CORE_ADDR address); 292 293 static void 294 init_hpacc_ops (void) 295 { 296 hpacc_abi_ops.shortname = "hpaCC"; 297 hpacc_abi_ops.longname = "HP aCC ABI"; 298 hpacc_abi_ops.doc = "HP aCC ABI"; 299 hpacc_abi_ops.is_destructor_name = hpacc_is_destructor_name; 300 hpacc_abi_ops.is_constructor_name = hpacc_is_constructor_name; 301 hpacc_abi_ops.is_vtable_name = hpacc_is_vtable_name; 302 hpacc_abi_ops.is_operator_name = hpacc_is_operator_name; 303 hpacc_abi_ops.virtual_fn_field = hpacc_virtual_fn_field; 304 hpacc_abi_ops.rtti_type = hpacc_value_rtti_type; 305 /* It seems that this function is specific to GNU G++ < 3.0. 306 However, it is called for data members even in the HP 307 case (although not for member functions). 308 FIXME: Is that correct? */ 309 hpacc_abi_ops.baseclass_offset = gnuv2_baseclass_offset; 310 } 311 312 extern initialize_file_ftype _initialize_hpacc_abi; /* -Wmissing-prototypes */ 313 314 void 315 _initialize_hpacc_abi (void) 316 { 317 init_hpacc_ops (); 318 319 regcomp (&constructor_pattern, 320 "^This will never match anything, please fill it in$", REG_NOSUB); 321 322 regcomp (&destructor_pattern, 323 "^This will never match anything, please fill it in$", REG_NOSUB); 324 325 regcomp (&operator_pattern, 326 "^This will never match anything, please fill it in$", REG_NOSUB); 327 328 register_cp_abi (&hpacc_abi_ops); 329 } 330