diff mbox series

[v2] elf: Avoid nested functions in the loader (all ports) [BZ #27220]

Message ID 20210923071719.315444-1-maskray@google.com
State Superseded
Headers show
Series [v2] elf: Avoid nested functions in the loader (all ports) [BZ #27220] | expand

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

Fāng-ruì Sòng Sept. 23, 2021, 7:17 a.m. UTC
[Alternative to https://sourceware.org/pipermail/libc-alpha/2021-August/130340.html
This version fixes all ports and doesn't add NESTING dispatches.]
[Available at
https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest ]

dynamic-link.h is included more than once in some elf/ files (rtld.c,
dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested
functions. This harms readability and the nested functions usage
is the biggest obstacle prevents CC=clang (which doesn't support the
feature).

To un-nest elf_machine_rela, the key idea is to pass the variable in
the containing scope as extra arguments.
Stan Shebs implemented ppc64/x86-64 parts in the google/grte/v5-2.27/master
branch by using static variables.
This patch is inspired by that but takes an approach avoiding static variables.

Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu.
On x86_64, ld.so size does not change (.text is slightly larger, .rodata
is slightly smaller).
On aarch64, .text is 64 bytes larger but .rodata is 240 bytes smaller.
On ppc64le, both .text and .rodata are smaller.
I think the performance does not matter because most cycles are spent in symbol
lookup.

Tested build-many-glibcs.py compilers with
{alpha,arc,csky,hppa,ia64,microblaze,s390,s390x,sh,sparc64,sparcv9}-linux-gnu,
arm-linux-gnueabi{,hf}, mips64{,el}-linux-gnu{,-n32,-n64}, and
riscv64-linux-gnu-rv64imafdc-lp64d.
---
Changes from v1
* Remove global variables: cur_l, cur_scope, cur_strtab
---
 elf/dl-conflict.c                      | 39 ++++++++--------
 elf/dl-reloc-static-pie.c              | 14 +++---
 elf/dl-reloc.c                         | 57 +++++++++++------------
 elf/do-rel.h                           | 26 +++++------
 elf/dynamic-link.h                     | 63 ++++++++++++++------------
 elf/get-dynamic-info.h                 | 12 ++---
 elf/rtld.c                             | 12 ++---
 sysdeps/aarch64/dl-machine.h           | 28 ++++++++----
 sysdeps/alpha/dl-machine.h             | 20 +++++---
 sysdeps/arc/dl-machine.h               | 22 ++++++---
 sysdeps/arm/dl-machine.h               | 34 ++++++++------
 sysdeps/csky/dl-machine.h              | 23 ++++++----
 sysdeps/hppa/dl-machine.h              | 16 +++----
 sysdeps/i386/dl-machine.h              | 47 +++++++++++--------
 sysdeps/ia64/dl-machine.h              | 21 +++++----
 sysdeps/m68k/dl-machine.h              | 23 ++++++----
 sysdeps/microblaze/dl-machine.h        | 23 ++++++----
 sysdeps/mips/dl-machine.h              | 63 ++++++++++++++++----------
 sysdeps/nios2/dl-machine.h             | 25 ++++++----
 sysdeps/powerpc/powerpc32/dl-machine.h | 22 +++++----
 sysdeps/powerpc/powerpc64/dl-machine.h | 22 +++++----
 sysdeps/riscv/dl-machine.h             | 23 ++++++----
 sysdeps/s390/s390-32/dl-machine.h      | 19 ++++----
 sysdeps/s390/s390-64/dl-machine.h      | 19 ++++----
 sysdeps/sh/dl-machine.h                | 23 ++++++----
 sysdeps/sparc/sparc32/dl-machine.h     | 22 +++++----
 sysdeps/sparc/sparc64/dl-machine.h     | 22 +++++----
 sysdeps/x86_64/dl-machine.h            | 28 +++++++-----
 28 files changed, 451 insertions(+), 317 deletions(-)

Comments

Andreas Schwab Sept. 23, 2021, 8:07 a.m. UTC | #1
On Sep 23 2021, Fangrui Song via Libc-alpha wrote:

> diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
> index 4aa2058abf..00a27ba40c 100644
> --- a/elf/get-dynamic-info.h
> +++ b/elf/get-dynamic-info.h
> @@ -19,15 +19,12 @@
>  /* This file is included multiple times and therefore lacks a header
>     file inclusion guard.  */
>  
> +#ifndef _GET_DYNAMIC_INFO_H
> +
>  #include <assert.h>
>  #include <libc-diag.h>
>  
> -#ifndef RESOLVE_MAP
> -static
> -#else
> -auto
> -#endif
> -inline void __attribute__ ((unused, always_inline))
> +static inline void __attribute__ ((unused, always_inline))
>  elf_get_dynamic_info (struct link_map *l)
>  {
>  #if __ELF_NATIVE_CLASS == 32
> @@ -165,3 +162,6 @@ elf_get_dynamic_info (struct link_map *l)
>      info[DT_RPATH] = NULL;
>  #endif
>  }
> +
> +#define _GET_DYNAMIC_INFO_H
> +#endif

Please define the guard macro at the top.

Andreas.
Fāng-ruì Sòng Sept. 23, 2021, 8:17 a.m. UTC | #2
On 2021-09-23, Andreas Schwab wrote:
>On Sep 23 2021, Fangrui Song via Libc-alpha wrote:
>
>> diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
>> index 4aa2058abf..00a27ba40c 100644
>> --- a/elf/get-dynamic-info.h
>> +++ b/elf/get-dynamic-info.h
>> @@ -19,15 +19,12 @@
>>  /* This file is included multiple times and therefore lacks a header
>>     file inclusion guard.  */
>>
>> +#ifndef _GET_DYNAMIC_INFO_H
>> +
>>  #include <assert.h>
>>  #include <libc-diag.h>
>>
>> -#ifndef RESOLVE_MAP
>> -static
>> -#else
>> -auto
>> -#endif
>> -inline void __attribute__ ((unused, always_inline))
>> +static inline void __attribute__ ((unused, always_inline))
>>  elf_get_dynamic_info (struct link_map *l)
>>  {
>>  #if __ELF_NATIVE_CLASS == 32
>> @@ -165,3 +162,6 @@ elf_get_dynamic_info (struct link_map *l)
>>      info[DT_RPATH] = NULL;
>>  #endif
>>  }
>> +
>> +#define _GET_DYNAMIC_INFO_H
>> +#endif
>
>Please define the guard macro at the top.
>
>Andreas.

What do you mean by at the top?

rg '#ifndef _.*H' -g '*.h'

Most files have the guard macro after file-level comments.
Andreas Schwab Sept. 23, 2021, 8:39 a.m. UTC | #3
On Sep 23 2021, Fangrui Song wrote:

> What do you mean by at the top?

The opposite of bottom.

Andreas.
Zack Weinberg Sept. 23, 2021, 1:08 p.m. UTC | #4
On Thu, Sep 23, 2021, at 4:39 AM, Andreas Schwab wrote:
> On Sep 23 2021, Fangrui Song wrote:
>
>> What do you mean by at the top?
>
> The opposite of bottom.

In actually helpful terms, please put the #define for the guard macro immediately after the matching #ifndef. That’s how all the other headers do it.

zw
Fāng-ruì Sòng Sept. 23, 2021, 4:11 p.m. UTC | #5
On 2021-09-23, Zack Weinberg wrote:
>On Thu, Sep 23, 2021, at 4:39 AM, Andreas Schwab wrote:
>> On Sep 23 2021, Fangrui Song wrote:
>>
>>> What do you mean by at the top?
>>
>> The opposite of bottom.
>
>In actually helpful terms, please put the #define for the guard macro immediately after the matching #ifndef. That’s how all the other headers do it.
>
>zw

Thanks for the explanation.

I fixed it and took the opportunity to fix the file-level comment as
well.

Updated https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest
but do not bother sending v2 since this is a trivial change.
H.J. Lu Sept. 23, 2021, 4:19 p.m. UTC | #6
On Thu, Sep 23, 2021 at 12:23 AM Fangrui Song via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> [Alternative to https://sourceware.org/pipermail/libc-alpha/2021-August/130340.html
> This version fixes all ports and doesn't add NESTING dispatches.]
> [Available at
> https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest ]
>
> dynamic-link.h is included more than once in some elf/ files (rtld.c,
> dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested
> functions. This harms readability and the nested functions usage
> is the biggest obstacle prevents CC=clang (which doesn't support the
> feature).
>
> To un-nest elf_machine_rela, the key idea is to pass the variable in
> the containing scope as extra arguments.
> Stan Shebs implemented ppc64/x86-64 parts in the google/grte/v5-2.27/master
> branch by using static variables.
> This patch is inspired by that but takes an approach avoiding static variables.
>
> Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu.
> On x86_64, ld.so size does not change (.text is slightly larger, .rodata
> is slightly smaller).

Please disassemble and show what additional/changed instructions are.

> On aarch64, .text is 64 bytes larger but .rodata is 240 bytes smaller.
> On ppc64le, both .text and .rodata are smaller.
> I think the performance does not matter because most cycles are spent in symbol
> lookup.
>
> Tested build-many-glibcs.py compilers with
> {alpha,arc,csky,hppa,ia64,microblaze,s390,s390x,sh,sparc64,sparcv9}-linux-gnu,
> arm-linux-gnueabi{,hf}, mips64{,el}-linux-gnu{,-n32,-n64}, and
> riscv64-linux-gnu-rv64imafdc-lp64d.

H.J.
Fāng-ruì Sòng Sept. 23, 2021, 4:58 p.m. UTC | #7
On Thu, Sep 23, 2021 at 9:20 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Thu, Sep 23, 2021 at 12:23 AM Fangrui Song via Libc-alpha
> <libc-alpha@sourceware.org> wrote:
> >
> > [Alternative to https://sourceware.org/pipermail/libc-alpha/2021-August/130340.html
> > This version fixes all ports and doesn't add NESTING dispatches.]
> > [Available at
> > https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest ]
> >
> > dynamic-link.h is included more than once in some elf/ files (rtld.c,
> > dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested
> > functions. This harms readability and the nested functions usage
> > is the biggest obstacle prevents CC=clang (which doesn't support the
> > feature).
> >
> > To un-nest elf_machine_rela, the key idea is to pass the variable in
> > the containing scope as extra arguments.
> > Stan Shebs implemented ppc64/x86-64 parts in the google/grte/v5-2.27/master
> > branch by using static variables.
> > This patch is inspired by that but takes an approach avoiding static variables.
> >
> > Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu.
> > On x86_64, ld.so size does not change (.text is slightly larger, .rodata
> > is slightly smaller).
>
> Please disassemble and show what additional/changed instructions are.
>
> > On aarch64, .text is 64 bytes larger but .rodata is 240 bytes smaller.
> > On ppc64le, both .text and .rodata are smaller.
> > I think the performance does not matter because most cycles are spent in symbol
> > lookup.
> >
> > Tested build-many-glibcs.py compilers with
> > {alpha,arc,csky,hppa,ia64,microblaze,s390,s390x,sh,sparc64,sparcv9}-linux-gnu,
> > arm-linux-gnueabi{,hf}, mips64{,el}-linux-gnu{,-n32,-n64}, and
> > riscv64-linux-gnu-rv64imafdc-lp64d.
>
> H.J.

For elf/dl-reloc.os on x86-64, I think the nested function version can
use *(rbp - offset) to get some arguments.
The new version needs more instructions but the cost is small compared
with the expensive _dl_lookup_symbol_x.

+<L57>:
+                       mov     rax, qword ptr [r15 + 104]
+                       mov     edi, dword ptr [r14]
+                       mov     rcx, qword ptr [rax + 8]
+                       xor     eax, eax
+                       test    byte ptr [r15 + 798], 2
+                       je       <L58>
+                       mov     rax, qword ptr [r15]
 <L58>:
-                       mov     edi, dword ptr [r15]
                        push    0
-                       lea     rdx, [rbp - 120]
-                       mov     rsi, r14
+                       add     rdi, rcx
                        mov     rcx, qword ptr [rbp - 168]
-                       add     rdi, qword ptr [rbp - 176]
+                       lea     rdx, [rbp - 120]
                        push    9
-                       mov     qword ptr [rbp - 184], r10
+                       add     rdi, rax
+                       mov     rsi, r15
+                       mov     qword ptr [rbp - 176], r10
                        call     <L59>
-               0000000000000970:  R_X86_64_PLT32       _dl_lookup_symbol_x-0x4
+               0000000000000996:  R_X86_64_PLT32       _dl_lookup_symbol_x-0x4
 <L59>:

For aarch64, the nested function seems to need more setup after prologue

-                       ldr     x22, [x2, #8]
-                       tbz     w1, #1, 0x4d8 <_dl_relocate_object+0x230>
-                       ldr     x28, [x26]
-                       add     x1, x22, x28
-                       str     x1, [x29, #168]
-                       cbnz    w0, 0x125c <_dl_relocate_object+0xfb4>
+                       cbnz    w0, 0x4d0 <_dl_relocate_object+0x228>

the call site saving may be canceled, so in the end the .text size
does not change.

-                       ldp     x3, x1, [x29, #160]
+                       ldrb    w3, [x26, #846]
+                       mov     x2, #0
+                       ldr     x0, [x26, #104]
+                       ldr     w1, [x24]
+                       ldr     x0, [x0, #8]
+                       tbz     w3, #1, 0x8cc <_dl_relocate_object+0x624>
+                       ldr     x2, [x26]
+                       add     x0, x1, x0
+                       ldr     x3, [x29, #168]
+                       add     x0, x0, x2
+                       mov     x1, x26
                        add     x2, x29, #176
-                       ldr     w0, [x23]
                        mov     x7, #0
                        mov     w6, #9
-                       add     x0, x1, x0
-                       mov     x1, x25
-                       bl      0x8a4 <_dl_relocate_object+0x5fc>
-               00000000000008a4:  R_AARCH64_CALL26     _dl_lookup_symbol_x
+                       bl      0x8e8 <_dl_relocate_object+0x640>
+               00000000000008e8:  R_AARCH64_CALL26     _dl_lookup_symbol_x
Florian Weimer Sept. 23, 2021, 5:13 p.m. UTC | #8
* Fāng-ruì Sòng:

> For elf/dl-reloc.os on x86-64, I think the nested function version can
> use *(rbp - offset) to get some arguments.
> The new version needs more instructions but the cost is small compared
> with the expensive _dl_lookup_symbol_x.

I have a patch that reduces the number of _dl_lookup_symbol_x calls for
the self-relocation (bootstrap or not):

  [v3,3/3] elf: Rework exception handling in the dynamic loader [BZ #25486]
  <https://patchwork.sourceware.org/project/glibc/patch/05e1b5b43416eba58f2bab968320fa3d38e33479.1607085588.git.fweimer@redhat.com/>

It needs rebase on the current tree.

We recently lost the internal _r_debug reference, which is probably a
bug.  Other architectures have some other crud in ld.so.  But I think we
can get the number of symbols used in self-relocation down to zero on
all architectures fairly easily.

Once we do that, how much of the bootstrap relocation goo is really
left?

Thanks,
Florian
Fāng-ruì Sòng Sept. 23, 2021, 5:34 p.m. UTC | #9
On Thu, Sep 23, 2021 at 10:13 AM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Fāng-ruì Sòng:
>
> > For elf/dl-reloc.os on x86-64, I think the nested function version can
> > use *(rbp - offset) to get some arguments.
> > The new version needs more instructions but the cost is small compared
> > with the expensive _dl_lookup_symbol_x.
>
> I have a patch that reduces the number of _dl_lookup_symbol_x calls for
> the self-relocation (bootstrap or not):
>
>   [v3,3/3] elf: Rework exception handling in the dynamic loader [BZ #25486]
>   <https://patchwork.sourceware.org/project/glibc/patch/05e1b5b43416eba58f2bab968320fa3d38e33479.1607085588.git.fweimer@redhat.com/>
>
> It needs rebase on the current tree.
>
> We recently lost the internal _r_debug reference, which is probably a
> bug.  Other architectures have some other crud in ld.so.  But I think we
> can get the number of symbols used in self-relocation down to zero on
> all architectures fairly easily.
>
> Once we do that, how much of the bootstrap relocation goo is really
> left?
>
> Thanks,
> Florian
>

If self-relocations means relocations used in rtld.c and
elf/dl-reloc-static-pie.o:

The new version doesn't cause differences near _dl_lookup_symbol_x call sites.
I think the relocation code sequence doesn't change.

@@ -5757,7 +5789,7 @@
                        push    0
                        push    1
                        call     <L509>
-               0000000000004ec7:  R_X86_64_PLT32       _dl_lookup_symbol_x-0x4
+               0000000000004f27:  R_X86_64_PLT32       _dl_lookup_symbol_x-0x4
 <L509>:
                        pop     r8
                        pop     r9

The new rtld.os is slightly larger, but I guess that it is just
because GCC inlines one more place.
Florian Weimer Sept. 23, 2021, 5:40 p.m. UTC | #10
* Fāng-ruì Sòng:

> On Thu, Sep 23, 2021 at 10:13 AM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * Fāng-ruì Sòng:
>>
>> > For elf/dl-reloc.os on x86-64, I think the nested function version can
>> > use *(rbp - offset) to get some arguments.
>> > The new version needs more instructions but the cost is small compared
>> > with the expensive _dl_lookup_symbol_x.
>>
>> I have a patch that reduces the number of _dl_lookup_symbol_x calls for
>> the self-relocation (bootstrap or not):
>>
>>   [v3,3/3] elf: Rework exception handling in the dynamic loader [BZ #25486]
>>   <https://patchwork.sourceware.org/project/glibc/patch/05e1b5b43416eba58f2bab968320fa3d38e33479.1607085588.git.fweimer@redhat.com/>
>>
>> It needs rebase on the current tree.
>>
>> We recently lost the internal _r_debug reference, which is probably a
>> bug.  Other architectures have some other crud in ld.so.  But I think we
>> can get the number of symbols used in self-relocation down to zero on
>> all architectures fairly easily.
>>
>> Once we do that, how much of the bootstrap relocation goo is really
>> left?
>>
>> Thanks,
>> Florian
>>
>
> If self-relocations means relocations used in rtld.c and
> elf/dl-reloc-static-pie.o:
>
> The new version doesn't cause differences near _dl_lookup_symbol_x call sites.
> I think the relocation code sequence doesn't change.
>
> @@ -5757,7 +5789,7 @@
>                         push    0
>                         push    1
>                         call     <L509>
> -               0000000000004ec7:  R_X86_64_PLT32       _dl_lookup_symbol_x-0x4
> +               0000000000004f27:  R_X86_64_PLT32       _dl_lookup_symbol_x-0x4
>  <L509>:
>                         pop     r8
>                         pop     r9
>
> The new rtld.os is slightly larger, but I guess that it is just
> because GCC inlines one more place.

What I meant is that we can toss out a lot of the self-relocation code
once we *know* that we don't need to call _dl_lookup_symbol_x because no
relocations use symbols.

Thanks,
Florian
Fāng-ruì Sòng Sept. 23, 2021, 7:05 p.m. UTC | #11
On 2021-09-23, Fangrui Song wrote:
>[Alternative to https://sourceware.org/pipermail/libc-alpha/2021-August/130340.html
>This version fixes all ports and doesn't add NESTING dispatches.]
>[Available at
>https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest ]
>
>dynamic-link.h is included more than once in some elf/ files (rtld.c,
>dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested
>functions. This harms readability and the nested functions usage
>is the biggest obstacle prevents CC=clang (which doesn't support the
>feature).
>
>To un-nest elf_machine_rela, the key idea is to pass the variable in
>the containing scope as extra arguments.
>Stan Shebs implemented ppc64/x86-64 parts in the google/grte/v5-2.27/master
>branch by using static variables.
>This patch is inspired by that but takes an approach avoiding static variables.
>
>Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu.
>On x86_64, ld.so size does not change (.text is slightly larger, .rodata
>is slightly smaller).
>On aarch64, .text is 64 bytes larger but .rodata is 240 bytes smaller.
>On ppc64le, both .text and .rodata are smaller.
>I think the performance does not matter because most cycles are spent in symbol
>lookup.
>
>Tested build-many-glibcs.py compilers with
>{alpha,arc,csky,hppa,ia64,microblaze,s390,s390x,sh,sparc64,sparcv9}-linux-gnu,
>arm-linux-gnueabi{,hf}, mips64{,el}-linux-gnu{,-n32,-n64}, and
>riscv64-linux-gnu-rv64imafdc-lp64d.
>---
>Changes from v1
>* Remove global variables: cur_l, cur_scope, cur_strtab
>---
> elf/dl-conflict.c                      | 39 ++++++++--------
> elf/dl-reloc-static-pie.c              | 14 +++---
> elf/dl-reloc.c                         | 57 +++++++++++------------
> elf/do-rel.h                           | 26 +++++------
> elf/dynamic-link.h                     | 63 ++++++++++++++------------
> elf/get-dynamic-info.h                 | 12 ++---
> elf/rtld.c                             | 12 ++---
> sysdeps/aarch64/dl-machine.h           | 28 ++++++++----
> sysdeps/alpha/dl-machine.h             | 20 +++++---
> sysdeps/arc/dl-machine.h               | 22 ++++++---
> sysdeps/arm/dl-machine.h               | 34 ++++++++------
> sysdeps/csky/dl-machine.h              | 23 ++++++----
> sysdeps/hppa/dl-machine.h              | 16 +++----
> sysdeps/i386/dl-machine.h              | 47 +++++++++++--------
> sysdeps/ia64/dl-machine.h              | 21 +++++----
> sysdeps/m68k/dl-machine.h              | 23 ++++++----
> sysdeps/microblaze/dl-machine.h        | 23 ++++++----
> sysdeps/mips/dl-machine.h              | 63 ++++++++++++++++----------
> sysdeps/nios2/dl-machine.h             | 25 ++++++----
> sysdeps/powerpc/powerpc32/dl-machine.h | 22 +++++----
> sysdeps/powerpc/powerpc64/dl-machine.h | 22 +++++----
> sysdeps/riscv/dl-machine.h             | 23 ++++++----
> sysdeps/s390/s390-32/dl-machine.h      | 19 ++++----
> sysdeps/s390/s390-64/dl-machine.h      | 19 ++++----
> sysdeps/sh/dl-machine.h                | 23 ++++++----
> sysdeps/sparc/sparc32/dl-machine.h     | 22 +++++----
> sysdeps/sparc/sparc64/dl-machine.h     | 22 +++++----
> sysdeps/x86_64/dl-machine.h            | 28 +++++++-----
> 28 files changed, 451 insertions(+), 317 deletions(-)



>
>diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
>index 64fa5793d2..f0b2e75dd9 100644
>--- a/elf/dl-conflict.c
>+++ b/elf/dl-conflict.c
>@@ -26,20 +26,12 @@
> #include <sys/types.h>
> #include "dynamic-link.h"
>
>-void
>-_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
>-		       ElfW(Rela) *conflictend)
>-{
>-#if ! ELF_MACHINE_NO_RELA
>-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
>-    _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
>-
>-  {
>-    /* Do the conflict relocation of the object and library GOT and other
>-       data.  */
>+/* Used by RESOLVE_CONFLICT_FIND_MAP at init time. Cannot be accessed
>+ * concurrently.  */
>+static struct link_map *resolve_conflict_map __attribute__ ((__unused__));
>
>     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
>-#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
>+#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL)
> #define RESOLVE(ref, version, flags) (*ref = NULL, 0)
> #define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
>   do {									      \
>@@ -50,12 +42,23 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
>     (map) = resolve_conflict_map;					      \
>   } while (0)
>
>+#include "dynamic-link.h"
>+
>+void
>+_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
>+		       ElfW(Rela) *conflictend)
>+{
>+#if ! ELF_MACHINE_NO_RELA
>+  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
>+    _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
>+
>+  {
>+    /* Do the conflict relocation of the object and library GOT and other
>+       data.  */
>+
>     /* Prelinking makes no sense for anything but the main namespace.  */
>     assert (l->l_ns == LM_ID_BASE);
>-    struct link_map *resolve_conflict_map __attribute__ ((__unused__))
>-      = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
>-
>-#include "dynamic-link.h"
>+    resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
>
>     /* Override these, defined in dynamic-link.h.  */
> #undef CHECK_STATIC_TLS
>@@ -66,8 +69,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
>     GL(dl_num_cache_relocations) += conflictend - conflict;
>
>     for (; conflict < conflictend; ++conflict)
>-      elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
>-			0);
>+      elf_machine_rela (l, NULL, conflict, NULL, NULL,
>+			(void *) conflict->r_offset, 0, NULL);
>   }
> #endif
> }
>diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
>index 68ded176cd..ab864b33b1 100644
>--- a/elf/dl-reloc-static-pie.c
>+++ b/elf/dl-reloc-static-pie.c
>@@ -19,8 +19,15 @@
> #if ENABLE_STATIC_PIE
> /* Mark symbols hidden in static PIE for early self relocation to work.  */
> # pragma GCC visibility push(hidden)
>+#include <assert.h>
> #include <unistd.h>
> #include <ldsodefs.h>
>+
>+#include <dl-machine.h>
>+
>+#define STATIC_PIE_BOOTSTRAP
>+#define BOOTSTRAP_MAP (main_map)
>+#define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
> #include "dynamic-link.h"
>
> /* Relocate static executable with PIE.  */
>@@ -30,11 +37,6 @@ _dl_relocate_static_pie (void)
> {
>   struct link_map *main_map = _dl_get_dl_main_map ();
>
>-# define STATIC_PIE_BOOTSTRAP
>-# define BOOTSTRAP_MAP (main_map)
>-# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
>-# include "dynamic-link.h"
>-
>   /* Figure out the run-time load address of static PIE.  */
>   main_map->l_addr = elf_machine_load_address ();
>
>@@ -58,7 +60,7 @@ _dl_relocate_static_pie (void)
>
>   /* Relocate ourselves so we can do normal function calls and
>      data access using the global offset table.  */
>-  ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
>+  ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0, main_map);
>   main_map->l_relocated = 1;
>
>   /* Initialize _r_debug_extended.  */
>diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
>index 6c957456b8..c1b0569992 100644
>--- a/elf/dl-reloc.c
>+++ b/elf/dl-reloc.c
>@@ -162,6 +162,32 @@ _dl_nothread_init_static_tls (struct link_map *map)
> }
> #endif /* !PTHREAD_IN_LIBC */
>
>+/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
>+#define RESOLVE_MAP(l, scope, ref, version, r_type)			      \
>+    ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
>+      && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref)))	      \
>+     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
>+	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
>+	? (bump_num_cache_relocations (),				      \
>+	   (*ref) = l->l_lookup_cache.ret,				      \
>+	   l->l_lookup_cache.value)					      \
>+	: ({ lookup_t _lr;						      \
>+	     int _tc = elf_machine_type_class (r_type);			      \
>+	     l->l_lookup_cache.type_class = _tc;			      \
>+	     l->l_lookup_cache.sym = (*ref);				      \
>+	     const struct r_found_version *v = NULL;			      \
>+	     if ((version) != NULL && (version)->hash != 0)		      \
>+	       v = (version);						      \
>+	     _lr = _dl_lookup_symbol_x ((const char *) D_PTR (l, l_info[DT_STRTAB]) + (*ref)->st_name, \
>+					l, (ref), scope, v, _tc,	      \
>+					DL_LOOKUP_ADD_DEPENDENCY	      \
>+					| DL_LOOKUP_FOR_RELOCATE, NULL);      \
>+	     l->l_lookup_cache.ret = (*ref);				      \
>+	     l->l_lookup_cache.value = _lr; }))				      \
>+     : l)
>+
>+#include "dynamic-link.h"
>+
> void
> _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
> 		     int reloc_mode, int consider_profiling)
>@@ -243,36 +269,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
>   {
>     /* Do the actual relocation of the object's GOT and other data.  */
>
>-    /* String table object symbols.  */
>-    const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
>-
>-    /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
>-#define RESOLVE_MAP(ref, version, r_type) \
>-    ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
>-      && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref)))	      \
>-     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
>-	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
>-	? (bump_num_cache_relocations (),				      \
>-	   (*ref) = l->l_lookup_cache.ret,				      \
>-	   l->l_lookup_cache.value)					      \
>-	: ({ lookup_t _lr;						      \
>-	     int _tc = elf_machine_type_class (r_type);			      \
>-	     l->l_lookup_cache.type_class = _tc;			      \
>-	     l->l_lookup_cache.sym = (*ref);				      \
>-	     const struct r_found_version *v = NULL;			      \
>-	     if ((version) != NULL && (version)->hash != 0)		      \
>-	       v = (version);						      \
>-	     _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref),   \
>-					scope, v, _tc,			      \
>-					DL_LOOKUP_ADD_DEPENDENCY	      \
>-					| DL_LOOKUP_FOR_RELOCATE, NULL);      \
>-	     l->l_lookup_cache.ret = (*ref);				      \
>-	     l->l_lookup_cache.value = _lr; }))				      \
>-     : l)
>-
>-#include "dynamic-link.h"
>-
>-    ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
>+    ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc, NULL);
>
> #ifndef PROF
>     if (__glibc_unlikely (consider_profiling)
>diff --git a/elf/do-rel.h b/elf/do-rel.h
>index 321ac2b359..187f64c9d2 100644
>--- a/elf/do-rel.h
>+++ b/elf/do-rel.h
>@@ -37,11 +37,11 @@
>    relocations; they should be set up to call _dl_runtime_resolve, rather
>    than fully resolved now.  */
>
>-auto inline void __attribute__ ((always_inline))
>-elf_dynamic_do_Rel (struct link_map *map,
>+static inline void __attribute__ ((always_inline))
>+elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
> 		    ElfW(Addr) reladdr, ElfW(Addr) relsize,
> 		    __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
>-		    int lazy, int skip_ifunc)
>+		    int lazy, int skip_ifunc, struct link_map *boot_map)
> {
>   const ElfW(Rel) *r = (const void *) reladdr;
>   const ElfW(Rel) *end = (const void *) (reladdr + relsize);
>@@ -68,13 +68,13 @@ elf_dynamic_do_Rel (struct link_map *map,
> 	  }
> 	else
> # endif
>-	  elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
>+	  elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc);
>
> # ifdef ELF_MACHINE_IRELATIVE
>       if (r2 != NULL)
> 	for (; r2 <= end2; ++r2)
> 	  if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
>-	    elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc);
>+	    elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc);
> # endif
>     }
>   else
>@@ -134,9 +134,9 @@ elf_dynamic_do_Rel (struct link_map *map,
> #endif
>
> 	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
>-	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
>+	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
> 			       &map->l_versions[ndx],
>-			       (void *) (l_addr + r->r_offset), skip_ifunc);
>+			       (void *) (l_addr + r->r_offset), skip_ifunc, boot_map);
> 	    }
>
> #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
>@@ -146,11 +146,11 @@ elf_dynamic_do_Rel (struct link_map *map,
> 		{
> 		  ElfW(Half) ndx
> 		    = version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
>-		  elf_machine_rel (map, r2,
>+		  elf_machine_rel (map, scope, r2,
> 				   &symtab[ELFW(R_SYM) (r2->r_info)],
> 				   &map->l_versions[ndx],
> 				   (void *) (l_addr + r2->r_offset),
>-				   skip_ifunc);
>+				   skip_ifunc, boot_map);
> 		}
> #endif
> 	}
>@@ -167,16 +167,16 @@ elf_dynamic_do_Rel (struct link_map *map,
> 	      }
> 	    else
> # endif
>-	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
>-			       (void *) (l_addr + r->r_offset), skip_ifunc);
>+	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
>+			       (void *) (l_addr + r->r_offset), skip_ifunc, boot_map);
>
> # ifdef ELF_MACHINE_IRELATIVE
> 	  if (r2 != NULL)
> 	    for (; r2 <= end2; ++r2)
> 	      if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
>-		elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
>+		elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
> 				 NULL, (void *) (l_addr + r2->r_offset),
>-				 skip_ifunc);
>+				 skip_ifunc, boot_map);
> # endif
> 	}
> #endif
>diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
>index 3eb24ba3a6..6b2f4fd129 100644
>--- a/elf/dynamic-link.h
>+++ b/elf/dynamic-link.h
>@@ -59,31 +59,34 @@ int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
>    copying memory, breaking the very code written to handle the
>    unaligned cases.  */
> # if ! ELF_MACHINE_NO_REL
>-auto inline void __attribute__((always_inline))
>-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
>-		 const ElfW(Sym) *sym, const struct r_found_version *version,
>-		 void *const reloc_addr, int skip_ifunc);
>-auto inline void __attribute__((always_inline))
>+static inline void __attribute__((always_inline))
>+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
>+		 const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
>+		 const struct r_found_version *version,
>+		 void *const reloc_addr, int skip_ifunc,
>+		 struct link_map *boot_map);
>+static inline void __attribute__((always_inline))
> elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
> 			  void *const reloc_addr);
> # endif
> # if ! ELF_MACHINE_NO_RELA
>-auto inline void __attribute__((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>-		  const ElfW(Sym) *sym, const struct r_found_version *version,
>-		  void *const reloc_addr, int skip_ifunc);
>-auto inline void __attribute__((always_inline))
>-elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>-			   void *const reloc_addr);
>+static inline void __attribute__((always_inline))
>+elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
>+		 const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
>+		 const struct r_found_version *version, void *const reloc_addr,
>+		 int skip_ifunc, struct link_map *boot_map);
>+static inline void __attribute__((always_inline))
>+elf_machine_rela_relative(ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>+	                  void *const reloc_addr);
> # endif
> # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
>-auto inline void __attribute__((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__((always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
> 		      int skip_ifunc);
> # else
>-auto inline void __attribute__((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__((always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
> 		      int skip_ifunc);
> # endif
>@@ -114,7 +117,7 @@ elf_machine_lazy_rel (struct link_map *map,
>    consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
>    are completely separate and there is a gap between them.  */
>
>-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
>+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel, boot_map) \
>   do {									      \
>     struct { ElfW(Addr) start, size;					      \
> 	     __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; }  \
>@@ -152,18 +155,18 @@ elf_machine_lazy_rel (struct link_map *map,
>       }									      \
> 									      \
>     if (ELF_DURING_STARTUP)						      \
>-      elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size,	      \
>-			      ranges[0].nrelative, 0, skip_ifunc);	      \
>+      elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size,  \
>+			      ranges[0].nrelative, 0, skip_ifunc, boot_map);  \
>     else								      \
>       {									      \
> 	int ranges_index;						      \
> 	for (ranges_index = 0; ranges_index < 2; ++ranges_index)	      \
>-	  elf_dynamic_do_##reloc ((map),				      \
>+	  elf_dynamic_do_##reloc ((map), scope,				      \
> 				  ranges[ranges_index].start,		      \
> 				  ranges[ranges_index].size,		      \
> 				  ranges[ranges_index].nrelative,	      \
> 				  ranges[ranges_index].lazy,		      \
>-				  skip_ifunc);				      \
>+				  skip_ifunc, boot_map);		      \
>       }									      \
>   } while (0)
>
>@@ -175,29 +178,29 @@ elf_machine_lazy_rel (struct link_map *map,
>
> # if ! ELF_MACHINE_NO_REL
> #  include "do-rel.h"
>-#  define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
>-  _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
>+#  define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc, boot_map)	      \
>+  _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
> # else
>-#  define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do.  */
>+#  define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc, boot_map) /* Nothing to do.  */
> # endif
>
> # if ! ELF_MACHINE_NO_RELA
> #  define DO_RELA
> #  include "do-rel.h"
>-#  define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
>-  _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
>+#  define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc, boot_map)	      \
>+  _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
> # else
>-#  define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do.  */
>+#  define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc, boot_map) /* Nothing to do.  */
> # endif
>
> /* This can't just be an inline function because GCC is too dumb
>    to inline functions containing inlines themselves.  */
>-# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \
>+# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc, boot_map) \
>   do {									      \
>     int edr_lazy = elf_machine_runtime_setup ((map), (lazy),		      \
> 					      (consider_profile));	      \
>-    ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc);			      \
>-    ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc);			      \
>+    ELF_DYNAMIC_DO_REL ((map), scope, edr_lazy, skip_ifunc, boot_map);	      \
>+    ELF_DYNAMIC_DO_RELA ((map), scope, edr_lazy, skip_ifunc, boot_map);	      \
>   } while (0)
>
> #endif
>diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
>index 4aa2058abf..00a27ba40c 100644
>--- a/elf/get-dynamic-info.h
>+++ b/elf/get-dynamic-info.h
>@@ -19,15 +19,12 @@
> /* This file is included multiple times and therefore lacks a header
>    file inclusion guard.  */
>
>+#ifndef _GET_DYNAMIC_INFO_H
>+
> #include <assert.h>
> #include <libc-diag.h>
>
>-#ifndef RESOLVE_MAP
>-static
>-#else
>-auto
>-#endif
>-inline void __attribute__ ((unused, always_inline))
>+static inline void __attribute__ ((unused, always_inline))
> elf_get_dynamic_info (struct link_map *l)
> {
> #if __ELF_NATIVE_CLASS == 32
>@@ -165,3 +162,6 @@ elf_get_dynamic_info (struct link_map *l)
>     info[DT_RPATH] = NULL;
> #endif
> }
>+
>+#define _GET_DYNAMIC_INFO_H
>+#endif
>diff --git a/elf/rtld.c b/elf/rtld.c
>index 8d2bba3d43..43b5b990fc 100644
>--- a/elf/rtld.c
>+++ b/elf/rtld.c
>@@ -500,13 +500,9 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
>   return start_addr;
> }
>
>-static ElfW(Addr) __attribute_used__
>-_dl_start (void *arg)
>-{
> #ifdef DONT_USE_BOOTSTRAP_MAP
> # define bootstrap_map GL(dl_rtld_map)
> #else
>-  struct dl_start_final_info info;
> # define bootstrap_map info.l
> #endif
>
>@@ -516,12 +512,16 @@ _dl_start (void *arg)
>      is trivial: always the map of ld.so itself.  */
> #define RTLD_BOOTSTRAP
> #define BOOTSTRAP_MAP (&bootstrap_map)
>-#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
>+#define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
> #include "dynamic-link.h"
>
>+static ElfW(Addr) __attribute_used__
>+_dl_start (void *arg)
>+{
> #ifdef DONT_USE_BOOTSTRAP_MAP
>   rtld_timer_start (&start_time);
> #else
>+  struct dl_start_final_info info;
>   rtld_timer_start (&info.start_time);
> #endif
>
>@@ -562,7 +562,7 @@ _dl_start (void *arg)
>       /* Relocate ourselves so we can do normal function calls and
> 	 data access using the global offset table.  */
>
>-      ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
>+      ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0, &bootstrap_map);
>     }
>   bootstrap_map.l_relocated = 1;
>
>diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
>index 3e10cb462f..30d6dfa56d 100644
>--- a/sysdeps/aarch64/dl-machine.h
>+++ b/sysdeps/aarch64/dl-machine.h
>@@ -237,11 +237,13 @@ elf_machine_plt_value (struct link_map *map,
>
> #ifdef RESOLVE_MAP
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>-		  const ElfW(Sym) *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
>@@ -253,7 +255,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>   else
>     {
>       const ElfW(Sym) *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -377,9 +384,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      ElfW(Addr) l_addr,
> 		      const ElfW(Rela) *reloc,
> 		      int skip_ifunc)
>@@ -406,8 +413,8 @@ elf_machine_lazy_rel (struct link_map *map,
> 		    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
> 		  version = &map->l_versions[vernum[symndx] & 0x7fff];
> 		}
>-	      elf_machine_rela (map, reloc, sym, version, reloc_addr,
>-				skip_ifunc);
>+	      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
>+				skip_ifunc, NULL);
> 	      return;
> 	    }
> 	}
>@@ -433,7 +440,8 @@ elf_machine_lazy_rel (struct link_map *map,
>
>       /* Always initialize TLS descriptors completely, because lazy
> 	 initialization requires synchronization at every TLS access.  */
>-      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
>+      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
>+			skip_ifunc, NULL);
>     }
>   else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE)))
>     {
>diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
>index 9e327b7f17..8d64bdd278 100644
>--- a/sysdeps/alpha/dl-machine.h
>+++ b/sysdeps/alpha/dl-machine.h
>@@ -360,14 +360,15 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
>
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map,
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> 		  const Elf64_Rela *reloc,
> 		  const Elf64_Sym *sym,
> 		  const struct r_found_version *version,
> 		  void *const reloc_addr_arg,
>-		  int skip_ifunc)
>+		  int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf64_Addr *const reloc_addr = reloc_addr_arg;
>   unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info);
>@@ -410,7 +411,12 @@ elf_machine_rela (struct link_map *map,
>       return;
>   else
>     {
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       Elf64_Addr sym_value;
>       Elf64_Addr sym_raw_value;
>
>@@ -488,7 +494,7 @@ elf_machine_rela (struct link_map *map,
>    can be skipped.  */
> #define ELF_MACHINE_REL_RELATIVE 1
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -505,9 +511,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
>   memcpy (reloc_addr_arg, &reloc_addr_val, 8);
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h
>index e6ce7f0ff6..d5f737c198 100644
>--- a/sysdeps/arc/dl-machine.h
>+++ b/sysdeps/arc/dl-machine.h
>@@ -228,11 +228,13 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
>
> #ifdef RESOLVE_MAP
>
>-inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>-                  const ElfW(Sym) *sym, const struct r_found_version *version,
>-                  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
>+		  const struct r_found_version *version,
>+                  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   ElfW(Addr) r_info = reloc->r_info;
>   const unsigned long int r_type = ELFW (R_TYPE) (r_info);
>@@ -245,7 +247,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>   else
>     {
>       const ElfW(Sym) *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       switch (r_type)
>@@ -326,8 +333,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>
> inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
>-                      const ElfW(Rela) *reloc, int skip_ifunc)
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
>+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>+		      int skip_ifunc)
> {
>   ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
>   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
>diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
>index eb13cb8b57..1dc65c5c52 100644
>--- a/sysdeps/arm/dl-machine.h
>+++ b/sysdeps/arm/dl-machine.h
>@@ -276,7 +276,7 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
>
> #ifdef RESOLVE_MAP
> /* Handle a PC24 reloc, including the out-of-range case.  */
>-auto void
>+static void
> relocate_pc24 (struct link_map *map, Elf32_Addr value,
>                Elf32_Addr *const reloc_addr, Elf32_Sword addend)
> {
>@@ -330,11 +330,11 @@ relocate_pc24 (struct link_map *map, Elf32_Addr value,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
>+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], const Elf32_Rel *reloc,
> 		 const Elf32_Sym *sym, const struct r_found_version *version,
>-		 void *const reloc_addr_arg, int skip_ifunc)
>+		 void *const reloc_addr_arg, int skip_ifunc, struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -364,7 +364,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
> #endif
>     {
>       const Elf32_Sym *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -508,11 +513,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
> }
>
> # ifndef RTLD_BOOTSTRAP
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const Elf32_Rela *reloc,
> 		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+		  void *const reloc_addr_arg, int skip_ifunc, struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -526,7 +531,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
> # ifndef RESOLVE_CONFLICT_FIND_MAP
>       const Elf32_Sym *const refsym = sym;
> # endif
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -601,7 +606,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
> }
> # endif
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
> 			  void *const reloc_addr_arg)
>@@ -611,7 +616,7 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
> }
>
> # ifndef RTLD_BOOTSTRAP
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -621,9 +626,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> }
> # endif
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
> 		      int skip_ifunc)
> {
>@@ -653,7 +658,8 @@ elf_machine_lazy_rel (struct link_map *map,
>
>       /* Always initialize TLS descriptors completely, because lazy
> 	 initialization requires synchronization at every TLS access.  */
>-      elf_machine_rel (map, reloc, sym, version, reloc_addr, skip_ifunc);
>+      elf_machine_rel (map, scope, reloc, sym, version, reloc_addr, skip_ifunc,
>+		       NULL);
>     }
>   else
>     _dl_reloc_bad_type (map, r_type, 1);
>diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h
>index b08f06d74c..8147e314bb 100644
>--- a/sysdeps/csky/dl-machine.h
>+++ b/sysdeps/csky/dl-machine.h
>@@ -215,10 +215,12 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void __attribute__ ((unused, always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+static inline void __attribute__ ((unused, always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -230,7 +232,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>   else
>     {
>       const Elf32_Sym *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
>       opcode16_addr = (unsigned short *)reloc_addr;
>
>@@ -331,7 +338,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void __attribute__ ((unused, always_inline))
>+static inline void __attribute__ ((unused, always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
> {
>@@ -339,8 +346,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void __attribute__ ((unused, always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__ ((unused, always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
>index ded9c193d6..84ffda2db2 100644
>--- a/sysdeps/hppa/dl-machine.h
>+++ b/sysdeps/hppa/dl-machine.h
>@@ -548,13 +548,13 @@ dl_platform_init (void)
>   (  (((as14) & 0x1fff) << 1) \
>    | (((as14) & 0x2000) >> 13))
>
>-auto void __attribute__((always_inline))
>-elf_machine_rela (struct link_map *map,
>+static void __attribute__((always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> 		  const Elf32_Rela *reloc,
> 		  const Elf32_Sym *sym,
> 		  const struct r_found_version *version,
> 		  void *const reloc_addr_arg,
>-		  int skip_ifunc)
>+		  int skip_ifunc, struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const Elf32_Sym *const refsym = sym;
>@@ -580,9 +580,9 @@ elf_machine_rela (struct link_map *map,
> # ifdef RTLD_BOOTSTRAP
>   /* RESOLVE_MAP in rtld.c doesn't have the local sym test.  */
>   sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL
>-	     ? RESOLVE_MAP (&sym, version, r_type) : map);
>+	     ? boot_map : map);
> # else
>-  sym_map = RESOLVE_MAP (&sym, version, r_type);
>+  sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
> # endif
>
>   if (sym_map)
>@@ -740,7 +740,7 @@ elf_machine_rela (struct link_map *map,
>
> /* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with
>    ELF32_R_SYM (info) == 0 for a similar purpose.  */
>-auto void __attribute__((always_inline))
>+static void __attribute__((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr,
> 			   const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -793,8 +793,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr,
>   *reloc_addr = value;
> }
>
>-auto void __attribute__((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static void __attribute__((always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
>index 590b41d8d7..891d005f41 100644
>--- a/sysdeps/i386/dl-machine.h
>+++ b/sysdeps/i386/dl-machine.h
>@@ -291,11 +291,13 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute ((always_inline))
>-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
>+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
>+		 const Elf32_Rel *reloc,
> 		 const Elf32_Sym *sym, const struct r_found_version *version,
>-		 void *const reloc_addr_arg, int skip_ifunc)
>+		 void *const reloc_addr_arg, int skip_ifunc,
>+		 struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -327,7 +329,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
> # ifndef RTLD_BOOTSTRAP
>       const Elf32_Sym *const refsym = sym;
> # endif
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -498,11 +501,13 @@ and creates an unsatisfiable circular dependency.\n",
> }
>
> # ifndef RTLD_BOOTSTRAP
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -514,7 +519,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
> #  ifndef RESOLVE_CONFLICT_FIND_MAP
>       const Elf32_Sym *const refsym = sym;
> #  endif
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -647,7 +653,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
> }
> # endif	/* !RTLD_BOOTSTRAP */
>
>-auto inline void
>+static inline void
> __attribute ((always_inline))
> elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
> 			  void *const reloc_addr_arg)
>@@ -658,7 +664,7 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
> }
>
> # ifndef RTLD_BOOTSTRAP
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -668,9 +674,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> }
> # endif	/* !RTLD_BOOTSTRAP */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
> 		      int skip_ifunc)
> {
>@@ -705,14 +711,14 @@ elf_machine_lazy_rel (struct link_map *map,
> 	  const ElfW(Half) *const version =
> 	    (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
> 	  ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
>-	  elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
>+	  elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
> 			   &map->l_versions[ndx],
>-			   (void *) (l_addr + r->r_offset), skip_ifunc);
>+			   (void *) (l_addr + r->r_offset), skip_ifunc, NULL);
> 	}
> # ifndef RTLD_BOOTSTRAP
>       else
>-	elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
>-			 (void *) (l_addr + r->r_offset), skip_ifunc);
>+	elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
>+			 (void *) (l_addr + r->r_offset), skip_ifunc, NULL);
> # endif
>     }
>   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
>@@ -728,9 +734,9 @@ elf_machine_lazy_rel (struct link_map *map,
>
> # ifndef RTLD_BOOTSTRAP
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rela (struct link_map *map,
>+elf_machine_lazy_rela (struct link_map *map, struct r_scope_elem *scope[],
> 		       Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		       int skip_ifunc)
> {
>@@ -754,7 +760,8 @@ elf_machine_lazy_rela (struct link_map *map,
>
>       /* Always initialize TLS descriptors completely at load time, in
> 	 case static TLS is allocated for it that requires locking.  */
>-      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
>+      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
>+			skip_ifunc, NULL);
>     }
>   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
>     {
>diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
>index 4403e7767a..afefe083d9 100644
>--- a/sysdeps/ia64/dl-machine.h
>+++ b/sysdeps/ia64/dl-machine.h
>@@ -371,14 +371,14 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
>
> /* Perform the relocation specified by RELOC and SYM (which is fully
>    resolved).  MAP is the object containing the reloc.  */
>-auto inline void
>+static inline void
> __attribute ((always_inline))
>-elf_machine_rela (struct link_map *map,
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> 		  const Elf64_Rela *reloc,
> 		  const Elf64_Sym *sym,
> 		  const struct r_found_version *version,
> 		  void *const reloc_addr_arg,
>-		  int skip_ifunc)
>+		  int skip_ifunc, struct link_map *boot_map)
> {
>   Elf64_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
>@@ -414,10 +414,15 @@ elf_machine_rela (struct link_map *map,
>       return;
>   else
>     {
>-      struct link_map *sym_map;
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>
>       /* RESOLVE_MAP() will return NULL if it fail to locate the symbol.  */
>-      if ((sym_map = RESOLVE_MAP (&sym, version, r_type)))
>+      if (sym_map != NULL)
> 	{
> 	  value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
>
>@@ -476,7 +481,7 @@ elf_machine_rela (struct link_map *map,
>    can be skipped.  */
> #define ELF_MACHINE_REL_RELATIVE 1
>
>-auto inline void
>+static inline void
> __attribute ((always_inline))
> elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -489,9 +494,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> }
>
> /* Perform a RELATIVE reloc on the .got entry that transfers to the .plt.  */
>-auto inline void
>+static inline void
> __attribute ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
>index 86a8c67e2a..43cb8d5a7b 100644
>--- a/sysdeps/m68k/dl-machine.h
>+++ b/sysdeps/m68k/dl-machine.h
>@@ -215,10 +215,12 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void __attribute__ ((unused, always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+static inline void __attribute__ ((unused, always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -228,7 +230,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>   else
>     {
>       const Elf32_Sym *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       switch (r_type)
>@@ -303,7 +310,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void __attribute__ ((unused, always_inline))
>+static inline void __attribute__ ((unused, always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
> {
>@@ -311,8 +318,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void __attribute__ ((unused, always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__ ((unused, always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
>index e460f6f195..5c37244291 100644
>--- a/sysdeps/microblaze/dl-machine.h
>+++ b/sysdeps/microblaze/dl-machine.h
>@@ -207,10 +207,12 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
>     ((unsigned short *)(rel_addr))[3] = (val) & 0xffff; \
>   } while (0)
>
>-auto inline void __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+static inline void __attribute__ ((always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -222,7 +224,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>   else
>     {
>       const Elf32_Sym *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       value += reloc->r_addend;
>@@ -277,7 +284,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
> {
>@@ -285,8 +292,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
>   PUT_REL_64 (reloc_addr, l_addr + reloc->r_addend);
> }
>
>-auto inline void
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
>index b74d427d64..afc43009d6 100644
>--- a/sysdeps/mips/dl-machine.h
>+++ b/sysdeps/mips/dl-machine.h
>@@ -474,11 +474,13 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc,
>    by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
>-		   const ElfW(Sym) *sym, const struct r_found_version *version,
>-		   void *reloc_addr, ElfW(Addr) r_addend, int inplace_p)
>+elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
>+		   ElfW(Addr) r_info, const ElfW(Sym) *sym,
>+		   const struct r_found_version *version, void *reloc_addr,
>+		   ElfW(Addr) r_addend, int inplace_p,
>+		   struct link_map *boot_map)
> {
>   const unsigned long int r_type = ELFW(R_TYPE) (r_info);
>   ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
>@@ -506,7 +508,12 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
>     case R_MIPS_TLS_TPREL32:
> # endif
>       {
>-	struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>
> 	switch (r_type)
> 	  {
>@@ -646,7 +653,11 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
> 	  _dl_signal_error (0, map->l_name, NULL,
> 			    "found jump slot relocation with non-zero addend");
>
>-	sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+        sym_map = boot_map;
>+#else
>+        sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>+#endif
> 	value = SYMBOL_ADDRESS (sym_map, sym, true);
> 	*addr_field = value;
>
>@@ -660,7 +671,11 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
> 	ElfW(Addr) value;
>
> 	/* Calculate the address of the symbol.  */
>-	sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+        sym_map = boot_map;
>+#else
>+        sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>+#endif
> 	value = SYMBOL_ADDRESS (sym_map, sym, true);
>
> 	if (__builtin_expect (sym == NULL, 0))
>@@ -707,16 +722,18 @@ elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
>-		 const ElfW(Sym) *sym, const struct r_found_version *version,
>-		 void *const reloc_addr, int skip_ifunc)
>+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
>+		 const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
>+		 const struct r_found_version *version, void *const reloc_addr,
>+		 int skip_ifunc, struct link_map *boot_map)
> {
>-  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1);
>+  elf_machine_reloc (map, scope, reloc->r_info, sym, version, reloc_addr, 0, 1,
>+		     boot_map);
> }
>
>-auto inline void
>+static inline void
> __attribute__((always_inline))
> elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
> 			  void *const reloc_addr)
>@@ -724,9 +741,9 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
>   /* XXX Nothing to do.  There is no relative relocation, right?  */
> }
>
>-auto inline void
>+static inline void
> __attribute__((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
> 		      int skip_ifunc)
> {
>@@ -747,17 +764,17 @@ elf_machine_lazy_rel (struct link_map *map,
>     _dl_reloc_bad_type (map, r_type, 1);
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const ElfW(Rela) *reloc,
> 		  const ElfW(Sym) *sym, const struct r_found_version *version,
>-		  void *const reloc_addr, int skip_ifunc)
>+		  void *const reloc_addr, int skip_ifunc, struct link_map *boot_map)
> {
>-  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr,
>-		     reloc->r_addend, 0);
>+  elf_machine_reloc (map, scope, reloc->r_info, sym, version, reloc_addr,
>+		     reloc->r_addend, 0, boot_map);
> }
>
>-auto inline void
>+static inline void
> __attribute__((always_inline))
> elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
> 			   void *const reloc_addr)
>@@ -766,7 +783,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>
> #ifndef RTLD_BOOTSTRAP
> /* Relocate GOT. */
>-auto inline void
>+static inline void
> __attribute__((always_inline))
> elf_machine_got_rel (struct link_map *map, int lazy)
> {
>@@ -867,7 +884,7 @@ elf_machine_got_rel (struct link_map *map, int lazy)
> /* Set up the loaded object described by L so its stub function
>    will jump to the on-demand fixup code __dl_runtime_resolve.  */
>
>-auto inline int
>+static inline int
> __attribute__((always_inline))
> elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
> {
>diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
>index e000cd081f..1e399980ea 100644
>--- a/sysdeps/nios2/dl-machine.h
>+++ b/sysdeps/nios2/dl-machine.h
>@@ -234,10 +234,12 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
>    LOADADDR is the load address of the object; INFO is an array indexed
>    by DT_* of the .dynamic section info.  */
>
>-auto inline void __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>-                  const ElfW(Sym) *sym, const struct r_found_version *version,
>-                  void *const reloc_addr_arg, int skip_ifunc)
>+static inline void __attribute__ ((always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -249,7 +251,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>   else
>     {
>       const Elf32_Sym *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       switch (r_type)
>@@ -314,7 +321,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>     }
> }
>
>-auto inline void __attribute__((always_inline))
>+static inline void __attribute__((always_inline))
> elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
> 			   void *const reloc_addr_arg)
> {
>@@ -322,10 +329,10 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void __attribute__((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__((always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>-		      int skip_ifunc)
>+		      int skip_ifunc, struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
>   if (ELF32_R_TYPE (reloc->r_info) == R_NIOS2_JUMP_SLOT)
>diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
>index ced3a7b659..3c80f5d9ca 100644
>--- a/sysdeps/powerpc/powerpc32/dl-machine.h
>+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
>@@ -286,10 +286,12 @@ extern void _dl_reloc_overflow (struct link_map *map,
>    LOADADDR is the load address of the object; INFO is an array indexed
>    by DT_* of the .dynamic section info.  */
>
>-auto inline void __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+static inline void __attribute__ ((always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const Elf32_Sym *const refsym = sym;
>@@ -317,7 +319,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
>   else
>     {
>-      sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      sym_map = boot_map;
>+#else
>+      sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>+#endif
>       value = SYMBOL_ADDRESS (sym_map, sym, true);
>     }
>   value += reloc->r_addend;
>@@ -441,7 +447,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void __attribute__ ((always_inline))
>+static inline void __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
> {
>@@ -449,8 +455,8 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__ ((always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
>index b90f407119..c1a7368603 100644
>--- a/sysdeps/powerpc/powerpc64/dl-machine.h
>+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
>@@ -620,7 +620,7 @@ extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
> 						 Elf64_Addr *const reloc_addr,
> 						 const Elf64_Sym *refsym);
>
>-auto inline void __attribute__ ((always_inline))
>+static inline void __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 			   void *const reloc_addr_arg)
> {
>@@ -629,7 +629,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> }
>
> /* This computes the value used by TPREL* relocs.  */
>-auto inline Elf64_Addr __attribute__ ((always_inline, const))
>+static inline Elf64_Addr __attribute__ ((always_inline, const))
> elf_machine_tprel (struct link_map *map,
> 		   struct link_map *sym_map,
> 		   const Elf64_Sym *sym,
>@@ -648,7 +648,7 @@ elf_machine_tprel (struct link_map *map,
> }
>
> /* Call function at address VALUE (an OPD entry) to resolve ifunc relocs.  */
>-auto inline Elf64_Addr __attribute__ ((always_inline))
>+static inline Elf64_Addr __attribute__ ((always_inline))
> resolve_ifunc (Elf64_Addr value,
> 	       const struct link_map *map, const struct link_map *sym_map)
> {
>@@ -678,13 +678,13 @@ resolve_ifunc (Elf64_Addr value,
>
> /* Perform the relocation specified by RELOC and SYM (which is fully
>    resolved).  MAP is the object containing the reloc.  */
>-auto inline void __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map,
>+static inline void __attribute__ ((always_inline))
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
> 		  const Elf64_Rela *reloc,
> 		  const Elf64_Sym *sym,
> 		  const struct r_found_version *version,
> 		  void *const reloc_addr_arg,
>-		  int skip_ifunc)
>+		  int skip_ifunc, struct link_map *boot_map)
> {
>   Elf64_Addr *const reloc_addr = reloc_addr_arg;
>   const int r_type = ELF64_R_TYPE (reloc->r_info);
>@@ -707,7 +707,11 @@ elf_machine_rela (struct link_map *map,
>
>   /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
>      and STT_GNU_IFUNC.  */
>-  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+  struct link_map *sym_map = boot_map;
>+#else
>+  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>+#endif
>   Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
>
>   if (sym != NULL
>@@ -1037,8 +1041,8 @@ elf_machine_rela (struct link_map *map,
>   MODIFIED_CODE_NOQUEUE (reloc_addr);
> }
>
>-auto inline void __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+static inline void __attribute__ ((always_inline))
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
>index 5b0746175c..5e8d7e17b0 100644
>--- a/sysdeps/riscv/dl-machine.h
>+++ b/sysdeps/riscv/dl-machine.h
>@@ -161,17 +161,19 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
>    by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>-		  const ElfW(Sym) *sym, const struct r_found_version *version,
>-		  void *const reloc_addr, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   ElfW(Addr) r_info = reloc->r_info;
>   const unsigned long int r_type = ELFW (R_TYPE) (r_info);
>   ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
>   const ElfW(Sym) *const __attribute__ ((unused)) refsym = sym;
>-  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>   ElfW(Addr) value = 0;
>   if (sym_map != NULL)
>     value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
>@@ -279,7 +281,7 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
> 			  void *const reloc_addr)
>@@ -287,10 +289,11 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>   *(ElfW(Addr) *) reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
>-		      const ElfW(Rela) *reloc, int skip_ifunc)
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
>+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>+		      int skip_ifunc)
> {
>   ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
>   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
>@@ -320,7 +323,7 @@ elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
> /* Set up the loaded object described by L so its stub function
>    will jump to the on-demand fixup code __dl_runtime_resolve.  */
>
>-auto inline int
>+static inline int
> __attribute__ ((always_inline))
> elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
> {
>diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
>index 73cc007e34..56760bb47d 100644
>--- a/sysdeps/s390/s390-32/dl-machine.h
>+++ b/sysdeps/s390/s390-32/dl-machine.h
>@@ -320,11 +320,13 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -356,7 +358,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>       /* Only needed for R_390_COPY below.  */
>       const Elf32_Sym *const refsym = sym;
> #endif
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -483,7 +486,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -492,9 +495,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
>index aa9d524bac..c34187e055 100644
>--- a/sysdeps/s390/s390-64/dl-machine.h
>+++ b/sysdeps/s390/s390-64/dl-machine.h
>@@ -267,11 +267,13 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
>-		  const Elf64_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf64_Rela *reloc, const Elf64_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf64_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
>@@ -303,7 +305,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
>       /* Only needed for R_390_COPY below.  */
>       const Elf64_Sym *const refsym = sym;
> #endif
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>       Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -437,7 +440,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -446,9 +449,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
>index 122b417a17..981ef1f538 100644
>--- a/sysdeps/sh/dl-machine.h
>+++ b/sysdeps/sh/dl-machine.h
>@@ -259,11 +259,13 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
>   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
>@@ -318,7 +320,12 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>   else
>     {
>       const Elf32_Sym *const refsym = sym;
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>
>       value = SYMBOL_ADDRESS (sym_map, sym, true);
>       value += reloc->r_addend;
>@@ -424,7 +431,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -443,9 +450,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> #undef COPY_UNALIGNED_WORD
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
>index 0269e458ea..3b7e069944 100644
>--- a/sysdeps/sparc/sparc32/dl-machine.h
>+++ b/sysdeps/sparc/sparc32/dl-machine.h
>@@ -327,11 +327,13 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>-		  const Elf32_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf32_Addr *const reloc_addr = reloc_addr_arg;
> #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
>@@ -381,7 +383,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
>   else
>     {
>-      sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      sym_map = boot_map;
>+#else
>+      sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>+#endif
>       value = SYMBOL_ADDRESS (sym_map, sym, true);
>     }
> #else
>@@ -536,7 +542,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -545,9 +551,9 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
>   *reloc_addr += l_addr + reloc->r_addend;
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
>index bbd4566d8a..0fa2682aec 100644
>--- a/sysdeps/sparc/sparc64/dl-machine.h
>+++ b/sysdeps/sparc/sparc64/dl-machine.h
>@@ -354,11 +354,13 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
>-		  const Elf64_Sym *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
>+		  const Elf64_Rela *reloc, const Elf64_Sym *sym,
>+		  const struct r_found_version *version,
>+		  void *const reloc_addr_arg, int skip_ifunc,
>+		  struct link_map *boot_map)
> {
>   Elf64_Addr *const reloc_addr = reloc_addr_arg;
> #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
>@@ -408,7 +410,11 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
>     }
>   else
>     {
>-      sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      sym_map = boot_map;
>+#else
>+      sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
>+#endif
>       value = SYMBOL_ADDRESS (sym_map, sym, true);
>     }
> #else
>@@ -646,7 +652,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
> elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 			   void *const reloc_addr_arg)
>@@ -655,9 +661,9 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
>   *reloc_addr = l_addr + reloc->r_addend;
> }
>
>-auto inline void
>+static inline void
> __attribute__ ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
> 		      int skip_ifunc)
> {
>diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
>index b3ed4dd467..0e893972f8 100644
>--- a/sysdeps/x86_64/dl-machine.h
>+++ b/sysdeps/x86_64/dl-machine.h
>@@ -250,12 +250,12 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
> /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
>    MAP is the object containing the reloc.  */
>
>-auto inline void
>-__attribute__ ((always_inline))
>-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>-		  const ElfW(Sym) *sym, const struct r_found_version *version,
>-		  void *const reloc_addr_arg, int skip_ifunc)
>-{
>+static inline void __attribute__((always_inline))
>+elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
>+		 const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
>+		 const struct r_found_version *version,
>+		 void *const reloc_addr_arg, int skip_ifunc,
>+		 struct link_map *boot_map) {
>   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
>   const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
>
>@@ -292,7 +292,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
> # ifndef RTLD_BOOTSTRAP
>       const ElfW(Sym) *const refsym = sym;
> # endif
>-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
>+      struct link_map *sym_map = boot_map;
>+#else
>+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>+					      r_type);
>+#endif
>       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
>
>       if (sym != NULL
>@@ -517,7 +522,7 @@ and creates an unsatisfiable circular dependency.\n",
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute ((always_inline))
> elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
> 			   void *const reloc_addr_arg)
>@@ -536,9 +541,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
>     }
> }
>
>-auto inline void
>+static inline void
> __attribute ((always_inline))
>-elf_machine_lazy_rel (struct link_map *map,
>+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
> 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
> 		      int skip_ifunc)
> {
>@@ -572,7 +577,8 @@ elf_machine_lazy_rel (struct link_map *map,
>
>       /* Always initialize TLS descriptors completely at load time, in
> 	 case static TLS is allocated for it that requires locking.  */
>-      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
>+      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc,
>+                        NULL);
>     }
>   else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
>     {
>-- 
>2.33.0.685.g46640cef36-goog

I made some simplification to
https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest

Now for a port, only the arguments of RESOLVE_MAP and the signatures of
elf_machine_rela_relative/elf_machine_lazy_rel need changes.
There is no more extra #ifdef STATIC_PIE_BOOTSTRAP
https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=sysdeps/x86_64/dl-machine.h;h=7cfdaa97989b6a2a079514a5be79928ff7b4777b;hp=b3ed4dd4673a89c33d5021535c0385c591c396f8;hb=d77904c92ff9a2e89e240aceffecadcfd8d240a4;hpb=b3f27d8150d4f3c64063a9a257ec1d228de66398


The existing sysdeps/hppa/dl-machine.h link map usage looks suspicious
but I cannot do runtime test on hppa.
Florian Weimer Sept. 23, 2021, 9:48 p.m. UTC | #12
* Fangrui Song:

> I made some simplification to
> https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest
>
> Now for a port, only the arguments of RESOLVE_MAP and the signatures of
> elf_machine_rela_relative/elf_machine_lazy_rel need changes.
> There is no more extra #ifdef STATIC_PIE_BOOTSTRAP
> https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=sysdeps/x86_64/dl-machine.h;h=7cfdaa97989b6a2a079514a5be79928ff7b4777b;hp=b3ed4dd4673a89c33d5021535c0385c591c396f8;hb=d77904c92ff9a2e89e240aceffecadcfd8d240a4;hpb=b3f27d8150d4f3c64063a9a257ec1d228de66398

This actually looks really reasonable in terms of invasiveness.  I
thought that we had to clean up loader self-relocation before we tackle
this, but if we only need a patch along these lines, we might not need
to wait for that before removing the nested functions.  I have not
reviewed the patch in detail and won't probably come to it for quite
some time, but the project looks a lot less scary now.

Thanks,
Florian
Fāng-ruì Sòng Sept. 23, 2021, 10:41 p.m. UTC | #13
On Thu, Sep 23, 2021 at 2:48 PM Florian Weimer <fweimer@redhat.com> wrote:
>
> * Fangrui Song:
>
> > I made some simplification to
> > https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest
> >
> > Now for a port, only the arguments of RESOLVE_MAP and the signatures of
> > elf_machine_rela_relative/elf_machine_lazy_rel need changes.
> > There is no more extra #ifdef STATIC_PIE_BOOTSTRAP
> > https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=sysdeps/x86_64/dl-machine.h;h=7cfdaa97989b6a2a079514a5be79928ff7b4777b;hp=b3ed4dd4673a89c33d5021535c0385c591c396f8;hb=d77904c92ff9a2e89e240aceffecadcfd8d240a4;hpb=b3f27d8150d4f3c64063a9a257ec1d228de66398
>
> This actually looks really reasonable in terms of invasiveness.  I
> thought that we had to clean up loader self-relocation before we tackle
> this, but if we only need a patch along these lines, we might not need
> to wait for that before removing the nested functions.

Thanks:)

> I have not
> reviewed the patch in detail and won't probably come to it for quite
> some time, but the project looks a lot less scary now.

Ugh😹 Isn't the patch in a ready-to-push state now ?

---

Looks like hppa-linux-gnu may be broken in master:

% (cd /tmp/glibc-many/src/glibc/; git checkout master)
% cd ~/Dev/glibc
% scripts/build-many-glibcs.py /tmp/glibc-many compilers hppa-linux-gnu
...
% /tmp/glibc-many/install/compilers/hppa-linux-gnu/sysroot/lib/ld.so.1
  # using qemu-hppa-static 6.1.0
Inconsistency detected by ld.so: rtld.c: 1593: dl_main: Assertion
`GL(dl_rtld_map).l_libname' failed!
Florian Weimer Sept. 24, 2021, 5:58 a.m. UTC | #14
* Fāng-ruì Sòng:

>> I have not
>> reviewed the patch in detail and won't probably come to it for quite
>> some time, but the project looks a lot less scary now.
>
> Ugh😹 Isn't the patch in a ready-to-push state now ?

It does not build on some !PI_STATIC_AND_HIDDEN targets.  The error
looks like this on those that I have checked:

../sysdeps/m68k/dl-machine.h: In function ‘elf_machine_rela’:
rtld.c:506:24: error: ‘info’ undeclared (first use in this function); did you mean ‘dlinfo’?
  506 | # define bootstrap_map info.l
      |                        ^~~~
rtld.c:514:25: note: in expansion of macro ‘bootstrap_map’
  514 | #define BOOTSTRAP_MAP (&bootstrap_map)
      |                         ^~~~~~~~~~~~~
rtld.c:515:54: note: in expansion of macro ‘BOOTSTRAP_MAP’
  515 | #define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
      |                                                      ^~~~~~~~~~~~~
../sysdeps/m68k/dl-machine.h:232:34: note: in expansion of macro ‘RESOLVE_MAP’
  232 |       struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
      |                                  ^~~~~~~~~~~
rtld.c:506:24: note: each undeclared identifier is reported only once for each function it appears in
  506 | # define bootstrap_map info.l
      |                        ^~~~
rtld.c:514:25: note: in expansion of macro ‘bootstrap_map’
  514 | #define BOOTSTRAP_MAP (&bootstrap_map)
      |                         ^~~~~~~~~~~~~
rtld.c:515:54: note: in expansion of macro ‘BOOTSTRAP_MAP’
  515 | #define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
      |                                                      ^~~~~~~~~~~~~
../sysdeps/m68k/dl-machine.h:232:34: note: in expansion of macro ‘RESOLVE_MAP’
  232 |       struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
      |                                  ^~~~~~~~~~~

mipsel-linux-gnu has a different error:

In file included from dynamic-link.h:94,
                 from dl-reloc.c:189:
../sysdeps/mips/dl-machine.h: In function ‘elf_machine_got_rel’:
../sysdeps/mips/dl-machine.h:840:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
  840 |                 *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
      |        ^        ~~~~~~~
dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
      | 
In file included from dynamic-link.h:94,
                 from dl-reloc.c:189:
../sysdeps/mips/dl-machine.h:791:17: error: ‘RESOLVE_MAP’ undeclared (first use in this function)
  791 |       sym_map = RESOLVE_MAP (&ref, version, reloc);                       \
      |                 ^~~~~~~~~~~
../sysdeps/mips/dl-machine.h:840:24: note: in expansion of macro ‘RESOLVE_GOTSYM’
  840 |                 *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
      |                        ^~~~~~~~~~~~~~
../sysdeps/mips/dl-machine.h:791:17: note: each undeclared identifier is reported only once for each function it appears in
  791 |       sym_map = RESOLVE_MAP (&ref, version, reloc);                       \
      |                 ^~~~~~~~~~~
../sysdeps/mips/dl-machine.h:840:24: note: in expansion of macro ‘RESOLVE_GOTSYM’
  840 |                 *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
      |                        ^~~~~~~~~~~~~~
../sysdeps/mips/dl-machine.h:843:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
  843 |             *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
      |        ^    ~~~~
dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
      | 
In file included from dynamic-link.h:94,
                 from dl-reloc.c:189:
../sysdeps/mips/dl-machine.h:846:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
  846 |         *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
      |        ^~~~~~~~~
dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
      | 
In file included from dynamic-link.h:94,
                 from dl-reloc.c:189:
../sysdeps/mips/dl-machine.h:855:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
  855 |             *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
      |        ^    ~~~~
dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
      | 
In file included from dynamic-link.h:94,
                 from dl-reloc.c:189:
../sysdeps/mips/dl-machine.h:863:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
  863 |         *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
      |        ^~~~~~~~~
dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
      | 

> ---
>
> Looks like hppa-linux-gnu may be broken in master:
>
> % (cd /tmp/glibc-many/src/glibc/; git checkout master)
> % cd ~/Dev/glibc
> % scripts/build-many-glibcs.py /tmp/glibc-many compilers hppa-linux-gnu
> ...
> % /tmp/glibc-many/install/compilers/hppa-linux-gnu/sysroot/lib/ld.so.1
>   # using qemu-hppa-static 6.1.0
> Inconsistency detected by ld.so: rtld.c: 1593: dl_main: Assertion
> `GL(dl_rtld_map).l_libname' failed!

I'm going to look into that.

Thanks,
Florian
Florian Weimer Sept. 24, 2021, 7:23 a.m. UTC | #15
* Florian Weimer:

>> Looks like hppa-linux-gnu may be broken in master:
>>
>> % (cd /tmp/glibc-many/src/glibc/; git checkout master)
>> % cd ~/Dev/glibc
>> % scripts/build-many-glibcs.py /tmp/glibc-many compilers hppa-linux-gnu
>> ...
>> % /tmp/glibc-many/install/compilers/hppa-linux-gnu/sysroot/lib/ld.so.1
>>   # using qemu-hppa-static 6.1.0
>> Inconsistency detected by ld.so: rtld.c: 1593: dl_main: Assertion
>> `GL(dl_rtld_map).l_libname' failed!
>
> I'm going to look into that.

It appears to be a qemu-static-user bug.  It does not happen natively.
I don't really know how to investigate this further, sorry.

Thanks,
Florian
Fāng-ruì Sòng Sept. 24, 2021, 7:32 a.m. UTC | #16
On 2021-09-24, Florian Weimer wrote:
>* Fāng-ruì Sòng:
>
>>> I have not
>>> reviewed the patch in detail and won't probably come to it for quite
>>> some time, but the project looks a lot less scary now.
>>
>> Ugh😹 Isn't the patch in a ready-to-push state now ?
>
>It does not build on some !PI_STATIC_AND_HIDDEN targets.  The error
>looks like this on those that I have checked:
>
>../sysdeps/m68k/dl-machine.h: In function ‘elf_machine_rela’:
>rtld.c:506:24: error: ‘info’ undeclared (first use in this function); did you mean ‘dlinfo’?
>  506 | # define bootstrap_map info.l
>      |                        ^~~~
>rtld.c:514:25: note: in expansion of macro ‘bootstrap_map’
>  514 | #define BOOTSTRAP_MAP (&bootstrap_map)
>      |                         ^~~~~~~~~~~~~
>rtld.c:515:54: note: in expansion of macro ‘BOOTSTRAP_MAP’
>  515 | #define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
>      |                                                      ^~~~~~~~~~~~~
>../sysdeps/m68k/dl-machine.h:232:34: note: in expansion of macro ‘RESOLVE_MAP’
>  232 |       struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>      |                                  ^~~~~~~~~~~
>rtld.c:506:24: note: each undeclared identifier is reported only once for each function it appears in
>  506 | # define bootstrap_map info.l
>      |                        ^~~~
>rtld.c:514:25: note: in expansion of macro ‘bootstrap_map’
>  514 | #define BOOTSTRAP_MAP (&bootstrap_map)
>      |                         ^~~~~~~~~~~~~
>rtld.c:515:54: note: in expansion of macro ‘BOOTSTRAP_MAP’
>  515 | #define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
>      |                                                      ^~~~~~~~~~~~~
>../sysdeps/m68k/dl-machine.h:232:34: note: in expansion of macro ‘RESOLVE_MAP’
>  232 |       struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
>      |                                  ^~~~~~~~~~~
>
>mipsel-linux-gnu has a different error:
>
>In file included from dynamic-link.h:94,
>                 from dl-reloc.c:189:
>../sysdeps/mips/dl-machine.h: In function ‘elf_machine_got_rel’:
>../sysdeps/mips/dl-machine.h:840:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
>  840 |                 *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
>      |        ^        ~~~~~~~
>dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
>  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
>      |
>In file included from dynamic-link.h:94,
>                 from dl-reloc.c:189:
>../sysdeps/mips/dl-machine.h:791:17: error: ‘RESOLVE_MAP’ undeclared (first use in this function)
>  791 |       sym_map = RESOLVE_MAP (&ref, version, reloc);                       \
>      |                 ^~~~~~~~~~~
>../sysdeps/mips/dl-machine.h:840:24: note: in expansion of macro ‘RESOLVE_GOTSYM’
>  840 |                 *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
>      |                        ^~~~~~~~~~~~~~
>../sysdeps/mips/dl-machine.h:791:17: note: each undeclared identifier is reported only once for each function it appears in
>  791 |       sym_map = RESOLVE_MAP (&ref, version, reloc);                       \
>      |                 ^~~~~~~~~~~
>../sysdeps/mips/dl-machine.h:840:24: note: in expansion of macro ‘RESOLVE_GOTSYM’
>  840 |                 *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
>      |                        ^~~~~~~~~~~~~~
>../sysdeps/mips/dl-machine.h:843:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
>  843 |             *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
>      |        ^    ~~~~
>dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
>  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
>      |
>In file included from dynamic-link.h:94,
>                 from dl-reloc.c:189:
>../sysdeps/mips/dl-machine.h:846:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
>  846 |         *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
>      |        ^~~~~~~~~
>dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
>  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
>      |
>In file included from dynamic-link.h:94,
>                 from dl-reloc.c:189:
>../sysdeps/mips/dl-machine.h:855:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
>  855 |             *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_JUMP_SLOT);
>      |        ^    ~~~~
>dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
>  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
>      |
>In file included from dynamic-link.h:94,
>                 from dl-reloc.c:189:
>../sysdeps/mips/dl-machine.h:863:8: error: macro "RESOLVE_MAP" requires 5 arguments, but only 3 given
>  863 |         *got = RESOLVE_GOTSYM (sym, vernum, symidx, R_MIPS_32);
>      |        ^~~~~~~~~
>dl-reloc.c:166: note: macro "RESOLVE_MAP" defined here
>  166 | #define RESOLVE_MAP(l, scope, ref, version, r_type)                           \
>      |

Adding the bootstrap_map parameter to ELF_MACHINE_BEFORE_RTLD_RELOC ?

I pushed a commit to https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest

It is unfortunate that elf_machine_runtime_setup now needs the `scope`
parameter as well.


>> ---
>>
>> Looks like hppa-linux-gnu may be broken in master:
>>
>> % (cd /tmp/glibc-many/src/glibc/; git checkout master)
>> % cd ~/Dev/glibc
>> % scripts/build-many-glibcs.py /tmp/glibc-many compilers hppa-linux-gnu
>> ...
>> % /tmp/glibc-many/install/compilers/hppa-linux-gnu/sysroot/lib/ld.so.1
>>   # using qemu-hppa-static 6.1.0
>> Inconsistency detected by ld.so: rtld.c: 1593: dl_main: Assertion
>> `GL(dl_rtld_map).l_libname' failed!
>
>I'm going to look into that.
>
>Thanks,
>Florian
>
Florian Weimer Sept. 24, 2021, 8:27 a.m. UTC | #17
* Fāng-ruì Sòng:

> Adding the bootstrap_map parameter to ELF_MACHINE_BEFORE_RTLD_RELOC ?
>
> I pushed a commit to https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest

This fixes all the build failures, thanks.

Florian
diff mbox series

Patch

diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
index 64fa5793d2..f0b2e75dd9 100644
--- a/elf/dl-conflict.c
+++ b/elf/dl-conflict.c
@@ -26,20 +26,12 @@ 
 #include <sys/types.h>
 #include "dynamic-link.h"
 
-void
-_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
-		       ElfW(Rela) *conflictend)
-{
-#if ! ELF_MACHINE_NO_RELA
-  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
-    _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
-
-  {
-    /* Do the conflict relocation of the object and library GOT and other
-       data.  */
+/* Used by RESOLVE_CONFLICT_FIND_MAP at init time. Cannot be accessed
+ * concurrently.  */
+static struct link_map *resolve_conflict_map __attribute__ ((__unused__));
 
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
-#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
+#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL)
 #define RESOLVE(ref, version, flags) (*ref = NULL, 0)
 #define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
   do {									      \
@@ -50,12 +42,23 @@  _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
     (map) = resolve_conflict_map;					      \
   } while (0)
 
+#include "dynamic-link.h"
+
+void
+_dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
+		       ElfW(Rela) *conflictend)
+{
+#if ! ELF_MACHINE_NO_RELA
+  if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
+    _dl_debug_printf ("\nconflict processing: %s\n", DSO_FILENAME (l->l_name));
+
+  {
+    /* Do the conflict relocation of the object and library GOT and other
+       data.  */
+
     /* Prelinking makes no sense for anything but the main namespace.  */
     assert (l->l_ns == LM_ID_BASE);
-    struct link_map *resolve_conflict_map __attribute__ ((__unused__))
-      = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
-
-#include "dynamic-link.h"
+    resolve_conflict_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
     /* Override these, defined in dynamic-link.h.  */
 #undef CHECK_STATIC_TLS
@@ -66,8 +69,8 @@  _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
     GL(dl_num_cache_relocations) += conflictend - conflict;
 
     for (; conflict < conflictend; ++conflict)
-      elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset,
-			0);
+      elf_machine_rela (l, NULL, conflict, NULL, NULL,
+			(void *) conflict->r_offset, 0, NULL);
   }
 #endif
 }
diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
index 68ded176cd..ab864b33b1 100644
--- a/elf/dl-reloc-static-pie.c
+++ b/elf/dl-reloc-static-pie.c
@@ -19,8 +19,15 @@ 
 #if ENABLE_STATIC_PIE
 /* Mark symbols hidden in static PIE for early self relocation to work.  */
 # pragma GCC visibility push(hidden)
+#include <assert.h>
 #include <unistd.h>
 #include <ldsodefs.h>
+
+#include <dl-machine.h>
+
+#define STATIC_PIE_BOOTSTRAP
+#define BOOTSTRAP_MAP (main_map)
+#define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
 #include "dynamic-link.h"
 
 /* Relocate static executable with PIE.  */
@@ -30,11 +37,6 @@  _dl_relocate_static_pie (void)
 {
   struct link_map *main_map = _dl_get_dl_main_map ();
 
-# define STATIC_PIE_BOOTSTRAP
-# define BOOTSTRAP_MAP (main_map)
-# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
-# include "dynamic-link.h"
-
   /* Figure out the run-time load address of static PIE.  */
   main_map->l_addr = elf_machine_load_address ();
 
@@ -58,7 +60,7 @@  _dl_relocate_static_pie (void)
 
   /* Relocate ourselves so we can do normal function calls and
      data access using the global offset table.  */
-  ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
+  ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0, main_map);
   main_map->l_relocated = 1;
 
   /* Initialize _r_debug_extended.  */
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index 6c957456b8..c1b0569992 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -162,6 +162,32 @@  _dl_nothread_init_static_tls (struct link_map *map)
 }
 #endif /* !PTHREAD_IN_LIBC */
 
+/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
+#define RESOLVE_MAP(l, scope, ref, version, r_type)			      \
+    ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
+      && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref)))	      \
+     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
+	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
+	? (bump_num_cache_relocations (),				      \
+	   (*ref) = l->l_lookup_cache.ret,				      \
+	   l->l_lookup_cache.value)					      \
+	: ({ lookup_t _lr;						      \
+	     int _tc = elf_machine_type_class (r_type);			      \
+	     l->l_lookup_cache.type_class = _tc;			      \
+	     l->l_lookup_cache.sym = (*ref);				      \
+	     const struct r_found_version *v = NULL;			      \
+	     if ((version) != NULL && (version)->hash != 0)		      \
+	       v = (version);						      \
+	     _lr = _dl_lookup_symbol_x ((const char *) D_PTR (l, l_info[DT_STRTAB]) + (*ref)->st_name, \
+					l, (ref), scope, v, _tc,	      \
+					DL_LOOKUP_ADD_DEPENDENCY	      \
+					| DL_LOOKUP_FOR_RELOCATE, NULL);      \
+	     l->l_lookup_cache.ret = (*ref);				      \
+	     l->l_lookup_cache.value = _lr; }))				      \
+     : l)
+
+#include "dynamic-link.h"
+
 void
 _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 		     int reloc_mode, int consider_profiling)
@@ -243,36 +269,7 @@  _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
   {
     /* Do the actual relocation of the object's GOT and other data.  */
 
-    /* String table object symbols.  */
-    const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
-
-    /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
-#define RESOLVE_MAP(ref, version, r_type) \
-    ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \
-      && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref)))	      \
-     ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \
-	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
-	? (bump_num_cache_relocations (),				      \
-	   (*ref) = l->l_lookup_cache.ret,				      \
-	   l->l_lookup_cache.value)					      \
-	: ({ lookup_t _lr;						      \
-	     int _tc = elf_machine_type_class (r_type);			      \
-	     l->l_lookup_cache.type_class = _tc;			      \
-	     l->l_lookup_cache.sym = (*ref);				      \
-	     const struct r_found_version *v = NULL;			      \
-	     if ((version) != NULL && (version)->hash != 0)		      \
-	       v = (version);						      \
-	     _lr = _dl_lookup_symbol_x (strtab + (*ref)->st_name, l, (ref),   \
-					scope, v, _tc,			      \
-					DL_LOOKUP_ADD_DEPENDENCY	      \
-					| DL_LOOKUP_FOR_RELOCATE, NULL);      \
-	     l->l_lookup_cache.ret = (*ref);				      \
-	     l->l_lookup_cache.value = _lr; }))				      \
-     : l)
-
-#include "dynamic-link.h"
-
-    ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc);
+    ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc, NULL);
 
 #ifndef PROF
     if (__glibc_unlikely (consider_profiling)
diff --git a/elf/do-rel.h b/elf/do-rel.h
index 321ac2b359..187f64c9d2 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -37,11 +37,11 @@ 
    relocations; they should be set up to call _dl_runtime_resolve, rather
    than fully resolved now.  */
 
-auto inline void __attribute__ ((always_inline))
-elf_dynamic_do_Rel (struct link_map *map,
+static inline void __attribute__ ((always_inline))
+elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[],
 		    ElfW(Addr) reladdr, ElfW(Addr) relsize,
 		    __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative,
-		    int lazy, int skip_ifunc)
+		    int lazy, int skip_ifunc, struct link_map *boot_map)
 {
   const ElfW(Rel) *r = (const void *) reladdr;
   const ElfW(Rel) *end = (const void *) (reladdr + relsize);
@@ -68,13 +68,13 @@  elf_dynamic_do_Rel (struct link_map *map,
 	  }
 	else
 # endif
-	  elf_machine_lazy_rel (map, l_addr, r, skip_ifunc);
+	  elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc);
 
 # ifdef ELF_MACHINE_IRELATIVE
       if (r2 != NULL)
 	for (; r2 <= end2; ++r2)
 	  if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
-	    elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc);
+	    elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc);
 # endif
     }
   else
@@ -134,9 +134,9 @@  elf_dynamic_do_Rel (struct link_map *map,
 #endif
 
 	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
-	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
+	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
 			       &map->l_versions[ndx],
-			       (void *) (l_addr + r->r_offset), skip_ifunc);
+			       (void *) (l_addr + r->r_offset), skip_ifunc, boot_map);
 	    }
 
 #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP
@@ -146,11 +146,11 @@  elf_dynamic_do_Rel (struct link_map *map,
 		{
 		  ElfW(Half) ndx
 		    = version[ELFW(R_SYM) (r2->r_info)] & 0x7fff;
-		  elf_machine_rel (map, r2,
+		  elf_machine_rel (map, scope, r2,
 				   &symtab[ELFW(R_SYM) (r2->r_info)],
 				   &map->l_versions[ndx],
 				   (void *) (l_addr + r2->r_offset),
-				   skip_ifunc);
+				   skip_ifunc, boot_map);
 		}
 #endif
 	}
@@ -167,16 +167,16 @@  elf_dynamic_do_Rel (struct link_map *map,
 	      }
 	    else
 # endif
-	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
-			       (void *) (l_addr + r->r_offset), skip_ifunc);
+	      elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
+			       (void *) (l_addr + r->r_offset), skip_ifunc, boot_map);
 
 # ifdef ELF_MACHINE_IRELATIVE
 	  if (r2 != NULL)
 	    for (; r2 <= end2; ++r2)
 	      if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE)
-		elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
+		elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)],
 				 NULL, (void *) (l_addr + r2->r_offset),
-				 skip_ifunc);
+				 skip_ifunc, boot_map);
 # endif
 	}
 #endif
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 3eb24ba3a6..6b2f4fd129 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -59,31 +59,34 @@  int _dl_try_allocate_static_tls (struct link_map *map, bool optional)
    copying memory, breaking the very code written to handle the
    unaligned cases.  */
 # if ! ELF_MACHINE_NO_REL
-auto inline void __attribute__((always_inline))
-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
-		 const ElfW(Sym) *sym, const struct r_found_version *version,
-		 void *const reloc_addr, int skip_ifunc);
-auto inline void __attribute__((always_inline))
+static inline void __attribute__((always_inline))
+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+		 const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
+		 const struct r_found_version *version,
+		 void *const reloc_addr, int skip_ifunc,
+		 struct link_map *boot_map);
+static inline void __attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 			  void *const reloc_addr);
 # endif
 # if ! ELF_MACHINE_NO_RELA
-auto inline void __attribute__((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
-		  const ElfW(Sym) *sym, const struct r_found_version *version,
-		  void *const reloc_addr, int skip_ifunc);
-auto inline void __attribute__((always_inline))
-elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
-			   void *const reloc_addr);
+static inline void __attribute__((always_inline))
+elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
+		 const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
+		 const struct r_found_version *version, void *const reloc_addr,
+		 int skip_ifunc, struct link_map *boot_map);
+static inline void __attribute__((always_inline))
+elf_machine_rela_relative(ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+	                  void *const reloc_addr);
 # endif
 # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL
-auto inline void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__((always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 		      int skip_ifunc);
 # else
-auto inline void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__((always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc);
 # endif
@@ -114,7 +117,7 @@  elf_machine_lazy_rel (struct link_map *map,
    consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL*
    are completely separate and there is a gap between them.  */
 
-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \
+# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel, boot_map) \
   do {									      \
     struct { ElfW(Addr) start, size;					      \
 	     __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; }  \
@@ -152,18 +155,18 @@  elf_machine_lazy_rel (struct link_map *map,
       }									      \
 									      \
     if (ELF_DURING_STARTUP)						      \
-      elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size,	      \
-			      ranges[0].nrelative, 0, skip_ifunc);	      \
+      elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size,  \
+			      ranges[0].nrelative, 0, skip_ifunc, boot_map);  \
     else								      \
       {									      \
 	int ranges_index;						      \
 	for (ranges_index = 0; ranges_index < 2; ++ranges_index)	      \
-	  elf_dynamic_do_##reloc ((map),				      \
+	  elf_dynamic_do_##reloc ((map), scope,				      \
 				  ranges[ranges_index].start,		      \
 				  ranges[ranges_index].size,		      \
 				  ranges[ranges_index].nrelative,	      \
 				  ranges[ranges_index].lazy,		      \
-				  skip_ifunc);				      \
+				  skip_ifunc, boot_map);		      \
       }									      \
   } while (0)
 
