S390: Use DT_JUMPREL in prelink undo code.

On s390, the current prelink undo code in elf_machine_lazy_rel()
has the requirement, that the plt stubs use the first got slots
after the 3 reserved ones.

In case of undoing prelink, the plt got slots are reset to the correct
addresses whithin the corresponding plt-stub. Therefore the address
is calculated by the address of the first plt-stub-address which
was written by prelink (see l->l_mach.plt) to got[1] and index of
current relocation multiplied with 32 (=size of one plt slot).
The index was calculated with &current-got-slot - &got[3].

This patch removes the requirement, that the plt-got-slots are
starting at got[3]. The index is now calculated with
&current-reloc - &reloc[0]. The first struct Elf64_Rela is stored
at DT_JMPREL.

This patch is needed to prepare for partial relro support.

Ulrich Weigand suggested this approach to use DT_JMPREL - Thanks.

ChangeLog:

	* sysdeps/s390/linkmap.h (struct link_map_machine):
	Remove member gotplt and add member jmprel.
	* sysdeps/s390/s390-32/dl-machine.h
	(elf_machine_runtime_setup): Setup member jmprel with DT_JMPREL
	instead of gotplt with &got[3].
	(elf_machine_lazy_rel): Calculate address with reloc and jmprel.
	* sysdeps/s390/s390-64/dl-machine.h: Likewise.
This commit is contained in:
Stefan Liebler 2016-07-06 15:22:35 +02:00
parent b95a6ebb93
commit dd8f8da99d
4 changed files with 16 additions and 10 deletions

View File

@ -1,3 +1,13 @@
2016-07-06 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/s390/linkmap.h (struct link_map_machine):
Remove member gotplt and add member jmprel.
* sysdeps/s390/s390-32/dl-machine.h
(elf_machine_runtime_setup): Setup member jmprel with DT_JMPREL
instead of gotplt with &got[3].
(elf_machine_lazy_rel): Calculate address with reloc and jmprel.
* sysdeps/s390/s390-64/dl-machine.h: Likewise.
2016-07-06 John David Anglin <danglin@gcc.gnu.org> 2016-07-06 John David Anglin <danglin@gcc.gnu.org>
* sysdeps/hppa/fpu/libm-test-ulps: Regenerate. * sysdeps/hppa/fpu/libm-test-ulps: Regenerate.

View File

@ -2,12 +2,12 @@
struct link_map_machine struct link_map_machine
{ {
Elf64_Addr plt; /* Address of .plt + 0x2e */ Elf64_Addr plt; /* Address of .plt + 0x2e */
Elf64_Addr gotplt; /* Address of .got + 0x18 */ const Elf64_Rela *jmprel; /* Address of first JMP_SLOT reloc */
}; };
#else #else
struct link_map_machine struct link_map_machine
{ {
Elf32_Addr plt; /* Address of .plt + 0x2c */ Elf32_Addr plt; /* Address of .plt + 0x2c */
Elf32_Addr gotplt; /* Address of .got + 0x0c */ const Elf32_Rela *jmprel; /* Address of first JMP_SLOT reloc */
}; };
#endif #endif

View File

@ -109,7 +109,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
if (got[1]) if (got[1])
{ {
l->l_mach.plt = got[1] + l->l_addr; l->l_mach.plt = got[1] + l->l_addr;
l->l_mach.gotplt = (Elf32_Addr) &got[3]; l->l_mach.jmprel = (const Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]);
} }
got[1] = (Elf32_Addr) l; /* Identify this shared object. */ got[1] = (Elf32_Addr) l; /* Identify this shared object. */
@ -506,9 +506,7 @@ elf_machine_lazy_rel (struct link_map *map,
if (__builtin_expect (map->l_mach.plt, 0) == 0) if (__builtin_expect (map->l_mach.plt, 0) == 0)
*reloc_addr += l_addr; *reloc_addr += l_addr;
else else
*reloc_addr = *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32;
map->l_mach.plt
+ (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 8;
} }
else if (__glibc_likely (r_type == R_390_IRELATIVE)) else if (__glibc_likely (r_type == R_390_IRELATIVE))
{ {

View File

@ -98,7 +98,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
if (got[1]) if (got[1])
{ {
l->l_mach.plt = got[1] + l->l_addr; l->l_mach.plt = got[1] + l->l_addr;
l->l_mach.gotplt = (Elf64_Addr) &got[3]; l->l_mach.jmprel = (const Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]);
} }
got[1] = (Elf64_Addr) l; /* Identify this shared object. */ got[1] = (Elf64_Addr) l; /* Identify this shared object. */
@ -460,9 +460,7 @@ elf_machine_lazy_rel (struct link_map *map,
if (__builtin_expect (map->l_mach.plt, 0) == 0) if (__builtin_expect (map->l_mach.plt, 0) == 0)
*reloc_addr += l_addr; *reloc_addr += l_addr;
else else
*reloc_addr = *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32;
map->l_mach.plt
+ (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 4;
} }
else if (__glibc_likely (r_type == R_390_IRELATIVE)) else if (__glibc_likely (r_type == R_390_IRELATIVE))
{ {