From patchwork Thu Oct 7 20:08:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 45969 Return-Path: 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 912DD3857C5F for ; Thu, 7 Oct 2021 20:10:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 912DD3857C5F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1633637446; bh=ADYWUcuEmFh/jkfKaS0hGnFCxa9sByTobzUGAonHdS0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=XcnEqUEcuh2udTAGK8GknOptQ0KVJh7mNHFWASmLPrU3R6v6s36bN9d3YgxNCweJG UciC+AOIAfAP9Y3ugL9Gt3tVJ6fLGhWiZ4fsRB0WXZBNFNdjuniDYKpTcNupNxm16H exN3os1WxF3vyb3ysdKi+XUo6tUvlWpaZUZ5CpAc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by sourceware.org (Postfix) with ESMTPS id CCAF63858431 for ; Thu, 7 Oct 2021 20:08:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CCAF63858431 Received: by mail-pl1-x631.google.com with SMTP id c4so4657413pls.6 for ; Thu, 07 Oct 2021 13:08:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ADYWUcuEmFh/jkfKaS0hGnFCxa9sByTobzUGAonHdS0=; b=JFCuwDTccSFrDP+MWUzUytWYg6NyqqzVj0Ra+vPbbnW0U4aflD0dyQOEtIX01y/CpS 9XHqGIktTnfPkP8eYPNKxSl6Mo5m592iF/PfUDPjQ3BJi5f0tu5J2ohyS31FKz1UxFzn eHc2db6N8gI4RLV232qBBiDXH0BcYZaSEWuQHcXhT8xLPEEr171uaZ0eRL58B30l9/q6 Wzew/IU7XNVD+RE5ACUWP0DZ0sPFshr044gmdHKzs6UnnaKp0OXz12Qa8Vh5okW295Za M7VYF3xsnVmD+eJQ/KNJ96p4WxyB6jS0bKX7vOeYxWwM+nAJrBitQfEDP32ac2zAKhP5 s3VQ== X-Gm-Message-State: AOAM532/z/vzxQPA3ZyaHcwfray0zI5RIUgnEHnu0PazPC7gtyihPVV4 y8X8ahHo4LS1FmJFez47MdlVpL1eiEQ= X-Google-Smtp-Source: ABdhPJxorBYjMgcOP4X3HSZCuGh6HSCZNeLAmrEzmi7Jjx+SbfYLFIo16PLazp8g0oBw36oi3fXpgg== X-Received: by 2002:a17:902:8b83:b029:12c:cbce:a52f with SMTP id ay3-20020a1709028b83b029012ccbcea52fmr5805873plb.9.1633637294960; Thu, 07 Oct 2021 13:08:14 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.58.39.6]) by smtp.gmail.com with ESMTPSA id u24sm263734pfm.27.2021.10.07.13.08.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 13:08:14 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 5E479C02FF; Thu, 7 Oct 2021 13:08:13 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH 1/3] Check linker suppor for -z indirect-extern-access Date: Thu, 7 Oct 2021 13:08:11 -0700 Message-Id: <20211007200813.1626777-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211007200813.1626777-1-hjl.tools@gmail.com> References: <20211007200813.1626777-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3032.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Binutils 2.37 supports -z indirect-extern-access. If GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS is set on any input relocatable files: 1. Don't generate copy relocations. 2. Turn off extern_protected_data since it implies GNU_PROPERTY_NO_COPY_ON_PROTECTED. 3. Treate reference to protected symbols with indirect external access as local. 4. Set GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS on output. 5. When generating executable, clear this bit when there are non-GOT or non-PLT relocations in input relocatable files without the bit set. 6. Add -z [no]indirect-extern-access to control indirect external access. --- configure | 32 ++++++++++++++++++++++++++++++++ configure.ac | 21 +++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/configure b/configure index 39d75eb4ed..ac24218009 100755 --- a/configure +++ b/configure @@ -5819,6 +5819,38 @@ fi $as_echo "$libc_cv_insert" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking -z indirect-extern-access" >&5 +$as_echo_n "checking -z indirect-extern-access... " >&6; } +if ${libc_cv_z_indirect_extern_access+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + libc_cv_z_indirect_extern_access=yes + else + libc_cv_z_indirect_extern_access=no + fi + rm -f conftest.* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_z_indirect_extern_access" >&5 +$as_echo "$libc_cv_z_indirect_extern_access" >&6; } +config_vars="$config_vars +have-z-indirect-extern-access = $libc_cv_z_indirect_extern_access" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken __attribute__((alias()))" >&5 $as_echo_n "checking for broken __attribute__((alias()))... " >&6; } if ${libc_cv_broken_alias_attribute+:} false; then : diff --git a/configure.ac b/configure.ac index 00f49f09f7..8bb0d1a838 100644 --- a/configure.ac +++ b/configure.ac @@ -1235,6 +1235,27 @@ EOF ]) AC_SUBST(libc_cv_insert) +AC_CACHE_CHECK(-z indirect-extern-access, + libc_cv_z_indirect_extern_access, + [cat > conftest.c <&AS_MESSAGE_LOG_FD]); then + libc_cv_z_indirect_extern_access=yes + else + libc_cv_z_indirect_extern_access=no + fi + rm -f conftest.* + ]) +LIBC_CONFIG_VAR([have-z-indirect-extern-access], + [$libc_cv_z_indirect_extern_access]) + AC_CACHE_CHECK(for broken __attribute__((alias())), libc_cv_broken_alias_attribute, [cat > conftest.c < X-Patchwork-Id: 45968 Return-Path: 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 3413D3857C6A for ; Thu, 7 Oct 2021 20:10:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3413D3857C6A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1633637404; bh=iEgNquMUyqQfpsQq7f7ljzuY6WA8CBvP5q0lQpAQuOw=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=dViM1eOBIhngwG1pIeXUKYxuDqZjLJpWbrwJq1STVYwB8tdmFrcRDBmyOtcIdSHDT 3GFCnEvRyFkXNrJvIIHdKFERXzhzeF3tvFIqmgUj2sD1EYuuZnVOFwMQ6EwHueHWbI PDY2zU9v1GhqfPNRw1Fvekttym1IlTammYOHomd4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pg1-x532.google.com (mail-pg1-x532.google.com [IPv6:2607:f8b0:4864:20::532]) by sourceware.org (Postfix) with ESMTPS id 60E133858001 for ; Thu, 7 Oct 2021 20:08:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 60E133858001 Received: by mail-pg1-x532.google.com with SMTP id 75so868009pga.3 for ; Thu, 07 Oct 2021 13:08:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iEgNquMUyqQfpsQq7f7ljzuY6WA8CBvP5q0lQpAQuOw=; b=HUKiQTKuzFl2cPZED3BDs9ucW4nbMUw13PPnHbDI/4dbVE5x5YukQdd/josBIYgFV1 TsiatxeHnfR0J+l586ydlTw3ZMRG+z+bUa5OsXOy/JtwO8QEpRlOtTG7WkCS5MmVn10D QrjDt4Ho40tn5eUwY/A371jIGfe7n9H7kbRJv7IJ6hCoLVJ5+1YwKZXGi+BPjPd7CFYT N5odchxTvH+rE2O6+j0S7xW27FwS3WXG94+6PIghC1qnVdlE9RvYeq5ObhtluYnXZIw/ cekopCZrJQp19SWg3eCCfPHrI5Fn8iYYG8UJks+Ro83TwmchqYy1cePFNM18mro4GlNe m9+w== X-Gm-Message-State: AOAM531eAuSM9WSQxoPkQuFe3nL5bznGx204k4ckdEx4IuqfVzZEfu85 7v9qsZ4F8FTdswKfyrlcOz8DI0/J7rU= X-Google-Smtp-Source: ABdhPJxojvZMJH9hSpxrEXkn6nCTwNMkKA1kFm90bjj3hFtwcuFuAQlVZbFhqyorfqSyN48MSaSq1Q== X-Received: by 2002:a63:1e03:: with SMTP id e3mr1236144pge.213.1633637295418; Thu, 07 Oct 2021 13:08:15 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.58.39.6]) by smtp.gmail.com with ESMTPSA id v2sm115005pje.15.2021.10.07.13.08.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 13:08:14 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 6A567C0305; Thu, 7 Oct 2021 13:08:13 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH 2/3] Check compiler support for -fno-direct-extern-access Date: Thu, 7 Oct 2021 13:08:12 -0700 Message-Id: <20211007200813.1626777-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211007200813.1626777-1-hjl.tools@gmail.com> References: <20211007200813.1626777-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3031.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_BLACK 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: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Compiler with -fno-direct-extern-access does: 1. Generate an indirect external access marker in relocatable objects. a. Always use GOT to access undefined data and function symbols, including in PIE and non-PIE. These will avoid copy relocations in executables. b. This is compatible with existing executables and shared libraries. 2. In executable and shared library, bind symbols with the STV_PROTECTED visibility locally: a. The address of data symbol is the address of data body. b. For systems without function descriptor, the function pointer is the address of function body. c. The resulting shared libraries may not be incompatible with executables which have copy relocations on protected symbols. Size comparison of non-PIE builds with GCC 12 -O2: 1. On x86-64: text data bss dec hex filename 189958 9304 416 199678 30bfe ld.so (original) 189974 9304 416 199694 30c0e ld.so (-fno-direct-extern-access) 1922458 20240 52432 1995130 1e717a libc.so (original) 1922474 20240 52432 1995146 1e718a libc.so (-fno-direct-extern-access) 49321 1363 192 50876 c6bc iconv_prog (original) 47053 3638 120 50811 c67b iconv_prog (-fno-direct-extern-access) 261978 10339 744 273061 42aa5 localedef (original) 233344 41734 648 275726 4350e localedef (-fno-direct-extern-access) The size difference in localedef mainly comes from .data.rel.ro .data.rel.ro 0x000005 (original) .data.rel.ro 0x007a88 (-fno-direct-extern-access) For example, with -fno-direct-extern-access, localedef.o has 172 relocation entries against section '.rela.data.rel.ro.local' vs none without -fno-direct-extern-access. --- configure | 27 +++++++++++++++++++++++++++ configure.ac | 16 ++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/configure b/configure index ac24218009..fb79301e72 100755 --- a/configure +++ b/configure @@ -5851,6 +5851,33 @@ $as_echo "$libc_cv_z_indirect_extern_access" >&6; } config_vars="$config_vars have-z-indirect-extern-access = $libc_cv_z_indirect_extern_access" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fno-direct-extern-access" >&5 +$as_echo_n "checking for -fno-direct-extern-access... " >&6; } +if ${libc_cv_fno_direct_extern_access+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat > conftest.c <&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + libc_cv_fno_direct_extern_access=yes + else + libc_cv_fno_direct_extern_access=no + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_fno_direct_extern_access" >&5 +$as_echo "$libc_cv_fno_direct_extern_access" >&6; } +config_vars="$config_vars +have-fno-direct-extern-access = $libc_cv_fno_direct_extern_access" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken __attribute__((alias()))" >&5 $as_echo_n "checking for broken __attribute__((alias()))... " >&6; } if ${libc_cv_broken_alias_attribute+:} false; then : diff --git a/configure.ac b/configure.ac index 8bb0d1a838..e9f9038f25 100644 --- a/configure.ac +++ b/configure.ac @@ -1256,6 +1256,22 @@ EOF LIBC_CONFIG_VAR([have-z-indirect-extern-access], [$libc_cv_z_indirect_extern_access]) +AC_CACHE_CHECK(for -fno-direct-extern-access, + libc_cv_fno_direct_extern_access, + [cat > conftest.c <&AS_MESSAGE_LOG_FD]); then + libc_cv_fno_direct_extern_access=yes + else + libc_cv_fno_direct_extern_access=no + fi + rm -f conftest*]) +LIBC_CONFIG_VAR([have-fno-direct-extern-access], + [$libc_cv_fno_direct_extern_access]) + AC_CACHE_CHECK(for broken __attribute__((alias())), libc_cv_broken_alias_attribute, [cat > conftest.c < X-Patchwork-Id: 45966 Return-Path: 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 A02A53857C62 for ; Thu, 7 Oct 2021 20:08:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A02A53857C62 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1633637319; bh=JPNkhYu9oL2evqU+RwKKeuVHrCxJz9j0+kQGK0is2no=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=XhGdLht+ZbyIv8xATFspgjLuszZSHkn7DSM5WftkkeDPP5vNCg+kBK1hO9rXZT3Qf kdf/aqMcm04aQo2wrT3VxudcvaSw8CU8G1gIn80Q5h72hkQQRDT6l9Ds6fWmZlOhgW 7Q3CoOiE9hEQ4WZzW5jYCC+fWt1uaaMW6qiKL8jc= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pl1-x629.google.com (mail-pl1-x629.google.com [IPv6:2607:f8b0:4864:20::629]) by sourceware.org (Postfix) with ESMTPS id 631213858002 for ; Thu, 7 Oct 2021 20:08:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 631213858002 Received: by mail-pl1-x629.google.com with SMTP id n11so4226947plf.4 for ; Thu, 07 Oct 2021 13:08:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JPNkhYu9oL2evqU+RwKKeuVHrCxJz9j0+kQGK0is2no=; b=wzV8bc0/z/l1AtS5XA6X/d+kMIduXAVJTwhP4e0OWa8l3HBZi/ulQGuT71m68EQx5v OzS2t1rnM3qKa0ImLvQjk8ojbaNhnfcrbX/Q0ooq61CkQfdfJiQDfbZOD4Jpho0VYE1m U+upnsiY/ozLzc7Yj2+JsMsm2V6W213vQ6apnW94ZA1i7xzegAXu/yRjo1atglWy9kGm /f/F7dehmlms20UAQjvdKif+ieQZs/yZRRahSDZ8UXh/lZv9pcA69FtiSdX/ktPyKqYM TxOkA3Xtubmd52AYzFUt8OKy1s37aTZRwEGpbzlTUZ7GOj1ENCey2fYV3ni9m1AV/KI/ MdTA== X-Gm-Message-State: AOAM533Lc85yVFRAEDWocYtlvhNbcHpscGPL31FZLBcc45LIYgqwxfK2 +GpHk39NOGP+EIufhObieqM= X-Google-Smtp-Source: ABdhPJzTfNA5FmesdpH+b+Rwa3TaLOiwnXvLK3+dsBnhu081BG1T3KjavCxdEDRKpQaenu76uZVM9Q== X-Received: by 2002:a17:903:246:b0:13a:8c8:8a31 with SMTP id j6-20020a170903024600b0013a08c88a31mr5754287plh.87.1633637295174; Thu, 07 Oct 2021 13:08:15 -0700 (PDT) Received: from gnu-cfl-2.localdomain ([172.58.39.6]) by smtp.gmail.com with ESMTPSA id c26sm131172pfo.96.2021.10.07.13.08.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 13:08:14 -0700 (PDT) Received: from gnu-cfl-2.. (localhost [IPv6:::1]) by gnu-cfl-2.localdomain (Postfix) with ESMTP id 6DC11C033B; Thu, 7 Oct 2021 13:08:13 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH 3/3] Update tests for protected data and function symbols Date: Thu, 7 Oct 2021 13:08:13 -0700 Message-Id: <20211007200813.1626777-4-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211007200813.1626777-1-hjl.tools@gmail.com> References: <20211007200813.1626777-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3032.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Protected data and function symbols don't work well without -fno-direct-extern-access: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37611 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=44166 1. Compile tst-protected1[ab].c and tst-protected1mod[ab].c with -fno-direct-extern-access if possible so that GOT entries are used for undefined data accesses. 2. Add tests for protected function pointers. 3. Build tst-prelink.c with direct external access to keep COPY relocation. --- elf/Makefile | 54 ++++++++++++++++ elf/tst-protected1moda.c | 10 +-- elf/tst-protected1modb.c | 4 +- elf/tst-protected2a.c | 130 ++++++++++++++++++++++++++++++++++++++ elf/tst-protected2apie.c | 1 + elf/tst-protected2b.c | 121 +++++++++++++++++++++++++++++++++++ elf/tst-protected2bpie.c | 1 + elf/tst-protected2mod.h | 35 ++++++++++ elf/tst-protected2moda.c | 52 +++++++++++++++ elf/tst-protected2moda2.c | 41 ++++++++++++ elf/tst-protected2modb.c | 45 +++++++++++++ elf/tst-protected2modb2.c | 28 ++++++++ 12 files changed, 512 insertions(+), 10 deletions(-) create mode 100644 elf/tst-protected2a.c create mode 100644 elf/tst-protected2apie.c create mode 100644 elf/tst-protected2b.c create mode 100644 elf/tst-protected2bpie.c create mode 100644 elf/tst-protected2mod.h create mode 100644 elf/tst-protected2moda.c create mode 100644 elf/tst-protected2moda2.c create mode 100644 elf/tst-protected2modb.c create mode 100644 elf/tst-protected2modb2.c diff --git a/elf/Makefile b/elf/Makefile index 26986c0692..85cfb876b5 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -380,15 +380,59 @@ tests += tst-protected1a tst-protected1b $(objpfx)tst-protected1a: $(addprefix $(objpfx),tst-protected1moda.so tst-protected1modb.so) $(objpfx)tst-protected1b: $(addprefix $(objpfx),tst-protected1modb.so tst-protected1moda.so) tst-protected1modb.so-no-z-defs = yes +ifeq (yes,$(have-fno-direct-extern-access)) +CFLAGS-tst-protected1a.c += -fno-direct-extern-access +CFLAGS-tst-protected1b.c += -fno-direct-extern-access +CFLAGS-tst-protected1moda.c += -fno-direct-extern-access +CFLAGS-tst-protected1modb.c += -fno-direct-extern-access +else # These tests fail with GCC versions prior to 5.1 and with some versions # of binutils. See https://sourceware.org/bugzilla/show_bug.cgi?id=17709 # and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248 for details. # Perhaps in future we can make these XFAILs conditional on some detection # of compiler/linker behavior/version. +# NB: These tests pass with -fno-direct-extern-access when GOT entries +# are used for undefined data accesses. test-xfail-tst-protected1a = yes test-xfail-tst-protected1b = yes endif +ifeq (yes,$(have-z-indirect-extern-access)) +LDFLAGS-tst-protected1moda.so += -Wl,-z,indirect-extern-access +LDFLAGS-tst-protected1modb.so += -Wl,-z,indirect-extern-access +endif +endif ifeq (yesyes,$(have-fpie)$(build-shared)) +ifeq (yes,$(have-z-indirect-extern-access)) +modules-names += tst-protected2moda tst-protected2modb +tests += tst-protected2a tst-protected2b +tests += tst-protected2apie tst-protected2bpie +tests-pie += tst-protected2apie tst-protected2bpie +test-extras += tst-protected2moda2 tst-protected2modb2 +extra-test-objs += tst-protected2moda2.os tst-protected2modb2.os +LDFLAGS-tst-protected2moda.so += -Wl,-z,indirect-extern-access +LDFLAGS-tst-protected2modb.so += -Wl,-z,indirect-extern-access +CFLAGS-tst-protected2apie.c += $(PIE-ccflag) +CFLAGS-tst-protected2bpie.c += $(PIE-ccflag) +ifeq (yes,$(have-fno-direct-extern-access)) +CFLAGS-tst-protected2a.c += -fno-direct-extern-access +CFLAGS-tst-protected2b.c += -fno-direct-extern-access +CFLAGS-tst-protected2moda.c += -fno-direct-extern-access +CFLAGS-tst-protected2moda2.c += -fno-direct-extern-access +CFLAGS-tst-protected2modb.c += -fno-direct-extern-access +CFLAGS-tst-protected2modb2.c += -fno-direct-extern-access +else +# These non-PIE tests fail when GOT entries are not used for undefined +# function pointers. +test-xfail-tst-protected2a = yes +test-xfail-tst-protected2b = yes +endif +$(objpfx)tst-protected2moda.so: $(objpfx)tst-protected2moda2.os +$(objpfx)tst-protected2modb.so: $(objpfx)tst-protected2modb2.os +$(objpfx)tst-protected2a: $(addprefix $(objpfx),tst-protected2moda.so tst-protected2modb.so) +$(objpfx)tst-protected2b: $(addprefix $(objpfx),tst-protected2modb.so tst-protected2moda.so) +$(objpfx)tst-protected2apie: $(addprefix $(objpfx),tst-protected2moda.so tst-protected2modb.so) +$(objpfx)tst-protected2bpie: $(addprefix $(objpfx),tst-protected2modb.so tst-protected2moda.so) +endif modules-names += tst-piemod1 tests += tst-pie1 tst-pie2 tst-dlopen-pie tst-dlopen-tlsmodid-pie \ tst-dlopen-self-pie @@ -483,6 +527,16 @@ tests += tst-prelink tests-internal += tst-prelink-cmp # Don't compile tst-prelink.c with PIE for GLOB_DAT relocation. CFLAGS-tst-prelink.c += -fno-pie +ifeq ($(have-fno-direct-extern-access),yes) +# Compile tst-prelink.c with -fdirect-extern-acces to keepp COPY +# relocation. +CFLAGS-tst-prelink.c += -fdirect-extern-access +endif +ifeq ($(have-z-indirect-extern-access),yes) +# Link tst-prelink with -z noindirect-extern-access to keepp COPY +# relocation. +LDFLAGS-tst-prelink += -Wl,-z,noindirect-extern-access +endif tst-prelink-no-pie = yes endif diff --git a/elf/tst-protected1moda.c b/elf/tst-protected1moda.c index eeb18306bb..3d0eb1e877 100644 --- a/elf/tst-protected1moda.c +++ b/elf/tst-protected1moda.c @@ -17,17 +17,13 @@ #include "tst-protected1mod.h" -int protected1 = 3; +int protected1 __attribute__ ((visibility("protected"))) = 3; static int expected_protected1 = 3; -int protected2 = 4; +int protected2 __attribute__ ((visibility("protected"))) = 4; static int expected_protected2 = 4; -int protected3 = 5; +int protected3 __attribute__ ((visibility("protected"))) = 5; static int expected_protected3 = 5; -asm (".protected protected1"); -asm (".protected protected2"); -asm (".protected protected3"); - void set_protected1a (int i) { diff --git a/elf/tst-protected1modb.c b/elf/tst-protected1modb.c index 2cb1e61b17..ca82c64689 100644 --- a/elf/tst-protected1modb.c +++ b/elf/tst-protected1modb.c @@ -19,11 +19,9 @@ #include "tst-protected1mod.h" int protected1 = -3; -int protected3 = -5; +int protected3 __attribute__ ((visibility("protected"))) = -5; static int expected_protected3 = -5; -asm (".protected protected3"); - void set_protected1b (int i) { diff --git a/elf/tst-protected2a.c b/elf/tst-protected2a.c new file mode 100644 index 0000000000..21b666e12b --- /dev/null +++ b/elf/tst-protected2a.c @@ -0,0 +1,130 @@ +/* Test the protected visibility when main is linked with moda and modb + in that order: + 1. Protected function symbols, protected1, protected2 and protected3, + defined in moda, are used in moda. + 2. Protected function symbol, protected3, defined in modb, are used + in modb. + 3. Symbol, protected1, defined in moda, is also used in main and modb. + 4. Symbol, protected2, defined in main, is used in main. + 5. Symbol, protected3, defined in moda, is also used in main. + + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +#include "tst-protected2mod.h" + +int +protected2 (void) +{ + return -1; +} + +int +__attribute__ ((weak, noclone, noinline)) +call_ptr (protected_func_type ptr) +{ + return ptr (); +} + +int +do_test (void) +{ + int res = 0; + + /* Check if we get the same address for the protected function symbol. */ + protected_func_type ptr = protected1a_p (); + if (&protected1 != ptr) + { + puts ("`protected1' in main and moda doesn't have the same address"); + res = 1; + } + ptr = protected1b_p (); + if (&protected1 != ptr) + { + puts ("`protected1' in main and modb doesn't have the same address"); + res = 1; + } + + /* Check if we get the right protected function symbol. */ + if (call_ptr (ptr) != 3) + { + puts ("`protected1' in main and moda doesn't return the same value"); + res = 1; + } + + /* Check if we get the right function defined in executable. */ + if (protected2 () != -1) + { + puts ("`protected2' in main returns the wrong value"); + res = 1; + } + + /* Check `protected1' in moda. */ + if (!check_protected1 ()) + { + puts ("`protected1' in moda returns the wrong value"); + res = 1; + } + + /* Check `protected2' in moda. */ + if (!check_protected2 ()) + { + puts ("`protected2' in moda returns the wrong value"); + res = 1; + } + + /* Check if we get the same address for the protected function symbol. */ + if (&protected3 != protected3a_p ()) + { + puts ("`protected3' in main and moda doesn't have the same address"); + res = 1; + } + if (&protected3 == protected3b_p ()) + { + puts ("`protected3' in main and modb has the same address"); + res = 1; + } + + /* Check if we get the right value for the protected data symbol. */ + if (protected3 () != 5) + { + puts ("`protected3' in main and moda doesn't return the same value"); + res = 1; + } + + /* Check `protected3' in moda. */ + if (!check_protected3a ()) + { + puts ("`protected3' in moda has the wrong value"); + res = 1; + } + + /* Check `protected3' in modb. */ + if (!check_protected3b ()) + { + puts ("`protected3' in modb has the wrong value"); + res = 1; + } + + return res; +} + +#include diff --git a/elf/tst-protected2apie.c b/elf/tst-protected2apie.c new file mode 100644 index 0000000000..28a7aa3d1a --- /dev/null +++ b/elf/tst-protected2apie.c @@ -0,0 +1 @@ +#include "tst-protected2a.c" diff --git a/elf/tst-protected2b.c b/elf/tst-protected2b.c new file mode 100644 index 0000000000..500323e33f --- /dev/null +++ b/elf/tst-protected2b.c @@ -0,0 +1,121 @@ +/* Test the protected visibility when main is linked with modb and moda + in that order: + 1. Protected function symbols, protected1, protected2 and protected3, + defined in moda, are used in moda. + 2. Protected function symbol, protected3, defined in modb, are used + in modb. + 3. Symbol, protected1, defined in modb, is used in main and modb. + 4. Symbol, protected2, defined in main, is used in main. + 5. Symbol, protected3, defined in modb, is also used in main. + + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +#include "tst-protected2mod.h" + +int +protected2 (void) +{ + return -1; +} + +int +do_test (void) +{ + int res = 0; + + /* Check if we get the same address for the protected data symbol. */ + if (&protected1 == protected1a_p ()) + { + puts ("`protected1' in main and moda has the same address"); + res = 1; + } + if (&protected1 != protected1b_p ()) + { + puts ("`protected1' in main and modb doesn't have the same address"); + res = 1; + } + + /* Check if we get the right protected function symbol. */ + if (protected1 () != -3) + { + puts ("`protected1' in main and modb doesn't return the same value"); + res = 1; + } + + /* Check if we get the right function defined in executable. */ + if (protected2 () != -1) + { + puts ("`protected2' in main returns the wrong value"); + res = 1; + } + + /* Check `protected1' in moda. */ + if (!check_protected1 ()) + { + puts ("`protected1' in moda returns the wrong value"); + res = 1; + } + + /* Check `protected2' in moda. */ + if (!check_protected2 ()) + { + puts ("`protected2' in moda returns the wrong value"); + res = 1; + } + + /* Check if we get the same address for the protected function symbol. */ + if (&protected3 == protected3a_p ()) + { + puts ("`protected3' in main and moda has the same address"); + res = 1; + } + if (&protected3 != protected3b_p ()) + { + puts ("`protected3' in main and modb doesn't have the same address"); + res = 1; + } + + /* Check if we get the right protected function symbol. */ + if (protected3 () != -5) + { + puts ("`protected3' in main and modb doesn't return the same value"); + res = 1; + } + + /* Check `protected3' in moda. */ + if (!check_protected3a ()) + { + puts ("`protected3' in moda returns the wrong value"); + res = 1; + } + + /* Check `protected3' in modb. */ + if (!check_protected3b ()) + { + puts ("`protected3' in modb returns the wrong value"); + res = 1; + } + + return res; +} + +#include diff --git a/elf/tst-protected2bpie.c b/elf/tst-protected2bpie.c new file mode 100644 index 0000000000..8dcfbd04cb --- /dev/null +++ b/elf/tst-protected2bpie.c @@ -0,0 +1 @@ +#include "tst-protected2b.c" diff --git a/elf/tst-protected2mod.h b/elf/tst-protected2mod.h new file mode 100644 index 0000000000..feb28ab0d5 --- /dev/null +++ b/elf/tst-protected2mod.h @@ -0,0 +1,35 @@ +/* Test protected function symbols. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* Prototypes for the functions in the DSOs. */ +extern int protected1 (void); +extern int protected2 (void); +extern int protected3 (void); + +typedef int (*protected_func_type) (void); + +extern protected_func_type protected1a_p (void); +extern protected_func_type protected1b_p (void); + +extern int check_protected1 (void); +extern int check_protected2 (void); + +extern int check_protected3a (void); +extern protected_func_type protected3a_p (void); +extern int check_protected3b (void); +extern protected_func_type protected3b_p (void); diff --git a/elf/tst-protected2moda.c b/elf/tst-protected2moda.c new file mode 100644 index 0000000000..db04e8dfb9 --- /dev/null +++ b/elf/tst-protected2moda.c @@ -0,0 +1,52 @@ +/* Test protected function symbols. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include "tst-protected2mod.h" + +__attribute__ ((visibility("protected"))) +int +protected1 (void) +{ + return 3; +} + +__attribute__ ((visibility("protected"))) +int +protected2 (void) +{ + return 4; +} + +__attribute__ ((visibility("protected"))) +int +protected3 (void) +{ + return 5; +} + +protected_func_type +protected1a_p (void) +{ + return &protected1; +} + +protected_func_type +protected3a_p (void) +{ + return &protected3; +} diff --git a/elf/tst-protected2moda2.c b/elf/tst-protected2moda2.c new file mode 100644 index 0000000000..fae72177f9 --- /dev/null +++ b/elf/tst-protected2moda2.c @@ -0,0 +1,41 @@ +/* Test protected function symbols. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include "tst-protected2mod.h" + +extern int protected1 (void) __attribute__ ((visibility("protected"))); +extern int protected2 (void) __attribute__ ((visibility("protected"))); +extern int protected3 (void) __attribute__ ((visibility("protected"))); + +int +check_protected1 (void) +{ + return protected1 () == 3; +} + +int +check_protected2 (void) +{ + return protected2 () == 4; +} + +int +check_protected3a (void) +{ + return protected3 () == 5; +} diff --git a/elf/tst-protected2modb.c b/elf/tst-protected2modb.c new file mode 100644 index 0000000000..3c5063f0c3 --- /dev/null +++ b/elf/tst-protected2modb.c @@ -0,0 +1,45 @@ +/* Test protected function symbols. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include "tst-protected2mod.h" + +int +protected1 (void) +{ + return -3; +} + +__attribute__ ((visibility("protected"))) +int +protected3 (void) +{ + return -5; +} + +protected_func_type +protected1b_p (void) +{ + return &protected1; +} + +protected_func_type +protected3b_p (void) +{ + return &protected3; +} diff --git a/elf/tst-protected2modb2.c b/elf/tst-protected2modb2.c new file mode 100644 index 0000000000..b21b827134 --- /dev/null +++ b/elf/tst-protected2modb2.c @@ -0,0 +1,28 @@ +/* Test protected function symbols. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include "tst-protected2mod.h" + +extern int protected3 (void) __attribute__ ((visibility("protected"))); + +int +check_protected3b (void) +{ + return protected3 () == -5; +}