This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[09/15] Revert C++ ABI gdbarch changes


Hello,

this patch basically reverts the change introduced here:
http://sourceware.org/ml/gdb-patches/2008-08/msg00700.html

Now that values carry an architecture, we can simply use this
architecture to determine ABI properties of C++ objects.
This removes the need to (ab-)use the TYPE_OBJFILE of C++
types in order to retrieve those properties from the objfile
architecture.

This requires adding a gdbarch parameter to those C++ ABI
functions that do not actually get a value parameter.  However,
as the call sites deal with values anyway, these are
straightforward to pass in.

In addition, two other minor changes are included:

- Provide a cplus_member_ptr_size analogous to cplus_method_ptr_size
  to remove the hard-coded assumption on member pointer size from
  gdbtypes.c (and make it possible to add a current_cp_abi indirection
  if required in the future)

- As noone directly calls gnuv2_baseclass_offset any more, the
  function can be made static and the gnu-v2-abi.h header file
  can be removed.

Bye,
Ulrich


ChangeLog:

	* cp-abi.h (baseclass_offset): Add GDBARCH parameter.
	(cplus_print_method_ptr): Likewise.
	(cplus_make_method_ptr): Likewise.
	(cplus_method_ptr_size): Remove TO_TYPE, add GDBARCH parameter.
	(cplus_member_ptr_size): Add prototype.
	(struct cp_abi_ops): Add GDBARCH parameter to baseclass_offset,
	print_method_ptr, make_method_ptr, method_ptr_size; remove TO_TYPE
	parameter from method_ptr_size callback.

	* cp-abi.c (baseclass_offset): Add GDBARCH parameter, pass on
	to current_cp_abi callback routine.
	(cplus_print_method_ptr): Likewise.
	(cplus_make_method_ptr): Likewise.
	(cplus_method_ptr_size): Remove TO_TYPE, add GDBARCH parameter.
	Pass changes on to current_cp_abi callback routine.
	(cplus_member_ptr_size): New function.

	* cp-valprint.c (cp_print_value): Pass architecture to
	baseclass_offset.
	* p-valprint.c (pascal_object_print_value): Likewise.
	* c-valprint.c (c_val_print): Pass architecture to
	cplus_print_method_ptr.
	* valops.c (value_cast): Pass architecture to cplus_make_method_ptr.
	(value_struct_elt_for_reference): Likewise.
	(search_struct_field): Pass architecture to baseclass_offset.
	(search_struct_method): Likewise.
	(find_method_list): Likewise.
	* gdbtypes.c (lookup_methodptr_type): Pass current_gdbarch instead
	of to_type to cplus_method_ptr_size.
	(smash_to_memberptr_type): Call cplus_member_ptr_size.

	* gnu-v2-abi.h: Remove file.
	* gnu-v2-abi.c: Do not include "gnu-v2-abi.c".
	(gnuv2_baseclass_offset): Make static.  Add GDBARCH parameter.
	Pass to baseclass_offset.

	* gnu-v3-abi.c (get_class_arch): Remove.
	(gnuv3_rtti_type): Use value architecture instead of get_class_arch.
	(gnuv3_virtual_fn_field): Likewise.
	(gnuv3_baseclass_offset): Add GDBARCH parameter.  Use it instead
	of get_class_arch.
	(gnuv3_print_method_ptr): Likewise.
	(gnuv3_make_method_ptr): Likewise.
	(gnuv3_method_ptr_to_value): Likewise.
	(gnuv3_method_ptr_size): Replace TO_TYPE parameter by GDBARCH.
	Use it instead of get_class_arch.



Index: gdb-head/gdb/cp-abi.c
===================================================================
--- gdb-head.orig/gdb/cp-abi.c
+++ gdb-head/gdb/cp-abi.c
@@ -70,12 +70,13 @@ is_operator_name (const char *name)
 }
 
 int
-baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
-		  CORE_ADDR address)
+baseclass_offset (struct type *type, struct gdbarch *gdbarch, int index,
+		  const bfd_byte *valaddr, CORE_ADDR address)
 {
   if (current_cp_abi.baseclass_offset == NULL)
     error (_("ABI doesn't define required function baseclass_offset"));
-  return (*current_cp_abi.baseclass_offset) (type, index, valaddr, address);
+  return (*current_cp_abi.baseclass_offset) (type, gdbarch,
+					     index, valaddr, address);
 }
 
 struct value *