@@ -175,29 +178,29 @@  elf_machine_lazy_rel (struct link_map *map,
 
 # if ! ELF_MACHINE_NO_REL
 #  include "do-rel.h"
-#  define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \
-  _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL)
+#  define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc, boot_map)	      \
+  _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
 # else
-#  define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do.  */
+#  define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc, boot_map) /* Nothing to do.  */
 # endif
 
 # if ! ELF_MACHINE_NO_RELA
 #  define DO_RELA
 #  include "do-rel.h"
-#  define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \
-  _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL)
+#  define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc, boot_map)	      \
+  _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map)
 # else
-#  define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do.  */
+#  define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc, boot_map) /* Nothing to do.  */
 # endif
 
 /* This can't just be an inline function because GCC is too dumb
    to inline functions containing inlines themselves.  */
-# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \
+# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc, boot_map) \
   do {									      \
     int edr_lazy = elf_machine_runtime_setup ((map), (lazy),		      \
 					      (consider_profile));	      \
-    ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc);			      \
-    ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc);			      \
+    ELF_DYNAMIC_DO_REL ((map), scope, edr_lazy, skip_ifunc, boot_map);	      \
+    ELF_DYNAMIC_DO_RELA ((map), scope, edr_lazy, skip_ifunc, boot_map);	      \
   } while (0)
 
 #endif
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index 4aa2058abf..00a27ba40c 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -19,15 +19,12 @@ 
 /* This file is included multiple times and therefore lacks a header
    file inclusion guard.  */
 
