* 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:
Andreas Jaeger 2002-06-25 12:32:52 +00:00
parent 05ae4d6ad9
commit 6c2b2a1987
1 changed files with 47 additions and 6 deletions

View File

@ -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)