X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Fjv-lang.c;h=6b68e7d6b0e3dc43cc665f650e9d8aaf8581dac1;hb=e17a4113357102b55cfa5b80557d590a46a43300;hp=0fb79b484270c09408c48e33b648e6f9cf846e7c;hpb=b6ba6518e9254bc25f88088228e93ac966ebccd1;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 0fb79b4842..6b68e7d6b0 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1,11 +1,13 @@
/* Java language support routines for GDB, the GNU debugger.
- Copyright 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+
+ Copyright (C) 1997, 1998, 1999, 2000, 2003, 2004, 2005, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -14,9 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see . */
#include "defs.h"
#include "symtab.h"
@@ -33,17 +33,11 @@
#include "c-lang.h"
#include "jv-lang.h"
#include "gdbcore.h"
+#include "block.h"
+#include "demangle.h"
+#include "dictionary.h"
#include
-
-struct type *java_int_type;
-struct type *java_byte_type;
-struct type *java_short_type;
-struct type *java_long_type;
-struct type *java_boolean_type;
-struct type *java_char_type;
-struct type *java_float_type;
-struct type *java_double_type;
-struct type *java_void_type;
+#include "gdb_assert.h"
/* Local functions */
@@ -53,12 +47,14 @@ static int java_demangled_signature_length (char *);
static void java_demangled_signature_copy (char *, char *);
static struct symtab *get_java_class_symtab (void);
-static char *get_java_utf8_name (struct obstack *obstack, value_ptr name);
-static int java_class_is_primitive (value_ptr clas);
-static struct type *java_lookup_type (char *signature);
-static value_ptr java_value_string (char *ptr, int len);
+static char *get_java_utf8_name (struct obstack *obstack, struct value *name);
+static int java_class_is_primitive (struct value *clas);
+static struct value *java_value_string (char *ptr, int len);
+
+static void java_emit_char (int c, struct type *type,
+ struct ui_file * stream, int quoter);
-static void java_emit_char (int c, struct ui_file * stream, int quoter);
+static char *java_class_name_from_physname (const char *physname);
/* This objfile contains symtabs that have been dynamically created
to record dynamically loaded Java classes and dynamically
@@ -66,7 +62,14 @@ static void java_emit_char (int c, struct ui_file * stream, int quoter);
static struct objfile *dynamics_objfile = NULL;
-static struct type *java_link_class_type (struct type *, value_ptr);
+static struct type *java_link_class_type (struct gdbarch *,
+ struct type *, struct value *);
+
+/* FIXME: carlton/2003-02-04: This is the main or only caller of
+ allocate_objfile with first argument NULL; as a result, this code
+ breaks every so often. Somebody should write a test case that
+ exercises GDB in various ways (e.g. something involving loading a
+ dynamic library) after this code has been called. */
static struct objfile *
get_dynamics_objfile (void)
@@ -83,9 +86,7 @@ get_dynamics_objfile (void)
static struct symtab *class_symtab = NULL;
-/* Maximum number of class in class_symtab before relocation is needed. */
-
-static int class_symtab_space;
+static void free_class_block (struct symtab *symtab);
static struct symtab *
get_java_class_symtab (void)
@@ -98,30 +99,22 @@ get_java_class_symtab (void)
class_symtab = allocate_symtab ("", objfile);
class_symtab->language = language_java;
bv = (struct blockvector *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct blockvector));
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct blockvector) + sizeof (struct block *));
BLOCKVECTOR_NBLOCKS (bv) = 1;
BLOCKVECTOR (class_symtab) = bv;
/* Allocate dummy STATIC_BLOCK. */
- bl = (struct block *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
- BLOCK_NSYMS (bl) = 0;
- BLOCK_START (bl) = 0;
- BLOCK_END (bl) = 0;
- BLOCK_FUNCTION (bl) = NULL;
- BLOCK_SUPERBLOCK (bl) = NULL;
- BLOCK_GCC_COMPILED (bl) = 0;
+ bl = allocate_block (&objfile->objfile_obstack);
+ BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
+ NULL);
BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
- /* Allocate GLOBAL_BLOCK. This has to be relocatable. */
- class_symtab_space = 128;
- bl = (struct block *)
- mmalloc (objfile->md,
- sizeof (struct block)
- + ((class_symtab_space - 1) * sizeof (struct symbol *)));
- *bl = *BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+ /* Allocate GLOBAL_BLOCK. */
+ bl = allocate_block (&objfile->objfile_obstack);
+ BLOCK_DICT (bl) = dict_create_hashed_expandable ();
BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
- class_symtab->free_ptr = (char *) bl;
+ class_symtab->free_func = free_class_block;
}
return class_symtab;
}
@@ -131,21 +124,7 @@ add_class_symtab_symbol (struct symbol *sym)
{
struct symtab *symtab = get_java_class_symtab ();
struct blockvector *bv = BLOCKVECTOR (symtab);
- struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- if (BLOCK_NSYMS (bl) >= class_symtab_space)
- {
- /* Need to re-allocate. */
- class_symtab_space *= 2;
- bl = (struct block *)
- mrealloc (symtab->objfile->md, bl,
- sizeof (struct block)
- + ((class_symtab_space - 1) * sizeof (struct symbol *)));
- class_symtab->free_ptr = (char *) bl;
- BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
- }
-
- BLOCK_SYM (bl, BLOCK_NSYMS (bl)) = sym;
- BLOCK_NSYMS (bl) = BLOCK_NSYMS (bl) + 1;
+ dict_add_symbol (BLOCK_DICT (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)), sym);
}
static struct symbol *add_class_symbol (struct type *type, CORE_ADDR addr);
@@ -155,25 +134,34 @@ add_class_symbol (struct type *type, CORE_ADDR addr)
{
struct symbol *sym;
sym = (struct symbol *)
- obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
+ obstack_alloc (&dynamics_objfile->objfile_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
SYMBOL_LANGUAGE (sym) = language_java;
- SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
+ SYMBOL_SET_LINKAGE_NAME (sym, TYPE_TAG_NAME (type));
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
/* SYMBOL_VALUE (sym) = valu; */
SYMBOL_TYPE (sym) = type;
- SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
+ SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
SYMBOL_VALUE_ADDRESS (sym) = addr;
return sym;
}
+
+/* Free the dynamic symbols block. */
+static void
+free_class_block (struct symtab *symtab)
+{
+ struct blockvector *bv = BLOCKVECTOR (symtab);
+ struct block *bl = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+
+ dict_free (BLOCK_DICT (bl));
+}
#endif
struct type *
java_lookup_class (char *name)
{
struct symbol *sym;
- sym = lookup_symbol (name, expression_context_block, STRUCT_NAMESPACE,
- (int *) 0, (struct symtab **) NULL);
+ sym = lookup_symbol (name, expression_context_block, STRUCT_DOMAIN, NULL);
if (sym != NULL)
return SYMBOL_TYPE (sym);
#if 0
@@ -192,8 +180,8 @@ java_lookup_class (char *name)
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
INIT_CPLUS_SPECIFIC (type);
- TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), &objfile->type_obstack);
- TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), &objfile->objfile_obstack);
+ TYPE_STUB (type) = 1;
TYPE ? = addr;
return type;
#else
@@ -206,33 +194,32 @@ java_lookup_class (char *name)
a name given by NAME (which has type Utf8Const*). */
char *
-get_java_utf8_name (struct obstack *obstack, value_ptr name)
+get_java_utf8_name (struct obstack *obstack, struct value *name)
{
char *chrs;
- value_ptr temp = name;
+ struct value *temp = name;
int name_length;
CORE_ADDR data_addr;
temp = value_struct_elt (&temp, NULL, "length", NULL, "structure");
name_length = (int) value_as_long (temp);
- data_addr = VALUE_ADDRESS (temp) + VALUE_OFFSET (temp)
- + TYPE_LENGTH (VALUE_TYPE (temp));
+ data_addr = value_address (temp) + TYPE_LENGTH (value_type (temp));
chrs = obstack_alloc (obstack, name_length + 1);
chrs[name_length] = '\0';
- read_memory (data_addr, chrs, name_length);
+ read_memory (data_addr, (gdb_byte *) chrs, name_length);
return chrs;
}
-value_ptr
-java_class_from_object (value_ptr obj_val)
+struct value *
+java_class_from_object (struct value *obj_val)
{
/* This is all rather inefficient, since the offsets of vtable and
class are fixed. FIXME */
- value_ptr vtable_val;
+ struct value *vtable_val;
- if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR
- && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0)
+ if (TYPE_CODE (value_type (obj_val)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (value_type (obj_val))) == 0)
obj_val = value_at (get_java_object_type (),
- value_as_pointer (obj_val), NULL);
+ value_as_address (obj_val));
vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
@@ -240,44 +227,43 @@ java_class_from_object (value_ptr obj_val)
/* Check if CLASS_IS_PRIMITIVE(value of clas): */
static int
-java_class_is_primitive (value_ptr clas)
+java_class_is_primitive (struct value *clas)
{
- value_ptr vtable = value_struct_elt (&clas, NULL, "vtable", NULL, "struct");
- CORE_ADDR i = value_as_pointer (vtable);
+ struct value *vtable = value_struct_elt (&clas, NULL, "vtable", NULL, "struct");
+ CORE_ADDR i = value_as_address (vtable);
return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
}
/* Read a GCJ Class object, and generated a gdb (TYPE_CODE_STRUCT) type. */
struct type *
-type_from_class (value_ptr clas)
+type_from_class (struct gdbarch *gdbarch, struct value *clas)
{
struct type *type;
char *name;
- value_ptr temp;
+ struct value *temp;
struct objfile *objfile;
- value_ptr utf8_name;
+ struct value *utf8_name;
char *nptr;
CORE_ADDR addr;
struct block *bl;
- int i;
+ struct dict_iterator iter;
int is_array = 0;
- type = check_typedef (VALUE_TYPE (clas));
+ type = check_typedef (value_type (clas));
if (TYPE_CODE (type) == TYPE_CODE_PTR)
{
if (value_logical_not (clas))
return NULL;
clas = value_ind (clas);
}
- addr = VALUE_ADDRESS (clas) + VALUE_OFFSET (clas);
+ addr = value_address (clas);
#if 0
get_java_class_symtab ();
bl = BLOCKVECTOR_BLOCK (BLOCKVECTOR (class_symtab), GLOBAL_BLOCK);
- for (i = BLOCK_NSYMS (bl); --i >= 0;)
+ ALL_BLOCK_SYMBOLS (block, iter, sym)
{
- struct symbol *sym = BLOCK_SYM (bl, i);
if (SYMBOL_VALUE_ADDRESS (sym) == addr)
return SYMBOL_TYPE (sym);
}
@@ -286,17 +272,17 @@ type_from_class (value_ptr clas)
objfile = get_dynamics_objfile ();
if (java_class_is_primitive (clas))
{
- value_ptr sig;
+ struct value *sig;
temp = clas;
sig = value_struct_elt (&temp, NULL, "method_count", NULL, "structure");
- return java_primitive_type (value_as_long (sig));
+ return java_primitive_type (gdbarch, value_as_long (sig));
}
/* Get Class name. */
/* if clasloader non-null, prepend loader address. FIXME */
temp = clas;
utf8_name = value_struct_elt (&temp, NULL, "name", NULL, "structure");
- name = get_java_utf8_name (&objfile->type_obstack, utf8_name);
+ name = get_java_utf8_name (&objfile->objfile_obstack, utf8_name);
for (nptr = name; *nptr != 0; nptr++)
{
if (*nptr == '/')
@@ -307,7 +293,10 @@ type_from_class (value_ptr clas)
if (type != NULL)
return type;
- type = alloc_type (objfile);
+ /* Do not use the "fake" dynamics objfile to own dynamically generated
+ types, as it does not provide an architecture, and it would not help
+ manage the lifetime of these types anyway. */
+ type = alloc_type_arch (gdbarch);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
INIT_CPLUS_SPECIFIC (type);
@@ -316,48 +305,53 @@ type_from_class (value_ptr clas)
char *signature = name;
int namelen = java_demangled_signature_length (signature);
if (namelen > strlen (name))
- name = obstack_alloc (&objfile->type_obstack, namelen + 1);
+ name = obstack_alloc (&objfile->objfile_obstack, namelen + 1);
java_demangled_signature_copy (name, signature);
name[namelen] = '\0';
is_array = 1;
temp = clas;
/* Set array element type. */
temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure");
- VALUE_TYPE (temp) = lookup_pointer_type (VALUE_TYPE (clas));
- TYPE_TARGET_TYPE (type) = type_from_class (temp);
+ deprecated_set_value_type (temp, lookup_pointer_type (value_type (clas)));
+ TYPE_TARGET_TYPE (type) = type_from_class (gdbarch, temp);
}
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_TAG_NAME (type) = name;
add_class_symtab_symbol (add_class_symbol (type, addr));
- return java_link_class_type (type, clas);
+ return java_link_class_type (gdbarch, type, clas);
}
/* Fill in class TYPE with data from the CLAS value. */
struct type *
-java_link_class_type (struct type *type, value_ptr clas)
+java_link_class_type (struct gdbarch *gdbarch,
+ struct type *type, struct value *clas)
{
- value_ptr temp;
+ struct value *temp;
char *unqualified_name;
char *name = TYPE_TAG_NAME (type);
int ninterfaces, nfields, nmethods;
int type_is_object = 0;
struct fn_field *fn_fields;
struct fn_fieldlist *fn_fieldlists;
- value_ptr fields, field, method, methods;
+ struct value *fields;
+ struct value *methods;
+ struct value *method = NULL;
+ struct value *field = NULL;
int i, j;
struct objfile *objfile = get_dynamics_objfile ();
struct type *tsuper;
+ gdb_assert (name != NULL);
unqualified_name = strrchr (name, '.');
if (unqualified_name == NULL)
unqualified_name = name;
temp = clas;
temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure");
- if (name != NULL && strcmp (name, "java.lang.Object") == 0)
+ if (strcmp (name, "java.lang.Object") == 0)
{
tsuper = get_java_object_type ();
if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR)
@@ -365,7 +359,7 @@ java_link_class_type (struct type *type, value_ptr clas)
type_is_object = 1;
}
else
- tsuper = type_from_class (temp);
+ tsuper = type_from_class (gdbarch, temp);
#if 1
ninterfaces = 0;
@@ -422,10 +416,9 @@ java_link_class_type (struct type *type, value_ptr clas)
fields = NULL;
nfields--; /* First set up dummy "class" field. */
- SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
- VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
+ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas));
TYPE_FIELD_NAME (type, nfields) = "class";
- TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
+ TYPE_FIELD_TYPE (type, nfields) = value_type (clas);
SET_TYPE_FIELD_PRIVATE (type, nfields);
for (i = TYPE_N_BASECLASSES (type); i < nfields; i++)
@@ -440,13 +433,15 @@ java_link_class_type (struct type *type, value_ptr clas)
}
else
{ /* Re-use field value for next field. */
- VALUE_ADDRESS (field) += TYPE_LENGTH (VALUE_TYPE (field));
- VALUE_LAZY (field) = 1;
+ CORE_ADDR addr
+ = value_address (field) + TYPE_LENGTH (value_type (field));
+ set_value_address (field, addr);
+ set_value_lazy (field, 1);
}
temp = field;
temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
TYPE_FIELD_NAME (type, i) =
- get_java_utf8_name (&objfile->type_obstack, temp);
+ get_java_utf8_name (&objfile->objfile_obstack, temp);
temp = field;
accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags",
NULL, "structure"));
@@ -479,7 +474,7 @@ java_link_class_type (struct type *type, value_ptr clas)
struct type *ftype;
temp = field;
temp = value_struct_elt (&temp, NULL, "type", NULL, "structure");
- ftype = type_from_class (temp);
+ ftype = type_from_class (gdbarch, temp);
if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT)
ftype = lookup_pointer_type (ftype);
TYPE_FIELD_TYPE (type, i) = ftype;
@@ -492,7 +487,7 @@ java_link_class_type (struct type *type, value_ptr clas)
TYPE_NFN_FIELDS_TOTAL (type) = nmethods;
j = nmethods * sizeof (struct fn_field);
fn_fields = (struct fn_field *)
- obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+ obstack_alloc (&dynamics_objfile->objfile_obstack, j);
memset (fn_fields, 0, j);
fn_fieldlists = (struct fn_fieldlist *)
alloca (nmethods * sizeof (struct fn_fieldlist));
@@ -510,14 +505,16 @@ java_link_class_type (struct type *type, value_ptr clas)
}
else
{ /* Re-use method value for next method. */
- VALUE_ADDRESS (method) += TYPE_LENGTH (VALUE_TYPE (method));
- VALUE_LAZY (method) = 1;
+ CORE_ADDR addr
+ = value_address (method) + TYPE_LENGTH (value_type (method));
+ set_value_address (method, addr);
+ set_value_lazy (method, 1);
}
/* Get method name. */
temp = method;
temp = value_struct_elt (&temp, NULL, "name", NULL, "structure");
- mname = get_java_utf8_name (&objfile->type_obstack, temp);
+ mname = get_java_utf8_name (&objfile->objfile_obstack, temp);
if (strcmp (mname, "") == 0)
mname = unqualified_name;
@@ -542,7 +539,7 @@ java_link_class_type (struct type *type, value_ptr clas)
{ /* Found an existing method with the same name. */
int l;
if (mname != unqualified_name)
- obstack_free (&objfile->type_obstack, mname);
+ obstack_free (&objfile->objfile_obstack, mname);
mname = fn_fieldlists[j].name;
fn_fieldlists[j].length++;
k = i - k; /* Index of new slot. */
@@ -557,13 +554,15 @@ java_link_class_type (struct type *type, value_ptr clas)
}
fn_fields[k].physname = "";
fn_fields[k].is_stub = 1;
- fn_fields[k].type = make_function_type (java_void_type, NULL); /* FIXME */
+ /* FIXME */
+ fn_fields[k].type = lookup_function_type
+ (builtin_java_type (gdbarch)->builtin_void);
TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD;
}
j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist);
TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
- obstack_alloc (&dynamics_objfile->symbol_obstack, j);
+ obstack_alloc (&dynamics_objfile->objfile_obstack, j);
memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j);
return type;
@@ -577,21 +576,20 @@ get_java_object_type (void)
if (java_object_type == NULL)
{
struct symbol *sym;
- sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_NAMESPACE,
- (int *) 0, (struct symtab **) NULL);
+ sym = lookup_symbol ("java.lang.Object", NULL, STRUCT_DOMAIN, NULL);
if (sym == NULL)
- error ("cannot find java.lang.Object");
+ error (_("cannot find java.lang.Object"));
java_object_type = SYMBOL_TYPE (sym);
}
return java_object_type;
}
int
-get_java_object_header_size (void)
+get_java_object_header_size (struct gdbarch *gdbarch)
{
struct type *objtype = get_java_object_type ();
if (objtype == NULL)
- return (2 * TARGET_PTR_BIT / TARGET_CHAR_BIT);
+ return (2 * gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
else
return TYPE_LENGTH (objtype);
}
@@ -623,77 +621,109 @@ is_object_type (struct type *type)
}
struct type *
-java_primitive_type (int signature)
+java_primitive_type (struct gdbarch *gdbarch, int signature)
{
+ const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
+
switch (signature)
{
case 'B':
- return java_byte_type;
+ return builtin->builtin_byte;
case 'S':
- return java_short_type;
+ return builtin->builtin_short;
case 'I':
- return java_int_type;
+ return builtin->builtin_int;
case 'J':
- return java_long_type;
+ return builtin->builtin_long;
case 'Z':
- return java_boolean_type;
+ return builtin->builtin_boolean;
case 'C':
- return java_char_type;
+ return builtin->builtin_char;
case 'F':
- return java_float_type;
+ return builtin->builtin_float;
case 'D':
- return java_double_type;
+ return builtin->builtin_double;
case 'V':
- return java_void_type;
+ return builtin->builtin_void;
}
- error ("unknown signature '%c' for primitive type", (char) signature);
+ error (_("unknown signature '%c' for primitive type"), (char) signature);
}
/* If name[0 .. namelen-1] is the name of a primitive Java type,
return that type. Otherwise, return NULL. */
struct type *
-java_primitive_type_from_name (char *name, int namelen)
+java_primitive_type_from_name (struct gdbarch *gdbarch,
+ char *name, int namelen)
{
+ const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
+
switch (name[0])
{
case 'b':
if (namelen == 4 && memcmp (name, "byte", 4) == 0)
- return java_byte_type;
+ return builtin->builtin_byte;
if (namelen == 7 && memcmp (name, "boolean", 7) == 0)
- return java_boolean_type;
+ return builtin->builtin_boolean;
break;
case 'c':
if (namelen == 4 && memcmp (name, "char", 4) == 0)
- return java_char_type;
+ return builtin->builtin_char;
case 'd':
if (namelen == 6 && memcmp (name, "double", 6) == 0)
- return java_double_type;
+ return builtin->builtin_double;
break;
case 'f':
if (namelen == 5 && memcmp (name, "float", 5) == 0)
- return java_float_type;
+ return builtin->builtin_float;
break;
case 'i':
if (namelen == 3 && memcmp (name, "int", 3) == 0)
- return java_int_type;
+ return builtin->builtin_int;
break;
case 'l':
if (namelen == 4 && memcmp (name, "long", 4) == 0)
- return java_long_type;
+ return builtin->builtin_long;
break;
case 's':
if (namelen == 5 && memcmp (name, "short", 5) == 0)
- return java_short_type;
+ return builtin->builtin_short;
break;
case 'v':
if (namelen == 4 && memcmp (name, "void", 4) == 0)
- return java_void_type;
+ return builtin->builtin_void;
break;
}
return NULL;
}
+static char *
+java_primitive_type_name (int signature)
+{
+ switch (signature)
+ {
+ case 'B':
+ return "byte";
+ case 'S':
+ return "short";
+ case 'I':
+ return "int";
+ case 'J':
+ return "long";
+ case 'Z':
+ return "boolean";
+ case 'C':
+ return "char";
+ case 'F':
+ return "float";
+ case 'D':
+ return "double";
+ case 'V':
+ return "void";
+ }
+ error (_("unknown signature '%c' for primitive type"), (char) signature);
+}
+
/* Return the length (in bytes) of demangled name of the Java type
signature string SIGNATURE. */
@@ -709,7 +739,7 @@ java_demangled_signature_length (char *signature)
/* Subtract 2 for 'L' and ';'. */
return strlen (signature) - 2 + array;
default:
- return strlen (TYPE_NAME (java_primitive_type (signature[0]))) + array;
+ return strlen (java_primitive_type_name (signature[0])) + array;
}
}
@@ -741,7 +771,7 @@ java_demangled_signature_copy (char *result, char *signature)
}
break;
default:
- ptr = TYPE_NAME (java_primitive_type (signature[0]));
+ ptr = java_primitive_type_name (signature[0]);
i = strlen (ptr);
strcpy (result, ptr);
ptr = result + i;
@@ -767,32 +797,16 @@ java_demangle_type_signature (char *signature)
return result;
}
-struct type *
-java_lookup_type (char *signature)
-{
- switch (signature[0])
- {
- case 'L':
- case '[':
- error ("java_lookup_type not fully implemented");
- default:
- return java_primitive_type (signature[0]);
- }
-}
-
/* Return the type of TYPE followed by DIMS pairs of [ ].
If DIMS == 0, TYPE is returned. */
struct type *
java_array_type (struct type *type, int dims)
{
- struct type *range_type;
-
while (dims-- > 0)
{
- range_type = create_range_type (NULL, builtin_type_int, 0, 0);
/* FIXME This is bogus! Java arrays are not gdb arrays! */
- type = create_array_type (NULL, type, range_type);
+ type = lookup_array_range_type (type, 0, 0);
}
return type;
@@ -800,10 +814,10 @@ java_array_type (struct type *type, int dims)
/* Create a Java string in the inferior from a (Utf8) literal. */
-static value_ptr
+static struct value *
java_value_string (char *ptr, int len)
{
- error ("not implemented - java_value_string"); /* FIXME */
+ error (_("not implemented - java_value_string")); /* FIXME */
}
/* Print the character C on STREAM as part of the contents of a literal
@@ -811,7 +825,7 @@ java_value_string (char *ptr, int len)
characters and strings is language specific. */
static void
-java_emit_char (int c, struct ui_file *stream, int quoter)
+java_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
{
switch (c)
{
@@ -843,15 +857,16 @@ java_emit_char (int c, struct ui_file *stream, int quoter)
}
}
-static value_ptr
-evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
- register int *pos, enum noside noside)
+static struct value *
+evaluate_subexp_java (struct type *expect_type, struct expression *exp,
+ int *pos, enum noside noside)
{
int pc = *pos;
int i;
char *name;
enum exp_opcode op = exp->elts[*pos].opcode;
- value_ptr arg1, arg2;
+ struct value *arg1;
+ struct value *arg2;
struct type *type;
switch (op)
{
@@ -860,11 +875,11 @@ evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
goto standard;
(*pos)++;
arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
- if (is_object_type (VALUE_TYPE (arg1)))
+ if (is_object_type (value_type (arg1)))
{
struct type *type;
- type = type_from_class (java_class_from_object (arg1));
+ type = type_from_class (exp->gdbarch, java_class_from_object (arg1));
arg1 = value_cast (lookup_pointer_type (type), arg1);
}
if (noside == EVAL_SKIP)
@@ -881,8 +896,8 @@ evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
array or pointer type (like a plain int variable for example),
then report this as an error. */
- COERCE_REF (arg1);
- type = check_typedef (VALUE_TYPE (arg1));
+ arg1 = coerce_ref (arg1);
+ type = check_typedef (value_type (arg1));
if (TYPE_CODE (type) == TYPE_CODE_PTR)
type = check_typedef (TYPE_TARGET_TYPE (type));
name = TYPE_NAME (type);
@@ -892,45 +907,46 @@ evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
&& i > 2 && name[i - 1] == ']')
{
+ enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch);
CORE_ADDR address;
long length, index;
struct type *el_type;
- char buf4[4];
+ gdb_byte buf4[4];
- value_ptr clas = java_class_from_object (arg1);
- value_ptr temp = clas;
+ struct value *clas = java_class_from_object (arg1);
+ struct value *temp = clas;
/* Get CLASS_ELEMENT_TYPE of the array type. */
temp = value_struct_elt (&temp, NULL, "methods",
NULL, "structure");
- VALUE_TYPE (temp) = VALUE_TYPE (clas);
- el_type = type_from_class (temp);
+ deprecated_set_value_type (temp, value_type (clas));
+ el_type = type_from_class (exp->gdbarch, temp);
if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
el_type = lookup_pointer_type (el_type);
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value_zero (el_type, VALUE_LVAL (arg1));
- address = value_as_pointer (arg1);
- address += JAVA_OBJECT_SIZE;
+ address = value_as_address (arg1);
+ address += get_java_object_header_size (exp->gdbarch);
read_memory (address, buf4, 4);
- length = (long) extract_signed_integer (buf4, 4);
+ length = (long) extract_signed_integer (buf4, 4, byte_order);
index = (long) value_as_long (arg2);
if (index >= length || index < 0)
- error ("array index (%ld) out of bounds (length: %ld)",
+ error (_("array index (%ld) out of bounds (length: %ld)"),
index, length);
address = (address + 4) + index * TYPE_LENGTH (el_type);
- return value_at (el_type, address, NULL);
+ return value_at (el_type, address);
}
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
else
- return value_subscript (arg1, arg2);
+ return value_subscript (arg1, value_as_long (arg2));
}
if (name)
- error ("cannot subscript something of type `%s'", name);
+ error (_("cannot subscript something of type `%s'"), name);
else
- error ("cannot subscript requested type");
+ error (_("cannot subscript requested type"));
case OP_STRING:
(*pos)++;
@@ -940,10 +956,10 @@ evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
goto nosideret;
return java_value_string (&exp->elts[pc + 2].string, i);
- case STRUCTOP_STRUCT:
+ case STRUCTOP_PTR:
arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
/* Convert object field (such as TYPE.class) to reference. */
- if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
+ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT)
arg1 = value_addr (arg1);
return arg1;
default:
@@ -952,38 +968,66 @@ evaluate_subexp_java (struct type *expect_type, register struct expression *exp,
standard:
return evaluate_subexp_standard (expect_type, exp, pos, noside);
nosideret:
- return value_from_longest (builtin_type_long, (LONGEST) 1);
+ return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
+}
+
+static char *java_demangle (const char *mangled, int options)
+{
+ return cplus_demangle (mangled, options | DMGL_JAVA);
+}
+
+/* Find the member function name of the demangled name NAME. NAME
+ must be a method name including arguments, in order to correctly
+ locate the last component.
+
+ This function return a pointer to the first dot before the
+ member function name, or NULL if the name was not of the
+ expected form. */
+
+static const char *
+java_find_last_component (const char *name)
+{
+ const char *p;
+
+ /* Find argument list. */
+ p = strchr (name, '(');
+
+ if (p == NULL)
+ return NULL;
+
+ /* Back up and find first dot prior to argument list. */
+ while (p > name && *p != '.')
+ p--;
+
+ if (p == name)
+ return NULL;
+
+ return p;
}
-static struct type *
-java_create_fundamental_type (struct objfile *objfile, int typeid)
+/* Return the name of the class containing method PHYSNAME. */
+
+static char *
+java_class_name_from_physname (const char *physname)
{
- switch (typeid)
+ char *ret = NULL;
+ const char *end;
+ int depth = 0;
+ char *demangled_name = java_demangle (physname, DMGL_PARAMS | DMGL_ANSI);
+
+ if (demangled_name == NULL)
+ return NULL;
+
+ end = java_find_last_component (demangled_name);
+ if (end != NULL)
{
- case FT_VOID:
- return java_void_type;
- case FT_BOOLEAN:
- return java_boolean_type;
- case FT_CHAR:
- return java_char_type;
- case FT_FLOAT:
- return java_float_type;
- case FT_DBL_PREC_FLOAT:
- return java_double_type;
- case FT_BYTE:
- case FT_SIGNED_CHAR:
- return java_byte_type;
- case FT_SHORT:
- case FT_SIGNED_SHORT:
- return java_short_type;
- case FT_INTEGER:
- case FT_SIGNED_INTEGER:
- return java_int_type;
- case FT_LONG:
- case FT_SIGNED_LONG:
- return java_long_type;
+ ret = xmalloc (end - demangled_name + 1);
+ memcpy (ret, demangled_name, end - demangled_name);
+ ret[end - demangled_name] = '\0';
}
- return c_create_fundamental_type (objfile, typeid);
+
+ xfree (demangled_name);
+ return ret;
}
/* Table mapping opcodes into strings for printing operators
@@ -1026,70 +1070,140 @@ const struct op_print java_op_print_tab[] =
{NULL, 0, 0, 0}
};
+enum java_primitive_types
+{
+ java_primitive_type_int,
+ java_primitive_type_short,
+ java_primitive_type_long,
+ java_primitive_type_byte,
+ java_primitive_type_boolean,
+ java_primitive_type_char,
+ java_primitive_type_float,
+ java_primitive_type_double,
+ java_primitive_type_void,
+ nr_java_primitive_types
+};
+
+static void
+java_language_arch_info (struct gdbarch *gdbarch,
+ struct language_arch_info *lai)
+{
+ const struct builtin_java_type *builtin = builtin_java_type (gdbarch);
+
+ lai->string_char_type = builtin->builtin_char;
+ lai->primitive_type_vector
+ = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_java_primitive_types + 1,
+ struct type *);
+ lai->primitive_type_vector [java_primitive_type_int]
+ = builtin->builtin_int;
+ lai->primitive_type_vector [java_primitive_type_short]
+ = builtin->builtin_short;
+ lai->primitive_type_vector [java_primitive_type_long]
+ = builtin->builtin_long;
+ lai->primitive_type_vector [java_primitive_type_byte]
+ = builtin->builtin_byte;
+ lai->primitive_type_vector [java_primitive_type_boolean]
+ = builtin->builtin_boolean;
+ lai->primitive_type_vector [java_primitive_type_char]
+ = builtin->builtin_char;
+ lai->primitive_type_vector [java_primitive_type_float]
+ = builtin->builtin_float;
+ lai->primitive_type_vector [java_primitive_type_double]
+ = builtin->builtin_double;
+ lai->primitive_type_vector [java_primitive_type_void]
+ = builtin->builtin_void;
+
+ lai->bool_type_symbol = "boolean";
+ lai->bool_type_default = builtin->builtin_boolean;
+}
+
+const struct exp_descriptor exp_descriptor_java =
+{
+ print_subexp_standard,
+ operator_length_standard,
+ op_name_standard,
+ dump_subexp_body_standard,
+ evaluate_subexp_java
+};
+
const struct language_defn java_language_defn =
{
"java", /* Language name */
language_java,
- c_builtin_types,
range_check_off,
type_check_off,
case_sensitive_on,
+ array_row_major,
+ macro_expansion_no,
+ &exp_descriptor_java,
java_parse,
java_error,
- evaluate_subexp_java,
+ null_post_parser,
c_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
java_emit_char, /* Function to print a single character */
- java_create_fundamental_type, /* Create fundamental type in this language */
java_print_type, /* Print a type using appropriate syntax */
+ default_print_typedef, /* Print a typedef using appropriate syntax */
java_val_print, /* Print a value using appropriate syntax */
java_value_print, /* Print a top-level value */
- {"", "", "", ""}, /* Binary format info */
- {"0%lo", "0", "o", ""}, /* Octal format info */
- {"%ld", "", "d", ""}, /* Decimal format info */
- {"0x%lx", "0x", "x", ""}, /* Hex format info */
+ NULL, /* Language specific skip_trampoline */
+ "this", /* name_of_this */
+ basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
+ basic_lookup_transparent_type,/* lookup_transparent_type */
+ java_demangle, /* Language specific symbol demangler */
+ java_class_name_from_physname,/* Language specific class name */
java_op_print_tab, /* expression operators for printing */
0, /* not c-style arrays */
0, /* String lower bound */
- &builtin_type_char, /* Type of string elements */
+ default_word_break_characters,
+ default_make_symbol_completion_list,
+ java_language_arch_info,
+ default_print_array_index,
+ default_pass_by_reference,
+ default_get_string,
LANG_MAGIC
};
-void
-_initialize_java_language (void)
+static void *
+build_java_types (struct gdbarch *gdbarch)
{
+ struct builtin_java_type *builtin_java_type
+ = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_java_type);
+
+ builtin_java_type->builtin_int
+ = arch_integer_type (gdbarch, 32, 0, "int");
+ builtin_java_type->builtin_short
+ = arch_integer_type (gdbarch, 16, 0, "short");
+ builtin_java_type->builtin_long
+ = arch_integer_type (gdbarch, 64, 0, "long");
+ builtin_java_type->builtin_byte
+ = arch_integer_type (gdbarch, 8, 0, "byte");
+ builtin_java_type->builtin_boolean
+ = arch_boolean_type (gdbarch, 8, 0, "boolean");
+ builtin_java_type->builtin_char
+ = arch_character_type (gdbarch, 16, 1, "char");
+ builtin_java_type->builtin_float
+ = arch_float_type (gdbarch, 32, "float", NULL);
+ builtin_java_type->builtin_double
+ = arch_float_type (gdbarch, 64, "double", NULL);
+ builtin_java_type->builtin_void
+ = arch_type (gdbarch, TYPE_CODE_VOID, 1, "void");
+
+ return builtin_java_type;
+}
- java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
- java_short_type = init_type (TYPE_CODE_INT, 2, 0, "short", NULL);
- java_long_type = init_type (TYPE_CODE_INT, 8, 0, "long", NULL);
- java_byte_type = init_type (TYPE_CODE_INT, 1, 0, "byte", NULL);
- java_boolean_type = init_type (TYPE_CODE_BOOL, 1, 0, "boolean", NULL);
- java_char_type = init_type (TYPE_CODE_CHAR, 2, TYPE_FLAG_UNSIGNED, "char", NULL);
- java_float_type = init_type (TYPE_CODE_FLT, 4, 0, "float", NULL);
- java_double_type = init_type (TYPE_CODE_FLT, 8, 0, "double", NULL);
- java_void_type = init_type (TYPE_CODE_VOID, 1, 0, "void", NULL);
+static struct gdbarch_data *java_type_data;
- add_language (&java_language_defn);
+const struct builtin_java_type *
+builtin_java_type (struct gdbarch *gdbarch)
+{
+ return gdbarch_data (gdbarch, java_type_data);
}
-/* Cleanup code that should be run on every "run".
- We should use make_run_cleanup to have this be called.
- But will that mess up values in value histry? FIXME */
-
-extern void java_rerun_cleanup (void);
void
-java_rerun_cleanup (void)
+_initialize_java_language (void)
{
- if (class_symtab != NULL)
- {
- free_symtab (class_symtab); /* ??? */
- class_symtab = NULL;
- }
- if (dynamics_objfile != NULL)
- {
- free_objfile (dynamics_objfile);
- dynamics_objfile = NULL;
- }
+ java_type_data = gdbarch_data_register_post_init (build_java_types);
- java_object_type = NULL;
+ add_language (&java_language_defn);
}