aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorStefan Liebler <stli@linux.ibm.com>2024-12-06 12:50:09 +0100
committerStefan Liebler <stli@linux.ibm.com>2024-12-13 09:44:38 +0100
commit97b74cbbb0724c26fbbd5037a6ab9f81ac0a10a1 (patch)
tree837b8b171b227c0c9f5867f33903b5c7d8ab9c70 /sysdeps
parente4e49583d99869378c33415e49a36041cd6e14c9 (diff)
downloadglibc-97b74cbbb0724c26fbbd5037a6ab9f81ac0a10a1.zip
glibc-97b74cbbb0724c26fbbd5037a6ab9f81ac0a10a1.tar.gz
glibc-97b74cbbb0724c26fbbd5037a6ab9f81ac0a10a1.tar.bz2
s390: Simplify elf_machine_{load_address, dynamic} [BZ #31799]
If an executable is static PIE and has a non-zero load address (compare to elf/tst-pie-address-static), it segfaults as elf_machine_load_address() returns 0x0 and elf_machine_dynamic() returns the run-time instead of link-time address of _DYNAMIC. Now rely on __ehdr_start and _DYNAMIC as also done on other architectures. Checked back to old arch-levels that this approach works fine: - 31bit: -march=g5 - 64bit: -march=z900 Note, that there is no static-PIE support on 31bit, but this approach cleans it also up. Furthermore this cleanup in glibc does not change anything regarding the first GOT-element as the s390 ABI (https://github.com/IBM/s390x-abi) explicitely defines: The doubleword at _GLOBAL_OFFSET_TABLE_[0] is set by the linkage editor to hold the address of the dynamic structure, referenced with the symbol _DYNAMIC. This allows a program, such as the dynamic linker, to find its own dynamic structure without having yet processed its relocation entries. This is especially important for the dynamic linker, because it must initialize itself without relying on other programs to relocate its memory image.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/s390/s390-32/dl-machine.h37
-rw-r--r--sysdeps/s390/s390-64/dl-machine.h31
2 files changed, 20 insertions, 48 deletions
diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h
index 15ff999..d7dc53f 100644
--- a/sysdeps/s390/s390-32/dl-machine.h
+++ b/sysdeps/s390/s390-32/dl-machine.h
@@ -50,39 +50,22 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
}
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT. This must be inlined in a function which
- uses global data. */
-
+/* Return the run-time load address of the shared object. */
static inline Elf32_Addr
-elf_machine_dynamic (void)
+elf_machine_load_address (void)
{
- register Elf32_Addr *got;
-
- __asm__( " bras %0,2f\n"
- "1: .long _GLOBAL_OFFSET_TABLE_-1b\n"
- "2: al %0,0(%0)"
- : "=&a" (got) : : "0" );
-
- return *got;
+ /* Starting from binutils-2.23, the linker will define the magic symbol
+ __ehdr_start to point to our own ELF header. */
+ extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+ return (ElfW(Addr)) &__ehdr_start;
}
-
-/* Return the run-time load address of the shared object. */
+/* Return the link-time address of _DYNAMIC. */
static inline Elf32_Addr
-elf_machine_load_address (void)
+elf_machine_dynamic (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;
+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
+ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
}
/* Set up the loaded object described by L so its unrelocated PLT
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h
index 5ed0b84..976b2e0 100644
--- a/sysdeps/s390/s390-64/dl-machine.h
+++ b/sysdeps/s390/s390-64/dl-machine.h
@@ -44,33 +44,22 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
&& ehdr->e_ident[EI_CLASS] == ELFCLASS64;
}
-/* Return the link-time address of _DYNAMIC. Conveniently, this is the
- first element of the GOT. This must be inlined in a function which
- uses global data. */
-
+/* Return the run-time load address of the shared object. */
static inline Elf64_Addr
-elf_machine_dynamic (void)
+elf_machine_load_address (void)
{
- register Elf64_Addr *got;
-
- __asm__ ( " larl %0,_GLOBAL_OFFSET_TABLE_\n"
- : "=&a" (got) : : "0" );
-
- return *got;
+ /* Starting from binutils-2.23, the linker will define the magic symbol
+ __ehdr_start to point to our own ELF header. */
+ extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
+ return (ElfW(Addr)) &__ehdr_start;
}
-/* Return the run-time load address of the shared object. */
+/* Return the link-time address of _DYNAMIC. */
static inline Elf64_Addr
-elf_machine_load_address (void)
+elf_machine_dynamic (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;
+ extern ElfW(Dyn) _DYNAMIC[] attribute_hidden;
+ return (ElfW(Addr)) _DYNAMIC - elf_machine_load_address ();
}
/* Set up the loaded object described by L so its unrelocated PLT