From patchwork Tue Dec 21 22:49:51 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicola Pero X-Patchwork-Id: 76338 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id D4CC9B7080 for ; Wed, 22 Dec 2010 09:50:17 +1100 (EST) Received: (qmail 19621 invoked by alias); 21 Dec 2010 22:50:09 -0000 Received: (qmail 19589 invoked by uid 22791); 21 Dec 2010 22:50:05 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL, BAYES_00, SARE_SUB_ENC_UTF8, TW_BJ, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (140.186.70.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 21 Dec 2010 22:49:55 +0000 Received: from eggs.gnu.org ([140.186.70.92]:54872) by fencepost.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1PVB1i-0006E8-Lw for gcc-patches@gnu.org; Tue, 21 Dec 2010 17:49:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PVB1k-0006kN-GA for gcc-patches@gnu.org; Tue, 21 Dec 2010 17:49:53 -0500 Received: from smtp191.iad.emailsrvr.com ([207.97.245.191]:51268) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PVB1k-0006kA-DP for gcc-patches@gnu.org; Tue, 21 Dec 2010 17:49:52 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp49.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id D6995190CF9 for ; Tue, 21 Dec 2010 17:49:51 -0500 (EST) Received: from dynamic8.wm-web.iad.mlsrvr.com (dynamic8.wm-web.iad1a.rsapps.net [192.168.2.149]) by smtp49.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id C4A1919099E for ; Tue, 21 Dec 2010 17:49:51 -0500 (EST) Received: from meta-innovation.com (localhost [127.0.0.1]) by dynamic8.wm-web.iad.mlsrvr.com (Postfix) with ESMTP id 8AEF7305006C for ; Tue, 21 Dec 2010 17:49:51 -0500 (EST) Received: by www2.webmail.us (Authenticated sender: nicola.pero@meta-innovation.com, from: nicola.pero@meta-innovation.com) with HTTP; Tue, 21 Dec 2010 23:49:51 +0100 (CET) Date: Tue, 21 Dec 2010 23:49:51 +0100 (CET) Subject: =?UTF-8?Q?Fix=20for=20PR=20libobjc/18764=20("segfault=20in=20libobjc=20w?= =?UTF-8?Q?hen=20sending=20a=20message=20to=20a=20conflicting=20class")?= From: "Nicola Pero" To: "gcc-patches@gnu.org" MIME-Version: 1.0 X-Type: plain Message-ID: <1292971791.565414440@192.168.2.228> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 + 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 + * 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