diff mbox series

riscv: Change the relocations handled for RTLD_BOOTSTRAP

Message ID 20220606050247.3125956-1-maskray@google.com
State New
Headers show
Series riscv: Change the relocations handled for RTLD_BOOTSTRAP | expand

Commit Message

Fangrui Song June 6, 2022, 5:02 a.m. UTC
The RTLD_BOOTSTRAP branch is used to relocate ld.so itself.  It only
needs to handle RELATIVE, GLOB_DAT, and the symbolic relocation type
(R_RISCV_{32,64}).  NONE and IRELATIVE can be removed.

The code relies on ld.so having DT_RELACOUNT so that the RTLD_BOOTSTRAP
branch does not need handle RELATIVE.  Drop this minor size
optimization for clarity.
---
 sysdeps/riscv/dl-machine.h | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

Comments

Fangrui Song June 10, 2022, 11:30 p.m. UTC | #1
On 2022-06-05, Fangrui Song wrote:
>The RTLD_BOOTSTRAP branch is used to relocate ld.so itself.  It only
>needs to handle RELATIVE, GLOB_DAT, and the symbolic relocation type
>(R_RISCV_{32,64}).  NONE and IRELATIVE can be removed.
>
>The code relies on ld.so having DT_RELACOUNT so that the RTLD_BOOTSTRAP
>branch does not need handle RELATIVE.  Drop this minor size
>optimization for clarity.
>---
> sysdeps/riscv/dl-machine.h | 23 ++++++++++-------------
> 1 file changed, 10 insertions(+), 13 deletions(-)
>
>diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
>index 9e026ae011..a60a452952 100644
>--- a/sysdeps/riscv/dl-machine.h
>+++ b/sysdeps/riscv/dl-machine.h
>@@ -181,7 +181,15 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>
>   switch (r_type)
>     {
>-#ifndef RTLD_BOOTSTRAP
>+    case R_RISCV_RELATIVE:
>+      *addr_field = map->l_addr + reloc->r_addend;
>+      break;
>+    case R_RISCV_JUMP_SLOT:
>+    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>+      *addr_field = value;
>+      break;
>+
>+# ifndef RTLD_BOOTSTRAP
>     case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
>       if (sym_map)
> 	*addr_field = sym_map->l_tls_modid;
>@@ -232,13 +240,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> 	memcpy (reloc_addr, (void *)value, size);
> 	break;
>       }
>-#endif
>-
>-#if !defined RTLD_BOOTSTRAP
>-    case R_RISCV_RELATIVE:
>-      *addr_field = map->l_addr + reloc->r_addend;
>-      break;
>-#endif
>
>     case R_RISCV_IRELATIVE:
>       value = map->l_addr + reloc->r_addend;
>@@ -247,13 +248,9 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>       *addr_field = value;
>       break;
>
>-    case R_RISCV_JUMP_SLOT:
>-    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>-      *addr_field = value;
>-      break;
>-
>     case R_RISCV_NONE:
>       break;
>+# endif /* !RTLD_BOOTSTRAP */
>
>     default:
>       _dl_reloc_bad_type (map, r_type, 0);
>-- 
>2.36.1.255.ge46751e96f-goog
>

