diff mbox series

elf: Remove elf_machine_load_address

Message ID 20240526134754.468541-1-hjl.tools@gmail.com
State New
Headers show
Series elf: Remove elf_machine_load_address | expand

Commit Message

H.J. Lu May 26, 2024, 1:47 p.m. UTC
rtld.c already uses __ehdr_start to get the ELF header and its load
address:

extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
...
  const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;

Remove elf_machine_load_address and use &__ehdr_start instead.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 elf/rtld.c                                   |  2 +-
 sysdeps/aarch64/dl-machine.h                 | 12 +----
 sysdeps/alpha/dl-machine.h                   | 10 ----
 sysdeps/arc/dl-machine.h                     | 15 ------
 sysdeps/arm/dl-machine.h                     | 11 +----
 sysdeps/csky/dl-machine.h                    | 13 ------
 sysdeps/generic/dl-machine.h                 |  8 ----
 sysdeps/hppa/dl-machine.h                    | 18 --------
 sysdeps/i386/dl-machine.h                    | 12 +----
 sysdeps/loongarch/dl-machine.h               | 10 +---
 sysdeps/m68k/dl-machine.h                    | 18 --------
 sysdeps/microblaze/dl-machine.h              | 16 -------
 sysdeps/mips/dl-machine.h                    | 36 ---------------
 sysdeps/nios2/dl-machine.h                   | 14 ------
 sysdeps/or1k/dl-machine.h                    | 18 --------
 sysdeps/powerpc/powerpc32/dl-machine.h       | 48 --------------------
 sysdeps/powerpc/powerpc64/dl-machine.h       | 36 ++-------------
 sysdeps/riscv/dl-machine.h                   | 11 +----
 sysdeps/s390/s390-32/dl-machine.h            | 18 --------
 sysdeps/s390/s390-64/dl-machine.h            | 14 ------
 sysdeps/sh/dl-machine.h                      | 20 --------
 sysdeps/sparc/sparc32/dl-machine.h           | 20 --------
 sysdeps/sparc/sparc64/dl-machine.h           | 21 ---------
 sysdeps/unix/sysv/linux/powerpc/libc-start.c |  7 +--
 sysdeps/x86_64/dl-machine.h                  | 12 +----
 25 files changed, 19 insertions(+), 401 deletions(-)

Comments

Florian Weimer May 26, 2024, 2:30 p.m. UTC | #1
* H. J. Lu:

> rtld.c already uses __ehdr_start to get the ELF header and its load
> address:
>
> extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
> ...
>   const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
>
> Remove elf_machine_load_address and use &__ehdr_start instead.
>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>

Does this really work on all HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets?
H.J. Lu May 26, 2024, 2:43 p.m. UTC | #2
On Sun, May 26, 2024 at 7:30 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>
> * H. J. Lu:
>
> > rtld.c already uses __ehdr_start to get the ELF header and its load
> > address:
> >
> > extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
> > ...
> >   const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
> >
> > Remove elf_machine_load_address and use &__ehdr_start instead.
> >
> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
>
> Does this really work on all HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets?

How do HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets work with existing

extern const ElfW(Ehdr) __ehdr_start attribute_hidden;

usages in rtld.c?  I tested it on ppc64le:

sysdeps/powerpc/powerpc64/configure.ac:AC_DEFINE(HIDDEN_VAR_NEEDS_DYNAMIC_RELOC)

There are no issues.
Florian Weimer May 26, 2024, 4:38 p.m. UTC | #3
* H. J. Lu:

> On Sun, May 26, 2024 at 7:30 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>>
>> * H. J. Lu:
>>
>> > rtld.c already uses __ehdr_start to get the ELF header and its load
>> > address:
>> >
>> > extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
>> > ...
>> >   const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
>> >
>> > Remove elf_machine_load_address and use &__ehdr_start instead.
>> >
>> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
>>
>> Does this really work on all HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets?
>
> How do HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets work with existing
>
> extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
>
> usages in rtld.c?

These references only happen after self-relocation in _dl_start_final.
The use of elf_machine_load_address comes before that.

