File: | src/gnu/usr.bin/binutils/gdb/jv-lang.c |
Warning: | line 387, column 3 Null pointer passed as 1st argument to memory set function |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* Java language support routines for GDB, the GNU debugger. | |||
2 | Copyright 1997, 1998, 1999, 2000, 2003, 2004 Free Software Foundation, Inc. | |||
3 | ||||
4 | This file is part of GDB. | |||
5 | ||||
6 | This program is free software; you can redistribute it and/or modify | |||
7 | it under the terms of the GNU General Public License as published by | |||
8 | the Free Software Foundation; either version 2 of the License, or | |||
9 | (at your option) any later version. | |||
10 | ||||
11 | This program is distributed in the hope that it will be useful, | |||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
14 | GNU General Public License for more details. | |||
15 | ||||
16 | You should have received a copy of the GNU General Public License | |||
17 | along with this program; if not, write to the Free Software | |||
18 | Foundation, Inc., 59 Temple Place - Suite 330, | |||
19 | Boston, MA 02111-1307, USA. */ | |||
20 | ||||
21 | #include "defs.h" | |||
22 | #include "symtab.h" | |||
23 | #include "gdbtypes.h" | |||
24 | #include "expression.h" | |||
25 | #include "parser-defs.h" | |||
26 | #include "language.h" | |||
27 | #include "gdbtypes.h" | |||
28 | #include "symtab.h" | |||
29 | #include "symfile.h" | |||
30 | #include "objfiles.h" | |||
31 | #include "gdb_string.h" | |||
32 | #include "value.h" | |||
33 | #include "c-lang.h" | |||
34 | #include "jv-lang.h" | |||
35 | #include "gdbcore.h" | |||
36 | #include "block.h" | |||
37 | #include "demangle.h" | |||
38 | #include "dictionary.h" | |||
39 | #include <ctype.h> | |||
40 | ||||
41 | struct type *java_int_type; | |||
42 | struct type *java_byte_type; | |||
43 | struct type *java_short_type; | |||
44 | struct type *java_long_type; | |||
45 | struct type *java_boolean_type; | |||
46 | struct type *java_char_type; | |||
47 | struct type *java_float_type; | |||
48 | struct type *java_double_type; | |||
49 | struct type *java_void_type; | |||
50 | ||||
51 | /* Local functions */ | |||
52 | ||||
53 | extern void _initialize_java_language (void); | |||
54 | ||||
55 | static int java_demangled_signature_length (char *); | |||
56 | static void java_demangled_signature_copy (char *, char *); | |||
57 | ||||
58 | static struct symtab *get_java_class_symtab (void); | |||
59 | static char *get_java_utf8_name (struct obstack *obstack, struct value *name); | |||
60 | static int java_class_is_primitive (struct value *clas); | |||
61 | static struct value *java_value_string (char *ptr, int len); | |||
62 | ||||
63 | static void java_emit_char (int c, struct ui_file * stream, int quoter); | |||
64 | ||||
65 | static char *java_class_name_from_physname (const char *physname); | |||
66 | ||||
67 | /* This objfile contains symtabs that have been dynamically created | |||
68 | to record dynamically loaded Java classes and dynamically | |||
69 | compiled java methods. */ | |||
70 | ||||
71 | static struct objfile *dynamics_objfile = NULL((void*)0); | |||
72 | ||||
73 | static struct type *java_link_class_type (struct type *, struct value *); | |||
74 | ||||
75 | /* FIXME: carlton/2003-02-04: This is the main or only caller of | |||
76 | allocate_objfile with first argument NULL; as a result, this code | |||
77 | breaks every so often. Somebody should write a test case that | |||
78 | exercises GDB in various ways (e.g. something involving loading a | |||
79 | dynamic library) after this code has been called. */ | |||
80 | ||||
81 | static struct objfile * | |||
82 | get_dynamics_objfile (void) | |||
83 | { | |||
84 | if (dynamics_objfile == NULL((void*)0)) | |||
85 | { | |||
86 | dynamics_objfile = allocate_objfile (NULL((void*)0), 0); | |||
87 | } | |||
88 | return dynamics_objfile; | |||
89 | } | |||
90 | ||||
91 | #if 1 | |||
92 | /* symtab contains classes read from the inferior. */ | |||
93 | ||||
94 | static struct symtab *class_symtab = NULL((void*)0); | |||
95 | ||||
96 | static void free_class_block (struct symtab *symtab); | |||
97 | ||||
98 | static struct symtab * | |||
99 | get_java_class_symtab (void) | |||
100 | { | |||
101 | if (class_symtab == NULL((void*)0)) | |||
102 | { | |||
103 | struct objfile *objfile = get_dynamics_objfile (); | |||
104 | struct blockvector *bv; | |||
105 | struct block *bl; | |||
106 | class_symtab = allocate_symtab ("<java-classes>", objfile); | |||
107 | class_symtab->language = language_java; | |||
108 | bv = (struct blockvector *) | |||
109 | obstack_alloc (&objfile->objfile_obstack,__extension__ ({ struct obstack *__h = (&objfile->objfile_obstack ); __extension__ ({ struct obstack *__o = (__h); int __len = ( (sizeof (struct blockvector) + sizeof (struct block *))); if ( __o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }) | |||
110 | sizeof (struct blockvector) + sizeof (struct block *))__extension__ ({ struct obstack *__h = (&objfile->objfile_obstack ); __extension__ ({ struct obstack *__o = (__h); int __len = ( (sizeof (struct blockvector) + sizeof (struct block *))); if ( __o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }); | |||
111 | BLOCKVECTOR_NBLOCKS (bv)(bv)->nblocks = 1; | |||
112 | BLOCKVECTOR (class_symtab)(class_symtab)->blockvector = bv; | |||
113 | ||||
114 | /* Allocate dummy STATIC_BLOCK. */ | |||
115 | bl = allocate_block (&objfile->objfile_obstack); | |||
116 | BLOCK_DICT (bl)(bl)->dict = dict_create_linear (&objfile->objfile_obstack, | |||
117 | NULL((void*)0)); | |||
118 | BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)(bv)->block[STATIC_BLOCK] = bl; | |||
119 | ||||
120 | /* Allocate GLOBAL_BLOCK. */ | |||
121 | bl = allocate_block (&objfile->objfile_obstack); | |||
122 | BLOCK_DICT (bl)(bl)->dict = dict_create_hashed_expandable (); | |||
123 | BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)(bv)->block[GLOBAL_BLOCK] = bl; | |||
124 | class_symtab->free_func = free_class_block; | |||
125 | } | |||
126 | return class_symtab; | |||
127 | } | |||
128 | ||||
129 | static void | |||
130 | add_class_symtab_symbol (struct symbol *sym) | |||
131 | { | |||
132 | struct symtab *symtab = get_java_class_symtab (); | |||
133 | struct blockvector *bv = BLOCKVECTOR (symtab)(symtab)->blockvector; | |||
134 | dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))((bv)->block[GLOBAL_BLOCK])->dict, sym); | |||
135 | } | |||
136 | ||||
137 | static struct symbol *add_class_symbol (struct type *type, CORE_ADDR addr); | |||
138 | ||||
139 | static struct symbol * | |||
140 | add_class_symbol (struct type *type, CORE_ADDR addr) | |||
141 | { | |||
142 | struct symbol *sym; | |||
143 | sym = (struct symbol *) | |||
144 | obstack_alloc (&dynamics_objfile->objfile_obstack, sizeof (struct symbol))__extension__ ({ struct obstack *__h = (&dynamics_objfile ->objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((sizeof (struct symbol))); if (__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len ); ((__o)->next_free += (__len)); (void) 0; }); __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void * ) __o1->object_base; if (__o1->next_free == value) __o1 ->maybe_empty_object = 1; __o1->next_free = (((((__o1-> next_free) - (char *) 0)+__o1->alignment_mask) & ~ (__o1 ->alignment_mask)) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1 ->chunk) __o1->next_free = __o1->chunk_limit; __o1-> object_base = __o1->next_free; value; }); }); | |||
145 | memset (sym, 0, sizeof (struct symbol)); | |||
146 | SYMBOL_LANGUAGE (sym)(sym)->ginfo.language = language_java; | |||
147 | DEPRECATED_SYMBOL_NAME (sym)(sym)->ginfo.name = TYPE_TAG_NAME (type)(type)->main_type->tag_name; | |||
148 | SYMBOL_CLASS (sym)(sym)->aclass = LOC_TYPEDEF; | |||
149 | /* SYMBOL_VALUE (sym) = valu; */ | |||
150 | SYMBOL_TYPE (sym)(sym)->type = type; | |||
151 | SYMBOL_DOMAIN (sym)(sym)->domain = STRUCT_DOMAIN; | |||
152 | SYMBOL_VALUE_ADDRESS (sym)(sym)->ginfo.value.address = addr; | |||
153 | return sym; | |||
154 | } | |||
155 | ||||
156 | /* Free the dynamic symbols block. */ | |||
157 | static void | |||
158 | free_class_block (struct symtab *symtab) | |||
159 | { | |||
160 | struct blockvector *bv = BLOCKVECTOR (symtab)(symtab)->blockvector; | |||
161 | struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)(bv)->block[GLOBAL_BLOCK]; | |||
162 | ||||
163 | dict_free (BLOCK_DICT (bl)(bl)->dict); | |||
164 | } | |||
165 | #endif | |||
166 | ||||
167 | struct type * | |||
168 | java_lookup_class (char *name) | |||
169 | { | |||
170 | struct symbol *sym; | |||
171 | sym = lookup_symbol (name, expression_context_block, STRUCT_DOMAIN, | |||
172 | (int *) 0, (struct symtab **) NULL((void*)0)); | |||
173 | if (sym != NULL((void*)0)) | |||
174 | return SYMBOL_TYPE (sym)(sym)->type; | |||
175 | #if 0 | |||
176 | CORE_ADDR addr; | |||
177 | if (called from parser) | |||
178 | { | |||
179 | call lookup_class (or similar) in inferior; | |||
180 | if not | |||
181 | found: | |||
182 | return NULL((void*)0); | |||
183 | addr = found in inferior; | |||
184 | } | |||
185 | else | |||
186 | addr = 0; | |||
187 | struct type *type; | |||
188 | type = alloc_type (objfile); | |||
189 | TYPE_CODE (type)(type)->main_type->code = TYPE_CODE_STRUCT; | |||
190 | INIT_CPLUS_SPECIFIC (type)((type)->main_type->type_specific.cplus_stuff=(struct cplus_struct_type *)&cplus_struct_default); | |||
191 | TYPE_TAG_NAME (type)(type)->main_type->tag_name = obsavestring (name, strlen (name), &objfile->objfile_obstack); | |||
192 | TYPE_FLAGS (type)(type)->main_type->flags |= TYPE_FLAG_STUB(1 << 2); | |||
193 | TYPE ? = addr; | |||
194 | return type; | |||
195 | #else | |||
196 | /* FIXME - should search inferior's symbol table. */ | |||
197 | return NULL((void*)0); | |||
198 | #endif | |||
199 | } | |||
200 | ||||
201 | /* Return a nul-terminated string (allocated on OBSTACK) for | |||
202 | a name given by NAME (which has type Utf8Const*). */ | |||
203 | ||||
204 | char * | |||
205 | get_java_utf8_name (struct obstack *obstack, struct value *name) | |||
206 | { | |||
207 | char *chrs; | |||
208 | struct value *temp = name; | |||
209 | int name_length; | |||
210 | CORE_ADDR data_addr; | |||
211 | temp = value_struct_elt (&temp, NULL((void*)0), "length", NULL((void*)0), "structure"); | |||
212 | name_length = (int) value_as_long (temp); | |||
213 | data_addr = VALUE_ADDRESS (temp)(temp)->location.address + VALUE_OFFSET (temp)(temp)->offset | |||
214 | + TYPE_LENGTH (VALUE_TYPE (temp))((temp)->type)->length; | |||
215 | chrs = obstack_alloc (obstack, name_length + 1)__extension__ ({ struct obstack *__h = (obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((name_length + 1 )); if (__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }); | |||
216 | chrs[name_length] = '\0'; | |||
217 | read_memory (data_addr, chrs, name_length); | |||
218 | return chrs; | |||
219 | } | |||
220 | ||||
221 | struct value * | |||
222 | java_class_from_object (struct value *obj_val) | |||
223 | { | |||
224 | /* This is all rather inefficient, since the offsets of vtable and | |||
225 | class are fixed. FIXME */ | |||
226 | struct value *vtable_val; | |||
227 | ||||
228 | if (TYPE_CODE (VALUE_TYPE (obj_val))((obj_val)->type)->main_type->code == TYPE_CODE_PTR | |||
229 | && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val)))(((obj_val)->type)->main_type->target_type)->length == 0) | |||
230 | obj_val = value_at (get_java_object_type (), | |||
231 | value_as_address (obj_val), NULL((void*)0)); | |||
232 | ||||
233 | vtable_val = value_struct_elt (&obj_val, NULL((void*)0), "vtable", NULL((void*)0), "structure"); | |||
234 | return value_struct_elt (&vtable_val, NULL((void*)0), "class", NULL((void*)0), "structure"); | |||
235 | } | |||
236 | ||||
237 | /* Check if CLASS_IS_PRIMITIVE(value of clas): */ | |||
238 | static int | |||
239 | java_class_is_primitive (struct value *clas) | |||
240 | { | |||
241 | struct value *vtable = value_struct_elt (&clas, NULL((void*)0), "vtable", NULL((void*)0), "struct"); | |||
242 | CORE_ADDR i = value_as_address (vtable); | |||
243 | return (int) (i & 0x7fffffff) == (int) 0x7fffffff; | |||
244 | } | |||
245 | ||||
246 | /* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */ | |||
247 | ||||
248 | struct type * | |||
249 | type_from_class (struct value *clas) | |||
250 | { | |||
251 | struct type *type; | |||
252 | char *name; | |||
253 | struct value *temp; | |||
254 | struct objfile *objfile; | |||
255 | struct value *utf8_name; | |||
256 | char *nptr; | |||
257 | CORE_ADDR addr; | |||
258 | struct block *bl; | |||
259 | struct dict_iterator iter; | |||
260 | int is_array = 0; | |||
261 | ||||
262 | type = check_typedef (VALUE_TYPE (clas)(clas)->type); | |||
263 | if (TYPE_CODE (type)(type)->main_type->code == TYPE_CODE_PTR) | |||
264 | { | |||
265 | if (value_logical_not (clas)) | |||
266 | return NULL((void*)0); | |||
267 | clas = value_ind (clas); | |||
268 | } | |||
269 | addr = VALUE_ADDRESS (clas)(clas)->location.address + VALUE_OFFSET (clas)(clas)->offset; | |||
270 | ||||
271 | #if 0 | |||
272 | get_java_class_symtab (); | |||
273 | bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK)((class_symtab)->blockvector)->block[GLOBAL_BLOCK]; | |||
274 | ALL_BLOCK_SYMBOLS (block, iter, sym)for ((sym) = dict_iterator_first (((block)->dict), &(iter )); (sym); (sym) = dict_iterator_next (&(iter))) | |||
275 | { | |||
276 | if (SYMBOL_VALUE_ADDRESS (sym)(sym)->ginfo.value.address == addr) | |||
277 | return SYMBOL_TYPE (sym)(sym)->type; | |||
278 | } | |||
279 | #endif | |||
280 | ||||
281 | objfile = get_dynamics_objfile (); | |||
282 | if (java_class_is_primitive (clas)) | |||
283 | { | |||
284 | struct value *sig; | |||
285 | temp = clas; | |||
286 | sig = value_struct_elt (&temp, NULL((void*)0), "method_count", NULL((void*)0), "structure"); | |||
287 | return java_primitive_type (value_as_long (sig)); | |||
288 | } | |||
289 | ||||
290 | /* Get Class name. */ | |||
291 | /* if clasloader non-null, prepend loader address. FIXME */ | |||
292 | temp = clas; | |||
293 | utf8_name = value_struct_elt (&temp, NULL((void*)0), "name", NULL((void*)0), "structure"); | |||
294 | name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name); | |||
295 | for (nptr = name; *nptr != 0; nptr++) | |||
296 | { | |||
297 | if (*nptr == '/') | |||
298 | *nptr = '.'; | |||
299 | } | |||
300 | ||||
301 | type = java_lookup_class (name); | |||
302 | if (type != NULL((void*)0)) | |||
303 | return type; | |||
304 | ||||
305 | type = alloc_type (objfile); | |||
306 | TYPE_CODE (type)(type)->main_type->code = TYPE_CODE_STRUCT; | |||
307 | INIT_CPLUS_SPECIFIC (type)((type)->main_type->type_specific.cplus_stuff=(struct cplus_struct_type *)&cplus_struct_default); | |||
308 | ||||
309 | if (name[0] == '[') | |||
310 | { | |||
311 | char *signature = name; | |||
312 | int namelen = java_demangled_signature_length (signature); | |||
313 | if (namelen > strlen (name)) | |||
314 | name = obstack_alloc (&objfile->objfile_obstack, namelen + 1)__extension__ ({ struct obstack *__h = (&objfile->objfile_obstack ); __extension__ ({ struct obstack *__o = (__h); int __len = ( (namelen + 1)); if (__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }); __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char * ) 0)+__o1->alignment_mask) & ~ (__o1->alignment_mask )) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; value; }); }); | |||
315 | java_demangled_signature_copy (name, signature); | |||
316 | name[namelen] = '\0'; | |||
317 | is_array = 1; | |||
318 | temp = clas; | |||
319 | /* Set array element type. */ | |||
320 | temp = value_struct_elt (&temp, NULL((void*)0), "methods", NULL((void*)0), "structure"); | |||
321 | VALUE_TYPE (temp)(temp)->type = lookup_pointer_type (VALUE_TYPE (clas)(clas)->type); | |||
322 | TYPE_TARGET_TYPE (type)(type)->main_type->target_type = type_from_class (temp); | |||
323 | } | |||
324 | ||||
325 | ALLOCATE_CPLUS_STRUCT_TYPE (type)allocate_cplus_struct_type (type); | |||
326 | TYPE_TAG_NAME (type)(type)->main_type->tag_name = name; | |||
327 | ||||
328 | add_class_symtab_symbol (add_class_symbol (type, addr)); | |||
329 | return java_link_class_type (type, clas); | |||
330 | } | |||
331 | ||||
332 | /* Fill in class TYPE with data from the CLAS value. */ | |||
333 | ||||
334 | struct type * | |||
335 | java_link_class_type (struct type *type, struct value *clas) | |||
336 | { | |||
337 | struct value *temp; | |||
338 | char *unqualified_name; | |||
339 | char *name = TYPE_TAG_NAME (type)(type)->main_type->tag_name; | |||
340 | int ninterfaces, nfields, nmethods; | |||
341 | int type_is_object = 0; | |||
342 | struct fn_field *fn_fields; | |||
343 | struct fn_fieldlist *fn_fieldlists; | |||
344 | struct value *fields; | |||
345 | struct value *methods; | |||
346 | struct value *method = NULL((void*)0); | |||
347 | struct value *field = NULL((void*)0); | |||
348 | int i, j; | |||
349 | struct objfile *objfile = get_dynamics_objfile (); | |||
350 | struct type *tsuper; | |||
351 | ||||
352 | unqualified_name = strrchr (name, '.'); | |||
353 | if (unqualified_name == NULL((void*)0)) | |||
| ||||
354 | unqualified_name = name; | |||
355 | ||||
356 | temp = clas; | |||
357 | temp = value_struct_elt (&temp, NULL((void*)0), "superclass", NULL((void*)0), "structure"); | |||
358 | if (name != NULL((void*)0) && strcmp (name, "java.lang.Object") == 0) | |||
359 | { | |||
360 | tsuper = get_java_object_type (); | |||
361 | if (tsuper && TYPE_CODE (tsuper)(tsuper)->main_type->code == TYPE_CODE_PTR) | |||
362 | tsuper = TYPE_TARGET_TYPE (tsuper)(tsuper)->main_type->target_type; | |||
363 | type_is_object = 1; | |||
364 | } | |||
365 | else | |||
366 | tsuper = type_from_class (temp); | |||
367 | ||||
368 | #if 1 | |||
369 | ninterfaces = 0; | |||
370 | #else | |||
371 | temp = clas; | |||
372 | ninterfaces = value_as_long (value_struct_elt (&temp, NULL((void*)0), "interface_len", NULL((void*)0), "structure")); | |||
373 | #endif | |||
374 | TYPE_N_BASECLASSES (type)(type)->main_type->type_specific.cplus_stuff->n_baseclasses = (tsuper == NULL((void*)0) ? 0 : 1) + ninterfaces; | |||
375 | temp = clas; | |||
376 | nfields = value_as_long (value_struct_elt (&temp, NULL((void*)0), "field_count", NULL((void*)0), "structure")); | |||
377 | nfields += TYPE_N_BASECLASSES (type)(type)->main_type->type_specific.cplus_stuff->n_baseclasses; | |||
378 | nfields++; /* Add one for dummy "class" field. */ | |||
379 | TYPE_NFIELDS (type)(type)->main_type->nfields = nfields; | |||
380 | TYPE_FIELDS (type)(type)->main_type->fields = (struct field *) | |||
381 | TYPE_ALLOC (type, sizeof (struct field) * nfields)((type)->main_type->objfile != ((void*)0) ? __extension__ ({ struct obstack *__h = (&(type)->main_type->objfile -> objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((sizeof (struct field) * nfields)); if (__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }) : xmalloc (sizeof (struct field) * nfields)); | |||
382 | ||||
383 | memset (TYPE_FIELDS (type)(type)->main_type->fields, 0, sizeof (struct field) * nfields); | |||
384 | ||||
385 | TYPE_FIELD_PRIVATE_BITS (type)(type)->main_type->type_specific.cplus_stuff->private_field_bits = | |||
386 | (B_TYPEunsigned char *) TYPE_ALLOC (type, B_BYTES (nfields))((type)->main_type->objfile != ((void*)0) ? __extension__ ({ struct obstack *__h = (&(type)->main_type->objfile -> objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((( 1 + ((nfields)>>3) ))); if (__o ->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }) : xmalloc (( 1 + ((nfields)>>3) ))); | |||
387 | B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields)memset (((type)->main_type->type_specific.cplus_stuff-> private_field_bits), 0, ( 1 + ((nfields)>>3) )); | |||
| ||||
388 | ||||
389 | TYPE_FIELD_PROTECTED_BITS (type)(type)->main_type->type_specific.cplus_stuff->protected_field_bits = | |||
390 | (B_TYPEunsigned char *) TYPE_ALLOC (type, B_BYTES (nfields))((type)->main_type->objfile != ((void*)0) ? __extension__ ({ struct obstack *__h = (&(type)->main_type->objfile -> objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((( 1 + ((nfields)>>3) ))); if (__o ->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }) : xmalloc (( 1 + ((nfields)>>3) ))); | |||
391 | B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields)memset (((type)->main_type->type_specific.cplus_stuff-> protected_field_bits), 0, ( 1 + ((nfields)>>3) )); | |||
392 | ||||
393 | TYPE_FIELD_IGNORE_BITS (type)(type)->main_type->type_specific.cplus_stuff->ignore_field_bits = | |||
394 | (B_TYPEunsigned char *) TYPE_ALLOC (type, B_BYTES (nfields))((type)->main_type->objfile != ((void*)0) ? __extension__ ({ struct obstack *__h = (&(type)->main_type->objfile -> objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((( 1 + ((nfields)>>3) ))); if (__o ->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len); ((__o)->next_free += (__len)); (void) 0; }) ; __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char *) 0)+__o1->alignment_mask ) & ~ (__o1->alignment_mask)) + (char *) 0); if (__o1-> next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = __o1->chunk_limit ; __o1->object_base = __o1->next_free; value; }); }) : xmalloc (( 1 + ((nfields)>>3) ))); | |||
395 | B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields)memset (((type)->main_type->type_specific.cplus_stuff-> ignore_field_bits), 0, ( 1 + ((nfields)>>3) )); | |||
396 | ||||
397 | TYPE_FIELD_VIRTUAL_BITS (type)(type)->main_type->type_specific.cplus_stuff->virtual_field_bits = (B_TYPEunsigned char *) | |||
398 | TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type)))((type)->main_type->objfile != ((void*)0) ? __extension__ ({ struct obstack *__h = (&(type)->main_type->objfile -> objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((( 1 + (((type)->main_type->type_specific .cplus_stuff->n_baseclasses)>>3) ))); if (__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, __len ); ((__o)->next_free += (__len)); (void) 0; }); __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void * ) __o1->object_base; if (__o1->next_free == value) __o1 ->maybe_empty_object = 1; __o1->next_free = (((((__o1-> next_free) - (char *) 0)+__o1->alignment_mask) & ~ (__o1 ->alignment_mask)) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1 ->chunk) __o1->next_free = __o1->chunk_limit; __o1-> object_base = __o1->next_free; value; }); }) : xmalloc (( 1 + (((type)->main_type->type_specific.cplus_stuff->n_baseclasses )>>3) ))); | |||
399 | B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type))memset (((type)->main_type->type_specific.cplus_stuff-> virtual_field_bits), 0, ( 1 + (((type)->main_type->type_specific .cplus_stuff->n_baseclasses)>>3) )); | |||
400 | ||||
401 | if (tsuper != NULL((void*)0)) | |||
402 | { | |||
403 | TYPE_BASECLASS (type, 0)(type)->main_type->fields[0].type = tsuper; | |||
404 | if (type_is_object) | |||
405 | SET_TYPE_FIELD_PRIVATE (type, 0)(((type)->main_type->type_specific.cplus_stuff->private_field_bits )[((0))>>3] |= (1 << (((0))&7))); | |||
406 | } | |||
407 | ||||
408 | i = strlen (name); | |||
409 | if (i > 2 && name[i - 1] == ']' && tsuper != NULL((void*)0)) | |||
410 | { | |||
411 | /* FIXME */ | |||
412 | TYPE_LENGTH (type)(type)->length = TYPE_LENGTH (tsuper)(tsuper)->length + 4; /* size with "length" */ | |||
413 | } | |||
414 | else | |||
415 | { | |||
416 | temp = clas; | |||
417 | temp = value_struct_elt (&temp, NULL((void*)0), "size_in_bytes", NULL((void*)0), "structure"); | |||
418 | TYPE_LENGTH (type)(type)->length = value_as_long (temp); | |||
419 | } | |||
420 | ||||
421 | fields = NULL((void*)0); | |||
422 | nfields--; /* First set up dummy "class" field. */ | |||
423 | SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),(((type)->main_type->fields[nfields]).static_kind = 2, ( ((type)->main_type->fields[nfields]).loc.physaddr) = (( clas)->location.address + (clas)->offset)) | |||
424 | VALUE_ADDRESS (clas) + VALUE_OFFSET (clas))(((type)->main_type->fields[nfields]).static_kind = 2, ( ((type)->main_type->fields[nfields]).loc.physaddr) = (( clas)->location.address + (clas)->offset)); | |||
425 | TYPE_FIELD_NAME (type, nfields)(((type)->main_type->fields[nfields]).name) = "class"; | |||
426 | TYPE_FIELD_TYPE (type, nfields)(((type)->main_type->fields[nfields]).type) = VALUE_TYPE (clas)(clas)->type; | |||
427 | SET_TYPE_FIELD_PRIVATE (type, nfields)(((type)->main_type->type_specific.cplus_stuff->private_field_bits )[((nfields))>>3] |= (1 << (((nfields))&7))); | |||
428 | ||||
429 | for (i = TYPE_N_BASECLASSES (type)(type)->main_type->type_specific.cplus_stuff->n_baseclasses; i < nfields; i++) | |||
430 | { | |||
431 | int accflags; | |||
432 | int boffset; | |||
433 | if (fields == NULL((void*)0)) | |||
434 | { | |||
435 | temp = clas; | |||
436 | fields = value_struct_elt (&temp, NULL((void*)0), "fields", NULL((void*)0), "structure"); | |||
437 | field = value_ind (fields); | |||
438 | } | |||
439 | else | |||
440 | { /* Re-use field value for next field. */ | |||
441 | VALUE_ADDRESS (field)(field)->location.address += TYPE_LENGTH (VALUE_TYPE (field))((field)->type)->length; | |||
442 | VALUE_LAZY (field)(field)->lazy = 1; | |||
443 | } | |||
444 | temp = field; | |||
445 | temp = value_struct_elt (&temp, NULL((void*)0), "name", NULL((void*)0), "structure"); | |||
446 | TYPE_FIELD_NAME (type, i)(((type)->main_type->fields[i]).name) = | |||
447 | get_java_utf8_name (&objfile->objfile_obstack, temp); | |||
448 | temp = field; | |||
449 | accflags = value_as_long (value_struct_elt (&temp, NULL((void*)0), "accflags", | |||
450 | NULL((void*)0), "structure")); | |||
451 | temp = field; | |||
452 | temp = value_struct_elt (&temp, NULL((void*)0), "info", NULL((void*)0), "structure"); | |||
453 | boffset = value_as_long (value_struct_elt (&temp, NULL((void*)0), "boffset", | |||
454 | NULL((void*)0), "structure")); | |||
455 | if (accflags & 0x0001) /* public access */ | |||
456 | { | |||
457 | /* ??? */ | |||
458 | } | |||
459 | if (accflags & 0x0002) /* private access */ | |||
460 | { | |||
461 | SET_TYPE_FIELD_PRIVATE (type, i)(((type)->main_type->type_specific.cplus_stuff->private_field_bits )[((i))>>3] |= (1 << (((i))&7))); | |||
462 | } | |||
463 | if (accflags & 0x0004) /* protected access */ | |||
464 | { | |||
465 | SET_TYPE_FIELD_PROTECTED (type, i)(((type)->main_type->type_specific.cplus_stuff->protected_field_bits )[((i))>>3] |= (1 << (((i))&7))); | |||
466 | } | |||
467 | if (accflags & 0x0008) /* ACC_STATIC */ | |||
468 | SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset)(((type)->main_type->fields[i]).static_kind = 2, (((type )->main_type->fields[i]).loc.physaddr) = (boffset)); | |||
469 | else | |||
470 | TYPE_FIELD_BITPOS (type, i)(((type)->main_type->fields[i]).loc.bitpos) = 8 * boffset; | |||
471 | if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */ | |||
472 | { | |||
473 | TYPE_FIELD_TYPE (type, i)(((type)->main_type->fields[i]).type) = get_java_object_type (); /* FIXME */ | |||
474 | } | |||
475 | else | |||
476 | { | |||
477 | struct type *ftype; | |||
478 | temp = field; | |||
479 | temp = value_struct_elt (&temp, NULL((void*)0), "type", NULL((void*)0), "structure"); | |||
480 | ftype = type_from_class (temp); | |||
481 | if (TYPE_CODE (ftype)(ftype)->main_type->code == TYPE_CODE_STRUCT) | |||
482 | ftype = lookup_pointer_type (ftype); | |||
483 | TYPE_FIELD_TYPE (type, i)(((type)->main_type->fields[i]).type) = ftype; | |||
484 | } | |||
485 | } | |||
486 | ||||
487 | temp = clas; | |||
488 | nmethods = value_as_long (value_struct_elt (&temp, NULL((void*)0), "method_count", | |||
489 | NULL((void*)0), "structure")); | |||
490 | TYPE_NFN_FIELDS_TOTAL (type)(type)->main_type->type_specific.cplus_stuff->nfn_fields_total = nmethods; | |||
491 | j = nmethods * sizeof (struct fn_field); | |||
492 | fn_fields = (struct fn_field *) | |||
493 | obstack_alloc (&dynamics_objfile->objfile_obstack, j)__extension__ ({ struct obstack *__h = (&dynamics_objfile ->objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((j)); if (__o->chunk_limit - __o-> next_free < __len) _obstack_newchunk (__o, __len); ((__o)-> next_free += (__len)); (void) 0; }); __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base ; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char * ) 0)+__o1->alignment_mask) & ~ (__o1->alignment_mask )) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; value; }); }); | |||
494 | memset (fn_fields, 0, j); | |||
495 | fn_fieldlists = (struct fn_fieldlist *) | |||
496 | alloca (nmethods * sizeof (struct fn_fieldlist))__builtin_alloca(nmethods * sizeof (struct fn_fieldlist)); | |||
497 | ||||
498 | methods = NULL((void*)0); | |||
499 | for (i = 0; i < nmethods; i++) | |||
500 | { | |||
501 | char *mname; | |||
502 | int k; | |||
503 | if (methods == NULL((void*)0)) | |||
504 | { | |||
505 | temp = clas; | |||
506 | methods = value_struct_elt (&temp, NULL((void*)0), "methods", NULL((void*)0), "structure"); | |||
507 | method = value_ind (methods); | |||
508 | } | |||
509 | else | |||
510 | { /* Re-use method value for next method. */ | |||
511 | VALUE_ADDRESS (method)(method)->location.address += TYPE_LENGTH (VALUE_TYPE (method))((method)->type)->length; | |||
512 | VALUE_LAZY (method)(method)->lazy = 1; | |||
513 | } | |||
514 | ||||
515 | /* Get method name. */ | |||
516 | temp = method; | |||
517 | temp = value_struct_elt (&temp, NULL((void*)0), "name", NULL((void*)0), "structure"); | |||
518 | mname = get_java_utf8_name (&objfile->objfile_obstack, temp); | |||
519 | if (strcmp (mname, "<init>") == 0) | |||
520 | mname = unqualified_name; | |||
521 | ||||
522 | /* Check for an existing method with the same name. | |||
523 | * This makes building the fn_fieldslists an O(nmethods**2) | |||
524 | * operation. That could be using hashing, but I doubt it | |||
525 | * is worth it. Note that we do maintain the order of methods | |||
526 | * in the inferior's Method table (as long as that is grouped | |||
527 | * by method name), which I think is desirable. --PB */ | |||
528 | for (k = 0, j = TYPE_NFN_FIELDS (type)(type)->main_type->type_specific.cplus_stuff->nfn_fields;;) | |||
529 | { | |||
530 | if (--j < 0) | |||
531 | { /* No match - new method name. */ | |||
532 | j = TYPE_NFN_FIELDS (type)(type)->main_type->type_specific.cplus_stuff->nfn_fields++; | |||
533 | fn_fieldlists[j].name = mname; | |||
534 | fn_fieldlists[j].length = 1; | |||
535 | fn_fieldlists[j].fn_fields = &fn_fields[i]; | |||
536 | k = i; | |||
537 | break; | |||
538 | } | |||
539 | if (strcmp (mname, fn_fieldlists[j].name) == 0) | |||
540 | { /* Found an existing method with the same name. */ | |||
541 | int l; | |||
542 | if (mname != unqualified_name) | |||
543 | obstack_free (&objfile->objfile_obstack, mname)__extension__ ({ struct obstack *__o = (&objfile->objfile_obstack ); void *__obj = (mname); if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) __o->next_free = __o->object_base = __obj; else (obstack_free) (__o, __obj ); }); | |||
544 | mname = fn_fieldlists[j].name; | |||
545 | fn_fieldlists[j].length++; | |||
546 | k = i - k; /* Index of new slot. */ | |||
547 | /* Shift intervening fn_fields (between k and i) down. */ | |||
548 | for (l = i; l > k; l--) | |||
549 | fn_fields[l] = fn_fields[l - 1]; | |||
550 | for (l = TYPE_NFN_FIELDS (type)(type)->main_type->type_specific.cplus_stuff->nfn_fields; --l > j;) | |||
551 | fn_fieldlists[l].fn_fields++; | |||
552 | break; | |||
553 | } | |||
554 | k += fn_fieldlists[j].length; | |||
555 | } | |||
556 | fn_fields[k].physname = ""; | |||
557 | fn_fields[k].is_stub = 1; | |||
558 | fn_fields[k].type = make_function_type (java_void_type, NULL((void*)0)); /* FIXME */ | |||
559 | TYPE_CODE (fn_fields[k].type)(fn_fields[k].type)->main_type->code = TYPE_CODE_METHOD; | |||
560 | } | |||
561 | ||||
562 | j = TYPE_NFN_FIELDS (type)(type)->main_type->type_specific.cplus_stuff->nfn_fields * sizeof (struct fn_fieldlist); | |||
563 | TYPE_FN_FIELDLISTS (type)(type)->main_type->type_specific.cplus_stuff->fn_fieldlists = (struct fn_fieldlist *) | |||
564 | obstack_alloc (&dynamics_objfile->objfile_obstack, j)__extension__ ({ struct obstack *__h = (&dynamics_objfile ->objfile_obstack); __extension__ ({ struct obstack *__o = (__h); int __len = ((j)); if (__o->chunk_limit - __o-> next_free < __len) _obstack_newchunk (__o, __len); ((__o)-> next_free += (__len)); (void) 0; }); __extension__ ({ struct obstack *__o1 = (__h); void *value; value = (void *) __o1->object_base ; if (__o1->next_free == value) __o1->maybe_empty_object = 1; __o1->next_free = (((((__o1->next_free) - (char * ) 0)+__o1->alignment_mask) & ~ (__o1->alignment_mask )) + (char *) 0); if (__o1->next_free - (char *)__o1->chunk > __o1->chunk_limit - (char *)__o1->chunk) __o1-> next_free = __o1->chunk_limit; __o1->object_base = __o1 ->next_free; value; }); }); | |||
565 | memcpy (TYPE_FN_FIELDLISTS (type)(type)->main_type->type_specific.cplus_stuff->fn_fieldlists, fn_fieldlists, j); | |||
566 | ||||
567 | return type; | |||
568 | } | |||
569 | ||||
570 | static struct type *java_object_type; | |||
571 | ||||
572 | struct type * | |||
573 | get_java_object_type (void) | |||
574 | { | |||
575 | if (java_object_type == NULL((void*)0)) | |||
576 | { | |||
577 | struct symbol *sym; | |||
578 | sym = lookup_symbol ("java.lang.Object", NULL((void*)0), STRUCT_DOMAIN, | |||
579 | (int *) 0, (struct symtab **) NULL((void*)0)); | |||
580 | if (sym == NULL((void*)0)) | |||
581 | error ("cannot find java.lang.Object"); | |||
582 | java_object_type = SYMBOL_TYPE (sym)(sym)->type; | |||
583 | } | |||
584 | return java_object_type; | |||
585 | } | |||
586 | ||||
587 | int | |||
588 | get_java_object_header_size (void) | |||
589 | { | |||
590 | struct type *objtype = get_java_object_type (); | |||
591 | if (objtype == NULL((void*)0)) | |||
592 | return (2 * TARGET_PTR_BIT(gdbarch_ptr_bit (current_gdbarch)) / TARGET_CHAR_BIT8); | |||
593 | else | |||
594 | return TYPE_LENGTH (objtype)(objtype)->length; | |||
595 | } | |||
596 | ||||
597 | int | |||
598 | is_object_type (struct type *type) | |||
599 | { | |||
600 | CHECK_TYPEDEF (type)(type) = check_typedef (type); | |||
601 | if (TYPE_CODE (type)(type)->main_type->code == TYPE_CODE_PTR) | |||
602 | { | |||
603 | struct type *ttype = check_typedef (TYPE_TARGET_TYPE (type)(type)->main_type->target_type); | |||
604 | char *name; | |||
605 | if (TYPE_CODE (ttype)(ttype)->main_type->code != TYPE_CODE_STRUCT) | |||
606 | return 0; | |||
607 | while (TYPE_N_BASECLASSES (ttype)(ttype)->main_type->type_specific.cplus_stuff->n_baseclasses > 0) | |||
608 | ttype = TYPE_BASECLASS (ttype, 0)(ttype)->main_type->fields[0].type; | |||
609 | name = TYPE_TAG_NAME (ttype)(ttype)->main_type->tag_name; | |||
610 | if (name != NULL((void*)0) && strcmp (name, "java.lang.Object") == 0) | |||
611 | return 1; | |||
612 | name = TYPE_NFIELDS (ttype)(ttype)->main_type->nfields > 0 ? TYPE_FIELD_NAME (ttype, 0)(((ttype)->main_type->fields[0]).name) : (char *) 0; | |||
613 | if (name != NULL((void*)0) && strcmp (name, "vtable") == 0) | |||
614 | { | |||
615 | if (java_object_type == NULL((void*)0)) | |||
616 | java_object_type = type; | |||
617 | return 1; | |||
618 | } | |||
619 | } | |||
620 | return 0; | |||
621 | } | |||
622 | ||||
623 | struct type * | |||
624 | java_primitive_type (int signature) | |||
625 | { | |||
626 | switch (signature) | |||
627 | { | |||
628 | case 'B': | |||
629 | return java_byte_type; | |||
630 | case 'S': | |||
631 | return java_short_type; | |||
632 | case 'I': | |||
633 | return java_int_type; | |||
634 | case 'J': | |||
635 | return java_long_type; | |||
636 | case 'Z': | |||
637 | return java_boolean_type; | |||
638 | case 'C': | |||
639 | return java_char_type; | |||
640 | case 'F': | |||
641 | return java_float_type; | |||
642 | case 'D': | |||
643 | return java_double_type; | |||
644 | case 'V': | |||
645 | return java_void_type; | |||
646 | } | |||
647 | error ("unknown signature '%c' for primitive type", (char) signature); | |||
648 | } | |||
649 | ||||
650 | /* If name[0 .. namelen-1] is the name of a primitive Java type, | |||
651 | return that type. Otherwise, return NULL. */ | |||
652 | ||||
653 | struct type * | |||
654 | java_primitive_type_from_name (char *name, int namelen) | |||
655 | { | |||
656 | switch (name[0]) | |||
657 | { | |||
658 | case 'b': | |||
659 | if (namelen == 4 && memcmp (name, "byte", 4) == 0) | |||
660 | return java_byte_type; | |||
661 | if (namelen == 7 && memcmp (name, "boolean", 7) == 0) | |||
662 | return java_boolean_type; | |||
663 | break; | |||
664 | case 'c': | |||
665 | if (namelen == 4 && memcmp (name, "char", 4) == 0) | |||
666 | return java_char_type; | |||
667 | case 'd': | |||
668 | if (namelen == 6 && memcmp (name, "double", 6) == 0) | |||
669 | return java_double_type; | |||
670 | break; | |||
671 | case 'f': | |||
672 | if (namelen == 5 && memcmp (name, "float", 5) == 0) | |||
673 | return java_float_type; | |||
674 | break; | |||
675 | case 'i': | |||
676 | if (namelen == 3 && memcmp (name, "int", 3) == 0) | |||
677 | return java_int_type; | |||
678 | break; | |||
679 | case 'l': | |||
680 | if (namelen == 4 && memcmp (name, "long", 4) == 0) | |||
681 | return java_long_type; | |||
682 | break; | |||
683 | case 's': | |||
684 | if (namelen == 5 && memcmp (name, "short", 5) == 0) | |||
685 | return java_short_type; | |||
686 | break; | |||
687 | case 'v': | |||
688 | if (namelen == 4 && memcmp (name, "void", 4) == 0) | |||
689 | return java_void_type; | |||
690 | break; | |||
691 | } | |||
692 | return NULL((void*)0); | |||
693 | } | |||
694 | ||||
695 | /* Return the length (in bytes) of demangled name of the Java type | |||
696 | signature string SIGNATURE. */ | |||
697 | ||||
698 | static int | |||
699 | java_demangled_signature_length (char *signature) | |||
700 | { | |||
701 | int array = 0; | |||
702 | for (; *signature == '['; signature++) | |||
703 | array += 2; /* Two chars for "[]". */ | |||
704 | switch (signature[0]) | |||
705 | { | |||
706 | case 'L': | |||
707 | /* Subtract 2 for 'L' and ';'. */ | |||
708 | return strlen (signature) - 2 + array; | |||
709 | default: | |||
710 | return strlen (TYPE_NAME (java_primitive_type (signature[0]))(java_primitive_type (signature[0]))->main_type->name) + array; | |||
711 | } | |||
712 | } | |||
713 | ||||
714 | /* Demangle the Java type signature SIGNATURE, leaving the result in RESULT. */ | |||
715 | ||||
716 | static void | |||
717 | java_demangled_signature_copy (char *result, char *signature) | |||
718 | { | |||
719 | int array = 0; | |||
720 | char *ptr; | |||
721 | int i; | |||
722 | while (*signature == '[') | |||
723 | { | |||
724 | array++; | |||
725 | signature++; | |||
726 | } | |||
727 | switch (signature[0]) | |||
728 | { | |||
729 | case 'L': | |||
730 | /* Subtract 2 for 'L' and ';', but add 1 for final nul. */ | |||
731 | signature++; | |||
732 | ptr = result; | |||
733 | for (; *signature != ';' && *signature != '\0'; signature++) | |||
734 | { | |||
735 | if (*signature == '/') | |||
736 | *ptr++ = '.'; | |||
737 | else | |||
738 | *ptr++ = *signature; | |||
739 | } | |||
740 | break; | |||
741 | default: | |||
742 | ptr = TYPE_NAME (java_primitive_type (signature[0]))(java_primitive_type (signature[0]))->main_type->name; | |||
743 | i = strlen (ptr); | |||
744 | strcpy (result, ptr); | |||
745 | ptr = result + i; | |||
746 | break; | |||
747 | } | |||
748 | while (--array >= 0) | |||
749 | { | |||
750 | *ptr++ = '['; | |||
751 | *ptr++ = ']'; | |||
752 | } | |||
753 | } | |||
754 | ||||
755 | /* Return the demangled name of the Java type signature string SIGNATURE, | |||
756 | as a freshly allocated copy. */ | |||
757 | ||||
758 | char * | |||
759 | java_demangle_type_signature (char *signature) | |||
760 | { | |||
761 | int length = java_demangled_signature_length (signature); | |||
762 | char *result = xmalloc (length + 1); | |||
763 | java_demangled_signature_copy (result, signature); | |||
764 | result[length] = '\0'; | |||
765 | return result; | |||
766 | } | |||
767 | ||||
768 | /* Return the type of TYPE followed by DIMS pairs of [ ]. | |||
769 | If DIMS == 0, TYPE is returned. */ | |||
770 | ||||
771 | struct type * | |||
772 | java_array_type (struct type *type, int dims) | |||
773 | { | |||
774 | struct type *range_type; | |||
775 | ||||
776 | while (dims-- > 0) | |||
777 | { | |||
778 | range_type = create_range_type (NULL((void*)0), builtin_type_int, 0, 0); | |||
779 | /* FIXME This is bogus! Java arrays are not gdb arrays! */ | |||
780 | type = create_array_type (NULL((void*)0), type, range_type); | |||
781 | } | |||
782 | ||||
783 | return type; | |||
784 | } | |||
785 | ||||
786 | /* Create a Java string in the inferior from a (Utf8) literal. */ | |||
787 | ||||
788 | static struct value * | |||
789 | java_value_string (char *ptr, int len) | |||
790 | { | |||
791 | error ("not implemented - java_value_string"); /* FIXME */ | |||
792 | } | |||
793 | ||||
794 | /* Print the character C on STREAM as part of the contents of a literal | |||
795 | string whose delimiter is QUOTER. Note that that format for printing | |||
796 | characters and strings is language specific. */ | |||
797 | ||||
798 | static void | |||
799 | java_emit_char (int c, struct ui_file *stream, int quoter) | |||
800 | { | |||
801 | switch (c) | |||
802 | { | |||
803 | case '\\': | |||
804 | case '\'': | |||
805 | fprintf_filtered (stream, "\\%c", c); | |||
806 | break; | |||
807 | case '\b': | |||
808 | fputs_filtered ("\\b", stream); | |||
809 | break; | |||
810 | case '\t': | |||
811 | fputs_filtered ("\\t", stream); | |||
812 | break; | |||
813 | case '\n': | |||
814 | fputs_filtered ("\\n", stream); | |||
815 | break; | |||
816 | case '\f': | |||
817 | fputs_filtered ("\\f", stream); | |||
818 | break; | |||
819 | case '\r': | |||
820 | fputs_filtered ("\\r", stream); | |||
821 | break; | |||
822 | default: | |||
823 | if (isprint (c)) | |||
824 | fputc_filtered (c, stream); | |||
825 | else | |||
826 | fprintf_filtered (stream, "\\u%.4x", (unsigned int) c); | |||
827 | break; | |||
828 | } | |||
829 | } | |||
830 | ||||
831 | static struct value * | |||
832 | evaluate_subexp_java (struct type *expect_type, struct expression *exp, | |||
833 | int *pos, enum noside noside) | |||
834 | { | |||
835 | int pc = *pos; | |||
836 | int i; | |||
837 | char *name; | |||
838 | enum exp_opcode op = exp->elts[*pos].opcode; | |||
839 | struct value *arg1; | |||
840 | struct value *arg2; | |||
841 | struct type *type; | |||
842 | switch (op) | |||
843 | { | |||
844 | case UNOP_IND: | |||
845 | if (noside == EVAL_SKIP) | |||
846 | goto standard; | |||
847 | (*pos)++; | |||
848 | arg1 = evaluate_subexp_java (NULL_TYPE((struct type *) 0), exp, pos, EVAL_NORMAL); | |||
849 | if (is_object_type (VALUE_TYPE (arg1)(arg1)->type)) | |||
850 | { | |||
851 | struct type *type; | |||
852 | ||||
853 | type = type_from_class (java_class_from_object (arg1)); | |||
854 | arg1 = value_cast (lookup_pointer_type (type), arg1); | |||
855 | } | |||
856 | if (noside == EVAL_SKIP) | |||
857 | goto nosideret; | |||
858 | return value_ind (arg1); | |||
859 | ||||
860 | case BINOP_SUBSCRIPT: | |||
861 | (*pos)++; | |||
862 | arg1 = evaluate_subexp_with_coercion (exp, pos, noside); | |||
863 | arg2 = evaluate_subexp_with_coercion (exp, pos, noside); | |||
864 | if (noside == EVAL_SKIP) | |||
865 | goto nosideret; | |||
866 | /* If the user attempts to subscript something that is not an | |||
867 | array or pointer type (like a plain int variable for example), | |||
868 | then report this as an error. */ | |||
869 | ||||
870 | COERCE_REF (arg1)do { struct type *value_type_arg_tmp = check_typedef ((arg1)-> type); if ((value_type_arg_tmp)->main_type->code == TYPE_CODE_REF ) arg1 = value_at_lazy ((value_type_arg_tmp)->main_type-> target_type, unpack_pointer ((arg1)->type, ((void)((arg1)-> lazy && value_fetch_lazy(arg1)), ((char *) (arg1)-> aligner.contents + (arg1)->embedded_offset))), ((arg1)-> bfd_section)); } while (0); | |||
871 | type = check_typedef (VALUE_TYPE (arg1)(arg1)->type); | |||
872 | if (TYPE_CODE (type)(type)->main_type->code == TYPE_CODE_PTR) | |||
873 | type = check_typedef (TYPE_TARGET_TYPE (type)(type)->main_type->target_type); | |||
874 | name = TYPE_NAME (type)(type)->main_type->name; | |||
875 | if (name == NULL((void*)0)) | |||
876 | name = TYPE_TAG_NAME (type)(type)->main_type->tag_name; | |||
877 | i = name == NULL((void*)0) ? 0 : strlen (name); | |||
878 | if (TYPE_CODE (type)(type)->main_type->code == TYPE_CODE_STRUCT | |||
879 | && i > 2 && name[i - 1] == ']') | |||
880 | { | |||
881 | CORE_ADDR address; | |||
882 | long length, index; | |||
883 | struct type *el_type; | |||
884 | char buf4[4]; | |||
885 | ||||
886 | struct value *clas = java_class_from_object (arg1); | |||
887 | struct value *temp = clas; | |||
888 | /* Get CLASS_ELEMENT_TYPE of the array type. */ | |||
889 | temp = value_struct_elt (&temp, NULL((void*)0), "methods", | |||
890 | NULL((void*)0), "structure"); | |||
891 | VALUE_TYPE (temp)(temp)->type = VALUE_TYPE (clas)(clas)->type; | |||
892 | el_type = type_from_class (temp); | |||
893 | if (TYPE_CODE (el_type)(el_type)->main_type->code == TYPE_CODE_STRUCT) | |||
894 | el_type = lookup_pointer_type (el_type); | |||
895 | ||||
896 | if (noside == EVAL_AVOID_SIDE_EFFECTS) | |||
897 | return value_zero (el_type, VALUE_LVAL (arg1)(arg1)->lval); | |||
898 | address = value_as_address (arg1); | |||
899 | address += JAVA_OBJECT_SIZE(get_java_object_header_size ()); | |||
900 | read_memory (address, buf4, 4); | |||
901 | length = (long) extract_signed_integer (buf4, 4); | |||
902 | index = (long) value_as_long (arg2); | |||
903 | if (index >= length || index < 0) | |||
904 | error ("array index (%ld) out of bounds (length: %ld)", | |||
905 | index, length); | |||
906 | address = (address + 4) + index * TYPE_LENGTH (el_type)(el_type)->length; | |||
907 | return value_at (el_type, address, NULL((void*)0)); | |||
908 | } | |||
909 | else if (TYPE_CODE (type)(type)->main_type->code == TYPE_CODE_ARRAY) | |||
910 | { | |||
911 | if (noside == EVAL_AVOID_SIDE_EFFECTS) | |||
912 | return value_zero (TYPE_TARGET_TYPE (type)(type)->main_type->target_type, VALUE_LVAL (arg1)(arg1)->lval); | |||
913 | else | |||
914 | return value_subscript (arg1, arg2); | |||
915 | } | |||
916 | if (name) | |||
917 | error ("cannot subscript something of type `%s'", name); | |||
918 | else | |||
919 | error ("cannot subscript requested type"); | |||
920 | ||||
921 | case OP_STRING: | |||
922 | (*pos)++; | |||
923 | i = longest_to_int (exp->elts[pc + 1].longconst); | |||
924 | (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1)(((i + 1) + sizeof (union exp_element) - 1) / sizeof (union exp_element )); | |||
925 | if (noside == EVAL_SKIP) | |||
926 | goto nosideret; | |||
927 | return java_value_string (&exp->elts[pc + 2].string, i); | |||
928 | ||||
929 | case STRUCTOP_STRUCT: | |||
930 | arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); | |||
931 | /* Convert object field (such as TYPE.class) to reference. */ | |||
932 | if (TYPE_CODE (VALUE_TYPE (arg1))((arg1)->type)->main_type->code == TYPE_CODE_STRUCT) | |||
933 | arg1 = value_addr (arg1); | |||
934 | return arg1; | |||
935 | default: | |||
936 | break; | |||
937 | } | |||
938 | standard: | |||
939 | return evaluate_subexp_standard (expect_type, exp, pos, noside); | |||
940 | nosideret: | |||
941 | return value_from_longest (builtin_type_long, (LONGESTlong) 1); | |||
942 | } | |||
943 | ||||
944 | static struct type * | |||
945 | java_create_fundamental_type (struct objfile *objfile, int typeid) | |||
946 | { | |||
947 | switch (typeid) | |||
948 | { | |||
949 | case FT_VOID0: | |||
950 | return java_void_type; | |||
951 | case FT_BOOLEAN1: | |||
952 | return java_boolean_type; | |||
953 | case FT_CHAR2: | |||
954 | return java_char_type; | |||
955 | case FT_FLOAT17: | |||
956 | return java_float_type; | |||
957 | case FT_DBL_PREC_FLOAT18: | |||
958 | return java_double_type; | |||
959 | case FT_BYTE26: | |||
960 | case FT_SIGNED_CHAR3: | |||
961 | return java_byte_type; | |||
962 | case FT_SHORT5: | |||
963 | case FT_SIGNED_SHORT6: | |||
964 | return java_short_type; | |||
965 | case FT_INTEGER8: | |||
966 | case FT_SIGNED_INTEGER9: | |||
967 | return java_int_type; | |||
968 | case FT_LONG11: | |||
969 | case FT_SIGNED_LONG12: | |||
970 | return java_long_type; | |||
971 | } | |||
972 | return c_create_fundamental_type (objfile, typeid); | |||
973 | } | |||
974 | ||||
975 | static char *java_demangle (const char *mangled, int options) | |||
976 | { | |||
977 | return cplus_demangle (mangled, options | DMGL_JAVA(1 << 2)); | |||
978 | } | |||
979 | ||||
980 | /* Find the member function name of the demangled name NAME. NAME | |||
981 | must be a method name including arguments, in order to correctly | |||
982 | locate the last component. | |||
983 | ||||
984 | This function return a pointer to the first dot before the | |||
985 | member function name, or NULL if the name was not of the | |||
986 | expected form. */ | |||
987 | ||||
988 | static const char * | |||
989 | java_find_last_component (const char *name) | |||
990 | { | |||
991 | const char *p; | |||
992 | ||||
993 | /* Find argument list. */ | |||
994 | p = strchr (name, '('); | |||
995 | ||||
996 | if (p == NULL((void*)0)) | |||
997 | return NULL((void*)0); | |||
998 | ||||
999 | /* Back up and find first dot prior to argument list. */ | |||
1000 | while (p > name && *p != '.') | |||
1001 | p--; | |||
1002 | ||||
1003 | if (p == name) | |||
1004 | return NULL((void*)0); | |||
1005 | ||||
1006 | return p; | |||
1007 | } | |||
1008 | ||||
1009 | /* Return the name of the class containing method PHYSNAME. */ | |||
1010 | ||||
1011 | static char * | |||
1012 | java_class_name_from_physname (const char *physname) | |||
1013 | { | |||
1014 | char *ret = NULL((void*)0); | |||
1015 | const char *end; | |||
1016 | int depth = 0; | |||
1017 | char *demangled_name = java_demangle (physname, DMGL_PARAMS(1 << 0) | DMGL_ANSI(1 << 1)); | |||
1018 | ||||
1019 | if (demangled_name == NULL((void*)0)) | |||
1020 | return NULL((void*)0); | |||
1021 | ||||
1022 | end = java_find_last_component (demangled_name); | |||
1023 | if (end != NULL((void*)0)) | |||
1024 | { | |||
1025 | ret = xmalloc (end - demangled_name + 1); | |||
1026 | memcpy (ret, demangled_name, end - demangled_name); | |||
1027 | ret[end - demangled_name] = '\0'; | |||
1028 | } | |||
1029 | ||||
1030 | xfree (demangled_name); | |||
1031 | return ret; | |||
1032 | } | |||
1033 | ||||
1034 | /* Table mapping opcodes into strings for printing operators | |||
1035 | and precedences of the operators. */ | |||
1036 | ||||
1037 | const struct op_print java_op_print_tab[] = | |||
1038 | { | |||
1039 | {",", BINOP_COMMA, PREC_COMMA, 0}, | |||
1040 | {"=", BINOP_ASSIGN, PREC_ASSIGN, 1}, | |||
1041 | {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, | |||
1042 | {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, | |||
1043 | {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, | |||
1044 | {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, | |||
1045 | {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, | |||
1046 | {"==", BINOP_EQUAL, PREC_EQUAL, 0}, | |||
1047 | {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, | |||
1048 | {"<=", BINOP_LEQ, PREC_ORDER, 0}, | |||
1049 | {">=", BINOP_GEQ, PREC_ORDER, 0}, | |||
1050 | {">", BINOP_GTR, PREC_ORDER, 0}, | |||
1051 | {"<", BINOP_LESS, PREC_ORDER, 0}, | |||
1052 | {">>", BINOP_RSH, PREC_SHIFT, 0}, | |||
1053 | {"<<", BINOP_LSH, PREC_SHIFT, 0}, | |||
1054 | #if 0 | |||
1055 | {">>>", BINOP_ ? ? ?, PREC_SHIFT, 0}, | |||
1056 | #endif | |||
1057 | {"+", BINOP_ADD, PREC_ADD, 0}, | |||
1058 | {"-", BINOP_SUB, PREC_ADD, 0}, | |||
1059 | {"*", BINOP_MUL, PREC_MUL, 0}, | |||
1060 | {"/", BINOP_DIV, PREC_MUL, 0}, | |||
1061 | {"%", BINOP_REM, PREC_MUL, 0}, | |||
1062 | {"-", UNOP_NEG, PREC_PREFIX, 0}, | |||
1063 | {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, | |||
1064 | {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0}, | |||
1065 | {"*", UNOP_IND, PREC_PREFIX, 0}, | |||
1066 | #if 0 | |||
1067 | {"instanceof", ? ? ?, ? ? ?, 0}, | |||
1068 | #endif | |||
1069 | {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, | |||
1070 | {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, | |||
1071 | {NULL((void*)0), 0, 0, 0} | |||
1072 | }; | |||
1073 | ||||
1074 | const struct exp_descriptor exp_descriptor_java = | |||
1075 | { | |||
1076 | print_subexp_standard, | |||
1077 | operator_length_standard, | |||
1078 | op_name_standard, | |||
1079 | dump_subexp_body_standard, | |||
1080 | evaluate_subexp_java | |||
1081 | }; | |||
1082 | ||||
1083 | const struct language_defn java_language_defn = | |||
1084 | { | |||
1085 | "java", /* Language name */ | |||
1086 | language_java, | |||
1087 | NULL((void*)0), | |||
1088 | range_check_off, | |||
1089 | type_check_off, | |||
1090 | case_sensitive_on, | |||
1091 | array_row_major, | |||
1092 | &exp_descriptor_java, | |||
1093 | java_parse, | |||
1094 | java_error, | |||
1095 | null_post_parser, | |||
1096 | c_printchar, /* Print a character constant */ | |||
1097 | c_printstr, /* Function to print string constant */ | |||
1098 | java_emit_char, /* Function to print a single character */ | |||
1099 | java_create_fundamental_type, /* Create fundamental type in this language */ | |||
1100 | java_print_type, /* Print a type using appropriate syntax */ | |||
1101 | java_val_print, /* Print a value using appropriate syntax */ | |||
1102 | java_value_print, /* Print a top-level value */ | |||
1103 | NULL((void*)0), /* Language specific skip_trampoline */ | |||
1104 | value_of_this, /* value_of_this */ | |||
1105 | basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ | |||
1106 | basic_lookup_transparent_type,/* lookup_transparent_type */ | |||
1107 | java_demangle, /* Language specific symbol demangler */ | |||
1108 | java_class_name_from_physname,/* Language specific class name */ | |||
1109 | java_op_print_tab, /* expression operators for printing */ | |||
1110 | 0, /* not c-style arrays */ | |||
1111 | 0, /* String lower bound */ | |||
1112 | NULL((void*)0), | |||
1113 | default_word_break_characters, | |||
1114 | c_language_arch_info, | |||
1115 | LANG_MAGIC910823L | |||
1116 | }; | |||
1117 | ||||
1118 | void | |||
1119 | _initialize_java_language (void) | |||
1120 | { | |||
1121 | ||||
1122 | java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL((void*)0)); | |||
1123 | java_short_type = init_type (TYPE_CODE_INT, 2, 0, "short", NULL((void*)0)); | |||
1124 | java_long_type = init_type (TYPE_CODE_INT, 8, 0, "long", NULL((void*)0)); | |||
1125 | java_byte_type = init_type (TYPE_CODE_INT, 1, 0, "byte", NULL((void*)0)); | |||
1126 | java_boolean_type = init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL((void*)0)); | |||
1127 | java_char_type = init_type (TYPE_CODE_CHAR, 2, TYPE_FLAG_UNSIGNED(1 << 0), "char", NULL((void*)0)); | |||
1128 | java_float_type = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL((void*)0)); | |||
1129 | java_double_type = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL((void*)0)); | |||
1130 | java_void_type = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL((void*)0)); | |||
1131 | ||||
1132 | add_language (&java_language_defn); | |||
1133 | } | |||
1134 | ||||
1135 | /* Cleanup code that should be run on every "run". | |||
1136 | We should use make_run_cleanup to have this be called. | |||
1137 | But will that mess up values in value histry? FIXME */ | |||
1138 | ||||
1139 | extern void java_rerun_cleanup (void); | |||
1140 | void | |||
1141 | java_rerun_cleanup (void) | |||
1142 | { | |||
1143 | if (class_symtab != NULL((void*)0)) | |||
1144 | { | |||
1145 | free_symtab (class_symtab); /* ??? */ | |||
1146 | class_symtab = NULL((void*)0); | |||
1147 | } | |||
1148 | if (dynamics_objfile != NULL((void*)0)) | |||
1149 | { | |||
1150 | free_objfile (dynamics_objfile); | |||
1151 | dynamics_objfile = NULL((void*)0); | |||
1152 | } | |||
1153 | ||||
1154 | java_object_type = NULL((void*)0); | |||
1155 | } |