From 3d2b3019e0efa9735370498122ac80298deff8c7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 21 Feb 2012 15:42:42 -0800 Subject: [PATCH] Use sparc GOTDATA relocations whenever possible. * sysdeps/sparc/crti.S: Try to use GOTDATA relocs. * sysdeps/sparc/sparc32/dl-machine.h (RTLD_START): Likewise. * sysdeps/sparc/sparc32/elf/start.S: Likewise. * sysdeps/sparc/sparc64/dl-machine.h (RTLD_START): Likewise. * sysdeps/sparc/sparc64/elf/start.S: Likewise. * sysdeps/sparc/sparc64/multiarch/memcpy.S: Likewise. * sysdeps/sparc/sparc64/multiarch/memset.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h (SYSCALL_ERROR_HANDLER): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/____longjmp_chk.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/brk.S: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h (SYSCALL_ERROR_HANDLER): Likewise. --- ChangeLog | 15 +++++++ sysdeps/sparc/crti.S | 6 +++ sysdeps/sparc/sparc32/dl-machine.h | 30 +++++++------ sysdeps/sparc/sparc32/elf/start.S | 30 +++++++++---- sysdeps/sparc/sparc64/dl-machine.h | 32 +++++++------- sysdeps/sparc/sparc64/elf/start.S | 42 ++++++++++++------- sysdeps/sparc/sparc64/multiarch/memcpy.S | 7 +--- sysdeps/sparc/sparc64/multiarch/memset.S | 14 +------ .../linux/sparc/sparc32/____longjmp_chk.S | 18 ++++---- .../unix/sysv/linux/sparc/sparc32/sysdep.h | 26 +++++++++++- .../linux/sparc/sparc64/____longjmp_chk.S | 18 ++++---- sysdeps/unix/sysv/linux/sparc/sparc64/brk.S | 34 +++++++++++---- .../unix/sysv/linux/sparc/sparc64/sysdep.h | 26 +++++++++++- 13 files changed, 202 insertions(+), 96 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6eb14f67d5..5f966e8072 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2012-02-20 David S. Miller + * sysdeps/sparc/crti.S: Try to use GOTDATA relocs. + * sysdeps/sparc/sparc32/dl-machine.h (RTLD_START): Likewise. + * sysdeps/sparc/sparc32/elf/start.S: Likewise. + * sysdeps/sparc/sparc64/dl-machine.h (RTLD_START): Likewise. + * sysdeps/sparc/sparc64/elf/start.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memcpy.S: Likewise. + * sysdeps/sparc/sparc64/multiarch/memset.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h + (SYSCALL_ERROR_HANDLER): Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/____longjmp_chk.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/brk.S: Likewise. + * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h + (SYSCALL_ERROR_HANDLER): Likewise. + * config.h.in (HAVE_BINUTILS_GOTDATA): New. (HAVE_GCC_GOTDATA): New. * sysdeps/sparc/elf/configure.in: Test for GOTDATA diff --git a/sysdeps/sparc/crti.S b/sysdeps/sparc/crti.S index 6ec4e9a5b3..caed362293 100644 --- a/sysdeps/sparc/crti.S +++ b/sysdeps/sparc/crti.S @@ -71,9 +71,15 @@ _init: save %sp, -STACKFRAME_SIZE, %sp #if PREINIT_FUNCTION_WEAK SETUP_PIC_REG(l7) +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(PREINIT_FUNCTION), %g1 + xor %g1, %gdop_lox10(PREINIT_FUNCTION), %g1 + GOT_LOAD [%l7 + %g1], %g1, %gdop(PREINIT_FUNCTION) +#else sethi %hi(PREINIT_FUNCTION), %g1 or %g1, %lo(PREINIT_FUNCTION), %g1 GOT_LOAD [%l7 + %g1], %g1 +#endif cmp %g1, 0 be 1f nop diff --git a/sysdeps/sparc/sparc32/dl-machine.h b/sysdeps/sparc/sparc32/dl-machine.h index a0c18dc1c4..7ea97fbffd 100644 --- a/sysdeps/sparc/sparc32/dl-machine.h +++ b/sysdeps/sparc/sparc32/dl-machine.h @@ -216,6 +216,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) The C function `_dl_start' is the real entry point; its return value is the user program's entry point. */ +#ifdef HAVE_BINUTILS_GOTDATA +#define RTLD_GOT_ADDRESS(pic_reg, reg, symbol) \ + "sethi %gdop_hix22(" #symbol "), " #reg "\n\t" \ + "xor " #reg ", %gdop_lox10(" #symbol "), " #reg "\n\t" \ + "ld [" #pic_reg " + " #reg "], " #reg ", %gdop(" #symbol ")" +#else +#define RTLD_GOT_ADDRESS(pic_reg, reg, symbol) \ + "sethi %hi(" #symbol "), " #reg "\n\t" \ + "or " #reg ", %lo(" #symbol "), " #reg "\n\t" \ + "ld [" #pic_reg " + " #reg "], " #reg +#endif + #define RTLD_START __asm__ ("\ .text\n\ .globl _start\n\ @@ -240,17 +252,13 @@ _dl_start_user:\n\ mov %o0, %l0\n\ /* See if we were run as a command with the executable file name as an\n\ extra leading argument. If so, adjust the contents of the stack. */\n\ - sethi %hi(_dl_skip_args), %g2\n\ - or %g2, %lo(_dl_skip_args), %g2\n\ - ld [%l7+%g2], %i0\n\ - ld [%i0], %i0\n\ + " RTLD_GOT_ADDRESS(%l7, %g2, _dl_skip_args) "\n\ + ld [%g2], %i0\n\ tst %i0\n\ beq 3f\n\ ld [%sp+22*4], %i5 /* load argc */\n\ /* Find out how far to shift. */\n\ - sethi %hi(_dl_argv), %l3\n\ - or %l3, %lo(_dl_argv), %l3\n\ - ld [%l7+%l3], %l3\n\ + " RTLD_GOT_ADDRESS(%l7, %l3, _dl_argv) "\n\ sub %i5, %i0, %i5\n\ ld [%l3], %l4\n\ sll %i0, 2, %i2\n\ @@ -283,20 +291,16 @@ _dl_start_user:\n\ bne 23b\n\ add %i1, 8, %i1\n\ /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n\ -3: sethi %hi(_rtld_local), %o0\n\ +3: " RTLD_GOT_ADDRESS(%l7, %o0, _rtld_local) "\n\ add %sp, 23*4, %o2\n\ - orcc %o0, %lo(_rtld_local), %o0\n\ sll %i5, 2, %o3\n\ - ld [%l7+%o0], %o0\n\ add %o3, 4, %o3\n\ mov %i5, %o1\n\ add %o2, %o3, %o3\n\ call _dl_init_internal\n\ ld [%o0], %o0\n\ /* Pass our finalizer function to the user in %g1. */\n\ - sethi %hi(_dl_fini), %g1\n\ - or %g1, %lo(_dl_fini), %g1\n\ - ld [%l7+%g1], %g1\n\ + " RTLD_GOT_ADDRESS(%l7, %g1, _dl_fini) "\n\ /* Jump to the user's entry point and deallocate the extra stack we got. */\n\ jmp %l0\n\ add %sp, 6*4, %sp\n\ diff --git a/sysdeps/sparc/sparc32/elf/start.S b/sysdeps/sparc/sparc32/elf/start.S index 11399109e3..0426714c5e 100644 --- a/sysdeps/sparc/sparc32/elf/start.S +++ b/sysdeps/sparc/sparc32/elf/start.S @@ -40,18 +40,11 @@ .section ".text" .align 4 -#ifdef SHARED -.LLGETPC0: - retl - add %o7, %l7, %l7 -#endif .global _start .type _start,#function _start: #ifdef SHARED - sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7 - call .LLGETPC0 - add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7 + SETUP_PIC_REG(l7) #endif /* Terminate the stack frame, and reserve space for functions to @@ -65,16 +58,35 @@ _start: add %sp, 23*4, %o2 /* Load the addresses of the user entry points. */ +#ifndef SHARED + sethi %hi(main), %o0 + sethi %hi(__libc_csu_init), %o3 + sethi %hi(__libc_csu_fini), %o4 + or %o0, %lo(main), %o0 + or %o3, %lo(__libc_csu_init), %o3 + or %o4, %lo(__libc_csu_fini), %o4 +#else +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(main), %o0 + sethi %gdop_hix22(__libc_csu_init), %o3 + sethi %gdop_hix22(__libc_csu_fini), %o4 + xor %o0, %gdop_lox10(main), %o0 + xor %o3, %gdop_lox10(__libc_csu_init), %o3 + xor %o4, %gdop_lox10(__libc_csu_fini), %o4 + ld [%l7 + %o0], %o0, %gdop(main) + ld [%l7 + %o3], %o3, %gdop(__libc_csu_init) + ld [%l7 + %o4], %o4, %gdop(__libc_csu_fini) +#else sethi %hi(main), %o0 sethi %hi(__libc_csu_init), %o3 sethi %hi(__libc_csu_fini), %o4 or %o0, %lo(main), %o0 or %o3, %lo(__libc_csu_init), %o3 or %o4, %lo(__libc_csu_fini), %o4 -#ifdef SHARED ld [%l7 + %o0], %o0 ld [%l7 + %o3], %o3 ld [%l7 + %o4], %o4 +#endif #endif /* When starting a binary via the dynamic linker, %g1 contains the diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index 5a00c9356e..6bab5ce310 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -264,6 +264,18 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) The C function `_dl_start' is the real entry point; its return value is the user program's entry point. */ +#ifdef HAVE_BINUTILS_GOTDATA +#define RTLD_GOT_ADDRESS(pic_reg, reg, symbol) \ + "sethi %gdop_hix22(" #symbol "), " #reg "\n\t" \ + "xor " #reg ", %gdop_lox10(" #symbol "), " #reg "\n\t" \ + "ldx [" #pic_reg " + " #reg "], " #reg ", %gdop(" #symbol ")\n" +#else +#define RTLD_GOT_ADDRESS(pic_reg, reg, symbol) \ + "sethi %hi(" #symbol "), " #reg "\n\t" \ + "or " #reg ", %lo(" #symbol "), " #reg "\n\t" \ + "ldx [" #pic_reg " + " #reg "], " #reg "\n" +#endif + #define __S1(x) #x #define __S(x) __S1(x) @@ -288,24 +300,20 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) "1: call 11f\n" \ " sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n" \ "11: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n" \ -" sethi %hi(_dl_skip_args), %g5\n" \ " add %l7, %o7, %l7\n" \ -" or %g5, %lo(_dl_skip_args), %g5\n" \ " /* Save the user entry point address in %l0. */\n" \ " mov %o0, %l0\n" \ " /* See if we were run as a command with the executable file name as an\n" \ " extra leading argument. If so, we must shift things around since we\n" \ " must keep the stack doubleword aligned. */\n" \ -" ldx [%l7 + %g5], %i0\n" \ -" ld [%i0], %i0\n" \ + RTLD_GOT_ADDRESS(%l7, %g5, _dl_skip_args) \ +" ld [%g5], %i0\n" \ " brz,pt %i0, 2f\n" \ " ldx [%sp + " __S(STACK_BIAS) " + 22*8], %i5\n" \ " /* Find out how far to shift. */\n" \ -" sethi %hi(_dl_argv), %l4\n" \ " sub %i5, %i0, %i5\n" \ -" or %l4, %lo(_dl_argv), %l4\n" \ " sllx %i0, 3, %l6\n" \ -" ldx [%l7 + %l4], %l4\n" \ + RTLD_GOT_ADDRESS(%l7, %l4, _dl_argv) \ " stx %i5, [%sp + " __S(STACK_BIAS) " + 22*8]\n" \ " add %sp, " __S(STACK_BIAS) " + 23*8, %i1\n" \ " add %i1, %l6, %i2\n" \ @@ -333,20 +341,16 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) " add %i1, 16, %i1\n" \ " stx %l5, [%l4]\n" \ " /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n" \ -"2: sethi %hi(_rtld_local), %o0\n" \ -" add %sp, " __S(STACK_BIAS) " + 23*8, %o2\n" \ -" orcc %o0, %lo(_rtld_local), %o0\n" \ +"2:\t" RTLD_GOT_ADDRESS(%l7, %o0, _rtld_local) \ " sllx %i5, 3, %o3\n" \ -" ldx [%l7 + %o0], %o0\n" \ +" add %sp, " __S(STACK_BIAS) " + 23*8, %o2\n" \ " add %o3, 8, %o3\n" \ " mov %i5, %o1\n" \ " add %o2, %o3, %o3\n" \ " call _dl_init_internal\n" \ " ldx [%o0], %o0\n" \ " /* Pass our finalizer function to the user in %g1. */\n" \ -" sethi %hi(_dl_fini), %g1\n" \ -" or %g1, %lo(_dl_fini), %g1\n" \ -" ldx [%l7 + %g1], %g1\n" \ + RTLD_GOT_ADDRESS(%l7, %g1, _dl_fini) \ " /* Jump to the user's entry point and deallocate the extra stack we got. */\n" \ " jmp %l0\n" \ " add %sp, 6*8, %sp\n" \ diff --git a/sysdeps/sparc/sparc64/elf/start.S b/sysdeps/sparc/sparc64/elf/start.S index afae70b4ba..50f2df2c7e 100644 --- a/sysdeps/sparc/sparc64/elf/start.S +++ b/sysdeps/sparc/sparc64/elf/start.S @@ -40,18 +40,11 @@ .section ".text" .align 4 -#ifdef SHARED -.LLGETPC0: - retl - add %o7, %l7, %l7 -#endif .global _start .type _start,#function _start: #ifdef SHARED - sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7 - call .LLGETPC0 - add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7 + SETUP_PIC_REG(l7) #endif /* Terminate the stack frame, and reserve space for functions to @@ -66,16 +59,35 @@ _start: add %sp, STACK_BIAS+23*8, %o2 /* Load the addresses of the user entry points. */ - sethi %hi(main), %o0 - sethi %hi(__libc_csu_init), %o3 - sethi %hi(__libc_csu_fini), %o4 - or %o0, %lo(main), %o0 - or %o3, %lo(__libc_csu_init), %o3 - or %o4, %lo(__libc_csu_fini), %o4 -#ifdef SHARED +#ifndef SHARED + sethi %hi(main), %o0 + sethi %hi(__libc_csu_init), %o3 + sethi %hi(__libc_csu_fini), %o4 + or %o0, %lo(main), %o0 + or %o3, %lo(__libc_csu_init), %o3 + or %o4, %lo(__libc_csu_fini), %o4 +#else +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(main), %o0 + sethi %gdop_hix22(__libc_csu_init), %o3 + sethi %gdop_hix22(__libc_csu_fini), %o4 + xor %o0, %gdop_lox10(main), %o0 + xor %o3, %gdop_lox10(__libc_csu_init), %o3 + xor %o4, %gdop_lox10(__libc_csu_fini), %o4 + ldx [%l7 + %o0], %o0, %gdop(main) + ldx [%l7 + %o3], %o3, %gdop(__libc_csu_init) + ldx [%l7 + %o4], %o4, %gdop(__libc_csu_fini) +#else + sethi %hi(main), %o0 + sethi %hi(__libc_csu_init), %o3 + sethi %hi(__libc_csu_fini), %o4 + or %o0, %lo(main), %o0 + or %o3, %lo(__libc_csu_init), %o3 + or %o4, %lo(__libc_csu_fini), %o4 ldx [%l7 + %o0], %o0 ldx [%l7 + %o3], %o3 ldx [%l7 + %o4], %o4 +#endif #endif /* When starting a binary via the dynamic linker, %g1 contains the diff --git a/sysdeps/sparc/sparc64/multiarch/memcpy.S b/sysdeps/sparc/sparc64/multiarch/memcpy.S index 2fd5e9bf9b..739687f3b8 100644 --- a/sysdeps/sparc/sparc64/multiarch/memcpy.S +++ b/sysdeps/sparc/sparc64/multiarch/memcpy.S @@ -25,12 +25,7 @@ ENTRY(memcpy) .type memcpy, @gnu_indirect_function # ifdef SHARED - mov %o7, %o5 - sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o3 - call 1f - or %o3, %lo(_GLOBAL_OFFSET_TABLE_+4), %o3 -1: add %o7, %o3, %o3 - mov %o5, %o7 + SETUP_PIC_REG_LEAF(o3, o5) # endif andcc %o0, HWCAP_SPARC_N2, %g0 be 1f diff --git a/sysdeps/sparc/sparc64/multiarch/memset.S b/sysdeps/sparc/sparc64/multiarch/memset.S index bf2eb637e6..13533450c2 100644 --- a/sysdeps/sparc/sparc64/multiarch/memset.S +++ b/sysdeps/sparc/sparc64/multiarch/memset.S @@ -25,12 +25,7 @@ ENTRY(memset) .type memset, @gnu_indirect_function # ifdef SHARED - mov %o7, %o5 - sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o3 - call 1f - or %o3, %lo(_GLOBAL_OFFSET_TABLE_+4), %o3 -1: add %o7, %o3, %o3 - mov %o5, %o7 + SETUP_PIC_REG_LEAF(o3, o5) # endif andcc %o0, HWCAP_SPARC_BLKINIT, %g0 be 9f @@ -61,12 +56,7 @@ END(memset) ENTRY(__bzero) .type bzero, @gnu_indirect_function # ifdef SHARED - mov %o7, %o5 - sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o3 - call 1f - or %o3, %lo(_GLOBAL_OFFSET_TABLE_+4), %o3 -1: add %o7, %o3, %o3 - mov %o5, %o7 + SETUP_PIC_REG_LEAF(o3, o5) # endif andcc %o0, HWCAP_SPARC_BLKINIT, %g0 be 9f diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S index 8b5ac7fceb..dfbf76165a 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S @@ -63,16 +63,20 @@ ENTRY (____longjmp_chk) nop .Lfail: -#ifdef PIC -1: call 2f - sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 -2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 - add %l7, %o7, %l7 -#endif +#ifndef PIC + sethi %hi(longjmp_msg), %o0 + or %o0, %lo(longjmp_msg), %o0 +#else + SETUP_PIC_REG(l7) +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(longjmp_msg), %o0 + xor %o0, %gdop_lox10(longjmp_msg), %o0 + ld [%l7 + %o0], %o0, %gdop(longjmp_msg) +#else sethi %hi(longjmp_msg), %o0 or %o0, %lo(longjmp_msg), %o0 -#ifdef PIC ld [%l7 + %o0], %o0 +#endif #endif call HIDDEN_JUMPTARGET(__fortify_fail) nop diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h index fd7ded5af9..3d6042e9ec 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h @@ -88,7 +88,17 @@ ENTRY(name); \ mov %g1, %o7; #else # if RTLD_PRIVATE_ERRNO -# define SYSCALL_ERROR_HANDLER \ +# ifdef HAVE_BINUTILS_GOTDATA +# define SYSCALL_ERROR_HANDLER \ +0: SETUP_PIC_REG_LEAF(o2,g1) \ + sethi %gdop_hix22(rtld_errno), %g1; \ + xor %g1, %gdop_lox10(rtld_errno), %g1;\ + ld [%o2 + %g1], %g1, %gdop(rtld_errno); \ + st %o0, [%g1]; \ + jmp %o7 + 8; \ + mov -1, %o0; +# else +# define SYSCALL_ERROR_HANDLER \ 0: SETUP_PIC_REG_LEAF(o2,g1) \ sethi %hi(rtld_errno), %g1; \ or %g1, %lo(rtld_errno), %g1; \ @@ -96,6 +106,7 @@ ENTRY(name); \ st %o0, [%g1]; \ jmp %o7 + 8; \ mov -1, %o0; +# endif # elif defined _LIBC_REENTRANT # ifndef NOT_IN_libc @@ -112,7 +123,17 @@ ENTRY(name); \ jmp %o7 + 8; \ mov -1, %o0; # else -# define SYSCALL_ERROR_HANDLER \ +# ifdef HAVE_BINUTILS_GOTDATA +# define SYSCALL_ERROR_HANDLER \ +0: SETUP_PIC_REG_LEAF(o2,g1) \ + sethi %gdop_hix22(errno), %g1;\ + xor %g1, %gdop_lox10(errno), %g1;\ + ld [%o2 + %g1], %g1, %gdop(errno);\ + st %o0, [%g1]; \ + jmp %o7 + 8; \ + mov -1, %o0; +# else +# define SYSCALL_ERROR_HANDLER \ 0: SETUP_PIC_REG_LEAF(o2,g1) \ sethi %hi(errno), %g1; \ or %g1, %lo(errno), %g1; \ @@ -120,6 +141,7 @@ ENTRY(name); \ st %o0, [%g1]; \ jmp %o7 + 8; \ mov -1, %o0; +# endif # endif /* _LIBC_REENTRANT */ #endif /* PIC */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/____longjmp_chk.S index c6587d5965..69cf5acb38 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/____longjmp_chk.S @@ -62,16 +62,20 @@ ENTRY (____longjmp_chk) nop .Lfail: -#ifdef PIC -1: call 2f - sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 -2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 - add %l7, %o7, %l7 -#endif +#ifndef PIC + sethi %hi(longjmp_msg), %o0 + or %o0, %lo(longjmp_msg), %o0 +#else + SETUP_PIC_REG(l7) +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(longjmp_msg), %o0 + xor %o0, %gdop_lox10(longjmp_msg), %o0 + ldx [%l7 + %o0], %o0, %gdop(longjmp_msg) +#else sethi %hi(longjmp_msg), %o0 or %o0, %lo(longjmp_msg), %o0 -#ifdef PIC ldx [%l7 + %o0], %o0 +#endif #endif call HIDDEN_JUMPTARGET(__fortify_fail) nop diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S index 74500eb486..a89d8775e1 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/brk.S @@ -42,10 +42,7 @@ ENTRY (__brk) cfi_window_save cfi_register(%o7, %i7) #ifdef PIC -1: call 2f - sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 -2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7 - add %l7, %o7, %l7 + SETUP_PIC_REG(l7) #endif LOADSYSCALL(brk) @@ -62,10 +59,20 @@ ENTRY (__brk) nop /* Update __curbrk and return cleanly. */ -.Lok: sethi %hi(__curbrk), %g1 +.Lok: +#ifndef PIC + sethi %hi(__curbrk), %g1 or %g1, %lo(__curbrk), %g1 -#ifdef PIC - ldx [%l7+%g1], %g1 +#else +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(__curbrk), %g1 + xor %g1, %gdop_lox10(__curbrk), %g1 + ldx [%l7 + %g1], %g1, %gdop(__curbrk) +#else + sethi %hi(__curbrk), %g1 + or %g1, %lo(__curbrk), %g1 + ldx [%l7 + %g1], %g1 +#endif #endif stx %o0, [%g1] mov %g0, %i0 @@ -78,10 +85,19 @@ ENTRY (__brk) .Lerr0: set ENOMEM, %o0 .Lerr1: #ifndef _LIBC_REENTRANT +#ifndef PIC sethi %hi(errno), %g1 or %g1, %lo(errno), %g1 -#ifdef PIC - ldx [%l7+%g1], %g1 +#else +#ifdef HAVE_BINUTILS_GOTDATA + sethi %gdop_hix22(errno), %g1 + xor %g1, %gdop_lox10(errno), %g1 + ldx [%l7 + %g1], %g1, %gdop(errno) +#else + sethi %hi(errno), %g1 + or %g1, %lo(errno), %g1 + ldx [%l7 + %g1], %g1 +#endif #endif st %o0, [%g1] #else diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h index 67ead22b50..33e1a41165 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h @@ -95,7 +95,17 @@ ENTRY(name); \ mov %g1, %o7; #else # if RTLD_PRIVATE_ERRNO -# define SYSCALL_ERROR_HANDLER \ +# ifdef HAVE_BINUTILS_GOTDATA +# define SYSCALL_ERROR_HANDLER \ +0: SETUP_PIC_REG_LEAF(o2,g1) \ + sethi %gdop_hix22(rtld_errno), %g1; \ + xor %g1, %gdop_lox10(rtld_errno), %g1;\ + ldx [%o2 + %g1], %g1, %gdop(rtld_errno); \ + st %o0, [%g1]; \ + jmp %o7 + 8; \ + mov -1, %o0; +# else +# define SYSCALL_ERROR_HANDLER \ 0: SETUP_PIC_REG_LEAF(o2,g1) \ sethi %hi(rtld_errno), %g1; \ or %g1, %lo(rtld_errno), %g1; \ @@ -103,6 +113,7 @@ ENTRY(name); \ st %o0, [%g1]; \ jmp %o7 + 8; \ mov -1, %o0; +# endif # elif defined _LIBC_REENTRANT # ifndef NOT_IN_libc @@ -119,7 +130,17 @@ ENTRY(name); \ jmp %o7 + 8; \ mov -1, %o0; # else -# define SYSCALL_ERROR_HANDLER \ +# ifdef HAVE_BINUTILS_GOTDATA +# define SYSCALL_ERROR_HANDLER \ +0: SETUP_PIC_REG_LEAF(o2,g1) \ + sethi %gdop_hix22(errno), %g1;\ + xor %g1, %gdop_lox10(errno), %g1;\ + ldx [%o2 + %g1], %g1, %gdop(errno);\ + st %o0, [%g1]; \ + jmp %o7 + 8; \ + mov -1, %o0; +# else +# define SYSCALL_ERROR_HANDLER \ 0: SETUP_PIC_REG_LEAF(o2,g1) \ sethi %hi(errno), %g1; \ or %g1, %lo(errno), %g1; \ @@ -127,6 +148,7 @@ ENTRY(name); \ st %o0, [%g1]; \ jmp %o7 + 8; \ mov -1, %o0; +# endif # endif /* _LIBC_REENTRANT */ #endif /* PIC */