Ping:)
Fangrui Song June 15, 2022, 11:07 p.m. UTC | #2
On 2022-06-05, Fangrui Song wrote:
>The RTLD_BOOTSTRAP branch is used to relocate ld.so itself.  It only
>needs to handle RELATIVE, GLOB_DAT, and the symbolic relocation type
>(R_RISCV_{32,64}).  NONE and IRELATIVE can be removed.
>
>The code relies on ld.so having DT_RELACOUNT so that the RTLD_BOOTSTRAP
>branch does not need handle RELATIVE.  Drop this minor size
>optimization for clarity.
>---
> sysdeps/riscv/dl-machine.h | 23 ++++++++++-------------
> 1 file changed, 10 insertions(+), 13 deletions(-)
>
>diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
>index 9e026ae011..a60a452952 100644
>--- a/sysdeps/riscv/dl-machine.h
>+++ b/sysdeps/riscv/dl-machine.h
>@@ -181,7 +181,15 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>
>   switch (r_type)
>     {
>-#ifndef RTLD_BOOTSTRAP
>+    case R_RISCV_RELATIVE:
>+      *addr_field = map->l_addr + reloc->r_addend;
>+      break;
>+    case R_RISCV_JUMP_SLOT:
>+    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>+      *addr_field = value;
>+      break;
>+
>+# ifndef RTLD_BOOTSTRAP
>     case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
>       if (sym_map)
> 	*addr_field = sym_map->l_tls_modid;
>@@ -232,13 +240,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> 	memcpy (reloc_addr, (void *)value, size);
> 	break;
>       }
>-#endif
>-
>-#if !defined RTLD_BOOTSTRAP
>-    case R_RISCV_RELATIVE:
>-      *addr_field = map->l_addr + reloc->r_addend;
>-      break;
>-#endif
>
>     case R_RISCV_IRELATIVE:
>       value = map->l_addr + reloc->r_addend;
>@@ -247,13 +248,9 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>       *addr_field = value;
>       break;
>
>-    case R_RISCV_JUMP_SLOT:
>-    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>-      *addr_field = value;
>-      break;
>-
>     case R_RISCV_NONE:
>       break;
>+# endif /* !RTLD_BOOTSTRAP */
>
>     default:
>       _dl_reloc_bad_type (map, r_type, 0);
>-- 
>2.36.1.255.ge46751e96f-goog
Palmer Dabbelt June 16, 2022, 12:14 a.m. UTC | #3
On Wed, 15 Jun 2022 16:07:37 PDT (-0700), maskray@google.com wrote:
> On 2022-06-05, Fangrui Song wrote:
>>The RTLD_BOOTSTRAP branch is used to relocate ld.so itself.  It only
>>needs to handle RELATIVE, GLOB_DAT, and the symbolic relocation type
>>(R_RISCV_{32,64}).  NONE and IRELATIVE can be removed.
>>
>>The code relies on ld.so having DT_RELACOUNT so that the RTLD_BOOTSTRAP
>>branch does not need handle RELATIVE.  Drop this minor size
>>optimization for clarity.
>>---
>> sysdeps/riscv/dl-machine.h | 23 ++++++++++-------------
>> 1 file changed, 10 insertions(+), 13 deletions(-)
>>
>>diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
>>index 9e026ae011..a60a452952 100644
>>--- a/sysdeps/riscv/dl-machine.h
>>+++ b/sysdeps/riscv/dl-machine.h
>>@@ -181,7 +181,15 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>>
>>   switch (r_type)
>>     {
>>-#ifndef RTLD_BOOTSTRAP
>>+    case R_RISCV_RELATIVE:
>>+      *addr_field = map->l_addr + reloc->r_addend;
>>+      break;
>>+    case R_RISCV_JUMP_SLOT:
>>+    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>>+      *addr_field = value;
>>+      break;
>>+
>>+# ifndef RTLD_BOOTSTRAP
>>     case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
>>       if (sym_map)
>> 	*addr_field = sym_map->l_tls_modid;
>>@@ -232,13 +240,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>> 	memcpy (reloc_addr, (void *)value, size);
>> 	break;
>>       }
>>-#endif
>>-
>>-#if !defined RTLD_BOOTSTRAP
>>-    case R_RISCV_RELATIVE:
>>-      *addr_field = map->l_addr + reloc->r_addend;
>>-      break;
>>-#endif
>>
>>     case R_RISCV_IRELATIVE:
>>       value = map->l_addr + reloc->r_addend;
>>@@ -247,13 +248,9 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>>       *addr_field = value;
>>       break;
>>
>>-    case R_RISCV_JUMP_SLOT:
>>-    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>>-      *addr_field = value;
>>-      break;
>>-
>>     case R_RISCV_NONE:
>>       break;
>>+# endif /* !RTLD_BOOTSTRAP */
>>
>>     default:
>>       _dl_reloc_bad_type (map, r_type, 0);
>>--
>>2.36.1.255.ge46751e96f-goog

Hey, sorry I missed the pings.  This is really doing two things 
(dropping IRELATIVE and merging the ifdef) which makes it harder to read 
the diff than it could be.

IIUC this should work right now, but it also adds a dependency on 
RTDL_BOOTSTRAP having no IRELATIVE.  That should be fine as it is, 
because we don't have any IFUNCs in ld.so.  I'm not sure if it's ever 
sane to end up with those, but there's been some discussion around how 
that all fits together in that dynamic resolver patch/psABI issue.

If IFUNCs currently work in ld.so then I think we could call this an ABI 
break, but that's kind of a stretch as we could also say no binaries 
exist that have that behavior.  If they're currently broken then this 
seems fine, but if they're not then I'd err on the side of keeping the 
IRELATIVE case under RTLD_BOOTSTRAP as we can always remove it later.

That said,

Acked-by: Palmer Dabbelt <palmer@rivosinc.com>

in case someone wants to commit it and I drop the ball again.