+#ifndef _GET_DYNAMIC_INFO_H
+
 #include <assert.h>
 #include <libc-diag.h>
 
-#ifndef RESOLVE_MAP
-static
-#else
-auto
-#endif
-inline void __attribute__ ((unused, always_inline))
+static inline void __attribute__ ((unused, always_inline))
 elf_get_dynamic_info (struct link_map *l)
 {
 #if __ELF_NATIVE_CLASS == 32
@@ -165,3 +162,6 @@  elf_get_dynamic_info (struct link_map *l)
     info[DT_RPATH] = NULL;
 #endif
 }
+
+#define _GET_DYNAMIC_INFO_H
+#endif
diff --git a/elf/rtld.c b/elf/rtld.c
index 8d2bba3d43..43b5b990fc 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -500,13 +500,9 @@  _dl_start_final (void *arg, struct dl_start_final_info *info)
   return start_addr;
 }
 
-static ElfW(Addr) __attribute_used__
-_dl_start (void *arg)
-{
 #ifdef DONT_USE_BOOTSTRAP_MAP
 # define bootstrap_map GL(dl_rtld_map)
 #else
-  struct dl_start_final_info info;
 # define bootstrap_map info.l
 #endif
 
@@ -516,12 +512,16 @@  _dl_start (void *arg)
      is trivial: always the map of ld.so itself.  */
 #define RTLD_BOOTSTRAP
 #define BOOTSTRAP_MAP (&bootstrap_map)
-#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
+#define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP
 #include "dynamic-link.h"
 
+static ElfW(Addr) __attribute_used__
+_dl_start (void *arg)
+{
 #ifdef DONT_USE_BOOTSTRAP_MAP
   rtld_timer_start (&start_time);
 #else
+  struct dl_start_final_info info;
   rtld_timer_start (&info.start_time);
 #endif
 
@@ -562,7 +562,7 @@  _dl_start (void *arg)
       /* Relocate ourselves so we can do normal function calls and
 	 data access using the global offset table.  */
 
-      ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0);
+      ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0, &bootstrap_map);
     }
   bootstrap_map.l_relocated = 1;
 
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 3e10cb462f..30d6dfa56d 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -237,11 +237,13 @@  elf_machine_plt_value (struct link_map *map,
 
 #ifdef RESOLVE_MAP
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
-		  const ElfW(Sym) *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
@@ -253,7 +255,12 @@  elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
   else
     {
       const ElfW(Sym) *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -377,9 +384,9 @@  elf_machine_rela_relative (ElfW(Addr) l_addr,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr,
 		      const ElfW(Rela) *reloc,
 		      int skip_ifunc)
@@ -406,8 +413,8 @@  elf_machine_lazy_rel (struct link_map *map,
 		    (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
 		  version = &map->l_versions[vernum[symndx] & 0x7fff];
 		}
-	      elf_machine_rela (map, reloc, sym, version, reloc_addr,
-				skip_ifunc);
+	      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
+				skip_ifunc, NULL);
 	      return;
 	    }
 	}
