Message ID | 5311422B-0209-43F1-A93F-61FE2C183831@me.com |
---|---|
State | New |
Headers |
Return-Path: <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AC3C6385841C for <patchwork@sourceware.org>; Tue, 21 Sep 2021 22:29:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AC3C6385841C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1632263397; bh=jnsTNJUanL3awzh4AtSyXI0cDwNEDA74qqaLMPL2w9U=; h=Subject:Date:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=my8PvkLc347mypUCgccZkfps0dOuIbHJeCEj4yRV3rgO065zShtrBN+FajkO38p4O wCE+jcZOpUPhQIQ85YWA4wzfBrmlANc9BPbmIkSCzdEOqXUchxJPSNCcsn/oMwfJOa IOhqxp5q5ngQdgsi2MV8CIUZWiROX5c83UiONjdU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from pv34p98im-ztdg02162201.me.com (pv34p98im-ztdg02162201.me.com [17.143.234.141]) by sourceware.org (Postfix) with ESMTPS id A7C143858D39 for <gcc-patches@gcc.gnu.org>; Tue, 21 Sep 2021 22:29:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A7C143858D39 Received: from [10.0.1.20] (cpe-98-26-0-177.nc.res.rr.com [98.26.0.177]) by pv34p98im-ztdg02162201.me.com (Postfix) with ESMTPSA id C0C0F1C008D for <gcc-patches@gcc.gnu.org>; Tue, 21 Sep 2021 22:29:26 +0000 (UTC) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.7\)) Subject: [PATCH] Objective-C: fix class_ro layout for non-LP64 Message-Id: <5311422B-0209-43F1-A93F-61FE2C183831@me.com> Date: Tue, 21 Sep 2021 18:29:24 -0400 To: gcc-patches@gcc.gnu.org X-Mailer: Apple Mail (2.3608.120.23.2.7) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.790 definitions=2021-09-21_07:2021-09-20, 2021-09-21 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=0 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=989 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-2009150000 definitions=main-2109210134 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: Matt Jacobson via Gcc-patches <gcc-patches@gcc.gnu.org> Reply-To: Matt Jacobson <mhjacobson@me.com> Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org> |
Series |
Objective-C: fix class_ro layout for non-LP64
|
|
Commit Message
Matt Jacobson
Sept. 21, 2021, 10:29 p.m. UTC
Fix class_ro layout for non-LP64. On LP64, the requisite padding is added at a lower level. For non-LP64, this fixes binary compatibility with clang-built classes/runtimes. Tested by examining the generated assembly for a class_ro in both cases (and in the case of clang), for both x86_64 (64-bit pointers) and AVR (16-bit pointers). Tested by running a program on AVR with a GCC-built class using a clang-built Objective-C runtime. Tested by running a program on x86_64/Darwin with a GCC- built class and the clang-built system Objective-C runtime. Patch also available at: <https://github.com/mhjacobson/gcc/commit/917dc8bb2f3265c2ca899ad750c5833b0161a11e> I don't have commit access, so if this patch is suitable, I'd need someone else to commit it for me. Thanks. gcc/objc/ChangeLog: 2021-09-21 Matt Jacobson <mhjacobson@me.com> * objc-next-runtime-abi-02.c (struct class_ro_t): Remove explicit alignment padding. (build_v2_class_templates): Remove explicit alignment padding. (build_v2_class_ro_t_initializer): Adjust initializer.
Comments
Hi Matt, thanks for the patch. > On 21 Sep 2021, at 23:29, Matt Jacobson via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Fix class_ro layout for non-LP64. > On LP64, the requisite padding is added at a lower level. However, the behaviour is changed - the existing implementation is explicit about the fields and clears the reserved ones (and, ISTR, that was based on what the gcc-4.2.1 compiler did). (as an aside, in general, I have to test changes in the runtime across the range of supported Darwin versions, since there have been clang changes too). > For non-LP64, this fixes binary compatibility with clang-built classes/runtimes. > Tested by examining the generated assembly for a class_ro in both cases (and in > the case of clang), for both x86_64 (64-bit pointers) and AVR (16-bit pointers). > Tested by running a program on AVR with a GCC-built class using a clang-built > Objective-C runtime. Tested by running a program on x86_64/Darwin with a GCC- > built class and the clang-built system Objective-C runtime. > > Patch also available at: > <https://github.com/mhjacobson/gcc/commit/917dc8bb2f3265c2ca899ad750c5833b0161a11e> > > I don't have commit access, so if this patch is suitable, I'd need someone else > to commit it for me. Thanks. how about we keep the LP64 behaviour unchanged and amend the comments and ifdefs as below, does this work for your case? (typed into email and thus untested). thanks Iain > gcc/objc/ChangeLog: > > 2021-09-21 Matt Jacobson <mhjacobson@me.com> > > * objc-next-runtime-abi-02.c (struct class_ro_t): Remove explicit alignment > padding. > (build_v2_class_templates): Remove explicit alignment padding. > (build_v2_class_ro_t_initializer): Adjust initializer. > > > diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c > index 42645e22316..c3af369ff0d 100644 > --- a/gcc/objc/objc-next-runtime-abi-02.c > +++ b/gcc/objc/objc-next-runtime-abi-02.c > @@ -632,9 +632,7 @@ struct class_ro_t > uint32_t const flags; > uint32_t const instanceStart; > uint32_t const instanceSize;\ > -#ifdef __LP64__ > - uint32_t const reserved; > -#endif > + // [32 bits of reserved space here on LP64 platforms] ^revert this > const uint8_t * const ivarLayout; > const char *const name; > const struct method_list_t * const baseMethods; > @@ -677,11 +675,6 @@ build_v2_class_templates (void) > /* uint32_t const instanceSize; */ > add_field_decl (integer_type_node, "instanceSize", &chain); > #ifdef __LP64__ /* For compatibility with existing implementations of the 64 bit NeXT library, explicitly describe reserved fileds used for alignment padding. */ > /* uint32_t const reserved; */ > add_field_decl (integer_type_node, "reserved", &chain); #endif > > /* const uint8_t * const ivarLayout; */ > cnst_strg_type = build_pointer_type (unsigned_char_type_node); > add_field_decl (cnst_strg_type, "ivarLayout", &chain); > @@ -3225,12 +3218,6 @@ build_v2_class_ro_t_initializer (tree type, tree name, > CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, > build_int_cst (integer_type_node, instanceSize)); #ifdef __LP64__ /* For compatibility with existing implementations of the 64 bit NeXT library, ensure that reserved padding fields are 0-initialized. */ > CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, > build_int_cst (integer_type_node, 0)); #endif > > /* ivarLayout */ > unsigned_char_star = build_pointer_type (unsigned_char_type_node); > if (ivarLayout)
Hi Iain, Thanks for reviewing. I’m happy to make the suggested changes. One comment inline. > On Sep 22, 2021, at 2:49 PM, Iain Sandoe <iain@sandoe.co.uk> wrote: > > However, the behaviour is changed - the existing implementation is explicit about the fields and > clears the reserved ones (and, ISTR, that was based on what the gcc-4.2.1 compiler did). My original change does in fact clear the reserved bytes on LP64 platforms. The padding space compiles down to a `.space` assembler directive, and GNU as is documented to fill that space with zeros. So the reserved bits are indeed cleared. However, I understand the argument that this is too implicit, in that the C standard makes no guarantee about the contents of padding bytes. So future standard-conforming changes to GCC *could* cause that space to be filled with other values (however unlikely that may actually be). (Of course, clang -- which also does not explicitly declare this field -- essentially faces this same theoretical peril...) One problem with the proposed diff: `__LP64__` there refers to the host, not the target. What's the right way to refer to the LP64-ness of the target? I see `TARGET_LP64`, but it's only defined for Intel. I'm using it below (and backstopping it to zero), but I'm not sure if that's correct. Note that it's a run-time-of-compiler (not build-time-of-compiler) check. === Here's v2. <https://github.com/mhjacobson/gcc/commit/8193903a1d5a1569a6799174e13cb22925f1f428> gcc/objc/ChangeLog: 2021-09-26 Matt Jacobson <mhjacobson@me.com> * objc-next-runtime-abi-02.c (build_v2_class_templates): Remove explicit padding on non-LP64. (build_v2_class_ro_t_initializer): Remove initialization of explicit padding on non-LP64. diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c index 42645e22316..22d5232614d 100644 --- a/gcc/objc/objc-next-runtime-abi-02.c +++ b/gcc/objc/objc-next-runtime-abi-02.c @@ -85,6 +85,10 @@ along with GCC; see the file COPYING3. If not see #define OBJC2_CLS_HAS_CXX_STRUCTORS 0x0004L +#ifndef TARGET_LP64 +#define TARGET_LP64 0 +#endif + enum objc_v2_tree_index { /* Templates. */ @@ -677,10 +681,12 @@ build_v2_class_templates (void) /* uint32_t const instanceSize; */ add_field_decl (integer_type_node, "instanceSize", &chain); - /* This ABI is currently only used on m64 NeXT. We always - explicitly declare the alignment padding. */ + /* For compatibility with existing implementations of the 64-bit NeXT v2 + ABI, explicitly declare reserved fields that otherwise would be filled + with alignment padding. */ /* uint32_t const reserved; */ - add_field_decl (integer_type_node, "reserved", &chain); + if (TARGET_LP64) + add_field_decl (integer_type_node, "reserved", &chain); /* const uint8_t * const ivarLayout; */ cnst_strg_type = build_pointer_type (unsigned_char_type_node); @@ -3225,10 +3231,12 @@ build_v2_class_ro_t_initializer (tree type, tree name, CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, build_int_cst (integer_type_node, instanceSize)); - /* This ABI is currently only used on m64 NeXT. We always - explicitly declare the alignment padding. */ - /* reserved, pads alignment. */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, + /* For compatibility with existing implementations of the 64-bit NeXT v2 + ABI, explicitly zero-fill reserved fields that otherwise would be filled + with alignment padding. */ + /* reserved */ + if (TARGET_LP64) + CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, build_int_cst (integer_type_node, 0)); /* ivarLayout */
Hi Matt > On 26 Sep 2021, at 09:10, Matt Jacobson via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Thanks for reviewing. I’m happy to make the suggested changes. One comment > inline. > >> On Sep 22, 2021, at 2:49 PM, Iain Sandoe <iain@sandoe.co.uk> wrote: >> >> However, the behaviour is changed - the existing implementation is explicit about the fields and >> clears the reserved ones (and, ISTR, that was based on what the gcc-4.2.1 compiler did). > > My original change does in fact clear the reserved bytes on LP64 platforms. > The padding space compiles down to a `.space` assembler directive, and GNU as > is documented to fill that space with zeros. So the reserved bits are indeed > cleared. Apologies for iterating here .. So it does, indeed, seem that clang does: target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128” <snip> %struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, (for -m64 -fobjc-runtime=macosx -emit-llvm -S) and,... target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128” <snip> %struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, (for -m32 -fobjc-runtime=macosx -emit-llvm -S), even if the target platform will fail to link that (at least macOS will). So the padding is not explicit in this and will accommodate whatever the target uses. Now - to change that such that the previously reserved field could be used on platforms which don’t have implicit padding would be an ABI break, so isn’t going to happen by accident (or at all, I imagine). Since we produce .space for Darwin9 and Darwin10 (where the system compiler is GCC) I am no longer concerned about dropping the reserved field. This is a long-winded way of saying that I now think your original approach is fine, and will put that patch into my testing queue (spot checks only so far) and apply if all goes without regression. thanks for the patch, Iain
diff --git a/gcc/objc/objc-next-runtime-abi-02.c b/gcc/objc/objc-next-runtime-abi-02.c index 42645e22316..c3af369ff0d 100644 --- a/gcc/objc/objc-next-runtime-abi-02.c +++ b/gcc/objc/objc-next-runtime-abi-02.c @@ -632,9 +632,7 @@ struct class_ro_t uint32_t const flags; uint32_t const instanceStart; uint32_t const instanceSize; -#ifdef __LP64__ - uint32_t const reserved; -#endif + // [32 bits of reserved space here on LP64 platforms] const uint8_t * const ivarLayout; const char *const name; const struct method_list_t * const baseMethods; @@ -677,11 +675,6 @@ build_v2_class_templates (void) /* uint32_t const instanceSize; */ add_field_decl (integer_type_node, "instanceSize", &chain); - /* This ABI is currently only used on m64 NeXT. We always - explicitly declare the alignment padding. */ - /* uint32_t const reserved; */ - add_field_decl (integer_type_node, "reserved", &chain); - /* const uint8_t * const ivarLayout; */ cnst_strg_type = build_pointer_type (unsigned_char_type_node); add_field_decl (cnst_strg_type, "ivarLayout", &chain); @@ -3225,12 +3218,6 @@ build_v2_class_ro_t_initializer (tree type, tree name, CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, build_int_cst (integer_type_node, instanceSize)); - /* This ABI is currently only used on m64 NeXT. We always - explicitly declare the alignment padding. */ - /* reserved, pads alignment. */ - CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, - build_int_cst (integer_type_node, 0)); - /* ivarLayout */ unsigned_char_star = build_pointer_type (unsigned_char_type_node); if (ivarLayout)