Thanks!
Fangrui Song June 16, 2022, 12:31 a.m. UTC | #4
On 2022-06-15, Palmer Dabbelt wrote:
>On Wed, 15 Jun 2022 16:07:37 PDT (-0700), maskray@google.com wrote:
>>On 2022-06-05, Fangrui Song wrote:
>>>The RTLD_BOOTSTRAP branch is used to relocate ld.so itself.  It only
>>>needs to handle RELATIVE, GLOB_DAT, and the symbolic relocation type
>>>(R_RISCV_{32,64}).  NONE and IRELATIVE can be removed.
>>>
>>>The code relies on ld.so having DT_RELACOUNT so that the RTLD_BOOTSTRAP
>>>branch does not need handle RELATIVE.  Drop this minor size
>>>optimization for clarity.
>>>---
>>>sysdeps/riscv/dl-machine.h | 23 ++++++++++-------------
>>>1 file changed, 10 insertions(+), 13 deletions(-)
>>>
>>>diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
>>>index 9e026ae011..a60a452952 100644
>>>--- a/sysdeps/riscv/dl-machine.h
>>>+++ b/sysdeps/riscv/dl-machine.h
>>>@@ -181,7 +181,15 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>>>
>>>  switch (r_type)
>>>    {
>>>-#ifndef RTLD_BOOTSTRAP
>>>+    case R_RISCV_RELATIVE:
>>>+      *addr_field = map->l_addr + reloc->r_addend;
>>>+      break;
>>>+    case R_RISCV_JUMP_SLOT:
>>>+    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>>>+      *addr_field = value;
>>>+      break;
>>>+
>>>+# ifndef RTLD_BOOTSTRAP
>>>    case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
>>>      if (sym_map)
>>>	*addr_field = sym_map->l_tls_modid;
>>>@@ -232,13 +240,6 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>>>	memcpy (reloc_addr, (void *)value, size);
>>>	break;
>>>      }
>>>-#endif
>>>-
>>>-#if !defined RTLD_BOOTSTRAP
>>>-    case R_RISCV_RELATIVE:
>>>-      *addr_field = map->l_addr + reloc->r_addend;
>>>-      break;
>>>-#endif
>>>
>>>    case R_RISCV_IRELATIVE:
>>>      value = map->l_addr + reloc->r_addend;
>>>@@ -247,13 +248,9 @@ elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>>>      *addr_field = value;
>>>      break;
>>>
>>>-    case R_RISCV_JUMP_SLOT:
>>>-    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
>>>-      *addr_field = value;
>>>-      break;
>>>-
>>>    case R_RISCV_NONE:
>>>      break;
>>>+# endif /* !RTLD_BOOTSTRAP */
>>>
>>>    default:
>>>      _dl_reloc_bad_type (map, r_type, 0);
>>>--
>>>2.36.1.255.ge46751e96f-goog
>
>Hey, sorry I missed the pings.  This is really doing two things 
>(dropping IRELATIVE and merging the ifdef) which makes it harder to 
>read the diff than it could be.

No worries:)  Just tring to figure out what email addresses you prefer
nowadays.  I assume that your adjustment of the Cc: list has answered my
question.

>IIUC this should work right now, but it also adds a dependency on 
>RTDL_BOOTSTRAP having no IRELATIVE.  That should be fine as it is, 
>because we don't have any IFUNCs in ld.so.  I'm not sure if it's ever 
>sane to end up with those, but there's been some discussion around how 
>that all fits together in that dynamic resolver patch/psABI issue.

Right.  ld.so should not have IRELATIVE.
sysdeps/x86_64/dl-machine.h's RTDL_BOOTSTRAP code does not handle IRELATIVE.
I am fixing aarch64
(https://sourceware.org/pipermail/libc-alpha/2022-June/139425.html) and
riscv so that new ports (e.g. LoongArch) will not unnecessarily copy
them due to cargo culting
(https://sourceware.org/pipermail/libc-alpha/2022-June/139689.html)

An idea is that we may need a `readelf -rW` check that there are only
expected relocations.  I may try adding such a test.

Thanks!

>If IFUNCs currently work in ld.so then I think we could call this an 
>ABI break, but that's kind of a stretch as we could also say no 
>binaries exist that have that behavior.  If they're currently broken 
>then this seems fine, but if they're not then I'd err on the side of 
>keeping the IRELATIVE case under RTLD_BOOTSTRAP as we can always 
>remove it later.
>
>That said,
>
>Acked-by: Palmer Dabbelt <palmer@rivosinc.com>
>
>in case someone wants to commit it and I drop the ball again.
>
>Thanks!
diff mbox series

Patch

diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index 9e026ae011..a60a452952 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -181,7 +181,15 @@  elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 
   switch (r_type)
     {
-#ifndef RTLD_BOOTSTRAP
+    case R_RISCV_RELATIVE:
+      *addr_field = map->l_addr + reloc->r_addend;
+      break;
+    case R_RISCV_JUMP_SLOT:
+    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
+      *addr_field = value;
+      break;
+
+# ifndef RTLD_BOOTSTRAP
     case __WORDSIZE == 64 ? R_RISCV_TLS_DTPMOD64 : R_RISCV_TLS_DTPMOD32:
       if (sym_map)
 	*addr_field = sym_map->l_tls_modid;
@@ -232,13 +240,6 @@  elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 	memcpy (reloc_addr, (void *)value, size);
 	break;
       }
-#endif
-
-#if !defined RTLD_BOOTSTRAP
-    case R_RISCV_RELATIVE:
-      *addr_field = map->l_addr + reloc->r_addend;
-      break;
-#endif
 
     case R_RISCV_IRELATIVE:
       value = map->l_addr + reloc->r_addend;
@@ -247,13 +248,9 @@  elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
       *addr_field = value;
       break;
 
-    case R_RISCV_JUMP_SLOT:
-    case __WORDSIZE == 64 ? R_RISCV_64 : R_RISCV_32:
-      *addr_field = value;
-      break;
-
     case R_RISCV_NONE:
       break;
+# endif /* !RTLD_BOOTSTRAP */
 
     default:
       _dl_reloc_bad_type (map, r_type, 0);