Historically, this code has not been very robust.  Maybe one day, we
can simplify the self-relocation procedure.
H.J. Lu May 26, 2024, 4:46 p.m. UTC | #4
On Sun, May 26, 2024 at 9:38 AM Florian Weimer <fw@deneb.enyo.de> wrote:
>
> * H. J. Lu:
>
> > On Sun, May 26, 2024 at 7:30 AM Florian Weimer <fw@deneb.enyo.de> wrote:
> >>
> >> * H. J. Lu:
> >>
> >> > rtld.c already uses __ehdr_start to get the ELF header and its load
> >> > address:
> >> >
> >> > extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
> >> > ...
> >> >   const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
> >> >
> >> > Remove elf_machine_load_address and use &__ehdr_start instead.
> >> >
> >> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> >>
> >> Does this really work on all HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets?
> >
> > How do HIDDEN_VAR_NEEDS_DYNAMIC_RELOC targets work with existing
> >
> > extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
> >
> > usages in rtld.c?
>
> These references only happen after self-relocation in _dl_start_final.
> The use of elf_machine_load_address comes before that.
>
> Historically, this code has not been very robust.  Maybe one day, we
> can simplify the self-relocation procedure.

You are right.  My patch is dropped.
diff mbox series

Patch

diff --git a/elf/rtld.c b/elf/rtld.c
index e9525ea987..e0042f7e24 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -540,7 +540,7 @@  _dl_start (void *arg)
 #endif
 
   /* Figure out the run-time load address of the dynamic linker itself.  */
-  bootstrap_map.l_addr = elf_machine_load_address ();
+  bootstrap_map.l_addr = (ElfW(Addr)) &__ehdr_start;
 
   /* Read our own dynamic section and fill in the info array.  */
   bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 71135aa568..2996dc0cc5 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -39,22 +39,14 @@  elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
   return ehdr->e_machine == EM_AARCH64;
 }
 
-/* Return the run-time load address of the shared object.  */
-
-static inline ElfW(Addr) __attribute__ ((unused))
-elf_machine_load_address (void)
-{
-  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
-  return (ElfW(Addr)) &__ehdr_start;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 
 static inline ElfW(Addr) __attribute__ ((unused))
 elf_machine_dynamic (void)
 {
   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
-  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+  return (ElfW(Addr)) _DYNAMIC - (ElfW(Addr)) &__ehdr_start;
 }
 
 /* Set up the loaded object described by L so its unrelocated PLT
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index 5b125f37db..7ce7c8faf1 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -57,16 +57,6 @@  elf_machine_dynamic (void)
 #endif
 }
 
-/* Return the run-time load address of the shared object.  */
-
-static inline Elf64_Addr
-elf_machine_load_address (void)
-{
-  /* This relies on the compiler using gp-relative addresses for static symbols.  */
-  static void *dot = &dot;
-  return (void *)&dot - dot;
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/arc/dl-machine.h b/sysdeps/arc/dl-machine.h
index affe1319b0..cd6033dfe0 100644
--- a/sysdeps/arc/dl-machine.h
+++ b/sysdeps/arc/dl-machine.h
@@ -104,21 +104,6 @@  elf_machine_dynamic (void)
   return _GLOBAL_OFFSET_TABLE_[0];
 }
 
-
-/* Return the run-time load address of the shared object.  */
-static inline ElfW(Addr)
-elf_machine_load_address (void)
-{
-  ElfW(Addr) build_addr, run_addr;
-
-  /* For build address, below generates
-     ld  r0, [pcl, _GLOBAL_OFFSET_TABLE_@pcl].  */
-  build_addr = elf_machine_dynamic ();
-  __asm__ ("add %0, pcl, _DYNAMIC@pcl	\n" : "=r" (run_addr));
-
-  return run_addr - build_addr;
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h
index dd1a0f6b6e..41a0f7b40d 100644
--- a/sysdeps/arm/dl-machine.h
+++ b/sysdeps/arm/dl-machine.h
@@ -40,20 +40,13 @@  elf_machine_matches_host (const Elf32_Ehdr *ehdr)
   return ehdr->e_machine == EM_ARM;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline ElfW(Addr) __attribute__ ((unused))
-elf_machine_load_address (void)
-{
-  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
-  return (ElfW(Addr)) &__ehdr_start;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline ElfW(Addr) __attribute__ ((unused))
 elf_machine_dynamic (void)
 {
   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
-  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+  return (ElfW(Addr)) _DYNAMIC - (ElfW(Addr)) &__ehdr_start;
 }
 
 /* Set up the loaded object described by L so its unrelocated PLT
diff --git a/sysdeps/csky/dl-machine.h b/sysdeps/csky/dl-machine.h
index ec45f9b3eb..ae1aa5e877 100644
--- a/sysdeps/csky/dl-machine.h
+++ b/sysdeps/csky/dl-machine.h
@@ -43,19 +43,6 @@  elf_machine_dynamic (void)
   return *got;
 }
 
-/* Return the run-time load address ,of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  extern Elf32_Addr __dl_start (void *) asm ("_dl_start");
-  Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
-  Elf32_Addr pcrel_addr;
-  asm  ("grs %0,_dl_start\n" : "=r" (pcrel_addr));
-
-  return pcrel_addr - got_addr;
-}
-
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/generic/dl-machine.h b/sysdeps/generic/dl-machine.h
index bf572ca999..7b3c291dfd 100644
--- a/sysdeps/generic/dl-machine.h
+++ b/sysdeps/generic/dl-machine.h
@@ -43,14 +43,6 @@  elf_machine_dynamic (void)
 #error "Damn, no _DYNAMIC"
 }
 
-
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-#error "Where am I?"
-}
-
 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
 
 static inline ElfW(Addr)
diff --git a/sysdeps/hppa/dl-machine.h b/sysdeps/hppa/dl-machine.h
index 35e45289eb..8b1460ac6e 100644
--- a/sysdeps/hppa/dl-machine.h
+++ b/sysdeps/hppa/dl-machine.h
@@ -98,24 +98,6 @@  elf_machine_dynamic (void)
   return dynamic;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void) __attribute__ ((const));
-
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  Elf32_Addr dynamic;
-
-  asm (
-"	bl	1f,%0\n"
-"	addil	L'_DYNAMIC - ($PIC_pcrel$0 - 1),%0\n"
-"1:	ldo	R'_DYNAMIC - ($PIC_pcrel$0 - 5)(%%r1),%0\n"
-   : "=r" (dynamic) : : "r1");
-
-  return dynamic - elf_machine_dynamic ();
-}
-
 /* Fixup a PLT entry to bounce directly to the function at VALUE. */
 static inline struct fdesc __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index 50d74fe6e9..44eb60b3aa 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -36,21 +36,13 @@  elf_machine_matches_host (const Elf32_Ehdr *ehdr)
   return ehdr->e_machine == EM_386;
 }
 
-
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr __attribute__ ((unused))
-elf_machine_load_address (void)
-{
-  extern const Elf32_Ehdr __ehdr_start attribute_hidden;
-  return (Elf32_Addr) &__ehdr_start;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline Elf32_Addr __attribute__ ((unused))
 elf_machine_dynamic (void)
 {
   extern Elf32_Dyn _DYNAMIC[] attribute_hidden;
-  return (Elf32_Addr) _DYNAMIC - elf_machine_load_address ();
+  extern const Elf32_Ehdr __ehdr_start attribute_hidden;
+  return (Elf32_Addr) _DYNAMIC - (Elf32_Addr) &__ehdr_start;
 }
 
 /* Set up the loaded object described by L so its unrelocated PLT
diff --git a/sysdeps/loongarch/dl-machine.h b/sysdeps/loongarch/dl-machine.h
index ab6f1da7c0..3018ae7a42 100644
--- a/sysdeps/loongarch/dl-machine.h
+++ b/sysdeps/loongarch/dl-machine.h
@@ -83,18 +83,12 @@  elf_machine_matches_host (const ElfW (Ehdr) *ehdr)
   return 1;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline ElfW (Addr) elf_machine_load_address (void)
-{
-  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
-  return (ElfW(Addr)) &__ehdr_start;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline ElfW (Addr) elf_machine_dynamic (void)
 {
   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
-  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+  return (ElfW(Addr)) _DYNAMIC - (ElfW(Addr)) &__ehdr_start;
 }
 
 /* Initial entry point code for the dynamic linker.
diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h
index 4bbf1ba5b9..4a1754977d 100644
--- a/sysdeps/m68k/dl-machine.h
+++ b/sysdeps/m68k/dl-machine.h
@@ -48,24 +48,6 @@  elf_machine_dynamic (void)
 }
 
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  Elf32_Addr addr;
-#ifdef SHARED
-  asm (PCREL_OP ("lea", "_dl_start", "%0", "%0", "%%pc") "\n\t"
-       "sub.l _dl_start@GOT.w(%%a5), %0"
-       : "=a" (addr));
-#else
-  asm (PCREL_OP ("lea", "_dl_relocate_static_pie", "%0", "%0", "%%pc") "\n\t"
-       "sub.l _dl_relocate_static_pie@GOT.w(%%a5), %0"
-       : "=a" (addr));
-#endif
-  return addr;
-}
-
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/microblaze/dl-machine.h b/sysdeps/microblaze/dl-machine.h
index cba2eafb1c..9baf98ed2e 100644
--- a/sysdeps/microblaze/dl-machine.h
+++ b/sysdeps/microblaze/dl-machine.h
@@ -51,22 +51,6 @@  elf_machine_dynamic (void)
   return got_entry_0;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  /* Compute the difference between the runtime address of _DYNAMIC as seen
-     by a GOTOFF reference, and the link-time address found in the special
-     unrelocated first GOT entry.  */
-
-  Elf32_Addr dyn;
-  __asm__ __volatile__ (
-    "addik %0,r20,_DYNAMIC@GOTOFF"
-    : "=r"(dyn)
-    );
-  return dyn - elf_machine_dynamic ();
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/mips/dl-machine.h b/sysdeps/mips/dl-machine.h
index 10e30f1e90..6b6ecdef9f 100644
--- a/sysdeps/mips/dl-machine.h
+++ b/sysdeps/mips/dl-machine.h
@@ -121,42 +121,6 @@  elf_machine_dynamic (void)
 #define STRINGXV(X) STRINGV_(X)
 #define STRINGV_(...) # __VA_ARGS__
 
-/* Return the run-time load address of the shared object.  */
-static inline ElfW(Addr)
-elf_machine_load_address (void)
-{
-  ElfW(Addr) addr;
-#ifndef __mips16
-  asm ("	.set noreorder\n"
-       "	" STRINGXP (PTR_LA) " %0, 0f\n"
-# if !defined __mips_isa_rev || __mips_isa_rev < 6
-       "	bltzal $0, 0f\n"
-       "	nop\n"
-       "0:	" STRINGXP (PTR_SUBU) " %0, $31, %0\n"
-# else
-       "0:	addiupc $31, 0\n"
-       "	" STRINGXP (PTR_SUBU) " %0, $31, %0\n"
-# endif
-       "	.set reorder\n"
-       :	"=r" (addr)
-       :	/* No inputs */
-       :	"$31");
-#else
-  ElfW(Addr) tmp;
-  asm ("	.set noreorder\n"
-       "	move %1,$gp\n"
-       "	lw %1,%%got(0f)(%1)\n"
-       "0:	.fill 0\n"		/* Clear the ISA bit on 0:.  */
-       "	la %0,0b\n"
-       "	addiu %1,%%lo(0b)\n"
-       "	subu %0,%1\n"
-       "	.set reorder\n"
-       :	"=d" (addr), "=d" (tmp)
-       :	/* No inputs */);
-#endif
-  return addr;
-}
-
 /* The MSB of got[1] of a gnu object is set to identify gnu objects.  */
 #if _MIPS_SIM == _ABI64
 # define ELF_MIPS_GNU_GOT1_MASK	0x8000000000000000L
diff --git a/sysdeps/nios2/dl-machine.h b/sysdeps/nios2/dl-machine.h
index 5ebc9a9b89..34deb9b29b 100644
--- a/sysdeps/nios2/dl-machine.h
+++ b/sysdeps/nios2/dl-machine.h
@@ -51,20 +51,6 @@  elf_machine_dynamic (void)
 }
 
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  Elf32_Addr result;
-  int tmp;
-  asm ("nextpc\t%0\n\t"
-       "1: movhi\t%1, %%hiadj(1b)\n\t"
-       "addi\t%1, %1, %%lo(1b)\n\t"
-       "sub\t%0, %0, %1\n"
-       : "=r" (result), "=r" (tmp));
-  return result;
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/or1k/dl-machine.h b/sysdeps/or1k/dl-machine.h
index 779011e001..09f0253648 100644
--- a/sysdeps/or1k/dl-machine.h
+++ b/sysdeps/or1k/dl-machine.h
@@ -59,24 +59,6 @@  elf_machine_dynamic (void)
 }
 
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  /* Compute the difference between the runtime address of _DYNAMIC as seen
-     by a GOTOFF reference, and the link-time address found in the special
-     unrelocated first GOT entry.  */
-  Elf32_Addr dyn;
-  Elf32_Addr *got = or1k_get_got ();
-
-  asm ("l.movhi %0, gotoffhi(_DYNAMIC);"
-       "l.ori   %0, %0, gotofflo(_DYNAMIC);"
-       "l.add   %0, %0, %1;"
-       : "=&r"(dyn) : "r"(got));
-
-  return dyn - *got;
-}
-
 /* Initial entry point code for the dynamic linker.  The function _dl_start
    is the real entry point; it's return value is the user program's entry
    point.
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index fb7ac9e405..8e0082640e 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -62,54 +62,6 @@  elf_machine_dynamic (void)
   return *ppc_got ();
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr __attribute__ ((const))
-elf_machine_load_address (void)
-{
-  Elf32_Addr *branchaddr;
-  Elf32_Addr runtime_dynamic;
-
-  /* This is much harder than you'd expect.  Possibly I'm missing something.
-     The 'obvious' way:
-
-       Apparently, "bcl 20,31,$+4" is what should be used to load LR
-       with the address of the next instruction.
-       I think this is so that machines that do bl/blr pairing don't
-       get confused.
-
-     asm ("bcl 20,31,0f ;"
-	  "0: mflr 0 ;"
-	  "lis %0,0b@ha;"
-	  "addi %0,%0,0b@l;"
-	  "subf %0,%0,0"
-	  : "=b" (addr) : : "r0", "lr");
-
-     doesn't work, because the linker doesn't have to (and in fact doesn't)
-     update the @ha and @l references; the loader (which runs after this
-     code) will do that.
-
-     Instead, we use the following trick:
-
-     The linker puts the _link-time_ address of _DYNAMIC at the first
-     word in the GOT. We could branch to that address, if we wanted,
-     by using an @local reloc; the linker works this out, so it's safe
-     to use now. We can't, of course, actually branch there, because
-     we'd cause an illegal instruction exception; so we need to compute
-     the address ourselves. That gives us the following code: */
-
-  /* Get address of the 'b _DYNAMIC@local'...  */
-  asm ("bcl 20,31,0f;"
-       "b _DYNAMIC@local;"
-       "0:"
-       : "=l" (branchaddr));
-
-  /* So now work out the difference between where the branch actually points,
-     and the offset of that location in memory from the start of the file.  */
-  runtime_dynamic = ((Elf32_Addr) branchaddr
-		     + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6));
-
-  return runtime_dynamic - elf_machine_dynamic ();
-}
 
 /* The PLT uses Elf32_Rela relocs.  */
 #define elf_machine_relplt elf_machine_rela
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index 2b6f5d2b08..635902e854 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -73,55 +73,27 @@  elf_host_tolerates_class (const Elf64_Ehdr *ehdr)
 }
 
 
