[RFA]: Java Inferior Call Take 2

Jeff Johnston
2004-05-17T20:53:00Z

This is the reworked java inferior call patch. My previous attempt tried to
modify the gdb v3 abi code to handle missing debug information from gcj. After
a couple of gcc patches from Andrew Haley, the gnu-v3-abi.c code doesn't require
any tampering.

I had to enhance dwarf2read.c to handle the java vtable name (which is vtable)
and to modify C++-only code to handle java syntax for class names.

I have included a test case.

Ok to commit?

-- Jeff J.

2004-05-17 Jeff Johnston <jjohnstn@redhat.com>

* dwarf2read.c (typename_concat): Change prototype to accept dwarf2_cu
struct pointer as argument. Change function to use new argument to
determine language. If language is Java, use "." as separator,
otherwise, use "::".
(partial_die_parent_scope): Change comment to include java. Check
language to determine if Java "." or C++ "::" separator should be used.
(add_partial_symbol): Enhance tests for C++ to also test for Java.
(guess_structure_name): Ditto.
(read_subroutine_type): Ditto.
(new_symbol): Ditto.
(dwarf2_add_member_fn): Add check for Java when reading member name.
Java debug info includes full class name which must be stripped off.
(read_structure_type): Add Java vtable support.
(read_namespace): Add Java support.
* jv-exp.y (FuncStart): New pattern.
(MethodInvocation): Add support for simple function calls. Change
warning message for other forms of inferior call currently not
supported.
* valarith.c (value_subscript): Treat an array with upper-bound
of -1 as unknown size.
gdb/testsuite/ChangeLog:

2004-05-17 Jeff Johnston <jjohnstn@redhat.com>

* gdb.java/jprint.exp: New test for java inferior call.
* gdb.java/jprint.java: Ditto.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.151
diff -u -p -r1.151 dwarf2read.c
--- dwarf2read.c 7 May 2004 14:29:33 -0000 1.151
+++ dwarf2read.c 17 May 2004 20:48:15 -0000
@@ -788,7 +788,8 @@ static void read_type_die (struct die_in

static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);

-static char *typename_concat (const char *prefix, const char *suffix);
+static char *typename_concat (const char *prefix, const char *suffix,
+ struct dwarf2_cu *);

static void read_typedef (struct die_info *, struct dwarf2_cu *);

