RISC-V: Support GNU indirect functions.

Message ID 1594183391-15614-1-git-send-email-nelson.chu@sifive.com
State New
Headers show
Series
  • RISC-V: Support GNU indirect functions.
Related show

Commit Message

Nelson Chu July 8, 2020, 4:43 a.m.
Hi binutils,

This patch is used to support GNU ifunc for RISC-V in binutils.
And we also have the ifunc supports in the gcc and glibc.  For glibc,
Vincent Chen have finished the related works, and he is waiting for
the binutils' patch accepted and upstreamed.  For gcc, the following
patch should be enough to enable the ifunc supports.  Jim also reminded
me that we need to check the bintuils ifunc feature in gcc, in case someone
actually uses the ifunc attribute, but they don't have good enough configure
checks.  The gcc check will be sent by another patch to gcc mail list.
However, We have tested and passed the toolchain regressions, including gcc
and binutils testsuites, and glibc testcases for ifunc support.


From c7ce689c15cc8b4609abcad476ea330eaff4308f Mon Sep 17 00:00:00 2001
From: Nelson Chu <nelson.chu@sifive.com>

Date: Mon, 18 May 2020 19:01:29 -0700
Subject: [PATCH] RISC-V: Enable ifunc attribute by default for RISC-V.

---
 gcc/config.gcc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)



For now, we handle the ifunc for the following relocations.
Please see the details in the first patch comments.

R_RISCV_32/64, R_RISCV_HI20, R_RISCV_LO12_I/S, R_RISCV_CALL,
R_RISCV_CALL_PLT, R_RISCV_PCREL_HI20, R_RISCV_GOT_HI20, and
R_RISCV_PCREL_LO12_I/S.

There should be two potential issues currently,

1. For R_RISCV_CALL and R_RISCV_CALL_PLT, GNU GCC and Binutils handle
them separately.  But in fact they can (should) be handled identically.
RISC-V lld had made the same improvement, and so had GNU AARCH64, they
has only R_AARCH64_CALL26 for calls rather than two seperate relocations.
Jim Wilson had suggested me that I should improve this, and also need to
change the ifunc checking rules in the riscv_elf_check_relocs.  I prefer
to improve the R_RISCV_CALL/R_RISCV_CALL_PLT, and also update the ifunc
checking in the riscv_elf_check_relocs by the future patches, if everyone
is OK.

2. Recent DT_TEXTREL changes will issue the warning for this patch.
Consider the commit cebd6b8ac1c5a2a847a50e3efe932ff2d0867b3e
(IFUNC: Update IFUNC resolver check with DT_TEXTREL).  At the beginning,
I think we don't need the ifunc resolver checks, since we don't allow
the R_RISCV_HI20 when generating the shared library or PIE executable.
And the R_RISCV_32/64 are used in the data section rather than the code
for now.  There should be no situations that make the IFUNC resolvers with
DT_TEXTREL happen currently, so I disable the ifunc resolver.

But consider the recent commit 3084d7a27b8e4d13f0fdd0fac62ffadc9c2223b5
(ELF: Add _bfd_elf_add_dynamic_tags).  The commit enables the ifunc resolver
checks for all targets, and helps to find that the R_RISCV_CALL and
R_RISCV_PCREL_HI20 may have chances to generate DT_TEXTREL for ifunc resolver.
This bring me back to see what happen here.  Consider the ifunc-2 testsuite in
the ld/testsuite/ld-riscv-elf/.  I notice that the dynamic relocation, which
cause the TEXTREL, are all R_RISCV_NONE and do nothing in the glibc and other
dynamic loaders.  I believe this shouldn't affect correctness, and can be
resolved by changing some checking rules in the riscv_elf_check_relocs by
the future patches.

Any suggestion and feedback are welcome.

Thanks
Nelson

Comments

Jim Wilson July 8, 2020, 6:45 p.m. | #1
On Tue, Jul 7, 2020 at 9:43 PM Nelson Chu <nelson.chu@sifive.com> wrote:
> This patch is used to support GNU ifunc for RISC-V in binutils.


The binutils patch is OK with me, provided that it is compatible with
the clang implementation.  I will leave that for Nelson and Fangrui to
work out.

Jim

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index ddd3b8f..a07c5b46 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3281,7 +3281,7 @@  case ${target} in
         ;;
 *-*-linux*)
        case ${target} in
-       aarch64*-* | arm*-* | i[34567]86-* | powerpc*-* | s390*-* | sparc*-* | x86_64-*)
+       aarch64*-* | arm*-* | i[34567]86-* | powerpc*-* | riscv*-*-* | s390*-* | sparc*-* | x86_64-*)
                default_gnu_indirect_function=yes
                ;;
        esac