Fix for PR libobjc/18764 ("segfault in libobjc when sending a message to a conflicting class")
Nicola Pero
nicola.pero@meta-innovation.com
Tue Dec 21 23:13:00 GMT 2010
This patch fixes libobjc/18764. It detects when a module contains a class
that already exists, and in that case, rather than segfaulting, it aborts
ordinately with an explanatory error message.
Committed to trunk.
Thanks
Index: init.c
===================================================================
--- init.c (revision 168133)
+++ init.c (working copy)
@@ -879,22 +879,26 @@ void
__objc_init_class (Class class)
{
/* Store the class in the class table and assign class numbers. */
- __objc_add_class_to_hash (class);
-
- /* Register all of the selectors in the class and meta class. */
- __objc_register_selectors_from_class (class);
- __objc_register_selectors_from_class ((Class) class->class_pointer);
-
- /* Install the fake dispatch tables. */
- __objc_install_premature_dtable (class);
- __objc_install_premature_dtable (class->class_pointer);
-
- /* Register the instance methods as class methods, this is only done
- for root classes. */
- __objc_register_instance_methods_to_class (class);
-
- if (class->protocols)
- __objc_init_protocols (class->protocols);
+ if (__objc_add_class_to_hash (class))
+ {
+ /* Register all of the selectors in the class and meta class. */
+ __objc_register_selectors_from_class (class);
+ __objc_register_selectors_from_class ((Class) class->class_pointer);
+
+ /* Install the fake dispatch tables. */
+ __objc_install_premature_dtable (class);
+ __objc_install_premature_dtable (class->class_pointer);
+
+ /* Register the instance methods as class methods, this is only
+ done for root classes. */
+ __objc_register_instance_methods_to_class (class);
+
+ if (class->protocols)
+ __objc_init_protocols (class->protocols);
+ }
+ else
+ _objc_abort ("Module contains duplicate class '%s'\n",
+ class->name);
}
/* __objc_init_protocol must be called with __objc_runtime_mutex
Index: objc-private/runtime.h
===================================================================
--- objc-private/runtime.h (revision 168132)
+++ objc-private/runtime.h (working copy)
@@ -52,17 +52,17 @@ objc/runtime.h. */
extern "C" {
#endif /* __cplusplus */
-extern void __objc_add_class_to_hash(Class); /* (objc-class.c) */
-extern void __objc_init_class_tables(void); /* (objc-class.c) */
-extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */
-extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */
-extern void __objc_resolve_class_links(void); /* (objc-class.c) */
+extern BOOL __objc_add_class_to_hash (Class); /* (objc-class.c) */
+extern void __objc_init_class_tables (void); /* (objc-class.c) */
+extern void __objc_init_dispatch_tables (void); /* (objc-dispatch.c) */
+extern void __objc_install_premature_dtable (Class); /* (objc-dispatch.c) */
+extern void __objc_resolve_class_links (void); /* (objc-class.c) */
extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */
-extern int __objc_init_thread_system(void); /* thread.c */
-extern int __objc_fini_thread_system(void); /* thread.c */
+extern int __objc_init_thread_system (void); /* thread.c */
+extern int __objc_fini_thread_system (void); /* thread.c */
extern void __objc_init_class (Class class); /* init.c */
-extern void class_add_method_list(Class, struct objc_method_list *);
+extern void class_add_method_list (Class, struct objc_method_list *);
/* Registering instance methods as class methods for root classes */
extern void __objc_register_instance_methods_to_class(Class);
Index: ChangeLog
===================================================================
--- ChangeLog (revision 168133)
+++ ChangeLog (working copy)
@@ -1,5 +1,15 @@
2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
+ PR libobjc/18764
+ * class.c (__objc_add_class_to_hash): Return YES if the class was
+ added, and NO if it already existed.
+ * init.c (__objc_init_class): If __objc_add_class_to_hash returns
+ NO, then abort the program with an error message.
+ * objc-private/runtime.h (__objc_add_class_to_hash): Updated
+ declaration.
+
+2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
+
* init.c (_objc_load_callback): Initialize with 0.
(__objc_call_callback): Renamed to __objc_call_load_callback.
Check _objc_load_callback only once, and if it is not set, return
Index: class.c
===================================================================
--- class.c (revision 168132)
+++ class.c (working copy)
@@ -446,11 +446,12 @@ __objc_init_class_tables (void)
}
/* This function adds a class to the class hash table, and assigns the
- class a number, unless it's already known. */
-void
+ class a number, unless it's already known. Return 'YES' if the
+ class was added. Return 'NO' if the class was already known. */
+BOOL
__objc_add_class_to_hash (Class class)
{
- Class h_class;
+ Class existing_class;
objc_mutex_lock (__objc_runtime_mutex);
@@ -461,21 +462,28 @@ __objc_add_class_to_hash (Class class)
assert (CLS_ISCLASS (class));
/* Check to see if the class is already in the hash table. */
- h_class = class_table_get_safe (class->name);
- if (! h_class)
+ existing_class = class_table_get_safe (class->name);
+
+ if (existing_class)
{
- /* The class isn't in the hash table. Add the class and assign a class
- number. */
+ objc_mutex_unlock (__objc_runtime_mutex);
+ return NO;
+ }
+ else
+ {
+ /* The class isn't in the hash table. Add the class and assign
+ a class number. */
static unsigned int class_number = 1;
-
+
CLS_SETNUMBER (class, class_number);
CLS_SETNUMBER (class->class_pointer, class_number);
++class_number;
class_table_insert (class->name, class);
+
+ objc_mutex_unlock (__objc_runtime_mutex);
+ return YES;
}
-
- objc_mutex_unlock (__objc_runtime_mutex);
}
Class
More information about the Gcc-patches
mailing list