aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/sparc/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/sparc/sparc64')
-rw-r--r--sysdeps/sparc/sparc64/dl-machine.h16
-rw-r--r--sysdeps/sparc/sparc64/strncmp.S11
2 files changed, 22 insertions, 5 deletions
diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h
index 4ced7deef8..fba323dece 100644
--- a/sysdeps/sparc/sparc64/dl-machine.h
+++ b/sysdeps/sparc/sparc64/dl-machine.h
@@ -39,6 +39,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. */
@@ -47,6 +59,8 @@ elf_machine_dynamic (void)
{
register Elf64_Addr *elf_pic_register __asm__("%l7");
+ LOAD_PIC_REG (elf_pic_register);
+
return *elf_pic_register;
}
@@ -56,6 +70,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:
diff --git a/sysdeps/sparc/sparc64/strncmp.S b/sysdeps/sparc/sparc64/strncmp.S
index 3bc21d6664..31fcfeee08 100644
--- a/sysdeps/sparc/sparc64/strncmp.S
+++ b/sysdeps/sparc/sparc64/strncmp.S
@@ -290,14 +290,15 @@ ENTRY(strncmp)
ldxa [%o0] ASI_PNF, %g4 /* Load */
11: sllx %g3, 3, %g5 /* IEU0 Group */
mov 64, %g7 /* IEU1 */
- sub %o1, %g3, %o1 /* IEU0 Group */
+ or %g1, %g2, %g1 /* IEU0 Group */
+ sub %o1, %g3, %o1 /* IEU1 */
- sub %g7, %g5, %g7 /* IEU1 */
+ sub %g7, %g5, %g7 /* IEU0 Group */
ldxa [%o1] ASI_PNF, %o4 /* Load */
- sllx %g1, 7, %g2 /* IEU0 Group */
- add %o1, 8, %o1 /* IEU1 */
+ sllx %g1, 7, %g2 /* IEU1 */
+ add %o1, 8, %o1 /* IEU0 Group */
/* %g1 = 0101010101010101
- %g2 = 8080808080800880
+ %g2 = 8080808080808080
%g3 = %o1 alignment
%g5 = number of bits to shift left
%g7 = number of bits to shift right */