@@ -433,7 +440,8 @@  elf_machine_lazy_rel (struct link_map *map,
 
       /* Always initialize TLS descriptors completely, because lazy
 	 initialization requires synchronization at every TLS access.  */
-      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
+      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
+			skip_ifunc, NULL);
     }
   else if (__glibc_unlikely (r_type == AARCH64_R(IRELATIVE)))
     {
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 9e327b7f17..8d64bdd278 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -360,14 +360,15 @@  elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map,
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg,
-		  int skip_ifunc)
+		  int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   unsigned long int const r_type = ELF64_R_TYPE (reloc->r_info);
@@ -410,7 +411,12 @@  elf_machine_rela (struct link_map *map,
       return;
   else
     {
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       Elf64_Addr sym_value;
       Elf64_Addr sym_raw_value;
 
@@ -488,7 +494,7 @@  elf_machine_rela (struct link_map *map,
    can be skipped.  */
 #define ELF_MACHINE_REL_RELATIVE 1
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -505,9 +511,9 @@  elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
   memcpy (reloc_addr_arg, &reloc_addr_val, 8);
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h
index e6ce7f0ff6..d5f737c198 100644
--- a/sysdeps/arc/dl-machine.h
+++ b/sysdeps/arc/dl-machine.h
@@ -228,11 +228,13 @@  elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 
 #ifdef RESOLVE_MAP
 
-inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
-                  const ElfW(Sym) *sym, const struct r_found_version *version,
-                  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
+		  const struct r_found_version *version,
+                  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   ElfW(Addr) r_info = reloc->r_info;
   const unsigned long int r_type = ELFW (R_TYPE) (r_info);
@@ -245,7 +247,12 @@  elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
   else
     {
       const ElfW(Sym) *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
@@ -326,8 +333,9 @@  elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 
 inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
-                      const ElfW(Rela) *reloc, int skip_ifunc)
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+		      int skip_ifunc)
 {
   ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index eb13cb8b57..1dc65c5c52 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -276,7 +276,7 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
 
 #ifdef RESOLVE_MAP
 /* Handle a PC24 reloc, including the out-of-range case.  */
-auto void
+static void
 relocate_pc24 (struct link_map *map, Elf32_Addr value,
                Elf32_Addr *const reloc_addr, Elf32_Sword addend)
 {
@@ -330,11 +330,11 @@  relocate_pc24 (struct link_map *map, Elf32_Addr value,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], const Elf32_Rel *reloc,
 		 const Elf32_Sym *sym, const struct r_found_version *version,
-		 void *const reloc_addr_arg, int skip_ifunc)
+		 void *const reloc_addr_arg, int skip_ifunc, struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -364,7 +364,12 @@  elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
 #endif
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -508,11 +513,11 @@  elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
 }
 
 # ifndef RTLD_BOOTSTRAP
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+		  void *const reloc_addr_arg, int skip_ifunc, struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -526,7 +531,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 # ifndef RESOLVE_CONFLICT_FIND_MAP
       const Elf32_Sym *const refsym = sym;
 # endif
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -601,7 +606,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 }
 # endif
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
 			  void *const reloc_addr_arg)