-/* Return the run-time load address of the shared object, assuming it
-   was originally linked at zero.  */
-static inline Elf64_Addr
-elf_machine_load_address (void) __attribute__ ((const));
-
 #ifndef __PCREL__
-static inline Elf64_Addr
-elf_machine_load_address (void)
-{
-  Elf64_Addr ret;
-
-  /* The first entry in .got (and thus the first entry in .toc) is the
-     link-time TOC_base, ie. r2.  So the difference between that and
-     the current r2 set by the kernel is how far the shared lib has
-     moved.  */
-  asm (	"	ld	%0,-32768(2)\n"
-	"	subf	%0,%0,2\n"
-	: "=r"	(ret));
-  return ret;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline Elf64_Addr
 elf_machine_dynamic (void)
 {
   Elf64_Addr runtime_dynamic;
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
   /* It's easier to get the run-time address.  */
   asm (	"	addis	%0,2,_DYNAMIC@toc@ha\n"
 	"	addi	%0,%0,_DYNAMIC@toc@l\n"
 	: "=b"	(runtime_dynamic));
   /* Then subtract off the load address offset.  */
-  return runtime_dynamic - elf_machine_load_address() ;
+  return runtime_dynamic - (ElfW(Addr)) &__ehdr_start;
 }
 #else /* __PCREL__ */
-/* In PCREL mode, r2 may have been clobbered.  Rely on relative
-   relocations instead.  */
-
-static inline ElfW(Addr)
-elf_machine_load_address (void)
-{
-  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
-  return (ElfW(Addr)) &__ehdr_start;
-}
-
 static inline ElfW(Addr)
 elf_machine_dynamic (void)
 {
   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
-  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+  return (ElfW(Addr)) _DYNAMIC - (ElfW(Addr)) &__ehdr_start;
 }
 #endif /* __PCREL__ */
 
diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
index b2f28697f7..a98f3037d6 100644
--- a/sysdeps/riscv/dl-machine.h
+++ b/sysdeps/riscv/dl-machine.h
@@ -75,20 +75,13 @@  elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
   return 1;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline ElfW(Addr)
-elf_machine_load_address (void)
-{
-  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
-  return (ElfW(Addr)) &__ehdr_start;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline ElfW(Addr)
 elf_machine_dynamic (void)
 {
   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
-  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+  return (ElfW(Addr)) _DYNAMIC - (ElfW(Addr)) &__ehdr_start;
 }
 
 #define STRINGXP(X) __STRING (X)
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 15ff999289..1b0d8df651 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -67,24 +67,6 @@  elf_machine_dynamic (void)
   return *got;
 }
 
-
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  Elf32_Addr addr;
-
-  __asm__( "   bras  1,2f\n"
-	   "1: .long _GLOBAL_OFFSET_TABLE_ - 1b\n"
-	   "   .long (_dl_start - 1b - 0x80000000) & 0x00000000ffffffff\n"
-	   "2: l     %0,4(1)\n"
-	   "   ar    %0,1\n"
-	   "   al    1,0(1)\n"
-	   "   sl    %0,_dl_start@GOT(1)"
-	   : "=&d" (addr) : : "1" );
-  return addr;
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index 5ed0b844e0..1d548e1288 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -59,20 +59,6 @@  elf_machine_dynamic (void)
   return *got;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf64_Addr
-elf_machine_load_address (void)
-{
-  Elf64_Addr addr;
-
-  __asm__( "   larl	 %0,_dl_start\n"
-	   "   larl	 1,_GLOBAL_OFFSET_TABLE_\n"
-	   "   lghi	 2,_dl_start@GOT\n"
-	   "   slg	 %0,0(2,1)"
-	   : "=&d" (addr) : : "1", "2" );
-  return addr;
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/sh/dl-machine.h b/sysdeps/sh/dl-machine.h
index c2c970d0c4..06ea38d98e 100644
--- a/sysdeps/sh/dl-machine.h
+++ b/sysdeps/sh/dl-machine.h
@@ -47,26 +47,6 @@  elf_machine_dynamic (void)
 }
 
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr __attribute__ ((unused))
-elf_machine_load_address (void)
-{
-  Elf32_Addr addr;
-  asm ("mov.l 1f,r0\n\
-	mov.l 3f,r2\n\
-	add r12,r2\n\
-	mov.l @(r0,r12),r0\n\
-	bra 2f\n\
-	 sub r0,r2\n\
-	.align 2\n\
-	1: .long _dl_start@GOT\n\
-	3: .long _dl_start@GOTOFF\n\
-	2: mov r2,%0"
-       : "=r" (addr) : : "r0", "r1", "r2");
-  return addr;
-}
-
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h
index d855c66fe3..73e24a7d8d 100644
--- a/sysdeps/sparc/sparc32/dl-machine.h
+++ b/sysdeps/sparc/sparc32/dl-machine.h
@@ -76,26 +76,6 @@  elf_machine_dynamic (void)
   return *got;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
-elf_machine_load_address (void)
-{
-  register Elf32_Addr *pc __asm ("%o7"), *got __asm ("%l7");
-
-  __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t"
-	 "call 1f\n\t"
-	 " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t"
-	 "call _DYNAMIC\n\t"
-	 "call _GLOBAL_OFFSET_TABLE_\n"
-	 "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got));
-
-  /* got is now l_addr + _GLOBAL_OFFSET_TABLE_
-     *got is _DYNAMIC
-     pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8
-     pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12  */
-  return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4;
-}
-
 /* Set up the loaded object described by L so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.  */
 
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 7f55e7d600..4dee2611c2 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -64,27 +64,6 @@  elf_machine_dynamic (void)
   return *elf_pic_register;
 }
 
