From: Ulrich Drepper Date: Tue, 21 May 2002 02:18:04 +0000 (+0000) Subject: (LOAD_PIC_REG): Define. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f5cb3df4c01af3c14aafb16ce310640b17ff6079;p=thirdparty%2Fglibc.git (LOAD_PIC_REG): Define. (elf_machine_dynamic): Use it to force PIC register to be loaded. (elf_machine_load_address): Likewise. --- diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index d98848b5dd7..8426ffb765b 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -64,6 +64,17 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr) return 0; } +/* We have to do this because elf_machine_{dynamic,load_address} can be + invoked from functions that have no GOT references, and thus the compiler + has no obligation to load the PIC register. */ +#define LOAD_PIC_REG(PIC_REG) \ +do { register Elf32_Addr pc __asm("o7"); \ + __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \ + "call 1f\n\t" \ + "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n" \ + "1:\tadd %1, %0, %1" \ + : "=r" (pc), "=r" (PIC_REG)); \ +} while (0) /* Return the link-time address of _DYNAMIC. Conveniently, this is the first element of the GOT. This must be inlined in a function which @@ -72,6 +83,9 @@ static inline Elf32_Addr elf_machine_dynamic (void) { register Elf32_Addr *got asm ("%l7"); + + LOAD_PIC_REG (got); + return *got; } @@ -81,6 +95,8 @@ elf_machine_load_address (void) { register Elf32_Addr pc __asm("%o7"), pic __asm("%l7"), got; + LOAD_PIC_REG (pic); + /* Utilize the fact that a local .got entry will be partially initialized at startup awaiting its RELATIVE fixup. */ diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index b0f3d367e8b..eb4af958a83 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -34,6 +34,18 @@ elf_machine_matches_host (const Elf64_Ehdr *ehdr) return ehdr->e_machine == EM_SPARCV9; } +/* We have to do this because elf_machine_{dynamic,load_address} can be + invoked from functions that have no GOT references, and thus the compiler + has no obligation to load the PIC register. */ +#define LOAD_PIC_REG(PIC_REG) \ +do { Elf64_Addr tmp; \ + __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \ + "rd %%pc, %0\n\t" \ + "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t" \ + "add %0, %1, %0" \ + : "=r" (PIC_REG), "=r" (tmp)); \ +} while (0) + /* 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. */ @@ -42,6 +54,8 @@ elf_machine_dynamic (void) { register Elf64_Addr *elf_pic_register __asm__("%l7"); + LOAD_PIC_REG (elf_pic_register); + return *elf_pic_register; } @@ -51,6 +65,8 @@ elf_machine_load_address (void) { register Elf64_Addr *elf_pic_register __asm__("%l7"); + LOAD_PIC_REG (elf_pic_register); + /* We used to utilize the fact that a local .got entry will be partially initialized at startup awaiting its RELATIVE fixup: