Index: init.c
===================================================================
--- init.c	(revision 147703)
+++ init.c	(working copy)
@@ -26,9 +26,12 @@
 
 #include "objc/runtime.h"
 
+#include <dlfcn.h>
+
 /* The version number of this runtime.  This must match the number 
    defined in gcc (objc-act.c).  */
-#define OBJC_VERSION 8
+#define OBJC_BACK_COMPATIBLE_VERSION 8
+#define OBJC_VERSION 9
 #define PROTOCOL_VERSION 2
 
 /* This list contains all modules currently loaded into the runtime.  */
@@ -701,6 +704,64 @@
 }
 
 static void
+__objc_compute_ivar_offsets (Class class)
+{
+  long ivar_start = 0;
+  int i = 0;
+  Class super = class_superclass_of_class(class);
+  /* If this class was compiled with support for late-bound ivars, the
+   * instance_size field will contain 0 - {the size of the instance variables
+   * declared for just this class}.  The individual instance variable offset
+   * fields will then be the offsets from the start of the class, and so must
+   * have the size of the parent class prepended. */
+  if (class->instance_size < 0)
+    {
+      ivar_start = super->instance_size;
+	  /* FIXME: I don't think this code path is ever used.  If it really isn't,
+	   * delete it. */
+      if (ivar_start < 0)
+        {
+          __objc_compute_ivar_offsets(super);
+          ivar_start = super->instance_size;
+        }
+      class->instance_size = ivar_start - class->instance_size;
+    }
+  /* For each instance variable, we add the offset if required (it will be zero
+   * if this class is compiled with a static ivar layout).  We then set the
+   * value of a global variable to the offset value.  Every compilation unit
+   * which accesses instance variables must emit __objc_ivar_offset_{class
+   * name}_{ivar name} for every class/ivar pair that it accesses with weak
+   * (link-once) linkage.  The linker / loader will then ensure that there is
+   * only one copy of this variable.  We set this for every ivar when the class
+   * is loaded, even if the class is compiled with a static layout.  This means
+   * that modules compiled with dynamic layout support can subclass classes
+   * with static layout and not break.  For example, we can use static layout
+   * in GNUstep Foundation classes, dynamic layout in other frameworks and
+   * applications, and not break the ABI when GNUstep classes add ivars.
+   *
+   * Note that using non-fragile ivars breaks @defs().  If you need equivalent
+   * functionality, declare the relevant __objc_ivar_offset_* variables extern
+   * and add these to the object pointer (as a char*) to get the instance
+   * variables outside the class.
+   */
+  while (i < class->ivars->ivar_count)
+    {
+      struct objc_ivar *ivar = &class->ivars->ivar_list[i];
+      char * symbol_name;
+      int *offset;
+      ivar->ivar_offset += ivar_start;
+      asprintf(&symbol_name, "__objc_ivar_offset_%s.%s", class->name,
+	      ivar->ivar_name);
+      if ((offset = dlsym(RTLD_DEFAULT, symbol_name)))
+	{
+	  *offset = ivar->ivar_offset;
+	}
+	  free(symbol_name);
+      i++;
+    }
+}
+
+static void
 objc_send_load (void)
 {
   if (! __objc_module_list)
@@ -776,6 +837,7 @@
       Class class = (Class) symtab->defs[i];
 
       objc_tree_insert_class (class);
+      __objc_compute_ivar_offsets (class);
     }
 }
 
@@ -816,7 +878,8 @@
 static void
 init_check_module_version (Module_t module)
 {
-  if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
+  if ((module->version < OBJC_BACK_COMPATIBLE_VERSION) || 
+	  (module->version > OBJC_VERSION) || (module->size != sizeof (Module)))
     {
       int code;
 