@@ -611,7 +616,7 @@  elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
 }
 
 # ifndef RTLD_BOOTSTRAP
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -621,9 +626,9 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 }
 # endif
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
 		      int skip_ifunc)
 {
@@ -653,7 +658,8 @@  elf_machine_lazy_rel (struct link_map *map,
 
       /* Always initialize TLS descriptors completely, because lazy
 	 initialization requires synchronization at every TLS access.  */
-      elf_machine_rel (map, reloc, sym, version, reloc_addr, skip_ifunc);
+      elf_machine_rel (map, scope, reloc, sym, version, reloc_addr, skip_ifunc,
+		       NULL);
     }
   else
     _dl_reloc_bad_type (map, r_type, 1);
diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h
index b08f06d74c..8147e314bb 100644
--- a/sysdeps/csky/dl-machine.h
+++ b/sysdeps/csky/dl-machine.h
@@ -215,10 +215,12 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void __attribute__ ((unused, always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+static inline void __attribute__ ((unused, always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -230,7 +232,12 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
       opcode16_addr = (unsigned short *)reloc_addr;
 
@@ -331,7 +338,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void __attribute__ ((unused, always_inline))
+static inline void __attribute__ ((unused, always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -339,8 +346,8 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void __attribute__ ((unused, always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__ ((unused, always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index ded9c193d6..84ffda2db2 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -548,13 +548,13 @@  dl_platform_init (void)
   (  (((as14) & 0x1fff) << 1) \
    | (((as14) & 0x2000) >> 13))
 
-auto void __attribute__((always_inline))
-elf_machine_rela (struct link_map *map,
+static void __attribute__((always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 		  const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg,
-		  int skip_ifunc)
+		  int skip_ifunc, struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const Elf32_Sym *const refsym = sym;
@@ -580,9 +580,9 @@  elf_machine_rela (struct link_map *map,
 # ifdef RTLD_BOOTSTRAP
   /* RESOLVE_MAP in rtld.c doesn't have the local sym test.  */
   sym_map = (ELF32_ST_BIND (sym->st_info) != STB_LOCAL
-	     ? RESOLVE_MAP (&sym, version, r_type) : map);
+	     ? boot_map : map);
 # else
-  sym_map = RESOLVE_MAP (&sym, version, r_type);
+  sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
 # endif
 
   if (sym_map)
@@ -740,7 +740,7 @@  elf_machine_rela (struct link_map *map,
 
 /* hppa doesn't have an R_PARISC_RELATIVE reloc, but uses relocs with
    ELF32_R_SYM (info) == 0 for a similar purpose.  */
-auto void __attribute__((always_inline))
+static void __attribute__((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr,
 			   const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -793,8 +793,8 @@  elf_machine_rela_relative (Elf32_Addr l_addr,
   *reloc_addr = value;
 }
 
-auto void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static void __attribute__((always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 590b41d8d7..891d005f41 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -291,11 +291,13 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute ((always_inline))
-elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+		 const Elf32_Rel *reloc,
 		 const Elf32_Sym *sym, const struct r_found_version *version,
-		 void *const reloc_addr_arg, int skip_ifunc)
+		 void *const reloc_addr_arg, int skip_ifunc,
+		 struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -327,7 +329,8 @@  elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
 # ifndef RTLD_BOOTSTRAP
       const Elf32_Sym *const refsym = sym;
 # endif
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -498,11 +501,13 @@  and creates an unsatisfiable circular dependency.\n",
 }
 
 # ifndef RTLD_BOOTSTRAP
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -514,7 +519,8 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 #  ifndef RESOLVE_CONFLICT_FIND_MAP
       const Elf32_Sym *const refsym = sym;
 #  endif
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -647,7 +653,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 }
 # endif	/* !RTLD_BOOTSTRAP */
 
-auto inline void
+static inline void
 __attribute ((always_inline))
 elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
 			  void *const reloc_addr_arg)
@@ -658,7 +664,7 @@  elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
 }
 
 # ifndef RTLD_BOOTSTRAP
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -668,9 +674,9 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 }
 # endif	/* !RTLD_BOOTSTRAP */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rel *reloc,
 		      int skip_ifunc)
 {
@@ -705,14 +711,14 @@  elf_machine_lazy_rel (struct link_map *map,
 	  const ElfW(Half) *const version =
 	    (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
 	  ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff;
-	  elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)],
+	  elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)],
 			   &map->l_versions[ndx],
-			   (void *) (l_addr + r->r_offset), skip_ifunc);
+			   (void *) (l_addr + r->r_offset), skip_ifunc, NULL);
 	}
 # ifndef RTLD_BOOTSTRAP
       else
-	elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
-			 (void *) (l_addr + r->r_offset), skip_ifunc);
+	elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
+			 (void *) (l_addr + r->r_offset), skip_ifunc, NULL);
 # endif
     }
   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
@@ -728,9 +734,9 @@  elf_machine_lazy_rel (struct link_map *map,
 
 # ifndef RTLD_BOOTSTRAP
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rela (struct link_map *map,
+elf_machine_lazy_rela (struct link_map *map, struct r_scope_elem *scope[],
 		       Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		       int skip_ifunc)
 {
@@ -754,7 +760,8 @@  elf_machine_lazy_rela (struct link_map *map,
 
       /* Always initialize TLS descriptors completely at load time, in
 	 case static TLS is allocated for it that requires locking.  */
-      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
+      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr,
+			skip_ifunc, NULL);
     }
   else if (__glibc_unlikely (r_type == R_386_IRELATIVE))
     {
diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h
index 4403e7767a..afefe083d9 100644
--- a/sysdeps/ia64/dl-machine.h
+++ b/sysdeps/ia64/dl-machine.h
@@ -371,14 +371,14 @@  elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 
 /* Perform the relocation specified by RELOC and SYM (which is fully
    resolved).  MAP is the object containing the reloc.  */
-auto inline void
+static inline void
 __attribute ((always_inline))
-elf_machine_rela (struct link_map *map,
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg,
-		  int skip_ifunc)
+		  int skip_ifunc, struct link_map *boot_map)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -414,10 +414,15 @@  elf_machine_rela (struct link_map *map,
       return;
   else
     {
-      struct link_map *sym_map;
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
 
       /* RESOLVE_MAP() will return NULL if it fail to locate the symbol.  */
-      if ((sym_map = RESOLVE_MAP (&sym, version, r_type)))
+      if (sym_map != NULL)
 	{
 	  value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
 
@@ -476,7 +481,7 @@  elf_machine_rela (struct link_map *map,
    can be skipped.  */
 #define ELF_MACHINE_REL_RELATIVE 1
 
-auto inline void
+static inline void
 __attribute ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -489,9 +494,9 @@  elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 }
 
 /* Perform a RELATIVE reloc on the .got entry that transfers to the .plt.  */
-auto inline void
+static inline void
 __attribute ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
index 86a8c67e2a..43cb8d5a7b 100644
--- a/sysdeps/m68k/dl-machine.h
+++ b/sysdeps/m68k/dl-machine.h
@@ -215,10 +215,12 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void __attribute__ ((unused, always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+static inline void __attribute__ ((unused, always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -228,7 +230,12 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
@@ -303,7 +310,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void __attribute__ ((unused, always_inline))
+static inline void __attribute__ ((unused, always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -311,8 +318,8 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void __attribute__ ((unused, always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__ ((unused, always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
index e460f6f195..5c37244291 100644
--- a/sysdeps/microblaze/dl-machine.h
+++ b/sysdeps/microblaze/dl-machine.h
@@ -207,10 +207,12 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
     ((unsigned short *)(rel_addr))[3] = (val) & 0xffff; \
   } while (0)
 
-auto inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+static inline void __attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -222,7 +224,12 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       value += reloc->r_addend;
@@ -277,7 +284,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void
+static inline void
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -285,8 +292,8 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   PUT_REL_64 (reloc_addr, l_addr + reloc->r_addend);
 }
 
-auto inline void
-elf_machine_lazy_rel (struct link_map *map,
+static inline void
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
index b74d427d64..afc43009d6 100644
--- a/sysdeps/mips/dl-machine.h
+++ b/sysdeps/mips/dl-machine.h
@@ -474,11 +474,13 @@  elf_machine_plt_value (struct link_map *map, const ElfW(Rel) *reloc,
    by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
-		   const ElfW(Sym) *sym, const struct r_found_version *version,
-		   void *reloc_addr, ElfW(Addr) r_addend, int inplace_p)
+elf_machine_reloc (struct link_map *map, struct r_scope_elem *scope[],
+		   ElfW(Addr) r_info, const ElfW(Sym) *sym,
+		   const struct r_found_version *version, void *reloc_addr,
+		   ElfW(Addr) r_addend, int inplace_p,
+		   struct link_map *boot_map)
 {
   const unsigned long int r_type = ELFW(R_TYPE) (r_info);
   ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
@@ -506,7 +508,12 @@  elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
     case R_MIPS_TLS_TPREL32:
 # endif
       {
-	struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
 
 	switch (r_type)
 	  {
@@ -646,7 +653,11 @@  elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
 	  _dl_signal_error (0, map->l_name, NULL,
 			    "found jump slot relocation with non-zero addend");
 
-	sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+        sym_map = boot_map;
+#else
+        sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+#endif
 	value = SYMBOL_ADDRESS (sym_map, sym, true);
 	*addr_field = value;
 
@@ -660,7 +671,11 @@  elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
 	ElfW(Addr) value;
 
 	/* Calculate the address of the symbol.  */
-	sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+        sym_map = boot_map;
+#else
+        sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+#endif
 	value = SYMBOL_ADDRESS (sym_map, sym, true);
 
 	if (__builtin_expect (sym == NULL, 0))
@@ -707,16 +722,18 @@  elf_machine_reloc (struct link_map *map, ElfW(Addr) r_info,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
-		 const ElfW(Sym) *sym, const struct r_found_version *version,
-		 void *const reloc_addr, int skip_ifunc)
+elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[],
+		 const ElfW(Rel) *reloc, const ElfW(Sym) *sym,
+		 const struct r_found_version *version, void *const reloc_addr,
+		 int skip_ifunc, struct link_map *boot_map)
 {
-  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr, 0, 1);
+  elf_machine_reloc (map, scope, reloc->r_info, sym, version, reloc_addr, 0, 1,
+		     boot_map);
 }
 
-auto inline void
+static inline void
 __attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 			  void *const reloc_addr)
@@ -724,9 +741,9 @@  elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
   /* XXX Nothing to do.  There is no relative relocation, right?  */
 }
 
-auto inline void
+static inline void
 __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
 		      int skip_ifunc)
 {
@@ -747,17 +764,17 @@  elf_machine_lazy_rel (struct link_map *map,
     _dl_reloc_bad_type (map, r_type, 1);
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], const ElfW(Rela) *reloc,
 		  const ElfW(Sym) *sym, const struct r_found_version *version,
-		  void *const reloc_addr, int skip_ifunc)
+		  void *const reloc_addr, int skip_ifunc, struct link_map *boot_map)
 {
-  elf_machine_reloc (map, reloc->r_info, sym, version, reloc_addr,
-		     reloc->r_addend, 0);
+  elf_machine_reloc (map, scope, reloc->r_info, sym, version, reloc_addr,
+		     reloc->r_addend, 0, boot_map);
 }
 
-auto inline void
+static inline void
 __attribute__((always_inline))
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 			   void *const reloc_addr)
@@ -766,7 +783,7 @@  elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 
 #ifndef RTLD_BOOTSTRAP
 /* Relocate GOT. */
-auto inline void
+static inline void
 __attribute__((always_inline))
 elf_machine_got_rel (struct link_map *map, int lazy)
 {
@@ -867,7 +884,7 @@  elf_machine_got_rel (struct link_map *map, int lazy)
 /* Set up the loaded object described by L so its stub function
    will jump to the on-demand fixup code __dl_runtime_resolve.  */
 
-auto inline int
+static inline int
 __attribute__((always_inline))
 elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 {
diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
index e000cd081f..1e399980ea 100644
--- a/sysdeps/nios2/dl-machine.h
+++ b/sysdeps/nios2/dl-machine.h
@@ -234,10 +234,12 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
    LOADADDR is the load address of the object; INFO is an array indexed
    by DT_* of the .dynamic section info.  */
 
-auto inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
-                  const ElfW(Sym) *sym, const struct r_found_version *version,
-                  void *const reloc_addr_arg, int skip_ifunc)
+static inline void __attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -249,7 +251,12 @@  elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
@@ -314,7 +321,7 @@  elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
     }
 }
 
-auto inline void __attribute__((always_inline))
+static inline void __attribute__((always_inline))
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -322,10 +329,10 @@  elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void __attribute__((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__((always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
-		      int skip_ifunc)
+		      int skip_ifunc, struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   if (ELF32_R_TYPE (reloc->r_info) == R_NIOS2_JUMP_SLOT)
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index ced3a7b659..3c80f5d9ca 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -286,10 +286,12 @@  extern void _dl_reloc_overflow (struct link_map *map,
    LOADADDR is the load address of the object; INFO is an array indexed
    by DT_* of the .dynamic section info.  */
 
-auto inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+static inline void __attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const Elf32_Sym *const refsym = sym;
@@ -317,7 +319,11 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
   else
     {
-      sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      sym_map = boot_map;
+#else
+      sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+#endif
       value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
   value += reloc->r_addend;
@@ -441,7 +447,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void __attribute__ ((always_inline))
+static inline void __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -449,8 +455,8 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index b90f407119..c1a7368603 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -620,7 +620,7 @@  extern void attribute_hidden _dl_reloc_overflow (struct link_map *map,
 						 Elf64_Addr *const reloc_addr,
 						 const Elf64_Sym *refsym);
 
-auto inline void __attribute__ ((always_inline))
+static inline void __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -629,7 +629,7 @@  elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 }
 
 /* This computes the value used by TPREL* relocs.  */
-auto inline Elf64_Addr __attribute__ ((always_inline, const))
+static inline Elf64_Addr __attribute__ ((always_inline, const))
 elf_machine_tprel (struct link_map *map,
 		   struct link_map *sym_map,
 		   const Elf64_Sym *sym,
@@ -648,7 +648,7 @@  elf_machine_tprel (struct link_map *map,
 }
 
 /* Call function at address VALUE (an OPD entry) to resolve ifunc relocs.  */
-auto inline Elf64_Addr __attribute__ ((always_inline))
+static inline Elf64_Addr __attribute__ ((always_inline))
 resolve_ifunc (Elf64_Addr value,
 	       const struct link_map *map, const struct link_map *sym_map)
 {
@@ -678,13 +678,13 @@  resolve_ifunc (Elf64_Addr value,
 
 /* Perform the relocation specified by RELOC and SYM (which is fully
    resolved).  MAP is the object containing the reloc.  */
-auto inline void __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map,
+static inline void __attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
 		  const Elf64_Rela *reloc,
 		  const Elf64_Sym *sym,
 		  const struct r_found_version *version,
 		  void *const reloc_addr_arg,
-		  int skip_ifunc)
+		  int skip_ifunc, struct link_map *boot_map)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -707,7 +707,11 @@  elf_machine_rela (struct link_map *map,
 
   /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt
      and STT_GNU_IFUNC.  */
-  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+  struct link_map *sym_map = boot_map;
+#else
+  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+#endif
   Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
 
   if (sym != NULL
@@ -1037,8 +1041,8 @@  elf_machine_rela (struct link_map *map,
   MODIFIED_CODE_NOQUEUE (reloc_addr);
 }
 
-auto inline void __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+static inline void __attribute__ ((always_inline))
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index 5b0746175c..5e8d7e17b0 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -161,17 +161,19 @@  elf_machine_fixup_plt (struct link_map *map, lookup_t t,
    by RELOC_ADDR.  SYM is the relocation symbol specified by R_INFO and
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
-		  const ElfW(Sym) *sym, const struct r_found_version *version,
-		  void *const reloc_addr, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   ElfW(Addr) r_info = reloc->r_info;
   const unsigned long int r_type = ELFW (R_TYPE) (r_info);
   ElfW(Addr) *addr_field = (ElfW(Addr) *) reloc_addr;
   const ElfW(Sym) *const __attribute__ ((unused)) refsym = sym;
-  struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+  struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
   ElfW(Addr) value = 0;
   if (sym_map != NULL)
     value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend;
@@ -279,7 +281,7 @@  elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 			  void *const reloc_addr)
@@ -287,10 +289,11 @@  elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
   *(ElfW(Addr) *) reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
-		      const ElfW(Rela) *reloc, int skip_ifunc)
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
+		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+		      int skip_ifunc)
 {
   ElfW(Addr) *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
@@ -320,7 +323,7 @@  elf_machine_lazy_rel (struct link_map *map, ElfW(Addr) l_addr,
 /* Set up the loaded object described by L so its stub function
    will jump to the on-demand fixup code __dl_runtime_resolve.  */
 
-auto inline int
+static inline int
 __attribute__ ((always_inline))
 elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 {
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 73cc007e34..56760bb47d 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -320,11 +320,13 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -356,7 +358,8 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
       /* Only needed for R_390_COPY below.  */
       const Elf32_Sym *const refsym = sym;
 #endif
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
       Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -483,7 +486,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -492,9 +495,9 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index aa9d524bac..c34187e055 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -267,11 +267,13 @@  elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
-		  const Elf64_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf64_Rela *reloc, const Elf64_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF64_R_TYPE (reloc->r_info);
@@ -303,7 +305,8 @@  elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
       /* Only needed for R_390_COPY below.  */
       const Elf64_Sym *const refsym = sym;
 #endif
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
       Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -437,7 +440,7 @@  elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -446,9 +449,9 @@  elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index 122b417a17..981ef1f538 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -259,11 +259,13 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -318,7 +320,12 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   else
     {
       const Elf32_Sym *const refsym = sym;
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
 
       value = SYMBOL_ADDRESS (sym_map, sym, true);
       value += reloc->r_addend;
@@ -424,7 +431,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -443,9 +450,9 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 #undef COPY_UNALIGNED_WORD
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index 0269e458ea..3b7e069944 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -327,11 +327,13 @@  elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
-		  const Elf32_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf32_Rela *reloc, const Elf32_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
 #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
@@ -381,7 +383,11 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
   else
     {
-      sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      sym_map = boot_map;
+#else
+      sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+#endif
       value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
 #else
@@ -536,7 +542,7 @@  elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -545,9 +551,9 @@  elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr += l_addr + reloc->r_addend;
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index bbd4566d8a..0fa2682aec 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -354,11 +354,13 @@  elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
-		  const Elf64_Sym *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
+elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[],
+		  const Elf64_Rela *reloc, const Elf64_Sym *sym,
+		  const struct r_found_version *version,
+		  void *const reloc_addr_arg, int skip_ifunc,
+		  struct link_map *boot_map)
 {
   Elf64_Addr *const reloc_addr = reloc_addr_arg;
 #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
@@ -408,7 +410,11 @@  elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
     }
   else
     {
-      sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      sym_map = boot_map;
+#else
+      sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type);
+#endif
       value = SYMBOL_ADDRESS (sym_map, sym, true);
     }
 #else
@@ -646,7 +652,7 @@  elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
 			   void *const reloc_addr_arg)
@@ -655,9 +661,9 @@  elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-auto inline void
+static inline void
 __attribute__ ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      Elf64_Addr l_addr, const Elf64_Rela *reloc,
 		      int skip_ifunc)
 {
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index b3ed4dd467..0e893972f8 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -250,12 +250,12 @@  elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc,
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-auto inline void
-__attribute__ ((always_inline))
-elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
-		  const ElfW(Sym) *sym, const struct r_found_version *version,
-		  void *const reloc_addr_arg, int skip_ifunc)
-{
+static inline void __attribute__((always_inline))
+elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[],
+		 const ElfW(Rela) *reloc, const ElfW(Sym) *sym,
+		 const struct r_found_version *version,
+		 void *const reloc_addr_arg, int skip_ifunc,
+		 struct link_map *boot_map) {
   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
   const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
 
@@ -292,7 +292,12 @@  elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 # ifndef RTLD_BOOTSTRAP
       const ElfW(Sym) *const refsym = sym;
 # endif
-      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_BOOTSTRAP
+      struct link_map *sym_map = boot_map;
+#else
+      struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version,
+					      r_type);
+#endif
       ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       if (sym != NULL
@@ -517,7 +522,7 @@  and creates an unsatisfiable circular dependency.\n",
     }
 }
 
-auto inline void
+static inline void
 __attribute ((always_inline))
 elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 			   void *const reloc_addr_arg)
@@ -536,9 +541,9 @@  elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
     }
 }
 
-auto inline void
+static inline void
 __attribute ((always_inline))
-elf_machine_lazy_rel (struct link_map *map,
+elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[],
 		      ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
 		      int skip_ifunc)
 {
@@ -572,7 +577,8 @@  elf_machine_lazy_rel (struct link_map *map,
 
       /* Always initialize TLS descriptors completely at load time, in
 	 case static TLS is allocated for it that requires locking.  */
-      elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc);
+      elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc,
+                        NULL);
     }
   else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
     {