-/* Return the run-time load address of the shared object.  */
-static inline Elf64_Addr
-elf_machine_load_address (void)
-{
-  register Elf32_Addr *pc __asm ("%o7");
-  register Elf64_Addr *got __asm ("%l7");
-
-  __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t"
-	 "call 1f\n\t"
-	 " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t"
-	 "call _DYNAMIC\n\t"
-	 "call _GLOBAL_OFFSET_TABLE_\n"
-	 "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got));
-
-  /* got is now l_addr + _GLOBAL_OFFSET_TABLE_
-     *got is _DYNAMIC
-     pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8
-     pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12  */
-  return (Elf64_Addr) got - *got + (Elf32_Sword) ((pc[2] - pc[3]) * 4) - 4;
-}
-
 static inline Elf64_Addr __attribute__ ((always_inline))
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
diff --git a/sysdeps/unix/sysv/linux/powerpc/libc-start.c b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
index 6a00cd88cd..80025dc93e 100644
--- a/sysdeps/unix/sysv/linux/powerpc/libc-start.c
+++ b/sysdeps/unix/sysv/linux/powerpc/libc-start.c
@@ -23,10 +23,6 @@ 
 #ifndef SHARED
 #include <hwcapinfo.h>
 #endif
-#if ENABLE_STATIC_PIE && !defined SHARED
-/* For elf_machine_load_address.  */
-#include <dl-machine.h>
-#endif
 
 /* The main work is done in the generic function.  */
 #define LIBC_START_MAIN generic_start_main