@@ -1502,7 +1503,8 @@ scan_partial_symbols (struct partial_die
/* Functions used to compute the fully scoped name of a partial DIE.

Normally, this is simple. For C++, the parent DIE's fully scoped
- name is concatenated with "::" and the partial DIE's name.
+ name is concatenated with "::" and the partial DIE's name. For
+ Java, the same thing occurs except that "." is used instead of "::".
Enumerators are an exception; they use the scope of their parent
enumeration type, i.e. the name of the enumeration type is not
prepended to the enumerator.
@@ -1558,7 +1560,7 @@ partial_die_parent_scope (struct partial
parent->scope = parent->name;
else
parent->scope = obconcat (&cu->comp_unit_obstack, grandparent_scope,
- "::", parent->name);
+ cu->language == language_java ? "." : "::", parent->name);
}
else if (parent->tag == DW_TAG_enumeration_type)
/* Enumerators should not get the name of the enumeration as a prefix. */
@@ -1590,7 +1592,11 @@ partial_die_full_name (struct partial_di
if (parent_scope == NULL)
return NULL;
else
- return concat (parent_scope, "::", pdi->name, NULL);
+ {
+ if (cu->language == language_java)
+ return concat (parent_scope, ".", pdi->name, NULL);
+ return concat (parent_scope, "::", pdi->name, NULL);
+ }
}

static void
@@ -1708,14 +1714,16 @@ add_partial_symbol (struct partial_die_i
return;
add_psymbol_to_list (actual_name, strlen (actual_name),
STRUCT_DOMAIN, LOC_TYPEDEF,
- cu->language == language_cplus
+ (cu->language == language_cplus
+ || cu->language == language_java)
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);

- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
- /* For C++, these implicitly act as typedefs as well. */
+ /* For C++ and Java, these implicitly act as typedefs as well. */
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
@@ -1725,7 +1733,8 @@ add_partial_symbol (struct partial_die_i
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_CONST,
- cu->language == language_cplus
+ (cu->language == language_cplus
+ || cu->language == language_java)
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
@@ -1805,7 +1814,8 @@ static void
guess_structure_name (struct partial_die_info *struct_pdi,
struct dwarf2_cu *cu)
{
- if (cu->language == language_cplus
+ if ((cu->language == language_cplus
+ || cu->language == language_java)
&& cu->has_namespace_info == 0
&& struct_pdi->has_children)
{
@@ -2460,7 +2470,8 @@ read_func_scope (struct die_info *die, s
if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
return;

- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
struct die_info *spec_die = die_specification (die, cu);

@@ -3101,7 +3112,29 @@ dwarf2_add_member_fn (struct field_info
/* Get name of member function. */
attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
- fieldname = DW_STRING (attr);
+ {
+ /* Note: C++ and Java currently differ in how the member function
+ name is stored in the debug info. For Java, the member name is
+ fully qualified with prototype while C++ just has the member
+ name. To get the Java member name, we strip off any dot qualifiers
+ and remove the trailing prototype. */
+ char *dot_index;
+ char *lparen;
+ fieldname = DW_STRING (attr);
+ if (cu->language == language_java)
+ {
+ dot_index = strchr (fieldname, '.');
+ while (dot_index)
+ {
+ fieldname = dot_index + 1;
+ dot_index = strchr (fieldname, '.');
+ }
+ lparen = strchr (fieldname + 1, '(');
+ if (lparen)
+ fieldname = obsavestring (fieldname, lparen - fieldname,
+ &objfile->objfile_obstack);
+ }
+ }
else
return;

@@ -3292,7 +3325,8 @@ read_structure_type (struct die_info *di
attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
char *new_prefix = determine_class_name (die, cu);
TYPE_TAG_NAME (type) = obsavestring (new_prefix,
@@ -3398,6 +3432,9 @@ read_structure_type (struct die_info *di
{
static const char vptr_name[] =
{'_', 'v', 'p', 't', 'r', '\0'};
+ static const char vtable_name[] =
+ {'v', 't', 'a', 'b', 'l', 'e', '\0'};
+
int i;

/* Our own class provides vtbl ptr. */
@@ -3407,10 +3444,18 @@ read_structure_type (struct die_info *di
{
char *fieldname = TYPE_FIELD_NAME (t, i);

- if ((strncmp (fieldname, vptr_name,
- strlen (vptr_name) - 1)
- == 0)
- && is_cplus_marker (fieldname[strlen (vptr_name)]))
+ if (cu->language == language_java
+ && (strncmp (fieldname, vtable_name,
+ strlen (vtable_name) - 1)
+ == 0))
+ {
+ TYPE_VPTR_FIELDNO (type) = i;
+ break;
+ }
+ else if ((strncmp (fieldname, vptr_name,
+ strlen (vptr_name) - 1)
+ == 0)
+ && is_cplus_marker (fieldname[strlen (vptr_name)]))
{
TYPE_VPTR_FIELDNO (type) = i;
break;
@@ -3502,7 +3547,9 @@ read_enumeration_type (struct die_info *
TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
processing_current_prefix[0] == '\0'
- ? "" : "::",
+ ? "" :
+ cu->language == language_java
+ ? "." : "::",
name);
}
else
@@ -3527,7 +3574,7 @@ read_enumeration_type (struct die_info *
}

/* Determine the name of the type represented by DIE, which should be
- a named C++ compound type. Return the name in question; the caller
+ a named C++ or Java compound type. Return the name in question; the caller
is responsible for xfree()'ing it. */

static char *
@@ -3573,7 +3620,8 @@ determine_class_name (struct die_info *d
{
const char *name = dwarf2_name (die, cu);
new_prefix = typename_concat (processing_current_prefix,
- name ? name : "<<anonymous>>");
+ name ? name : "<<anonymous>>",
+ cu);
}

if (back_to != NULL)
@@ -3810,7 +3858,10 @@ read_namespace (struct die_info *die, st
char *temp_name = alloca (strlen (previous_prefix)
+ 2 + strlen(name) + 1);
strcpy (temp_name, previous_prefix);
- strcat (temp_name, "::");
+ if (cu->language == language_java)
+ strcat (temp_name, ".");
+ else
+ strcat (temp_name, "::");
strcat (temp_name, name);

processing_current_prefix = temp_name;
@@ -4099,10 +4150,11 @@ read_subroutine_type (struct die_info *d
type = die_type (die, cu);
ftype = lookup_function_type (type);

- /* All functions in C++ have prototypes. */
+ /* All functions in C++ and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if ((attr && (DW_UNSND (attr) != 0))
- || cu->language == language_cplus)
+ || cu->language == language_cplus
+ || cu->language == language_java)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;

if (die->child != NULL)
@@ -4753,7 +4805,8 @@ load_partial_dies (bfd *abfd, char *info
else if (building_psymtab)
add_psymbol_to_list (part_die->name, strlen (part_die->name),
VAR_DOMAIN, LOC_CONST,
- cu->language == language_cplus
+ (cu->language == language_cplus
+ || cu->language == language_java)
? &cu->objfile->global_psymbols
: &cu->objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, cu->objfile);
@@ -6357,7 +6410,8 @@ new_symbol (struct die_info *die, struct
read_structure_type, and the correct name is saved in
the type. */

- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
struct type *type = SYMBOL_TYPE (sym);

@@ -6374,7 +6428,7 @@ new_symbol (struct die_info *die, struct
}

{
- /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+ /* NOTE: carlton/2003-11-10: C++ and Java class symbols shouldn't
really ever be static objects: otherwise, if you try
to, say, break of a class's method and you're in a file
which doesn't mention that class, it won't work unless
@@ -6385,15 +6439,17 @@ new_symbol (struct die_info *die, struct
struct pending **list_to_add;

list_to_add = (cu->list_in_scope == &file_symbols
- && cu->language == language_cplus
+ && (cu->language == language_cplus
+ || cu->language == language_java)
? &global_symbols : cu->list_in_scope);

add_symbol_to_list (sym, list_to_add);

- /* The semantics of C++ state that "struct foo { ... }" also
+ /* The semantics of C++ and Java state that "struct foo { ... }" also
defines a typedef for "foo". Synthesize a typedef symbol so
that "ptype foo" works as expected. */
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
struct symbol *typedef_sym = (struct symbol *)
obstack_alloc (&objfile->objfile_obstack,
@@ -6415,7 +6471,8 @@ new_symbol (struct die_info *die, struct
{
SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
- "::",
+ cu->language == language_java
+ ? "." : "::",
name);
}
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -6434,7 +6491,8 @@ new_symbol (struct die_info *die, struct
{
SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
- "::",
+ cu->language == language_java
+ ? "." : "::",
name);
}
attr = dwarf2_attr (die, DW_AT_const_value, cu);
@@ -6449,7 +6507,8 @@ new_symbol (struct die_info *die, struct
struct pending **list_to_add;

list_to_add = (cu->list_in_scope == &file_symbols
- && cu->language == language_cplus
+ && (cu->language == language_cplus
+ || cu->language == language_java)
? &global_symbols : cu->list_in_scope);

add_symbol_to_list (sym, list_to_add);
@@ -6758,7 +6817,8 @@ determine_prefix (struct die_info *die,
{
struct die_info *parent;

- if (cu->language != language_cplus)
+ if (cu->language != language_cplus
+ && cu->language != language_java)
return NULL;

parent = die->parent;
@@ -6784,7 +6844,8 @@ determine_prefix (struct die_info *die,
char *parent_prefix = determine_prefix (parent, cu);
char *retval = typename_concat (parent_prefix,
namespace_name (parent, &dummy,
- cu));
+ cu),
+ cu);
xfree (parent_prefix);
return retval;
}
@@ -6818,11 +6879,11 @@ determine_prefix (struct die_info *die,
}

/* Return a newly-allocated string formed by concatenating PREFIX,
- "::", and SUFFIX, except that if PREFIX is NULL or the empty
+ "::" or ".", and SUFFIX, except that if PREFIX is NULL or the empty
string, just return a copy of SUFFIX. */

static char *
-typename_concat (const char *prefix, const char *suffix)
+typename_concat (const char *prefix, const char *suffix, struct dwarf2_cu *cu)
{
if (prefix == NULL || prefix[0] == '\0')
return xstrdup (suffix);
@@ -6831,7 +6892,10 @@ typename_concat (const char *prefix, con
char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);

strcpy (retval, prefix);
- strcat (retval, "::");
+ if (cu->language == language_java)
+ strcat (retval, ".");
+ else
+ strcat (retval, "::");
strcat (retval, suffix);

return retval;
Index: jv-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/jv-exp.y,v
retrieving revision 1.18
diff -u -p -r1.18 jv-exp.y
--- jv-exp.y 23 Nov 2003 20:41:17 -0000 1.18
+++ jv-exp.y 17 May 2004 20:48:15 -0000
@@ -446,13 +446,22 @@ FieldAccess:
/*| SUPER '.' SimpleName { FIXME } */
;

+FuncStart:
+ Name '('
+ { push_expression_name ($1); }
+;
+
MethodInvocation:
- Name '(' ArgumentList_opt ')'
- { error (_("Method invocation not implemented")); }
+ FuncStart
+ { start_arglist(); }
+ ArgumentList_opt ')'
+ { write_exp_elt_opcode (OP_FUNCALL);
+ write_exp_elt_longcst ((LONGEST) end_arglist ());
+ write_exp_elt_opcode (OP_FUNCALL); }
| Primary '.' SimpleName '(' ArgumentList_opt ')'
- { error (_("Method invocation not implemented")); }
+ { error (_("Form of method invocation not implemented")); }
| SUPER '.' SimpleName '(' ArgumentList_opt ')'
- { error (_("Method invocation not implemented")); }
+ { error (_("Form of method invocation not implemented")); }
;

ArrayAccess:
Index: valarith.c
===================================================================
RCS file: /cvs/src/src/gdb/valarith.c,v
retrieving revision 1.22
diff -u -p -r1.22 valarith.c
--- valarith.c 1 Apr 2004 12:08:30 -0000 1.22
+++ valarith.c 17 May 2004 20:48:15 -0000
@@ -202,7 +202,10 @@ value_subscript (struct value *array, st
LONGEST index = value_as_long (idx);
if (index >= lowerbound && index <= upperbound)
return value_subscripted_rvalue (array, idx, lowerbound);
- warning ("array or string index out of range");
+ /* Emit warning unless we have an array of unknown size.
+ An array of unknown size has lowerbound 0 and upperbound -1. */
+ if (upperbound > -1)
+ warning ("array or string index out of range");
/* fall doing C stuff */
c_style = 1;
}
Index: gdb.java/jprint.exp
===================================================================
RCS file: gdb.java/jprint.exp
diff -N gdb.java/jprint.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb.java/jprint.exp 17 May 2004 20:52:27 -0000
@@ -0,0 +1,83 @@
+# Copyright 2004 Free Software Foundation, Inc.
+
+# 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
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# 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.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Jeff Johnston. (jjohnstn@redhat.com)
+#
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+load_lib "java.exp"
+
+set testfile "jprint"
+set srcfile ${srcdir}/$subdir/${testfile}.java
+set binfile ${objdir}/${subdir}/${testfile}
+if { [compile_java_from_source ${srcfile} ${binfile} "-g"] != "" } {
+ untested "Couldn't compile ${srcfile}"
+ return -1
+}
+
+# Set the current language to java. This counts as a test. If it
+# fails, then we skip the other tests.
+
+proc set_lang_java {} {
+ global gdb_prompt
+ global binfile objdir subdir
+
+ verbose "loading file '$binfile'"
+ gdb_load $binfile
+
+ send_gdb "set language java\n"
+ gdb_expect {
+ -re ".*$gdb_prompt $" {}
+ timeout { fail "set language java (timeout)" ; return 0 }
+ }
+
+ return [gdb_test "show language" ".* source language is \"java\".*" \
+ "set language to \"java\""]
+}
+
+set prms_id 0
+set bug_id 0
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+gdb_test "set print sevenbit-strings" ".*"
+
+if ![set_lang_java] then {
+ # Ref PR gdb:java/1565. Don't use the simpler "break jmisc.main".
+ # As of 2004-02-24 it wasn't working and is being tested separatly.
+ runto "\'${testfile}.main(java.lang.String\[\])\'"
+
+ gdb_test "p jvclass.addprint(4,5,6)" "sum is 15\r\n.*" "unambiguous static call"
+
+ gdb_test "next" ""
+ gdb_test "next" ""
+
+ gdb_test "p x.print(44)" "x is 44\r\n.*" "single argument print call"
+ gdb_test "p x.print(22,33)" "y is 33\r\n.*" "double argument print call"
+ gdb_test "call x.dothat(55)" "new value is 58\r\n.*= 62.*" "virtual fn call"
+ gdb_test "p x.addprint(1,2,3)" "sum is 6\r\n.*" "inherited static call"
+ gdb_test "call x.addk(44)" "adding k gives 121\r\n.*= 121.*" "inherited virtual fn call"
+}
Index: gdb.java/jprint.java
===================================================================
RCS file: gdb.java/jprint.java
diff -N gdb.java/jprint.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb.java/jprint.java 17 May 2004 20:52:27 -0000
@@ -0,0 +1,62 @@
+// jprint.java test program.
+//
+// Copyright 2004
+// Free Software Foundation, Inc.
+//
+// Written by Jeff Johnston <jjohnstn@redhat.com>
+// Contributed by Red Hat
+//
+// 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
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// 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.
+
+class jvclass {
+ public static int k;
+ static {
+ k = 77;
+ }
+ public static void addprint (int x, int y, int z) {
+ int sum = x + y + z;
+ System.out.println ("sum is " + sum);
+ }
+
+ public int addk (int x) {
+ int sum = x + k;
+ System.out.println ("adding k gives " + sum);
+ return sum;
+ }
+}
+
+public class jprint extends jvclass {
+ public int dothat (int x) {
+ int y = x + 3;
+ System.out.println ("new value is " + y);
+ return y + 4;
+ }
+ public static void print (int x) {
+ System.out.println("x is " + x);
+ }
+ public static void print (int x, int y) {
+ System.out.println("y is " + y);
+ }
+ public static void main(String[] args) {
+ jprint x = new jprint ();
+ x.print (44);
+ print (k, 33);
+ }
+}
+
+
From jimb@redhat.com Mon May 17 20:53:00 2004
From: Jim Blandy <jimb@redhat.com>
To: gdb-patches@sources.redhat.com
Subject: RFA: use constructor to build 'struct regset' objects
Date: Mon, 17 May 2004 20:53:00 -0000
Message-id: <vt2smdy93u9.fsf@zenia.home>
X-SW-Source: 2004-05/msg00510.html
Content-length: 15431

2004-05-17 Jim Blandy <jimb@redhat.com>

Use a constructor function to create regset structures.
* regset.h (supply_regset_ftype): New typedef.
(struct regset): Use supply_regset_ftype.
(readonly_regset_xmalloc): New declaration.
* regset.c: New file.
* am64-tdep.c (amd64_regset_from_core_section): Use
readonly_regset_xmalloc to construct regset structures.
* amd64obsd-tdep.c (amd64obsd_regset_from_core_section): Same.
* i386-tdep.c (i386_regset_from_core_section): Same.
* i386nbsd-tdep.c (i386nbsd_aout_regset_from_core_section): Same.
* i386obsd-tdep.c (i386obsd_aout_regset_from_core_section): Same.
* sparc64fbsd-tdep.c (sparc64fbsd_init_abi): Same.
* sparc64nbsd-tdep.c (sparc64nbsd_init_abi): Same.
* sparc64obsd-tdep.c (sparc64obsd_init_abi): Same.
* sparcnbsd-tdep.c (sparc32nbsd_init_abi): Same.
* Makefile.in (COMMON_OBS): Add regset.o.
(regset.o): New rule.

Index: gdb/regset.h
===================================================================
RCS file: /cvs/src/src/gdb/regset.h,v
retrieving revision 1.1
diff -c -p -r1.1 regset.h
*** gdb/regset.h 26 Sep 2003 14:36:56 -0000 1.1
--- gdb/regset.h 17 May 2004 19:24:09 -0000
*************** struct gdbarch;
*** 26,31 ****
--- 26,33 ----
struct regcache;

/* Data structure describing a register set. */
+ typedef void (supply_regset_ftype) (const struct regset *, struct regcache *,
+ int, const void *, size_t);

struct regset
{
*************** struct regset
*** 34,41 ****
const void *descr;

/* Function supplying a register set to a register cache. */
! void (*supply_regset) (const struct regset *, struct regcache *,
! int, const void *, size_t);
};

#endif /* regset.h */
--- 36,51 ----
const void *descr;

/* Function supplying a register set to a register cache. */
! supply_regset_ftype *supply_regset;
};
+
+
+ /* Allocate a fresh 'struct regset' whose descr is DESCR and whose
+ supply_regset function is SUPPLY_REGSET. The object returned is
+ allocated using xmalloc. */
+ extern struct regset *(readonly_regset_xmalloc
+ (void *descr,
+ supply_regset_ftype *supply_regset));
+

#endif /* regset.h */
Index: gdb/regset.c
===================================================================
RCS file: gdb/regset.c
diff -N gdb/regset.c
*** gdb/regset.c 1 Jan 1970 00:00:00 -0000
--- gdb/regset.c 17 May 2004 19:24:09 -0000
***************
*** 0 ****
--- 1,35 ----
+ /* Regset support functions, for GDB.
+
+ Copyright 2004 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+ #include "defs.h"
+ #include "regset.h"
+
+
+ struct regset *readonly_regset_xmalloc (void *descr,
+ supply_regset_ftype *supply_regset)
+ {
+ struct regset *r = (struct regset *) xmalloc (sizeof (*r));
+
+ r->descr = descr;
+ r->supply_regset = supply_regset;
+
+ return r;
+ }
Index: gdb/amd64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64-tdep.c,v
retrieving revision 1.9
diff -c -p -r1.9 amd64-tdep.c
*** gdb/amd64-tdep.c 9 May 2004 19:48:25 -0000 1.9
--- gdb/amd64-tdep.c 17 May 2004 19:24:06 -0000
*************** amd64_regset_from_core_section (struct g
*** 1074,1084 ****
if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
{
if (tdep->fpregset == NULL)
! {
! tdep->fpregset = XMALLOC (struct regset);
! tdep->fpregset->descr = tdep;
! tdep->fpregset->supply_regset = amd64_supply_fpregset;
! }

return tdep->fpregset;
}
--- 1074,1080 ----
if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
{
if (tdep->fpregset == NULL)
! tdep->fpregset = readonly_regset_xmalloc (tdep, amd64_supply_fpregset);

return tdep->fpregset;
}
Index: gdb/amd64obsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64obsd-tdep.c,v
retrieving revision 1.9
diff -c -p -r1.9 amd64obsd-tdep.c
*** gdb/amd64obsd-tdep.c 9 Apr 2004 23:26:19 -0000 1.9
--- gdb/amd64obsd-tdep.c 17 May 2004 19:24:06 -0000
*************** amd64obsd_regset_from_core_section (stru
*** 63,73 ****
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE)
{
if (tdep->gregset == NULL)
! {
! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = tdep;
! tdep->gregset->supply_regset = amd64obsd_supply_regset;
! }
return tdep->gregset;
}

--- 63,70 ----
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE)
{
if (tdep->gregset == NULL)
! tdep->gregset
! = readonly_regset_xmalloc (tdep, amd64obsd_supply_regset);
return tdep->gregset;
}

Index: gdb/i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.191
diff -c -p -r1.191 i386-tdep.c
*** gdb/i386-tdep.c 8 May 2004 23:02:10 -0000 1.191
--- gdb/i386-tdep.c 17 May 2004 19:24:07 -0000
*************** i386_regset_from_core_section (struct gd
*** 1662,1672 ****
if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
{
if (tdep->gregset == NULL)
! {
! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = tdep;
! tdep->gregset->supply_regset = i386_supply_gregset;
! }
return tdep->gregset;
}

--- 1662,1668 ----
if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
{
if (tdep->gregset == NULL)
! tdep->gregset = readonly_regset_xmalloc (tdep, i386_supply_gregset);
return tdep->gregset;
}

*************** i386_regset_from_core_section (struct gd
*** 1675,1685 ****
&& sect_size == I387_SIZEOF_FXSAVE))
{
if (tdep->fpregset == NULL)
! {
! tdep->fpregset = XMALLOC (struct regset);
! tdep->fpregset->descr = tdep;
! tdep->fpregset->supply_regset = i386_supply_fpregset;
! }
return tdep->fpregset;
}

--- 1671,1677 ----
&& sect_size == I387_SIZEOF_FXSAVE))
{
if (tdep->fpregset == NULL)
! tdep->fpregset = readonly_regset_xmalloc (tdep, i386_supply_fpregset);
return tdep->fpregset;
}

Index: gdb/i386nbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386nbsd-tdep.c,v
retrieving revision 1.24
diff -c -p -r1.24 i386nbsd-tdep.c
*** gdb/i386nbsd-tdep.c 9 Apr 2004 23:26:19 -0000 1.24
--- gdb/i386nbsd-tdep.c 17 May 2004 19:24:07 -0000
*************** i386nbsd_aout_regset_from_core_section (
*** 86,96 ****
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
{
if (tdep->gregset == NULL)
! {
! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = tdep;
! tdep->gregset->supply_regset = i386nbsd_aout_supply_regset;
! }
return tdep->gregset;
}

--- 86,93 ----
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
{
if (tdep->gregset == NULL)
! tdep->gregset
! = readonly_regset_xmalloc (tdep, i386nbsd_aout_supply_regset);
return tdep->gregset;
}

Index: gdb/i386obsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386obsd-tdep.c,v
retrieving revision 1.15
diff -c -p -r1.15 i386obsd-tdep.c
*** gdb/i386obsd-tdep.c 9 Apr 2004 23:26:19 -0000 1.15
--- gdb/i386obsd-tdep.c 17 May 2004 19:24:07 -0000
*************** i386obsd_aout_regset_from_core_section (
*** 141,151 ****
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
{
if (tdep->gregset == NULL)
! {
! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = tdep;
! tdep->gregset->supply_regset = i386obsd_aout_supply_regset;
! }
return tdep->gregset;
}

--- 141,148 ----
&& sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE)
{
if (tdep->gregset == NULL)
! tdep->gregset
! = readonly_regset_xmalloc (tdep, i386obsd_aout_supply_regset);
return tdep->gregset;
}

Index: gdb/sparc64fbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64fbsd-tdep.c,v
retrieving revision 1.6
diff -c -p -r1.6 sparc64fbsd-tdep.c
*** gdb/sparc64fbsd-tdep.c 10 Apr 2004 09:40:02 -0000 1.6
--- gdb/sparc64fbsd-tdep.c 17 May 2004 19:24:11 -0000
*************** sparc64fbsd_init_abi (struct gdbarch_inf
*** 199,211 ****
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = &sparc64fbsd_gregset;
! tdep->gregset->supply_regset = sparc64fbsd_supply_gregset;
tdep->sizeof_gregset = 256;

! tdep->fpregset = XMALLOC (struct regset);
! tdep->fpregset->supply_regset = sparc64fbsd_supply_fpregset;
tdep->sizeof_fpregset = 272;

frame_unwind_append_sniffer (gdbarch, sparc64fbsd_sigtramp_frame_sniffer);
--- 199,209 ----
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

! tdep->gregset = readonly_regset_xmalloc (&sparc64fbsd_gregset,
! sparc64fbsd_supply_gregset);
tdep->sizeof_gregset = 256;

! tdep->fpregset = readonly_regset_xmalloc (NULL, sparc64fbsd_supply_fpregset);
tdep->sizeof_fpregset = 272;

frame_unwind_append_sniffer (gdbarch, sparc64fbsd_sigtramp_frame_sniffer);
Index: gdb/sparc64nbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64nbsd-tdep.c,v
retrieving revision 1.7
diff -c -p -r1.7 sparc64nbsd-tdep.c
*** gdb/sparc64nbsd-tdep.c 10 Apr 2004 09:40:02 -0000 1.7
--- gdb/sparc64nbsd-tdep.c 17 May 2004 19:24:12 -0000
*************** sparc64nbsd_init_abi (struct gdbarch_inf
*** 226,238 ****
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = &sparc64nbsd_gregset;
! tdep->gregset->supply_regset = sparc64nbsd_supply_gregset;
tdep->sizeof_gregset = 160;

! tdep->fpregset = XMALLOC (struct regset);
! tdep->fpregset->supply_regset = sparc64nbsd_supply_fpregset;
tdep->sizeof_fpregset = 272;

frame_unwind_append_sniffer (gdbarch, sparc64nbsd_sigtramp_frame_sniffer);
--- 226,236 ----
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

! tdep->gregset = readonly_regset_xmalloc (&sparc64nbsd_gregset,
! sparc64nbsd_supply_gregset);
tdep->sizeof_gregset = 160;

! tdep->fpregset = readonly_regset_xmalloc (NULL, sparc64nbsd_supply_fpregset);
tdep->sizeof_fpregset = 272;

frame_unwind_append_sniffer (gdbarch, sparc64nbsd_sigtramp_frame_sniffer);
Index: gdb/sparc64obsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64obsd-tdep.c,v
retrieving revision 1.3
diff -c -p -r1.3 sparc64obsd-tdep.c
*** gdb/sparc64obsd-tdep.c 10 Apr 2004 09:40:02 -0000 1.3
--- gdb/sparc64obsd-tdep.c 17 May 2004 19:24:12 -0000
*************** sparc64obsd_init_abi (struct gdbarch_inf
*** 184,192 ****
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = &sparc64obsd_core_gregset;
! tdep->gregset->supply_regset = sparc64obsd_supply_gregset;
tdep->sizeof_gregset = 832;

frame_unwind_append_sniffer (gdbarch, sparc64obsd_sigtramp_frame_sniffer);
--- 184,191 ----
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

! tdep->gregset = readonly_regset_xmalloc (&sparc64obsd_core_gregset,
! sparc64obsd_supply_gregset);
tdep->sizeof_gregset = 832;

frame_unwind_append_sniffer (gdbarch, sparc64obsd_sigtramp_frame_sniffer);
Index: gdb/sparcnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparcnbsd-tdep.c,v
retrieving revision 1.18
diff -c -p -r1.18 sparcnbsd-tdep.c
*** gdb/sparcnbsd-tdep.c 18 Apr 2004 22:58:06 -0000 1.18
--- gdb/sparcnbsd-tdep.c 17 May 2004 19:24:12 -0000
*************** sparc32nbsd_init_abi (struct gdbarch_inf
*** 274,286 ****
set_gdbarch_long_double_bit (gdbarch, 64);
set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);

! tdep->gregset = XMALLOC (struct regset);
! tdep->gregset->descr = &sparc32nbsd_gregset;
! tdep->gregset->supply_regset = sparc32nbsd_supply_gregset;
tdep->sizeof_gregset = 20 * 4;

! tdep->fpregset = XMALLOC (struct regset);
! tdep->fpregset->supply_regset = sparc32nbsd_supply_fpregset;
tdep->sizeof_fpregset = 33 * 4;

frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer);
--- 274,284 ----
set_gdbarch_long_double_bit (gdbarch, 64);
set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big);

! tdep->gregset = readonly_regset_xmalloc (&sparc32nbsd_gregset,
! sparc32nbsd_supply_gregset);
tdep->sizeof_gregset = 20 * 4;

! tdep->fpregset = readonly_regset_xmalloc (NULL, sparc32nbsd_supply_fpregset);
tdep->sizeof_fpregset = 33 * 4;

frame_unwind_append_sniffer (gdbarch, sparc32nbsd_sigtramp_frame_sniffer);
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.569
diff -c -p -r1.569 Makefile.in
*** gdb/Makefile.in 11 May 2004 04:55:31 -0000 1.569
--- gdb/Makefile.in 17 May 2004 19:24:04 -0000
*************** COMMON_OBS = $(DEPFILES) $(YYOBJ) \
*** 910,916 ****
frame-base.o \
gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \
cp-namespace.o \
! reggroups.o \
trad-frame.o \
tramp-frame.o

--- 910,916 ----
frame-base.o \
gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \
cp-namespace.o \
! reggroups.o regset.o \
trad-frame.o \
tramp-frame.o

*************** regcache.o: regcache.c $(defs_h) $(infer
*** 2199,2204 ****
--- 2199,2205 ----
$(gdb_string_h) $(gdbcmd_h) $(observer_h)
reggroups.o: reggroups.c $(defs_h) $(reggroups_h) $(gdbtypes_h) \
$(gdb_assert_h) $(regcache_h) $(command_h) $(gdbcmd_h)
+ regset.o: regset.c $(defs_h) $(regset_h)
remote.o: remote.c $(defs_h) $(gdb_string_h) $(inferior_h) $(bfd_h) \
$(symfile_h) $(target_h) $(gdbcmd_h) $(objfiles_h) $(gdb_stabs_h) \
$(gdbthread_h) $(remote_h) $(regcache_h) $(value_h) $(gdb_assert_h) \