From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by sourceware.org (Postfix) with ESMTPS id EFBEC3858288 for ; Wed, 1 Jun 2022 01:15:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org EFBEC3858288 Received: by mail-pl1-x62f.google.com with SMTP id o17so334706pla.6 for ; Tue, 31 May 2022 18:15:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=Deur1aY9M5d5bffPASsfa94Y1hK0NJfDemgwPrzc7yI=; b=uy5cn39NviN6oogtGFkO+/2mOMMvMB9vUzB+A0nz6pjo4bdURCoAQrwrl8hk8+ZHdm 8IxOiGEb55IuTajlAXfrYpZXDro9vrQuUBzNz7bCLR77PbblMgroWnFBzKCXPNuSmXNq DUtDQRRFUJS+SDrTiL5+FYX3ou/WFMkZwzgpIwCAgadKDEnc2i/xZM6hJGyivJNOgZgn 45jcVVLtHst+9bqeSDMekxpQ1C4sY1NFWCeGfGUk4qJW8VqreVNBbxDCHzTKAR1Tb1L/ 5KS17ewxs0XnIDzojCgkfTUhMUrjUr39EqnA8tnQC6zpret4T0XffQsZ8z7x4mFUdNPY RZ7g== X-Gm-Message-State: AOAM532ilYI6k1H3bWo+QMriZETgRwOkmFf8jqkM5fhZORgkpy/FyyRm U2mvdtY4FXXOr9sOBGmisEWGazvWgvHgA6xTWXqFmSk/ X-Google-Smtp-Source: ABdhPJwu4Gxa/BOC8E9TSurBYGf/hLOIeqGP1iSS1SWDDyPVYNTdVNFi9jIwnSFBmg5obeXXajj7pJpN8R10ZjtDghg= X-Received: by 2002:a17:90b:23d8:b0:1e2:e3cb:ac08 with SMTP id md24-20020a17090b23d800b001e2e3cbac08mr16485586pjb.35.1654046154710; Tue, 31 May 2022 18:15:54 -0700 (PDT) MIME-Version: 1.0 References: <20220531224734.634761-1-hjl.tools@gmail.com> In-Reply-To: <20220531224734.634761-1-hjl.tools@gmail.com> From: "H.J. Lu" Date: Tue, 31 May 2022 18:15:18 -0700 Message-ID: Subject: Re: [PATCH] x86: Properly handle IFUNC function pointer reference To: Binutils Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-3025.7 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, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Jun 2022 01:15:57 -0000 On Tue, May 31, 2022 at 3:47 PM H.J. Lu wrote: > > Update > > commit 68c4956b1401de70173848a6bdf620cb42fa9358 > Author: H.J. Lu > Date: Tue Apr 26 09:08:54 2022 -0700 > > x86: Properly handle function pointer reference > > to properly handle IFUNC function pointer reference. Since IFUNC symbol > value is only known at run-time, set pointer_equality_needed for IFUNC > function pointer reference in PDE so that it will be resolved to its PLT > entry directly. > > bfd/ > > PR ld/29216 > * elf32-i386.c (elf_i386_scan_relocs): Set pointer_equality_needed > for IFUNC function pointer reference in PDE. > * elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise. > > ld/ > > PR ld/29216 > * testsuite/ld-ifunc/ifunc.exp: Run PR ld/29216 test. > * testsuite/ld-ifunc/pr29216.c: New file. > --- > bfd/elf32-i386.c | 8 ++++- > bfd/elf64-x86-64.c | 8 ++++- > ld/testsuite/ld-ifunc/ifunc.exp | 9 +++++ > ld/testsuite/ld-ifunc/pr29216.c | 62 +++++++++++++++++++++++++++++++++ > 4 files changed, 85 insertions(+), 2 deletions(-) > create mode 100644 ld/testsuite/ld-ifunc/pr29216.c > > diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c > index b034154fb97..3bc710096aa 100644 > --- a/bfd/elf32-i386.c > +++ b/bfd/elf32-i386.c > @@ -1778,7 +1778,13 @@ elf_i386_scan_relocs (bfd *abfd, > if (r_type == R_386_32 > && (sec->flags & SEC_READONLY) == 0) > func_pointer_ref = true; > - else > + > + /* IFUNC symbol needs pointer equality in PDE so that > + function pointer reference will be resolved to its > + PLT entry directly. */ > + if (!func_pointer_ref > + || (bfd_link_pde (info) > + && h->type == STT_GNU_IFUNC)) > h->pointer_equality_needed = 1; > } > > diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c > index 6d69d6141ee..eac5e83d7f1 100644 > --- a/bfd/elf64-x86-64.c > +++ b/bfd/elf64-x86-64.c > @@ -2221,7 +2221,13 @@ elf_x86_64_scan_relocs (bfd *abfd, struct bfd_link_info *info, > && (r_type == R_X86_64_32 > || r_type == R_X86_64_32S)))) > func_pointer_ref = true; > - else > + > + /* IFUNC symbol needs pointer equality in PDE so that > + function pointer reference will be resolved to its > + PLT entry directly. */ > + if (!func_pointer_ref > + || (bfd_link_pde (info) > + && h->type == STT_GNU_IFUNC)) > h->pointer_equality_needed = 1; > } > > diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp > index 1cd8d388b26..fdb65d01f9f 100644 > --- a/ld/testsuite/ld-ifunc/ifunc.exp > +++ b/ld/testsuite/ld-ifunc/ifunc.exp > @@ -714,6 +714,15 @@ run_ld_link_exec_tests [list \ > "pr18841cn" \ > "pr18841.out" \ > ] \ > + [list \ > + "Run pr29216" \ > + "$NOPIE_LDFLAGS" \ > + "" \ > + { pr29216.c } \ > + "pr29216" \ > + "pass.out" \ > + "-fPIC" \ > + ] \ > ] > > # The pr23169 testcase is not valid. In general, you can't call ifunc > diff --git a/ld/testsuite/ld-ifunc/pr29216.c b/ld/testsuite/ld-ifunc/pr29216.c > new file mode 100644 > index 00000000000..5019c723c2b > --- /dev/null > +++ b/ld/testsuite/ld-ifunc/pr29216.c > @@ -0,0 +1,62 @@ > +#include > + > +static int > +one (void) > +{ > + return -30; > +} > + > +int foo (void) __attribute__ ((ifunc ("resolve_foo"))); > + > +void * > +resolve_foo (void) > +{ > + return (void *) one; > +} > + > +typedef int (*foo_p) (void); > + > +foo_p foo_ptr = foo; > + > +foo_p > +__attribute__ ((noinline)) > +get_foo_p (void) > +{ > + return foo_ptr; > +} > + > +foo_p > +__attribute__ ((noinline)) > +get_foo (void) > +{ > + return foo; > +} > + > +int > +main (void) > +{ > + foo_p p; > + > + p = get_foo (); > + if (p != foo) > + __builtin_abort (); > + if ((*p) () != -30) > + __builtin_abort (); > + > + p = get_foo_p (); > + if (p != foo) > + __builtin_abort (); > + if ((*p) () != -30) > + __builtin_abort (); > + > + if (foo_ptr != foo) > + __builtin_abort (); > + if ((*foo_ptr) () != -30) > + __builtin_abort (); > + if (foo () != -30) > + __builtin_abort (); > + > + printf ("PASS\n"); > + > + return 0; > +} > -- > 2.36.1 > I am backporting this to 2.38 branch. -- H.J.