@@ -108,8 +104,9 @@  __libc_start_main_impl (int argc, char **argv,
   void *stmain = stinfo->main;
 #if ENABLE_STATIC_PIE && !defined SHARED
   struct link_map *map = _dl_get_dl_main_map ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
   if (!map->l_relocated)
-    stmain = (char *) stmain + elf_machine_load_address ();
+    stmain = (char *) stmain + (ElfW(Addr)) &__ehdr_start;
 #endif
 
   return generic_start_main (stmain, argc, argv, auxvec,
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index ff5d45f7cb..dd00152b39 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -46,21 +46,13 @@  elf_machine_matches_host (const ElfW(Ehdr) *ehdr)
   return ehdr->e_machine == EM_X86_64;
 }
 
-
-/* Return the run-time load address of the shared object.  */
-static inline ElfW(Addr) __attribute__ ((unused))
-elf_machine_load_address (void)
-{
-  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
-  return (ElfW(Addr)) &__ehdr_start;
-}
-
 /* Return the link-time address of _DYNAMIC.  */
 static inline ElfW(Addr) __attribute__ ((unused))
 elf_machine_dynamic (void)
 {
   extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
-  return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
+  extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+  return (ElfW(Addr)) _DYNAMIC - (ElfW(Addr)) &__ehdr_start;
 }
 
 /* Set up the loaded object described by L so its unrelocated PLT