@@ -105,28 +106,38 @@ value_rtti_type (struct value *v, int *f
 
 void
 cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
-			struct ui_file *stream)
+			struct gdbarch *gdbarch, struct ui_file *stream)
 {
   if (current_cp_abi.print_method_ptr == NULL)
     error (_("GDB does not support pointers to methods on this target"));
-  (*current_cp_abi.print_method_ptr) (contents, type, stream);
+  (*current_cp_abi.print_method_ptr) (contents, type, gdbarch, stream);
 }
 
 int
-cplus_method_ptr_size (struct type *to_type)
+cplus_member_ptr_size (struct gdbarch *gdbarch)
+{
+  /* Assume that a data member pointer is the same size
+     as a normal pointer.  */
+  return gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT;
+}
+
+int
+cplus_method_ptr_size (struct gdbarch *gdbarch)
 {
   if (current_cp_abi.method_ptr_size == NULL)
     error (_("GDB does not support pointers to methods on this target"));
-  return (*current_cp_abi.method_ptr_size) (to_type);
+  return (*current_cp_abi.method_ptr_size) (gdbarch);
 }
 
 void
-cplus_make_method_ptr (struct type *type, gdb_byte *contents,
+cplus_make_method_ptr (gdb_byte *contents,
+		       struct type *type, struct gdbarch *gdbarch,
 		       CORE_ADDR value, int is_virtual)
 {
   if (current_cp_abi.make_method_ptr == NULL)
     error (_("GDB does not support pointers to methods on this target"));
-  (*current_cp_abi.make_method_ptr) (type, contents, value, is_virtual);
+  (*current_cp_abi.make_method_ptr) (contents, type, gdbarch,
+				     value, is_virtual);
 }
 
 CORE_ADDR
Index: gdb-head/gdb/cp-abi.h
===================================================================
--- gdb-head.orig/gdb/cp-abi.h
+++ gdb-head/gdb/cp-abi.h
@@ -143,17 +143,21 @@ extern struct type *value_rtti_type (str
 
    -1 is returned on error. */
 
-extern int baseclass_offset (struct type *type, int index,
+extern int baseclass_offset (struct type *type,
+			     struct gdbarch *gdbarch, int index,
 			     const bfd_byte *valaddr, CORE_ADDR address);
                   
 /* Describe the target of a pointer to method.  CONTENTS is the byte
    pattern representing the pointer to method.  TYPE is the pointer to
    method type.  STREAM is the stream to print it to.  */
 void cplus_print_method_ptr (const gdb_byte *contents, struct type *type,
-			     struct ui_file *stream);
+			     struct gdbarch *gdbarch, struct ui_file *stream);
 
-/* Return the size of a pointer to member function of type TO_TYPE.  */
-int cplus_method_ptr_size (struct type *to_type);
+/* Return the size of a pointer to data member in GDBARCH.  */
+int cplus_member_ptr_size (struct gdbarch *gdbarch);
+
+/* Return the size of a pointer to member function in GDBARCH.  */
+int cplus_method_ptr_size (struct gdbarch *gdbarch);
 
 /* Return the method which should be called by applying METHOD_PTR
    to *THIS_P, and adjust *THIS_P if necessary.  */
@@ -164,7 +168,8 @@ struct value *cplus_method_ptr_to_value 
    type TYPE to member function at ADDRESS (if IS_VIRTUAL is 0)
    or with virtual table offset ADDRESS (if IS_VIRTUAL is 1).
    This is the opposite of cplus_method_ptr_to_value.  */
-void cplus_make_method_ptr (struct type *type, gdb_byte *CONTENTS,
+void cplus_make_method_ptr (gdb_byte *contents,
+			    struct type *type, struct gdbarch *gdbarch,
 			    CORE_ADDR address, int is_virtual);
 
 /* Determine if we are currently in a C++ thunk.  If so, get the address
@@ -191,12 +196,14 @@ struct cp_abi_ops
 				     int j, struct type * type, int offset);
   struct type *(*rtti_type) (struct value *v, int *full, int *top,
 			     int *using_enc);
-  int (*baseclass_offset) (struct type *type, int index,
+  int (*baseclass_offset) (struct type *type,
+			   struct gdbarch *gdbarch, int index,
 			   const bfd_byte *valaddr, CORE_ADDR address);
   void (*print_method_ptr) (const gdb_byte *contents, struct type *type,
-			    struct ui_file *stream);
-  int (*method_ptr_size) (struct type *);
-  void (*make_method_ptr) (struct type *, gdb_byte *, CORE_ADDR, int);
+			    struct gdbarch *gdbarch, struct ui_file *stream);
+  int (*method_ptr_size) (struct gdbarch *);
+  void (*make_method_ptr) (gdb_byte *, struct type *, struct gdbarch *,
+			   CORE_ADDR, int);
   struct value * (*method_ptr_to_value) (struct value **, struct value *);
   CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
   int (*pass_by_reference) (struct type *type);
Index: gdb-head/gdb/cp-valprint.c
===================================================================
--- gdb-head.orig/gdb/cp-valprint.c
+++ gdb-head/gdb/cp-valprint.c
@@ -377,7 +377,7 @@ cp_print_value (struct type *type, struc
       thisoffset = offset;
       thistype = real_type;
 
-      boffset = baseclass_offset (type, i, valaddr + offset, address);
+      boffset = baseclass_offset (type, gdbarch, i, valaddr + offset, address);
       skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
 
       if (BASETYPE_VIA_VIRTUAL (type, i))
Index: gdb-head/gdb/c-valprint.c
===================================================================
--- gdb-head.orig/gdb/c-valprint.c
+++ gdb-head/gdb/c-valprint.c
@@ -219,7 +219,8 @@ c_val_print (struct type *type, struct g
       break;
 
     case TYPE_CODE_METHODPTR:
-      cplus_print_method_ptr (valaddr + embedded_offset, type, stream);
+      cplus_print_method_ptr (valaddr + embedded_offset,
+			      type, gdbarch, stream);
       break;
 
     case TYPE_CODE_PTR:
Index: gdb-head/gdb/gdbtypes.c
===================================================================
--- gdb-head.orig/gdb/gdbtypes.c
+++ gdb-head/gdb/gdbtypes.c
@@ -671,7 +671,7 @@ lookup_methodptr_type (struct type *to_t
   mtype = alloc_type (TYPE_OBJFILE (to_type));
   TYPE_TARGET_TYPE (mtype) = to_type;
   TYPE_DOMAIN_TYPE (mtype) = TYPE_DOMAIN_TYPE (to_type);
-  TYPE_LENGTH (mtype) = cplus_method_ptr_size (to_type);
+  TYPE_LENGTH (mtype) = cplus_method_ptr_size (current_gdbarch);
   TYPE_CODE (mtype) = TYPE_CODE_METHODPTR;
   return mtype;
 }
@@ -992,9 +992,7 @@ smash_to_memberptr_type (struct type *ty
   TYPE_OBJFILE (type) = objfile;
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
-  /* Assume that a data member pointer is the same size as a normal
-     pointer.  */
-  TYPE_LENGTH (type) = gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT;
+  TYPE_LENGTH (type) = cplus_member_ptr_size (current_gdbarch);
   TYPE_CODE (type) = TYPE_CODE_MEMBERPTR;
 }
 
Index: gdb-head/gdb/gnu-v2-abi.c
===================================================================
--- gdb-head.orig/gdb/gnu-v2-abi.c
+++ gdb-head/gdb/gnu-v2-abi.c
@@ -28,7 +28,6 @@
 #include "demangle.h"
 #include "cp-abi.h"
 #include "cp-support.h"
-#include "gnu-v2-abi.h"
 
 #include <ctype.h>
 
@@ -348,8 +347,8 @@ vb_match (struct type *type, int index, 
 
    -1 is returned on error. */
 
-int
-gnuv2_baseclass_offset (struct type *type, int index,
+static int
+gnuv2_baseclass_offset (struct type *type, struct gdbarch *gdbarch, int index,
 			const bfd_byte *valaddr, CORE_ADDR address)
 {
   struct type *basetype = TYPE_BASECLASS (type, index);
@@ -377,7 +376,7 @@ gnuv2_baseclass_offset (struct type *typ
       for (i = index + 1; i < n_baseclasses; i++)
 	{
 	  int boffset =
-	  baseclass_offset (type, i, valaddr, address);
+	  baseclass_offset (type, gdbarch, i, valaddr, address);
 	  if (boffset)
 	    return boffset;
 	}
Index: gdb-head/gdb/gnu-v2-abi.h
===================================================================
--- gdb-head.orig/gdb/gnu-v2-abi.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Abstraction of GNU v2 abi.
-
-   Copyright (C) 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GNU_V2_ABI_H
-#define GNU_V2_ABI_H
-
-extern int gnuv2_baseclass_offset (struct type *type, int index,
-				   const bfd_byte *valaddr,
-				   CORE_ADDR address);
-
-#endif
Index: gdb-head/gdb/gnu-v3-abi.c
===================================================================
--- gdb-head.orig/gdb/gnu-v3-abi.c
+++ gdb-head/gdb/gnu-v3-abi.c
@@ -45,21 +45,6 @@ gnuv3_is_operator_name (const char *name
 }
 
 
-/* Determine architecture of class DOMAIN.  This architecture is used
-   to query C++ ABI details (types, method pointer layout, etc.).
-
-   Note that we assume DOMAIN must have been allocated with an OBJFILE;
-   GDB does not provide any built-in class types.  Thus we use the
-   architecture of that OBJFILE to define the C++ ABI.  */
-
-static struct gdbarch *
-get_class_arch (struct type *domain)
-{
-  gdb_assert (TYPE_CODE (domain) == TYPE_CODE_CLASS);
-  gdb_assert (TYPE_OBJFILE (domain) != NULL);
-  return get_objfile_arch (TYPE_OBJFILE (domain));
-}
-
 /* To help us find the components of a vtable, we build ourselves a
    GDB type object representing the vtable structure.  Following the
    V3 ABI, it goes something like this:
@@ -214,8 +199,8 @@ static struct type *
 gnuv3_rtti_type (struct value *value,
                  int *full_p, int *top_p, int *using_enc_p)
 {
-  struct gdbarch *gdbarch;
-  struct type *vtable_type;
+  struct gdbarch *gdbarch = value_arch (value);
+  struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
   struct type *values_type = check_typedef (value_type (value));
   CORE_ADDR vtable_address;
   struct value *vtable;
@@ -232,16 +217,6 @@ gnuv3_rtti_type (struct value *value,
   if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
     return NULL;
 
-  /* This routine may be called for Java types that do not have
-     a proper objfile.  Just return NULL for those.  */
-  if (!TYPE_OBJFILE (values_type)
-      || !TYPE_OBJFILE (values_type)->obfd)
-    return NULL;
-
-  /* Determine architecture.  */
-  gdbarch = get_class_arch (values_type);
-  vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
-
   /* If we can't find the virtual table pointer for values_type, we
      can't find the RTTI.  */
   values_type_vptr_fieldno = get_vptr_fieldno (values_type,
@@ -385,16 +360,13 @@ gnuv3_virtual_fn_field (struct value **v
                         struct fn_field *f, int j,
 			struct type *vfn_base, int offset)
 {
+  struct gdbarch *gdbarch = value_arch (*value_p);
   struct type *values_type = check_typedef (value_type (*value_p));
-  struct gdbarch *gdbarch;
 
   /* Some simple sanity checks.  */
   if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
     error (_("Only classes can have virtual functions."));
 
-  /* Determine architecture.  */
-  gdbarch = get_class_arch (values_type);
-
   /* Cast our value to the base class which defines this virtual
      function.  This takes care of any necessary `this'
      adjustments.  */
@@ -413,10 +385,9 @@ gnuv3_virtual_fn_field (struct value **v
 
    -1 is returned on error. */
 static int
-gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
-			CORE_ADDR address)
+gnuv3_baseclass_offset (struct type *type, struct gdbarch *gdbarch, int index,
+			const bfd_byte *valaddr, CORE_ADDR address)
 {
-  struct gdbarch *gdbarch;
   struct type *vtable_type;
   struct type *ptr_type;
   struct value *vtable;
@@ -427,7 +398,6 @@ gnuv3_baseclass_offset (struct type *typ
   int vbasetype_vptr_fieldno;
 
   /* Determine architecture.  */
-  gdbarch = get_class_arch (type);
   vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
   ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
 
@@ -581,10 +551,10 @@ gnuv3_decode_method_ptr (struct gdbarch 
 static void
 gnuv3_print_method_ptr (const gdb_byte *contents,
 			struct type *type,
+			struct gdbarch *gdbarch,
 			struct ui_file *stream)
 {
   struct type *domain = TYPE_DOMAIN_TYPE (type);
-  struct gdbarch *gdbarch = get_class_arch (domain);
   CORE_ADDR ptr_value;
   LONGEST adjustment;
   int vbit;
@@ -647,21 +617,18 @@ gnuv3_print_method_ptr (const gdb_byte *
 /* GNU v3 implementation of cplus_method_ptr_size.  */
 
 static int
-gnuv3_method_ptr_size (struct type *type)
+gnuv3_method_ptr_size (struct gdbarch *gdbarch)
 {
-  struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
-  struct gdbarch *gdbarch = get_class_arch (domain_type);
   return 2 * TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
 }
 
 /* GNU v3 implementation of cplus_make_method_ptr.  */
 
 static void
-gnuv3_make_method_ptr (struct type *type, gdb_byte *contents,
+gnuv3_make_method_ptr (gdb_byte *contents,
+		       struct type *type, struct gdbarch *gdbarch,
 		       CORE_ADDR value, int is_virtual)
 {
-  struct type *domain_type = check_typedef (TYPE_DOMAIN_TYPE (type));
-  struct gdbarch *gdbarch = get_class_arch (domain_type);
   int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
 
   /* FIXME drow/2006-12-24: The adjustment of "this" is currently
@@ -690,7 +657,7 @@ gnuv3_make_method_ptr (struct type *type
 static struct value *
 gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
 {
-  struct gdbarch *gdbarch;
+  struct gdbarch *gdbarch = value_arch (method_ptr);
   const gdb_byte *contents = value_contents (method_ptr);
   CORE_ADDR ptr_value;
   struct type *domain_type, *final_type, *method_type;
@@ -704,7 +671,6 @@ gnuv3_method_ptr_to_value (struct value 
   method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));
 
   /* Extract the pointer to member.  */
-  gdbarch = get_class_arch (domain_type);
   vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);
 
   /* First convert THIS to match the containing type of the pointer to
Index: gdb-head/gdb/p-valprint.c
===================================================================
--- gdb-head.orig/gdb/p-valprint.c
+++ gdb-head/gdb/p-valprint.c
@@ -873,7 +873,7 @@ pascal_object_print_value (struct type *
 	  obstack_ptr_grow (&dont_print_vb_obstack, baseclass);
 	}
 
-      boffset = baseclass_offset (type, i, valaddr, address);
+      boffset = baseclass_offset (type, gdbarch, i, valaddr, address);
 
       if (options->pretty)
 	{
Index: gdb-head/gdb/valops.c
===================================================================
--- gdb-head.orig/gdb/valops.c
+++ gdb-head/gdb/valops.c
@@ -470,7 +470,8 @@ value_cast (struct type *type, struct va
 	   && value_as_long (arg2) == 0)
     {
       struct value *result = allocate_value (type, value_arch (arg2));
-      cplus_make_method_ptr (type, value_contents_writeable (result), 0, 0);
+      cplus_make_method_ptr (value_contents_writeable (result),
+			     type, value_arch (arg2), 0, 0);
       return result;
     }
   else if (code1 == TYPE_CODE_MEMBERPTR && code2 == TYPE_CODE_INT
@@ -1592,7 +1593,7 @@ search_struct_field (char *name, struct 
 	  int boffset;
 	  struct value *v2;
 
-	  boffset = baseclass_offset (type, i,
+	  boffset = baseclass_offset (type, value_arch (arg1), i,
 				      value_contents (arg1) + offset,
 				      value_address (arg1) + offset);
 	  if (boffset == -1)
@@ -1747,7 +1748,8 @@ search_struct_method (char *name, struct
 	  else
 	    base_valaddr = value_contents (*arg1p) + offset;
 
-	  base_offset = baseclass_offset (type, i, base_valaddr,
+	  base_offset = baseclass_offset (type, value_arch (*arg1p), i,
+					  base_valaddr,
 					  value_address (*arg1p) + offset);
 	  if (base_offset == -1)
 	    error (_("virtual baseclass botch"));
@@ -1955,7 +1957,7 @@ find_method_list (struct value **argp, c
       if (BASETYPE_VIA_VIRTUAL (type, i))
 	{
 	  base_offset = value_offset (*argp) + offset;
-	  base_offset = baseclass_offset (type, i,
+	  base_offset = baseclass_offset (type, value_arch (*argp), i,
 					  value_contents (*argp) + base_offset,
 					  value_address (*argp) + base_offset);
 	  if (base_offset == -1)
@@ -2693,8 +2695,9 @@ value_struct_elt_for_reference (struct g
 		{
 		  ptr = lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j));
 		  result = allocate_value (ptr, gdbarch);
-		  cplus_make_method_ptr (value_type (result),
-					 value_contents_writeable (result),
+		  cplus_make_method_ptr (value_contents_writeable (result),
+					 value_type (result),
+					 value_arch (result),
 					 TYPE_FN_FIELD_VOFFSET (f, j), 1);
 		}
 	      else if (noside == EVAL_AVOID_SIDE_EFFECTS)
@@ -2718,8 +2721,9 @@ value_struct_elt_for_reference (struct g
 		{
 		  ptr = lookup_methodptr_type (TYPE_FN_FIELD_TYPE (f, j));
 		  result = allocate_value (ptr, gdbarch);
-		  cplus_make_method_ptr (value_type (result),
-					 value_contents_writeable (result),
+		  cplus_make_method_ptr (value_contents_writeable (result),
+					 value_type (result),
+					 value_arch (result),
 					 value_address (v), 0);
 		}
 	    }
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]