* sysdeps/x86-64/dl-machine.h (elf_machine_load_address): Rewrite
to not use 32-bit pc relative relocations. (elf_machine_dynamic): Likewise.
This commit is contained in:
parent
05ae4d6ad9
commit
6c2b2a1987
@ -39,9 +39,12 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr)
|
||||
static inline Elf64_Addr __attribute__ ((unused))
|
||||
elf_machine_dynamic (void)
|
||||
{
|
||||
register Elf64_Addr addr;
|
||||
Elf64_Addr addr;
|
||||
|
||||
/* This works because we have our GOT address available in the small PIC
|
||||
model. */
|
||||
addr = (Elf64_Addr) &_DYNAMIC;
|
||||
|
||||
asm ("leaq _DYNAMIC, %0\n" : "=r" (addr));
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -52,10 +55,25 @@ elf_machine_load_address (void)
|
||||
{
|
||||
register Elf64_Addr addr, tmp;
|
||||
|
||||
asm ("leaq _dl_start, %0\n"
|
||||
"leaq _dl_start(%%rip), %1\n"
|
||||
"subq %0, %1\n"
|
||||
: "=r" (tmp), "=r" (addr) : : "cc");
|
||||
/* The easy way is just the same as on x86:
|
||||
leaq _dl_start, %0
|
||||
leaq _dl_start(%%rip), %1
|
||||
subq %0, %1
|
||||
but this does not work with binutils since we then have
|
||||
a R_X86_64_32S relocation in a shared lib.
|
||||
|
||||
Instead we store the address of _dl_start in the data section
|
||||
and compare it with the current value that we can get via
|
||||
an RIP relative addressing mode. */
|
||||
|
||||
asm ("movq .L1(%%rip), %1\n"
|
||||
"0:\tleaq _dl_start(%%rip), %0\n\t"
|
||||
"subq %1, %0\n\t"
|
||||
".section\t.data\n"
|
||||
".L1:\t.quad _dl_start\n\t"
|
||||
".previous\n\t"
|
||||
: "=r" (addr), "=r" (tmp) : : "cc");
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
@ -367,10 +385,33 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
|
||||
break;
|
||||
case R_X86_64_32:
|
||||
*(unsigned int *) reloc_addr = value + reloc->r_addend;
|
||||
if (value + reloc->r_addend > UINT_MAX)
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
|
||||
_dl_error_printf ("\
|
||||
%s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
break;
|
||||
case R_X86_64_PC32:
|
||||
*(unsigned int *) reloc_addr = value + reloc->r_addend
|
||||
- (Elf64_Addr) reloc_addr;
|
||||
if (value + reloc->r_addend - (Elf64_Addr) reloc_addr
|
||||
!= (unsigned int)(value + reloc->r_addend - (Elf64_Addr) reloc_addr))
|
||||
{
|
||||
const char *strtab;
|
||||
|
||||
strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
|
||||
|
||||
_dl_error_printf ("\
|
||||
%s: Symbol `%s' causes overflow in R_X86_64_PC32 relocation\n",
|
||||
rtld_progname ?: "<program name unknown>",
|
||||
strtab + refsym->st_name);
|
||||
}
|
||||
break;
|
||||
case R_X86_64_COPY:
|
||||
if (sym == NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user