File: | src/gnu/usr.bin/binutils/gdb/hpacc-abi.c |
Warning: | line 88, column 16 Value stored to 'type1' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 (regexecxregexec (&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 (regexecxregexec (&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 regexecxregexec (&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)(arg1)->type); |
Value stored to 'type1' during its initialization is never read | |
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)(f)[j].type; /* method type */ |
96 | |
97 | argp = value_cast (type, *arg1p); |
98 | |
99 | if (VALUE_ADDRESS (argp)(argp)->location.address == 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)((void)((argp)->lazy && value_fetch_lazy(argp)), ( (char *) (argp)->aligner.contents + (argp)->embedded_offset ))); /* 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)((f)[j].voffset-2) + |
131 | HP_ACC_VFUNC_START4), NULL((void*)0)); |
132 | |
133 | coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)((void)((vp)->lazy && value_fetch_lazy(vp)), ((char *) (vp)->aligner.contents + (vp)->embedded_offset))); |
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_START4 + class_index), NULL((void*)0)); |
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)((void)((vp)->lazy && value_fetch_lazy(vp)), ((char *) (vp)->aligner.contents + (vp)->embedded_offset)) + |
155 | 4 * TYPE_FN_FIELD_VOFFSET (f, j)((f)[j].voffset-2)); |
156 | vp = value_at (builtin_type_int, coreptr, NULL((void*)0)); |
157 | coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)((void)((vp)->lazy && value_fetch_lazy(vp)), ((char *) (vp)->aligner.contents + (vp)->embedded_offset))); |
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)(vp)->type = ftype; |
170 | VALUE_ADDRESS (vp)(vp)->location.address = 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)(v)->type; |
197 | CHECK_TYPEDEF (known_type)(known_type) = check_typedef (known_type); |
198 | /* RTTI works only or class objects */ |
199 | if (TYPE_CODE (known_type)(known_type)->main_type->code != TYPE_CODE_CLASSTYPE_CODE_STRUCT) |
200 | return NULL((void*)0); |
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)(((known_type)->main_type->type_specific.cplus_stuff-> runtime_ptr) && (((known_type)->main_type->type_specific .cplus_stuff->runtime_ptr)->has_vtable))) |
206 | { |
207 | known_type = VALUE_ENCLOSING_TYPE (v)(v)->enclosing_type; |
208 | CHECK_TYPEDEF (known_type)(known_type) = check_typedef (known_type); |
209 | if ((TYPE_CODE (known_type)(known_type)->main_type->code != TYPE_CODE_CLASSTYPE_CODE_STRUCT) || |
210 | !TYPE_HAS_VTABLE (known_type)(((known_type)->main_type->type_specific.cplus_stuff-> runtime_ptr) && (((known_type)->main_type->type_specific .cplus_stuff->runtime_ptr)->has_vtable))) |
211 | return NULL((void*)0); /* No RTTI, or not HP-compiled types */ |
212 | CHECK_TYPEDEF (known_type)(known_type) = 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)((void) ((v)->lazy && value_fetch_lazy(v)), ((char *) (v)->aligner.contents))) |
221 | + VALUE_OFFSET (v)(v)->offset |
222 | + (using_enclosing |
223 | ? 0 |
224 | : VALUE_EMBEDDED_OFFSET (v)((v)->embedded_offset))); |
225 | if (coreptr == 0) |
226 | /* return silently -- maybe called on gdb-generated value */ |
227 | return NULL((void*)0); |
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_OFFSET1, |
233 | VALUE_BFD_SECTION (v)((v)->bfd_section)); |
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_OFFSET2, |
241 | VALUE_BFD_SECTION (v)((v)->bfd_section)); |
242 | /* Indirect through the typeinfo pointer and retrieve the pointer |
243 | * to the string name */ |
244 | coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)((void)((vp)->lazy && value_fetch_lazy(vp)), ((char *) (vp)->aligner.contents + (vp)->embedded_offset))); |
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)((v)->bfd_section)); |
250 | /* FIXME possible 32x64 problem */ |
251 | |
252 | coreptr = *(CORE_ADDR *) (VALUE_CONTENTS (vp)((void)((vp)->lazy && value_fetch_lazy(vp)), ((char *) (vp)->aligner.contents + (vp)->embedded_offset))); |
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)(rtti_type) = check_typedef (rtti_type); |
266 | #if 0 |
267 | printf ("RTTI type name %s, tag %s, full? %d\n", TYPE_NAME (rtti_type)(rtti_type)->main_type->name, |
268 | TYPE_TAG_NAME (rtti_type)(rtti_type)->main_type->tag_name, 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)(known_type)->length == TYPE_LENGTH (rtti_type)(rtti_type)->length) |
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)((v)->embedded_offset)) && |
282 | !using_enclosing && |
283 | TYPE_LENGTH (VALUE_ENCLOSING_TYPE (v))((v)->enclosing_type)->length == TYPE_LENGTH (rtti_type)(rtti_type)->length))) |
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 | regcompxregcomp (&constructor_pattern, |
320 | "^This will never match anything, please fill it in$", REG_NOSUB(((1 << 1) << 1) << 1)); |
321 | |
322 | regcompxregcomp (&destructor_pattern, |
323 | "^This will never match anything, please fill it in$", REG_NOSUB(((1 << 1) << 1) << 1)); |
324 | |
325 | regcompxregcomp (&operator_pattern, |
326 | "^This will never match anything, please fill it in$", REG_NOSUB(((1 << 1) << 1) << 1)); |
327 | |
328 | register_cp_abi (&hpacc_abi_ops); |
329 | } |