diff options
Diffstat (limited to 'REORG.TODO/sysdeps/s390/s390-64')
41 files changed, 2817 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/s390/s390-64/Implies b/REORG.TODO/sysdeps/s390/s390-64/Implies new file mode 100644 index 0000000000..a8cae95f9d --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/Implies @@ -0,0 +1 @@ +wordsize-64 diff --git a/REORG.TODO/sysdeps/s390/s390-64/Makefile b/REORG.TODO/sysdeps/s390/s390-64/Makefile new file mode 100644 index 0000000000..b4d793bb3d --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/Makefile @@ -0,0 +1,9 @@ +ifeq ($(subdir),gmon) +sysdep_routines += s390x-mcount +endif + +ifeq ($(subdir),elf) +CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused +CFLAGS-dl-load.c += -Wno-unused +CFLAGS-dl-reloc.c += -Wno-unused +endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/__longjmp.c b/REORG.TODO/sysdeps/s390/s390-64/__longjmp.c new file mode 100644 index 0000000000..f7be9ddb18 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/__longjmp.c @@ -0,0 +1,89 @@ +/* Copyright (C) 2001-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <sysdep.h> +#include <setjmp.h> +#include <bits/setjmp.h> +#include <stdlib.h> +#include <unistd.h> +#include <stap-probe.h> + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +void +__longjmp (__jmp_buf env, int val) +{ +#ifdef PTR_DEMANGLE + uintptr_t guard = THREAD_GET_POINTER_GUARD (); +# ifdef CHECK_SP + CHECK_SP (env, guard); +# endif +#elif defined CHECK_SP + CHECK_SP (env, 0); +#endif + register long int r2 __asm__ ("%r2") = val == 0 ? 1 : val; +#ifdef PTR_DEMANGLE + register uintptr_t r3 __asm__ ("%r3") = guard; + register void *r1 __asm__ ("%r1") = (void *) env; +#endif + /* Restore registers and jump back. */ + __asm__ __volatile__ ( + /* longjmp probe expects longjmp first argument, second + argument and target address. */ +#ifdef PTR_DEMANGLE + "lmg %%r4,%%r5,64(%1)\n\t" + "xgr %%r4,%2\n\t" + "xgr %%r5,%2\n\t" + LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r4) +#else + LIBC_PROBE_ASM (longjmp, 8@%1 -4@%0 8@%%r14) +#endif + + /* restore fpregs */ + "ld %%f8,80(%1)\n\t" + "ld %%f9,88(%1)\n\t" + "ld %%f10,96(%1)\n\t" + "ld %%f11,104(%1)\n\t" + "ld %%f12,112(%1)\n\t" + "ld %%f13,120(%1)\n\t" + "ld %%f14,128(%1)\n\t" + "ld %%f15,136(%1)\n\t" + + /* restore gregs and return to jmp_buf target */ +#ifdef PTR_DEMANGLE + "lmg %%r6,%%r13,0(%1)\n\t" + "lgr %%r15,%%r5\n\t" + LIBC_PROBE_ASM (longjmp_target, 8@%1 -4@%0 8@%%r4) + "br %%r4" +#else + "lmg %%r6,%%r15,0(%1)\n\t" + LIBC_PROBE_ASM (longjmp_target, 8@%1 -4@%0 8@%%r14) + "br %%r14" +#endif + : : "r" (r2), +#ifdef PTR_DEMANGLE + "r" (r1), "r" (r3) +#else + "a" (env) +#endif + ); + + /* Avoid `volatile function does return' warnings. */ + for (;;); +} diff --git a/REORG.TODO/sysdeps/s390/s390-64/add_n.S b/REORG.TODO/sysdeps/s390/s390-64/add_n.S new file mode 100644 index 0000000000..89197b2dbf --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/add_n.S @@ -0,0 +1,63 @@ +/* Add two limb vectors of the same length > 0 and store sum in a third + limb vector. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU MP Library. + + The GNU MP Library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your + option) any later version. + + The GNU MP Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the GNU MP Library; see the file COPYING.LIB. If not, + see <http://www.gnu.org/licenses/>. */ + +/* + INPUT PARAMETERS + res_ptr %r2 + s1_ptr %r3 + s2_ptr %r4 + size %r5 +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__mpn_add_n) + stg %r6,48(%r15) # save register 6 + cfi_offset (%r6,-112) + slgr %r1,%r1 + lghi %r0,1 # cannot use ahi to add carry, use alr +.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last add + alg %r6,0(%r1,%r4) + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 3,.L3 +.L1: brct %r5,.L0 + slgr %r2,%r2 # no last carry to return + j .Lexit +.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last add + alg %r6,0(%r1,%r4) + brc 3,.L4 + algr %r6,%r0 # no carry yet, add carry from last add + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 12,.L1 # new carry ? +.L3: brct %r5,.L2 + lgr %r2,%r0 # return last carry + j .Lexit +.L4: algr %r6,%r0 # already a carry, add carry from last add + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brct %r5,.L2 + lgr %r2,%r0 # return last carry +.Lexit: lg %r6,48(%r15) # restore register 6 + br %r14 +END(__mpn_add_n) diff --git a/REORG.TODO/sysdeps/s390/s390-64/backtrace.c b/REORG.TODO/sysdeps/s390/s390-64/backtrace.c new file mode 100644 index 0000000000..4843db623a --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/backtrace.c @@ -0,0 +1,147 @@ +/* Return backtrace of current program state. 64 bit S/390 version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <libc-lock.h> +#include <dlfcn.h> +#include <execinfo.h> +#include <stddef.h> +#include <stdlib.h> +#include <unwind.h> + + +/* This is a global variable set at program start time. It marks the + highest used stack address. */ +extern void *__libc_stack_end; + + +/* This is the stack layout we see for every non-leaf function. + size offset + %r15 -> +------------------+ + 8 | back chain | 0 + 8 | end of stack | 8 + 32 | scratch | 16 + 80 | save area r6-r15 | 48 + 16 | save area f4,f6 | 128 + 16 | empty | 144 + +------------------+ + r14 in the save area holds the return address. +*/ + +struct layout +{ + long back_chain; + long end_of_stack; + long scratch[4]; + long save_grps[10]; + long save_fp[2]; + long empty[2]; +}; + +struct trace_arg +{ + void **array; + int cnt, size; +}; + +#ifdef SHARED +static _Unwind_Reason_Code (*unwind_backtrace) (_Unwind_Trace_Fn, void *); +static _Unwind_Ptr (*unwind_getip) (struct _Unwind_Context *); + +static void +init (void) +{ + void *handle = __libc_dlopen ("libgcc_s.so.1"); + + if (handle == NULL) + return; + + unwind_backtrace = __libc_dlsym (handle, "_Unwind_Backtrace"); + unwind_getip = __libc_dlsym (handle, "_Unwind_GetIP"); + if (unwind_getip == NULL) + unwind_backtrace = NULL; +} + +static int +__backchain_backtrace (void **array, int size) +{ + /* We assume that all the code is generated with frame pointers set. */ + struct layout *stack; + int cnt = 0; + + __asm__ ("LGR %0,%%r15" : "=d" (stack) ); + /* We skip the call to this function, it makes no sense to record it. */ + stack = (struct layout *) stack->back_chain; + while (cnt < size) + { + if (stack == NULL || (void *) stack > __libc_stack_end) + /* This means the address is out of range. Note that for the + toplevel we see a frame pointer with value NULL which clearly is + out of range. */ + break; + + array[cnt++] = (void *) stack->save_grps[8]; + + stack = (struct layout *) stack->back_chain; + } + + return cnt; +} +#else +# define unwind_backtrace _Unwind_Backtrace +# define unwind_getip _Unwind_GetIP +#endif + +static _Unwind_Reason_Code +backtrace_helper (struct _Unwind_Context *ctx, void *a) +{ + struct trace_arg *arg = a; + + /* We are first called with address in the __backtrace function. + Skip it. */ + if (arg->cnt != -1) + arg->array[arg->cnt] = (void *) unwind_getip (ctx); + if (++arg->cnt == arg->size) + return _URC_END_OF_STACK; + return _URC_NO_REASON; +} + +int +__backtrace (void **array, int size) +{ + struct trace_arg arg = { .array = array, .size = size, .cnt = -1 }; + + if (size <= 0) + return 0; + +#ifdef SHARED + __libc_once_define (static, once); + + __libc_once (once, init); + + if (unwind_backtrace == NULL) + return __backchain_backtrace (array, size); +#endif + + unwind_backtrace (backtrace_helper, &arg); + + return arg.cnt != -1 ? arg.cnt : 0; +} + +weak_alias (__backtrace, backtrace) +libc_hidden_def (__backtrace) diff --git a/REORG.TODO/sysdeps/s390/s390-64/bcopy.S b/REORG.TODO/sysdeps/s390/s390-64/bcopy.S new file mode 100644 index 0000000000..235fc85568 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/bcopy.S @@ -0,0 +1,71 @@ +/* bcopy -- copy a block from source to destination. 64 bit S/390 version. + This file is part of the GNU C Library. + Copyright (C) 2000-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = address of source + %r3 = address of destination + %r4 = number of bytes to copy. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__bcopy) + ltgr %r1,%r4 # zero bcopy ? + jz .L4 + clgr %r2,%r3 # check against destructive overlap + jnl .L0 + algr %r1,%r2 + clgr %r1,%r3 + jh .L7 +.L0: aghi %r4,-1 # length - 1 + srlg %r1,%r4,8 + ltgr %r1,%r1 # < 256 bytes to move ? + jz .L2 + cghi %r1,255 # > 1MB to move ? + jh .L5 +.L1: mvc 0(256,%r3),0(%r2) # move in 256 byte chunks + la %r2,256(%r2) + la %r3,256(%r3) + brctg %r1,.L1 +.L2: bras %r1,.L3 # setup base pointer for execute + mvc 0(1,%r3),0(%r2) # instruction for execute +.L3: ex %r4,0(%r1) # execute mvc with length ((%r4)&255)+1 +.L4: br %r14 + # data copies > 1MB are faster with mvcle. +.L5: aghi %r4,1 # length + 1 + lgr %r5,%r4 # source length + lgr %r4,%r2 # source address + lgr %r2,%r3 # set destination + lgr %r3,%r5 # destination length = source length +.L6: mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L6 + br %r14 +.L7: # destructive overlay, can not use mvcle + lgr %r1,%r2 # bcopy is called with source,dest + lgr %r2,%r3 # memmove with dest,source! Oh, well... + lgr %r3,%r1 + jg HIDDEN_BUILTIN_JUMPTARGET(memmove) + +END(__bcopy) + +#ifndef NO_WEAK_ALIAS +weak_alias (__bcopy, bcopy) +#endif + diff --git a/REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h b/REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h new file mode 100644 index 0000000000..00e88b0628 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/bits/wordsize.h @@ -0,0 +1,11 @@ +/* Determine the wordsize from the preprocessor defines. */ + +#if defined __s390x__ +# define __WORDSIZE 64 +#else +# define __WORDSIZE 32 +# define __WORDSIZE32_SIZE_ULONG 1 +# define __WORDSIZE32_PTRDIFF_LONG 0 +#endif + +#define __WORDSIZE_TIME64_COMPAT32 0 diff --git a/REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S b/REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/bsd-_setjmp.S @@ -0,0 +1 @@ +/* We don't need any code here since the setjmp.S file contains it. */ diff --git a/REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S b/REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S new file mode 100644 index 0000000000..1417270201 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/bsd-setjmp.S @@ -0,0 +1 @@ +/* We don't need any code here since the setjmp.S file contains it. */ diff --git a/REORG.TODO/sysdeps/s390/s390-64/bzero.S b/REORG.TODO/sysdeps/s390/s390-64/bzero.S new file mode 100644 index 0000000000..119c20dcb9 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/bzero.S @@ -0,0 +1,41 @@ +/* bzero -- set a block of memory to zero. 64 bit S/390 version. + This file is part of the GNU C Library. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = address of memory area + %r3 = number of bytes to fill. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(__bzero) + ltgr %r3,%r3 + jz .L1 + sgr %r1,%r1 # set pad byte to zero + sgr %r4,%r4 # no source for MVCLE, only a pad byte + sgr %r5,%r5 +.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend + jo .L0 +.L1: br %r14 +END(__bzero) + +#ifndef NO_WEAK_ALIAS +weak_alias (__bzero, bzero) +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/crti.S b/REORG.TODO/sysdeps/s390/s390-64/crti.S new file mode 100644 index 0000000000..c9583bb9c9 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/crti.S @@ -0,0 +1,91 @@ +/* Special .init and .fini section support for 64 bit S/390. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* crti.S puts a function prologue at the beginning of the .init and + .fini sections and defines global symbols for those addresses, so + they can be called as functions. The symbols _init and _fini are + magic and cause the linker to emit DT_INIT and DT_FINI. */ + +#include <libc-symbols.h> +#include <sysdep.h> + +#ifndef PREINIT_FUNCTION +# define PREINIT_FUNCTION __gmon_start__ +#endif + +#ifndef PREINIT_FUNCTION_WEAK +# define PREINIT_FUNCTION_WEAK 1 +#endif + +#if PREINIT_FUNCTION_WEAK + weak_extern (PREINIT_FUNCTION) +#else + .hidden PREINIT_FUNCTION +#endif + + .section .init,"ax",@progbits + .align 4 + .globl _init + .type _init,@function +_init: + stmg %r6,%r15,48(%r15) + lgr %r1,%r15 + aghi %r15,-160 + stg %r1,0(%r15) + larl %r12,_GLOBAL_OFFSET_TABLE_ +#if PREINIT_FUNCTION_WEAK + larl %r1,PREINIT_FUNCTION@GOTENT + lg %r1,0(%r1) + ltgr %r1,%r1 + je 1f + basr %r14,%r1 +#else + brasl %r14,PREINIT_FUNCTION +#endif + .align 4,0x07 +1: + + .section .fini,"ax",@progbits + .align 4 + .globl _fini + .type _fini,@function +_fini: + stmg %r6,%r15,48(%r15) + lgr %r1,%r15 + aghi %r15,-160 + stg %r1,0(%r15) + larl %r12,_GLOBAL_OFFSET_TABLE_ + .align 4,0x07 diff --git a/REORG.TODO/sysdeps/s390/s390-64/crtn.S b/REORG.TODO/sysdeps/s390/s390-64/crtn.S new file mode 100644 index 0000000000..2bb3211e57 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/crtn.S @@ -0,0 +1,50 @@ +/* Special .init and .fini section support for 64 bit S/390. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* crtn.S puts function epilogues in the .init and .fini sections + corresponding to the prologues in crti.S. */ + + .section .init + .align 4 + lg %r4,272(%r15) + lmg %r6,%r15,208(%r15) + br %r4 + + .section .fini + .align 4 + lg %r4,272(%r15) + lmg %r6,%r15,208(%r15) + br %r4 diff --git a/REORG.TODO/sysdeps/s390/s390-64/dl-machine.h b/REORG.TODO/sysdeps/s390/s390-64/dl-machine.h new file mode 100644 index 0000000000..f2aeb1e78e --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/dl-machine.h @@ -0,0 +1,476 @@ +/* Machine-dependent ELF dynamic relocation inline functions. + 64 bit S/390 Version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "s390x" + +#include <sys/param.h> +#include <string.h> +#include <link.h> +#include <sysdeps/s390/dl-procinfo.h> +#include <dl-irel.h> + +#define ELF_MACHINE_IRELATIVE R_390_IRELATIVE + +/* This is an older, now obsolete value. */ +#define EM_S390_OLD 0xA390 + +/* Return nonzero iff E_MACHINE is compatible with the running host. */ +static inline int +elf_machine_matches_host (const Elf64_Ehdr *ehdr) +{ + return (ehdr->e_machine == EM_S390 || ehdr->e_machine == EM_S390_OLD) + && ehdr->e_ident[EI_CLASS] == ELFCLASS64; +} + +/* 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. */ + +static inline Elf64_Addr +elf_machine_dynamic (void) +{ + register Elf64_Addr *got; + + __asm__ ( " larl %0,_GLOBAL_OFFSET_TABLE_\n" + : "=&a" (got) : : "0" ); + + return *got; +} + +/* Return the run-time load address of the shared object. */ +static inline Elf64_Addr +elf_machine_load_address (void) +{ + Elf64_Addr addr; + + __asm__( " larl %0,_dl_start\n" + " larl 1,_GLOBAL_OFFSET_TABLE_\n" + " lghi 2,_dl_start@GOT\n" + " slg %0,0(2,1)" + : "=&d" (addr) : : "1", "2" ); + return addr; +} + +/* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +static inline int __attribute__ ((unused)) +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +{ + extern void _dl_runtime_resolve (Elf64_Word); + extern void _dl_runtime_profile (Elf64_Word); +#if defined HAVE_S390_VX_ASM_SUPPORT + extern void _dl_runtime_resolve_vx (Elf64_Word); + extern void _dl_runtime_profile_vx (Elf64_Word); +#endif + + if (l->l_info[DT_JMPREL] && lazy) + { + /* The GOT entries for functions in the PLT have not yet been filled + in. Their initial contents will arrange when called to push an + offset into the .rela.plt section, push _GLOBAL_OFFSET_TABLE_[1], + and then jump to _GLOBAL_OFFSET_TABLE[2]. */ + Elf64_Addr *got; + got = (Elf64_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + /* If a library is prelinked but we have to relocate anyway, + we have to be able to undo the prelinking of .got.plt. + The prelinker saved us here address of .plt + 0x2e. */ + if (got[1]) + { + l->l_mach.plt = got[1] + l->l_addr; + l->l_mach.jmprel = (const Elf64_Rela *) D_PTR (l, l_info[DT_JMPREL]); + } + got[1] = (Elf64_Addr) l; /* Identify this shared object. */ + + /* The got[2] entry contains the address of a function which gets + called to get the address of a so far unresolved function and + jump to it. The profiling extension of the dynamic linker allows + to intercept the calls to collect information. In this case we + don't store the address in the GOT so that all future calls also + end in this function. */ + if (__glibc_unlikely (profile)) + { +#if defined HAVE_S390_VX_ASM_SUPPORT + if (GLRO(dl_hwcap) & HWCAP_S390_VX) + got[2] = (Elf64_Addr) &_dl_runtime_profile_vx; + else + got[2] = (Elf64_Addr) &_dl_runtime_profile; +#else + got[2] = (Elf64_Addr) &_dl_runtime_profile; +#endif + + if (GLRO(dl_profile) != NULL + && _dl_name_match_p (GLRO(dl_profile), l)) + /* This is the object we are looking for. Say that we really + want profiling and the timers are started. */ + GL(dl_profile_map) = l; + } + else + { + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ +#if defined HAVE_S390_VX_ASM_SUPPORT + if (GLRO(dl_hwcap) & HWCAP_S390_VX) + got[2] = (Elf64_Addr) &_dl_runtime_resolve_vx; + else + got[2] = (Elf64_Addr) &_dl_runtime_resolve; +#else + got[2] = (Elf64_Addr) &_dl_runtime_resolve; +#endif + } + } + + return lazy; +} + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. */ + +#define RTLD_START __asm__ ("\n\ +.text\n\ +.align 4\n\ +.globl _start\n\ +.globl _dl_start_user\n\ +_start:\n\ + lgr %r2,%r15\n\ + # Alloc stack frame\n\ + aghi %r15,-160\n\ + # Set the back chain to zero\n\ + xc 0(8,%r15),0(%r15)\n\ + # Call _dl_start with %r2 pointing to arg on stack\n\ + brasl %r14,_dl_start # call _dl_start\n\ +_dl_start_user:\n\ + # Save the user entry point address in %r8.\n\ + lgr %r8,%r2\n\ + # Point %r12 at the GOT.\n\ + larl %r12,_GLOBAL_OFFSET_TABLE_\n\ + # See if we were run as a command with the executable file\n\ + # name as an extra leading argument.\n\ + lghi %r1,_dl_skip_args@GOT\n\ + lg %r1,0(%r1,%r12)\n\ + lgf %r1,0(%r1) # load _dl_skip_args\n\ + # Get the original argument count.\n\ + lg %r0,160(%r15)\n\ + # Subtract _dl_skip_args from it.\n\ + sgr %r0,%r1\n\ + # Adjust the stack pointer to skip _dl_skip_args words.\n\ + sllg %r1,%r1,3\n\ + agr %r15,%r1\n\ + # Set the back chain to zero again\n\ + xc 0(8,%r15),0(%r15)\n\ + # Store back the modified argument count.\n\ + stg %r0,160(%r15)\n\ + # The special initializer gets called with the stack just\n\ + # as the application's entry point will see it; it can\n\ + # switch stacks if it moves these contents over.\n\ +" RTLD_START_SPECIAL_INIT "\n\ + # Call the function to run the initializers.\n\ + # Load the parameters:\n\ + # (%r2, %r3, %r4, %r5) = (_dl_loaded, argc, argv, envp)\n\ + lghi %r2,_rtld_local@GOT\n\ + lg %r2,0(%r2,%r12)\n\ + lg %r2,0(%r2)\n\ + lg %r3,160(%r15)\n\ + la %r4,168(%r15)\n\ + lgr %r5,%r3\n\ + sllg %r5,%r5,3\n\ + la %r5,176(%r5,%r15)\n\ + brasl %r14,_dl_init@PLT\n\ + # Pass our finalizer function to the user in %r14, as per ELF ABI.\n\ + lghi %r14,_dl_fini@GOT\n\ + lg %r14,0(%r14,%r12)\n\ + # Free stack frame\n\ + aghi %r15,160\n\ + # Jump to the user's entry point (saved in %r8).\n\ + br %r8\n\ +"); + +#ifndef RTLD_START_SPECIAL_INIT +#define RTLD_START_SPECIAL_INIT /* nothing */ +#endif + +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or + TLS variable, so undefined references should not be allowed to + define the value. + ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one + of the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_type_class(type) \ + ((((type) == R_390_JMP_SLOT || (type) == R_390_TLS_DTPMOD \ + || (type) == R_390_TLS_DTPOFF || (type) == R_390_TLS_TPOFF) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_390_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ +#define ELF_MACHINE_JMP_SLOT R_390_JMP_SLOT + +/* The 64 bit S/390 never uses Elf64_Rel relocations. */ +#define ELF_MACHINE_NO_REL 1 +#define ELF_MACHINE_NO_RELA 0 + +/* We define an initialization functions. This is called very early in + _dl_sysdep_start. */ +#define DL_PLATFORM_INIT dl_platform_init () + +static inline void __attribute__ ((unused)) +dl_platform_init (void) +{ + if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0') + /* Avoid an empty string which would disturb us. */ + GLRO(dl_platform) = NULL; +} + +static inline Elf64_Addr +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const Elf64_Rela *reloc, + Elf64_Addr *reloc_addr, Elf64_Addr value) +{ + return *reloc_addr = value; +} + +/* Return the final value of a plt relocation. */ +static inline Elf64_Addr +elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, + Elf64_Addr value) +{ + return value; +} + +/* Names of the architecture-specific auditing callback functions. */ +#define ARCH_LA_PLTENTER s390_64_gnu_pltenter +#define ARCH_LA_PLTEXIT s390_64_gnu_pltexit + +#endif /* !dl_machine_h */ + +#ifdef RESOLVE_MAP + +/* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + const Elf64_Sym *sym, const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) +{ + Elf64_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); + +#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC + if (__glibc_unlikely (r_type == R_390_RELATIVE)) + { +# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC + /* This is defined in rtld.c, but nowhere in the static libc.a; + make the reference weak so static programs can still link. + This declaration cannot be done when compiling rtld.c + (i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the + common defn for _dl_rtld_map, which is incompatible with a + weak decl in the same file. */ +# ifndef SHARED + weak_extern (GL(dl_rtld_map)); +# endif + if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */ +# endif + *reloc_addr = map->l_addr + reloc->r_addend; + } + else +#endif + if (__glibc_unlikely (r_type == R_390_NONE)) + return; + else + { +#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP + /* Only needed for R_390_COPY below. */ + const Elf64_Sym *const refsym = sym; +#endif + struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; + + if (sym != NULL + && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, + 0) + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) + && __builtin_expect (!skip_ifunc, 1)) + value = elf_ifunc_invoke (value); + + switch (r_type) + { + case R_390_IRELATIVE: + value = map->l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = elf_ifunc_invoke (value); + *reloc_addr = value; + break; + case R_390_GLOB_DAT: + case R_390_JMP_SLOT: + *reloc_addr = value + reloc->r_addend; + break; + +#ifndef RESOLVE_CONFLICT_FIND_MAP + case R_390_TLS_DTPMOD: +# ifdef RTLD_BOOTSTRAP + /* During startup the dynamic linker is always the module + with index 1. + XXX If this relocation is necessary move before RESOLVE + call. */ + *reloc_addr = 1; +# else + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; +# endif + break; + case R_390_TLS_DTPOFF: +# ifndef RTLD_BOOTSTRAP + /* During relocation all TLS symbols are defined and used. + Therefore the offset is already correct. */ + if (sym != NULL) + *reloc_addr = sym->st_value + reloc->r_addend; +# endif + break; + case R_390_TLS_TPOFF: + /* The offset is negative, forward from the thread pointer. */ +# ifdef RTLD_BOOTSTRAP + *reloc_addr = sym->st_value + reloc->r_addend - map->l_tls_offset; +# else + /* We know the offset of the object the symbol is contained in. + It is a negative value which will be added to the + thread pointer. */ + if (sym != NULL) + { + CHECK_STATIC_TLS (map, sym_map); + *reloc_addr = (sym->st_value + reloc->r_addend + - sym_map->l_tls_offset); + } +#endif + break; +#endif /* use TLS */ + +#ifndef RTLD_BOOTSTRAP +# ifndef RESOLVE_CONFLICT_FIND_MAP + /* Not needed for dl-conflict.c. */ + case R_390_COPY: + if (sym == NULL) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (__builtin_expect (sym->st_size > refsym->st_size, 0) + || (__builtin_expect (sym->st_size < refsym->st_size, 0) + && __builtin_expect (GLRO(dl_verbose), 0))) + { + const char *strtab; + + strtab = (const char *) D_PTR (map,l_info[DT_STRTAB]); + _dl_error_printf ("\ +%s: Symbol `%s' has different size in shared object, consider re-linking\n", + RTLD_PROGNAME, strtab + refsym->st_name); + } + memcpy (reloc_addr_arg, (void *) value, + MIN (sym->st_size, refsym->st_size)); + break; +# endif + case R_390_64: + *reloc_addr = value + reloc->r_addend; + break; + case R_390_32: + *(unsigned int *) reloc_addr = value + reloc->r_addend; + break; + case R_390_16: + *(unsigned short *) reloc_addr = value + reloc->r_addend; + break; + case R_390_8: + *(char *) reloc_addr = value + reloc->r_addend; + break; +# ifndef RESOLVE_CONFLICT_FIND_MAP + case R_390_PC64: + *reloc_addr = value +reloc->r_addend - (Elf64_Addr) reloc_addr; + break; + case R_390_PC32DBL: + *(unsigned int *) reloc_addr = (unsigned int) + ((int) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); + break; + case R_390_PC32: + *(unsigned int *) reloc_addr = + value + reloc->r_addend - (Elf64_Addr) reloc_addr; + break; + case R_390_PC16DBL: + *(unsigned short *) reloc_addr = (unsigned short) + ((short) (value + reloc->r_addend - (Elf64_Addr) reloc_addr) >> 1); + break; + case R_390_PC16: + *(unsigned short *) reloc_addr = + value + reloc->r_addend - (Elf64_Addr) reloc_addr; + break; + case R_390_NONE: + break; +# endif +#endif +#if !defined(RTLD_BOOTSTRAP) || defined(_NDEBUG) + default: + /* We add these checks in the version to relocate ld.so only + if we are still debugging. */ + _dl_reloc_bad_type (map, r_type, 0); + break; +#endif + } + } +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, + void *const reloc_addr_arg) +{ + Elf64_Addr *const reloc_addr = reloc_addr_arg; + *reloc_addr = l_addr + reloc->r_addend; +} + +auto inline void +__attribute__ ((always_inline)) +elf_machine_lazy_rel (struct link_map *map, + Elf64_Addr l_addr, const Elf64_Rela *reloc, + int skip_ifunc) +{ + Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); + /* Check for unexpected PLT reloc type. */ + if (__glibc_likely (r_type == R_390_JMP_SLOT)) + { + if (__builtin_expect (map->l_mach.plt, 0) == 0) + *reloc_addr += l_addr; + else + *reloc_addr = map->l_mach.plt + (reloc - map->l_mach.jmprel) * 32; + } + else if (__glibc_likely (r_type == R_390_IRELATIVE)) + { + Elf64_Addr value = map->l_addr + reloc->r_addend; + if (__glibc_likely (!skip_ifunc)) + value = elf_ifunc_invoke (value); + *reloc_addr = value; + } + else + _dl_reloc_bad_type (map, r_type, 1); +} + +#endif /* RESOLVE_MAP */ diff --git a/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S new file mode 100644 index 0000000000..2e3b141e30 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.S @@ -0,0 +1,33 @@ +/* PLT trampolines. s390x version. + Copyright (C) 2005-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + + .text +/* Create variant of _dl_runtime_resolve/profile for machines before z13. + No vector registers are saved/restored. */ +#include <dl-trampoline.h> + +#if defined HAVE_S390_VX_ASM_SUPPORT +/* Create variant of _dl_runtime_resolve/profile for z13 and newer. + The vector registers are saved/restored, too.*/ +# define _dl_runtime_resolve _dl_runtime_resolve_vx +# define _dl_runtime_profile _dl_runtime_profile_vx +# define RESTORE_VRS +# include <dl-trampoline.h> +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h new file mode 100644 index 0000000000..e1f95e2ecd --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/dl-trampoline.h @@ -0,0 +1,225 @@ +/* PLT trampolines. s390x version. + Copyright (C) 2016-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* The PLT stubs will call _dl_runtime_resolve/_dl_runtime_profile + * with the following linkage: + * r2 - r6 : parameter registers + * f0, f2, f4, f6 : floating point parameter registers + * v24, v26, v28, v30, v25, v27, v29, v31 : vector parameter registers + * 48(r15), 56(r15) : PLT arguments PLT1, PLT2 + * 160(r15) : additional stack parameters + * The normal clobber rules for function calls apply: + * r0 - r5 : call clobbered + * r6 - r13 : call saved + * r14 : return address (call clobbered) + * r15 : stack pointer (call saved) + * f0 - f7 : call clobbered + * f8 - f15 : call saved + * v0 - v7 : bytes 0-7 overlap with f0-f7: call clobbered + bytes 8-15: call clobbered + * v8 - v15 : bytes 0-7 overlap with f8-f15: call saved + bytes 8-15: call clobbered + * v16 - v31 : call clobbered + */ + + .globl _dl_runtime_resolve + .type _dl_runtime_resolve, @function + cfi_startproc + .align 16 +_dl_runtime_resolve: + stmg %r2,%r5,64(%r15) # save call-clobbered argument registers + cfi_offset (r2, -96) + cfi_offset (r3, -88) + cfi_offset (r4, -80) + cfi_offset (r5, -72) + std %f0,104(%r15) + cfi_offset (f0, -56) + std %f2,112(%r15) + cfi_offset (f2, -48) + std %f4,120(%r15) + cfi_offset (f4, -40) + std %f6,128(%r15) + cfi_offset (f6, -32) + stg %r14,96(15) + cfi_offset (r14, -64) + lmg %r2,%r3,48(%r15) # load args for fixup saved by PLT + lgr %r0,%r15 +#ifdef RESTORE_VRS + aghi %r15,-288 # create stack frame + cfi_adjust_cfa_offset (288) + .machine push + .machine "z13" + vstm %v24,%v31,160(%r15)# store call-clobbered vector argument registers + cfi_offset (v24, -288) + cfi_offset (v25, -272) + cfi_offset (v26, -256) + cfi_offset (v27, -240) + cfi_offset (v28, -224) + cfi_offset (v29, -208) + cfi_offset (v30, -192) + cfi_offset (v31, -176) + .machine pop +#else + aghi %r15,-160 # create stack frame + cfi_adjust_cfa_offset (160) +#endif + stg %r0,0(%r15) # write backchain + brasl %r14,_dl_fixup # call _dl_fixup + lgr %r1,%r2 # function addr returned in r2 +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vlm %v24,%v31,160(%r15)# restore vector registers + .machine pop + aghi %r15,288 # remove stack frame + cfi_adjust_cfa_offset (-288) +#else + aghi %r15,160 # remove stack frame + cfi_adjust_cfa_offset (-160) +#endif + lg %r14,96(%r15) # restore registers + ld %f0,104(%r15) + ld %f2,112(%r15) + ld %f4,120(%r15) + ld %f6,128(%r15) + lmg %r2,%r5,64(%r15) + br %r1 + cfi_endproc + .size _dl_runtime_resolve, .-_dl_runtime_resolve + + +#ifndef PROF + .globl _dl_runtime_profile + .type _dl_runtime_profile, @function + cfi_startproc + .align 16 +_dl_runtime_profile: + stg %r12,24(%r15) # r12 is used as backup of r15 + cfi_offset (r12, -136) + stg %r14,32(%r15) + cfi_offset (r14, -128) + lgr %r12,%r15 # backup stack pointer + cfi_def_cfa_register (12) + aghi %r15,-360 # create stack frame: + # 160 + sizeof(La_s390_64_regs) + stg %r12,0(%r15) # save backchain + + stmg %r2,%r6,160(%r15) # save call-clobbered arg regs + cfi_offset (r2, -360) # + r6 needed as arg for + cfi_offset (r3, -352) # _dl_profile_fixup + cfi_offset (r4, -344) + cfi_offset (r5, -336) + cfi_offset (r6, -328) + std %f0,200(%r15) + cfi_offset (f0, -320) + std %f2,208(%r15) + cfi_offset (f2, -312) + std %f4,216(%r15) + cfi_offset (f4, -304) + std %f6,224(%r15) + cfi_offset (f6, -296) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vstm %v24,%v31,232(%r15) # store call-clobbered vector arguments + cfi_offset (v24, -288) + cfi_offset (v25, -272) + cfi_offset (v26, -256) + cfi_offset (v27, -240) + cfi_offset (v28, -224) + cfi_offset (v29, -208) + cfi_offset (v30, -192) + cfi_offset (v31, -176) + .machine pop +#endif + lmg %r2,%r3,48(%r12) # load arguments saved by PLT + lgr %r4,%r14 # return address as third parameter + la %r5,160(%r15) # pointer to struct La_s390_64_regs + la %r6,40(%r12) # long int * framesize + brasl %r14,_dl_profile_fixup # call resolver + lgr %r1,%r2 # function addr returned in r2 + ld %f0,200(%r15) # restore call-clobbered arg fprs + ld %f2,208(%r15) + ld %f4,216(%r15) + ld %f6,224(%r15) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vlm %v24,%v31,232(%r15) # restore call-clobbered arg vrs + .machine pop +#endif + lg %r0,40(%r12) # load framesize + ltgr %r0,%r0 + jnm 1f + + lmg %r2,%r6,160(%r15) # framesize < 0 means no pltexit call + # so we can do a tail call without + # copying the arg overflow area + lgr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) + br %r1 # tail-call to resolved function + + cfi_def_cfa_register (12) +1: la %r4,160(%r15) # pointer to struct La_s390_64_regs + stg %r4,64(%r12) + jz 4f # framesize == 0 ? + aghi %r0,7 # align framesize to 8 + nill %r0,0xfff8 + slgr %r15,%r0 # make room for framesize bytes + stg %r12,0(%r15) # save backchain + la %r2,160(%r15) + la %r3,160(%r12) + srlg %r0,%r0,3 +3: mvc 0(8,%r2),0(%r3) # copy additional parameters + la %r2,8(%r2) # depending on framesize + la %r3,8(%r3) + brctg %r0,3b +4: lmg %r2,%r6,0(%r4) # restore call-clobbered arg gprs + basr %r14,%r1 # call resolved function + stg %r2,72(%r12) # store return values r2, f0 + std %f0,80(%r12) # to struct La_s390_64_retval +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vst %v24,88(%r12) # store return value v24 + .machine pop +#endif + lmg %r2,%r4,48(%r12) # r2, r3: load arguments saved by PLT + # r4: pointer to struct La_s390_64_regs + la %r5,72(%r12) # pointer to struct La_s390_64_retval + brasl %r14,_dl_call_pltexit + + lgr %r15,%r12 # remove stack frame + cfi_def_cfa_register (15) + lg %r14,32(%r15) # restore registers + lg %r12,24(%r15) + lg %r2,72(%r15) # restore return values + ld %f0,80(%r15) +#ifdef RESTORE_VRS + .machine push + .machine "z13" + vl %v24,88(%r15) # restore return value v24 + .machine pop +#endif + br %r14 # Jump back to caller + + cfi_endproc + .size _dl_runtime_profile, .-_dl_runtime_profile +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/memchr.S b/REORG.TODO/sysdeps/s390/s390-64/memchr.S new file mode 100644 index 0000000000..7deee3d6f3 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/memchr.S @@ -0,0 +1,40 @@ +/* Search a character in a block of memory. 64 bit S/390 version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = address to memory area + %r3 = character to find + %r4 = number of bytes to search. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(memchr) + lghi %r0,0xff + ngr %r0,%r3 + lgr %r1,%r2 + la %r2,0(%r4,%r1) +0: srst %r2,%r1 + jo 0b + brc 13,1f + slgr %r2,%r2 +1: br %r14 +END(memchr) +libc_hidden_builtin_def (memchr) diff --git a/REORG.TODO/sysdeps/s390/s390-64/memcmp.S b/REORG.TODO/sysdeps/s390/s390-64/memcmp.S new file mode 100644 index 0000000000..cecffc39f9 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/memcmp.S @@ -0,0 +1,64 @@ +/* memcmp - compare two memory blocks. 64 bit S/390 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include <sysdep.h> +#include "asm-syntax.h" + +/* INPUT PARAMETERS + %r2 = address of first memory area + %r3 = address of second memory area + %r4 = number of bytes to compare. */ + + .text +#ifdef USE_MULTIARCH +ENTRY(__memcmp_default) +#else +ENTRY(memcmp) +#endif + .machine "z900" + ltgr %r4,%r4 + je .L_Z900_4 + aghi %r4,-1 + srlg %r1,%r4,8 + ltgr %r1,%r1 + jne .L_Z900_12 +.L_Z900_3: + larl %r1,.L_Z900_15 + ex %r4,0(%r1) +.L_Z900_4: + ipm %r2 + sllg %r2,%r2,34 + srag %r2,%r2,62 + br %r14 +.L_Z900_12: + clc 0(256,%r3),0(%r2) + jne .L_Z900_4 + la %r3,256(%r3) + la %r2,256(%r2) + brctg %r1,.L_Z900_12 + j .L_Z900_3 +.L_Z900_15: + clc 0(1,%r3),0(%r2) +#ifdef USE_MULTIARCH +END(__memcmp_default) +#else +END(memcmp) +libc_hidden_builtin_def (memcmp) +weak_alias (memcmp, bcmp) +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/memcpy.S b/REORG.TODO/sysdeps/s390/s390-64/memcpy.S new file mode 100644 index 0000000000..3df07b5e23 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/memcpy.S @@ -0,0 +1,88 @@ +/* memcpy - copy a block from source to destination. 64 bit S/390 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include <sysdep.h> +#include "asm-syntax.h" + +/* INPUT PARAMETERS + %r2 = address of destination memory area + %r3 = address of source memory area + %r4 = number of bytes to copy. */ + + + .text +ENTRY(__mempcpy) + .machine "z900" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z900_start +END(__mempcpy) +#ifndef USE_MULTIARCH +libc_hidden_def (__mempcpy) +weak_alias (__mempcpy, mempcpy) +libc_hidden_builtin_def (mempcpy) +#endif + +ENTRY(memcpy) + .machine "z900" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z900_start: + ltgr %r4,%r4 + je .L_Z900_4 + aghi %r4,-1 + srlg %r5,%r4,8 + ltgr %r5,%r5 + jne .L_Z900_13 +.L_Z900_3: + larl %r5,.L_Z900_15 + ex %r4,0(%r5) +.L_Z900_4: + br %r14 +.L_Z900_13: + cghi %r5,4096 # Switch to mvcle for copies >1MB + jh __memcpy_mvcle +.L_Z900_12: + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) + la %r3,256(%r3) + brctg %r5,.L_Z900_12 + j .L_Z900_3 +.L_Z900_15: + mvc 0(1,%r1),0(%r3) +END(memcpy) +#ifndef USE_MULTIARCH +libc_hidden_builtin_def (memcpy) +#endif + +ENTRY(__memcpy_mvcle) + # Using as standalone function will result in unexpected + # results since the length field is incremented by 1 in order to + # compensate the changes already done in the functions above. + lgr %r0,%r2 # backup return dest [ + n ] + aghi %r4,1 # length + 1 + lgr %r5,%r4 # source length + lgr %r4,%r3 # source address + lgr %r2,%r1 # destination address + lgr %r3,%r5 # destination length = source length +.L_MVCLE_1: + mvcle %r2,%r4,0 # thats it, MVCLE is your friend + jo .L_MVCLE_1 + lgr %r2,%r0 # return destination address + br %r14 +END(__memcpy_mvcle) diff --git a/REORG.TODO/sysdeps/s390/s390-64/memset.S b/REORG.TODO/sysdeps/s390/s390-64/memset.S new file mode 100644 index 0000000000..e653f12134 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/memset.S @@ -0,0 +1,64 @@ +/* Set a block of memory to some byte value. 64 bit S/390 version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include <sysdep.h> +#include "asm-syntax.h" + +/* INPUT PARAMETERS + %r2 = address of memory area + %r3 = byte to fill memory with + %r4 = number of bytes to fill. */ + + .text + +#ifdef USE_MULTIARCH +ENTRY(__memset_default) +#else +ENTRY(memset) +#endif + .machine "z900" + ltgr %r4,%r4 + je .L_Z900_4 + stc %r3,0(%r2) + cghi %r4,1 + lgr %r1,%r2 + je .L_Z900_4 + aghi %r4,-2 + srlg %r3,%r4,8 + ltgr %r3,%r3 + jne .L_Z900_14 +.L_Z900_3: + larl %r3,.L_Z900_18 + ex %r4,0(%r3) +.L_Z900_4: + br %r14 +.L_Z900_14: + mvc 1(256,%r1),0(%r1) + la %r1,256(%r1) + brctg %r3,.L_Z900_14 + j .L_Z900_3 +.L_Z900_18: + mvc 1(1,%r1),0(%r1) +#ifdef USE_MULTIARCH +END(__memset_default) +#else +END(memset) +libc_hidden_builtin_def (memset) +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile b/REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile new file mode 100644 index 0000000000..91053b5364 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/Makefile @@ -0,0 +1,4 @@ +ifeq ($(subdir),string) +sysdep_routines += memset memset-s390x memcpy memcpy-s390x \ + memcmp memcmp-s390x +endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c new file mode 100644 index 0000000000..808c3b837a --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memchr.c @@ -0,0 +1,21 @@ +/* Multiple versions of memchr. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This wrapper-file is needed, because otherwise file + sysdeps/s390/s390-[32|64]/memchr.S will be used. */ +#include <sysdeps/s390/multiarch/memchr.c> diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S new file mode 100644 index 0000000000..da956d2568 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp-s390x.S @@ -0,0 +1,104 @@ +/* CPU specific memcmp implementations. 64 bit S/390 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include "sysdep.h" +#include "asm-syntax.h" + +/* INPUT PARAMETERS + %r2 = address of first memory area + %r3 = address of second memory area + %r4 = number of bytes to compare. */ + + .text + +#if IS_IN (libc) + +ENTRY(__memcmp_z196) + .machine "z196" + ltgr %r4,%r4 + je .L_Z196_4 + aghi %r4,-1 + srlg %r1,%r4,8 + ltgr %r1,%r1 + jne .L_Z196_2 +.L_Z196_3: + exrl %r4,.L_Z196_14 +.L_Z196_4: + ipm %r2 + sllg %r2,%r2,34 + srag %r2,%r2,62 + br %r14 +.L_Z196_17: + la %r3,256(%r3) + la %r2,256(%r2) + aghi %r1,-1 + je .L_Z196_3 +.L_Z196_2: + pfd 1,512(%r3) + pfd 1,512(%r2) + clc 0(256,%r3),0(%r2) + je .L_Z196_17 + ipm %r2 + sllg %r2,%r2,34 + srag %r2,%r2,62 + br %r14 +.L_Z196_14: + clc 0(1,%r3),0(%r2) +END(__memcmp_z196) + +ENTRY(__memcmp_z10) + .machine "z10" + ltgr %r4,%r4 + je .L_Z10_4 + aghi %r4,-1 + srlg %r1,%r4,8 + cgijlh %r1,0,.L_Z10_12 +.L_Z10_3: + exrl %r4,.L_Z10_15 +.L_Z10_4: + ipm %r2 + sllg %r2,%r2,34 + srag %r2,%r2,62 + br %r14 +.L_Z10_12: + pfd 1,512(%r3) + pfd 1,512(%r2) + clc 0(256,%r3),0(%r2) + jne .L_Z10_4 + la %r3,256(%r3) + la %r2,256(%r2) + brctg %r1,.L_Z10_12 + j .L_Z10_3 +.L_Z10_15: + clc 0(1,%r3),0(%r2) +END(__memcmp_z10) + +#endif /* IS_IN (libc) */ + +#include "../memcmp.S" + +#if !IS_IN (libc) +.globl memcmp +.set memcmp,__memcmp_default +.weak bcmp +.set bcmp,__memcmp_default +#elif defined SHARED && IS_IN (libc) +.globl __GI_memcmp +.set __GI_memcmp,__memcmp_default +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c new file mode 100644 index 0000000000..2d8d8f4d50 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcmp.c @@ -0,0 +1,27 @@ +/* Multiple versions of memcmp. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#if IS_IN (libc) +# define memcmp __redirect_memcmp +# include <string.h> +# undef memcmp +# include <ifunc-resolve.h> + +s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp) +weak_alias (memcmp, bcmp); +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S new file mode 100644 index 0000000000..a9ffa9cc98 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy-s390x.S @@ -0,0 +1,122 @@ +/* CPU specific memcpy implementations. 64 bit S/390 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include "sysdep.h" +#include "asm-syntax.h" + +/* INPUT PARAMETERS + %r2 = target operands address + %r3 = source operands address + %r4 = number of bytes to copy. */ + + .text + +#if defined SHARED && IS_IN (libc) + +ENTRY(____mempcpy_z196) + .machine "z196" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z196_start +END(____mempcpy_z196) + +ENTRY(__memcpy_z196) + .machine "z196" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z196_start: + ltgr %r4,%r4 + je .L_Z196_4 + aghi %r4,-1 + srlg %r5,%r4,8 + ltgr %r5,%r5 + jne .L_Z196_5 +.L_Z196_3: + exrl %r4,.L_Z196_14 +.L_Z196_4: + br %r14 +.L_Z196_5: + cgfi %r5,262144 # Switch to mvcle for copies >64MB + jh __memcpy_mvcle +.L_Z196_2: + pfd 1,768(%r3) + pfd 2,768(%r1) + mvc 0(256,%r1),0(%r3) + aghi %r5,-1 + la %r1,256(%r1) + la %r3,256(%r3) + jne .L_Z196_2 + j .L_Z196_3 +.L_Z196_14: + mvc 0(1,%r1),0(%r3) +END(__memcpy_z196) + +ENTRY(____mempcpy_z10) + .machine "z10" + lgr %r1,%r2 # Use as dest + la %r2,0(%r4,%r2) # Return dest + n + j .L_Z10_start +END(____mempcpy_z10) + +ENTRY(__memcpy_z10) + .machine "z10" + lgr %r1,%r2 # r1: Use as dest ; r2: Return dest +.L_Z10_start: + cgije %r4,0,.L_Z10_4 + aghi %r4,-1 + srlg %r5,%r4,8 + cgijlh %r5,0,.L_Z10_13 +.L_Z10_3: + exrl %r4,.L_Z10_15 +.L_Z10_4: + br %r14 +.L_Z10_13: + cgfi %r5,65535 # Switch to mvcle for copies >16MB + jh __memcpy_mvcle +.L_Z10_12: + pfd 1,768(%r3) + pfd 2,768(%r1) + mvc 0(256,%r1),0(%r3) + la %r1,256(%r1) + la %r3,256(%r3) + brctg %r5,.L_Z10_12 + j .L_Z10_3 +.L_Z10_15: + mvc 0(1,%r1),0(%r3) +END(__memcpy_z10) + +# define __mempcpy ____mempcpy_default +#endif /* SHARED && IS_IN (libc) */ + +#define memcpy __memcpy_default +#include "../memcpy.S" +#undef memcpy + +#if defined SHARED && IS_IN (libc) +.globl __GI_memcpy +.set __GI_memcpy,__memcpy_default +.globl __GI_mempcpy +.set __GI_mempcpy,____mempcpy_default +.globl __GI___mempcpy +.set __GI___mempcpy,____mempcpy_default +#else +.globl memcpy +.set memcpy,__memcpy_default +.weak mempcpy +.set mempcpy,__mempcpy +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c new file mode 100644 index 0000000000..4b8e546fb0 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memcpy.c @@ -0,0 +1,27 @@ +/* Multiple versions of memcpy. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* In the static lib memcpy is needed before the reloc is resolved. */ +#if defined SHARED && IS_IN (libc) +# define memcpy __redirect_memcpy +# include <string.h> +# undef memcpy +# include <ifunc-resolve.h> + +s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy) +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S new file mode 100644 index 0000000000..ca0c4326b1 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset-s390x.S @@ -0,0 +1,112 @@ +/* Set a block of memory to some byte value. 64 bit S/390 version. + Copyright (C) 2012-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + + +#include "sysdep.h" +#include "asm-syntax.h" + +/* INPUT PARAMETERS + %r2 = address of memory area + %r3 = byte to fill memory with + %r4 = number of bytes to fill. */ + + .text + +#if IS_IN (libc) + +ENTRY(__memset_z196) + .machine "z196" + ltgr %r4,%r4 + je .L_Z196_4 + stc %r3,0(%r2) + lgr %r1,%r2 + cghi %r4,1 + je .L_Z196_4 + aghi %r4,-2 + srlg %r5,%r4,8 + ltgr %r5,%r5 + jne .L_Z196_1 +.L_Z196_3: + exrl %r4,.L_Z196_17 +.L_Z196_4: + br %r14 +.L_Z196_1: + cgfi %r5,1048576 + jh __memset_mvcle # Switch to mvcle for >256MB +.L_Z196_2: + pfd 2,1024(%r1) + mvc 1(256,%r1),0(%r1) + aghi %r5,-1 + la %r1,256(%r1) + jne .L_Z196_2 + j .L_Z196_3 +.L_Z196_17: + mvc 1(1,%r1),0(%r1) +END(__memset_z196) + +ENTRY(__memset_z10) + .machine "z10" + cgije %r4,0,.L_Z10_4 + stc %r3,0(%r2) + lgr %r1,%r2 + cgije %r4,1,.L_Z10_4 + aghi %r4,-2 + srlg %r5,%r4,8 + cgijlh %r5,0,.L_Z10_15 +.L_Z10_3: + exrl %r4,.L_Z10_18 +.L_Z10_4: + br %r14 +.L_Z10_15: + cgfi %r5,163840 # Switch to mvcle for >40MB + jh __memset_mvcle +.L_Z10_14: + pfd 2,1024(%r1) + mvc 1(256,%r1),0(%r1) + la %r1,256(%r1) + brctg %r5,.L_Z10_14 + j .L_Z10_3 +.L_Z10_18: + mvc 1(1,%r1),0(%r1) +END(__memset_z10) + +ENTRY(__memset_mvcle) + aghi %r4,2 # take back the change done by the caller + lgr %r0,%r2 # save source address + lgr %r1,%r3 # move pad byte to R1 + lgr %r3,%r4 # move length to r3 + sgr %r4,%r4 # no source for MVCLE, only a pad byte + sgr %r5,%r5 +.L0: mvcle %r2,%r4,0(%r1) # thats it, MVCLE is your friend + jo .L0 + lgr %r2,%r0 # return value is source address +.L1: + br %r14 +END(__memset_mvcle) + +#endif /* IS_IN (libc) */ + +#include "../memset.S" + +#if !IS_IN (libc) +.globl memset +.set memset,__memset_default +#elif defined SHARED && IS_IN (libc) +.globl __GI_memset +.set __GI_memset,__memset_default +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c new file mode 100644 index 0000000000..421c0854a0 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/memset.c @@ -0,0 +1,26 @@ +/* Multiple versions of memset. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#if IS_IN (libc) +# define memset __redirect_memset +# include <string.h> +# undef memset +# include <ifunc-resolve.h> + +s390_libc_ifunc (__redirect_memset, __memset, memset) +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c new file mode 100644 index 0000000000..6a20a304cc --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcmp.c @@ -0,0 +1,21 @@ +/* Multiple versions of strcmp. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This wrapper-file is needed, because otherwise file + sysdeps/s390/s390-[32|64]/strcmp.S will be used. */ +#include <sysdeps/s390/multiarch/strcmp.c> diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c new file mode 100644 index 0000000000..7f380a471d --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strcpy.c @@ -0,0 +1,21 @@ +/* Multiple versions of strcpy. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This wrapper-file is needed, because otherwise file + sysdeps/s390/s390-[32|64]/strcpy.S will be used. */ +#include <sysdeps/s390/multiarch/strcpy.c> diff --git a/REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c new file mode 100644 index 0000000000..15dacec974 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/multiarch/strncpy.c @@ -0,0 +1,21 @@ +/* Multiple versions of strncpy. + Copyright (C) 2015-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* This wrapper-file is needed, because otherwise file + sysdeps/s390/s390-[32|64]/strncpy.S will be used. */ +#include <sysdeps/s390/multiarch/strncpy.c> diff --git a/REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S b/REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S new file mode 100644 index 0000000000..510834aa05 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/s390x-mcount.S @@ -0,0 +1,77 @@ +/* 64 bit S/390-specific implementation of profiling support. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com) + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> + +/* How profiling works on 64 bit S/390: + On the start of each function _mcount is called with the address of a + data word in %r1 (initialized to 0, used for counting). The compiler + with the option -p generates code of the form: + + STM 6,15,24(15) + BRAS 13,.LTN0_0 + .LT0_0: + .LC13: .long .LP0 + .data + .align 4 + .LP0: .long 0 + .text + # function profiler + stg 14,4(15) + lg 1,.LC13-.LT0_0(13) + brasl 14,_mcount + lg 14,4(15) + + The _mcount implementation now has to call __mcount_internal with the + address of .LP0 as first parameter and the return address as second + parameter. &.LP0 was loaded to %r1 and the return address is in %r14. + _mcount may not modify any register. */ + + .globl C_SYMBOL_NAME(_mcount) + .type C_SYMBOL_NAME(_mcount), @function + cfi_startproc + .align ALIGNARG(4) +C_LABEL(_mcount) + /* Save the caller-clobbered registers. */ + aghi %r15,-224 + cfi_adjust_cfa_offset (224) + stmg %r14,%r5,160(%r15) + cfi_offset (r14, 0) + cfi_offset (r15, 8) + lg %r2,232(%r15) # callers address = first parameter + la %r2,0(%r2) # clear bit 0 + la %r3,0(%r14) # callees address = second parameter + +#ifdef PIC + brasl %r14,__mcount_internal@PLT +#else + brasl %r14,__mcount_internal +#endif + + /* Pop the saved registers. Please note that `mcount' has no + return value. */ + lmg %r14,%r5,160(%r15) + aghi %r15,224 + cfi_adjust_cfa_offset (-224) + br %r14 + cfi_endproc + ASM_SIZE_DIRECTIVE(C_SYMBOL_NAME(_mcount)) + +#undef mcount +weak_alias (_mcount, mcount) diff --git a/REORG.TODO/sysdeps/s390/s390-64/setjmp.S b/REORG.TODO/sysdeps/s390/s390-64/setjmp.S new file mode 100644 index 0000000000..ac9c878346 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/setjmp.S @@ -0,0 +1,118 @@ +/* setjmp for 64 bit S/390, ELF version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdep.h> +#define _ASM +#define _SETJMP_H +#include <bits/setjmp.h> +#include <shlib-compat.h> +#include <stap-probe.h> + +#if !IS_IN (rtld) && defined SHARED \ + && SHLIB_COMPAT (libc, GLIBC_2_19, GLIBC_2_20) +# define NEED_COMPAT_SYMBOLS 1 +/* We need a unique name in case of symbol versioning. */ +# define setjmp __v1setjmp +# define _setjmp __v1_setjmp +# define __sigsetjmp __v1__sigsetjmp +#else +# define NEED_COMPAT_SYMBOLS 0 +#endif + + /* We include the BSD entry points here as well. */ +ENTRY (setjmp) + lghi %r3,1 /* Second argument of one. */ + j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */ +END (setjmp) + + /* Binary compatibility entry point. */ +ENTRY(_setjmp) + slgr %r3,%r3 /* Second argument of zero. */ + j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */ +END (_setjmp) +#if NEED_COMPAT_SYMBOLS +strong_alias (_setjmp, __GI__setjmp) +#else +libc_hidden_def (_setjmp) +#endif + +ENTRY(__setjmp) + slgr %r3,%r3 /* Second argument of zero. */ + j .Linternal_sigsetjmp /* Branch relativ to __sigsetjmp. */ +END (__setjmp) + +ENTRY(__sigsetjmp) +.Linternal_sigsetjmp: + /* setjmp probe expects sig/setjmp first argument (8@%r2), second + argument (-8@%r3) and target address (8@%r14). */ + LIBC_PROBE (setjmp, 3, 8@%r2, -4@%r3, 8@%r14) +#ifdef PTR_MANGLE + stmg %r6,%r13,0(%r2) /* Store registers in jmp_buf. */ + lgr %r4,%r14 + lgr %r5,%r15 + PTR_MANGLE (%r4, %r1) + PTR_MANGLE2 (%r5, %r1) + stmg %r4,%r5,64(%r2) +#else + stmg %r6,%r15,0(%r2) /* Store registers in jmp_buf. */ +#endif + std %f8,80(%r2) + std %f9,88(%r2) + std %f10,96(%r2) + std %f11,104(%r2) + std %f12,112(%r2) + std %f13,120(%r2) + std %f14,128(%r2) + std %f15,136(%r2) +#if IS_IN (rtld) + /* In ld.so we never save the signal mask. */ + lghi %r2,0 + br %r14 +#elif defined PIC + jg __sigjmp_save@PLT /* Branch to PLT of __sigsetjmp. */ +#else + jg __sigjmp_save +#endif +END (__sigsetjmp) +#if NEED_COMPAT_SYMBOLS +strong_alias (__sigsetjmp, __GI___sigsetjmp) +#else +libc_hidden_def (__sigsetjmp) +#endif + +#if NEED_COMPAT_SYMBOLS +/* In glibc release 2.19 new versions of setjmp-functions were introduced, + but were reverted before 2.20. Thus both versions are the same function. */ + +# undef setjmp +# undef _setjmp +# undef __sigsetjmp + +strong_alias (__v1setjmp, __v2setjmp); +versioned_symbol (libc, __v1setjmp, setjmp, GLIBC_2_0); +compat_symbol (libc, __v2setjmp, setjmp, GLIBC_2_19); + +strong_alias (__v1_setjmp, __v2_setjmp); +versioned_symbol (libc, __v1_setjmp, _setjmp, GLIBC_2_0); +compat_symbol (libc, __v2_setjmp, _setjmp, GLIBC_2_19); + +strong_alias (__v1__sigsetjmp, __v2__sigsetjmp); +versioned_symbol (libc, __v1__sigsetjmp, __sigsetjmp, GLIBC_2_0); +compat_symbol (libc, __v2__sigsetjmp, __sigsetjmp, GLIBC_2_19); +#endif /* NEED_COMPAT_SYMBOLS */ diff --git a/REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h b/REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h new file mode 100644 index 0000000000..2c97d3824f --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/stackguard-macros.h @@ -0,0 +1,18 @@ +#include <stdint.h> + +#define STACK_CHK_GUARD \ + ({ uintptr_t x; __asm__ ("ear %0,%%a0; sllg %0,%0,32; ear %0,%%a1; lg %0,0x28(%0)" : "=a" (x)); x; }) + +/* On s390/s390x there is no unique pointer guard, instead we use the + same value as the stack guard. */ +#define POINTER_CHK_GUARD \ + ({ \ + uintptr_t x; \ + __asm__ ("ear %0,%%a0;" \ + "sllg %0,%0,32;" \ + "ear %0,%%a1;" \ + "lg %0,%1(%0)" \ + : "=a" (x) \ + : "i" (offsetof (tcbhead_t, stack_guard))); \ + x; \ + }) diff --git a/REORG.TODO/sysdeps/s390/s390-64/start.S b/REORG.TODO/sysdeps/s390/s390-64/start.S new file mode 100644 index 0000000000..d8e65450d8 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/start.S @@ -0,0 +1,100 @@ +/* Startup code compliant to the 64 bit S/390 ELF ABI. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + In addition to the permissions in the GNU Lesser General Public + License, the Free Software Foundation gives you unlimited + permission to link the compiled version of this file with other + programs, and to distribute those programs without any restriction + coming from the use of this file. (The GNU Lesser General Public + License restrictions do apply in other respects; for example, they + cover modification of the file, and distribution when not linked + into another program.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* + This is the canonical entry point, usually the first thing in the text + segment. Most registers' values are unspecified, except for: + + %r14 Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + %r15 The stack contains the arguments and environment: + 0(%r15) argc + 8(%r15) argv[0] + ... + (8*argc)(%r15) NULL + (8*(argc+1))(%r15) envp[0] + ... + NULL +*/ + + .text + .globl _start + .type _start,@function +_start: + /* Load argc and argv from stack. */ + la %r4,8(%r15) # get argv + lg %r3,0(%r15) # get argc + + /* Align the stack to a double word boundary. */ + lghi %r0,-16 + ngr %r15,%r0 + + /* Setup a stack frame and a parameter area. */ + aghi %r15,-176 # make room on stack + xc 0(8,%r15),0(%r15) # clear back-chain + + /* Set up arguments for __libc_start_main: + main, argc, argv, envp, _init, _fini, rtld_fini, stack_end + Note that envp will be determined later in __libc_start_main. + */ + stmg %r14,%r15,160(%r15) # store rtld_fini/stack_end to parameter area + la %r7,160(%r15) + larl %r6,__libc_csu_fini # load pointer to __libc_csu_fini + larl %r5,__libc_csu_init # load pointer to __libc_csu_init + + /* Ok, now branch to the libc main routine. */ +#ifdef PIC + larl %r2,main@GOTENT # load pointer to main + lg %r2,0(%r2) + brasl %r14,__libc_start_main@plt +#else + larl %r2,main # load pointer to main + brasl %r14,__libc_start_main +#endif + + /* Crash if __libc_start_main returns. */ + .word 0 + + /* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/REORG.TODO/sysdeps/s390/s390-64/strcmp.S b/REORG.TODO/sysdeps/s390/s390-64/strcmp.S new file mode 100644 index 0000000000..640493b4df --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/strcmp.S @@ -0,0 +1,41 @@ +/* strcmp - compare two string. 64 bit S/390 version. + This file is part of the GNU C Library. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = address of string 1 + %r3 = address of string 2. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(strcmp) + slr %r0,%r0 +0: clst %r2,%r3 + jo 0b + jp 1f + jm 2f + slgr %r2,%r2 + br %r14 +1: lghi %r2,1 + br %r14 +2: lghi %r2,-1 + br %r14 +END(strcmp) +libc_hidden_builtin_def (strcmp) diff --git a/REORG.TODO/sysdeps/s390/s390-64/strcpy.S b/REORG.TODO/sysdeps/s390/s390-64/strcpy.S new file mode 100644 index 0000000000..fee1d3ede6 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/strcpy.S @@ -0,0 +1,35 @@ +/* strcpy - copy a string from source to destination. 64 bit S/390 version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = address of destination + %r3 = address of source. */ + +#include "sysdep.h" +#include "asm-syntax.h" + + .text +ENTRY(strcpy) + slgr %r0,%r0 + lgr %r1,%r2 +0: mvst %r1,%r3 + jo 0b + br %r14 +END(strcpy) +libc_hidden_builtin_def (strcpy) diff --git a/REORG.TODO/sysdeps/s390/s390-64/strncpy.S b/REORG.TODO/sysdeps/s390/s390-64/strncpy.S new file mode 100644 index 0000000000..80aee312e4 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/strncpy.S @@ -0,0 +1,90 @@ +/* strncpy - copy at most n characters from a string from source to + destination. 64 bit S/390 version + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = address of destination (dst) + %r3 = address of source (src) + %r4 = max of bytes to copy. */ + +#include "sysdep.h" +#include "asm-syntax.h" + +ENTRY(strncpy) + .text + stg %r2,48(%r15) # save dst pointer + slgr %r2,%r3 # %r3 points to src, %r2+%r3 to dst + lghi %r1,7 + ngr %r1,%r4 # last 3 bits of # bytes + srlg %r4,%r4,3 + ltgr %r4,%r4 # less than 8 bytes to copy ? + jz .L1 + bras %r5,.L0 # enter loop & load address of a 0 + .long 0 +.L0: icmh %r0,8,0(%r3) # first byte + jz .L3 + icmh %r0,4,1(%r3) # second byte + jz .L4 + icmh %r0,2,2(%r3) # third byte + jz .L5 + icmh %r0,1,3(%r3) # fourth byte + jz .L6 + icm %r0,8,4(%r3) # fifth byte + jz .L7 + icm %r0,4,5(%r3) # sixth byte + jz .L8 + icm %r0,2,6(%r3) # seventh byte + jz .L9 + icm %r0,1,7(%r3) # eigth byte + jz .L10 + stg %r0,0(%r2,%r3) # store all eight to dest. + la %r3,8(%r3) + brct %r4,.L0 +.L1: ltgr %r1,%r1 + jz .Lexit +.L2: icm %r0,1,0(%r3) + stc %r0,0(%r2,%r3) + la %r3,1(%r3) + jz .L11 + brct %r1,.L2 + j .Lexit +.L3: icmh %r0,4,0(%r5) +.L4: icmh %r0,2,0(%r5) +.L5: icmh %r0,1,0(%r5) +.L6: icm %r0,8,0(%r5) +.L7: icm %r0,4,0(%r5) +.L8: icm %r0,2,0(%r5) +.L9: icm %r0,1,0(%r5) +.L10: stg %r0,0(%r2,%r3) + la %r3,8(%r3) + aghi %r4,-1 + j .L12 +.L11: aghi %r1,-1 +.L12: sllg %r4,%r4,3 + algr %r4,%r1 + algr %r2,%r3 # start of dst area to be zeroed + lgr %r3,%r4 + slgr %r4,%r4 + slgr %r5,%r5 +.L13: mvcle %r2,%r4,0 # pad dst with zeroes + jo .L13 +.Lexit: lg %r2,48(%r15) # return dst pointer + br %r14 +END(strncpy) +libc_hidden_builtin_def (strncpy) diff --git a/REORG.TODO/sysdeps/s390/s390-64/sub_n.S b/REORG.TODO/sysdeps/s390/s390-64/sub_n.S new file mode 100644 index 0000000000..dc6572ca36 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/sub_n.S @@ -0,0 +1,60 @@ +/* __mpn_sub_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. 64 bit S/390 version. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU MP Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + see <http://www.gnu.org/licenses/>. */ + +/* INPUT PARAMETERS + %r2 = res_ptr + %r3 = s1_ptr + %r4 = s2_ptr + %r5 = size. */ + +#include "sysdep.h" +#include "asm-syntax.h" + +ENTRY(__mpn_sub_n) + stg %r6,48(%r15) # save register 6 + cfi_offset (%r6,-112) + sgr %r1,%r1 + lghi %r0,1 # cannot use ahi to add carry, use slr +.L0: lg %r6,0(%r1,%r3) # .L0 -> no carry from last sub + slg %r6,0(%r1,%r4) + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 4,.L3 +.L1: brct %r5,.L0 + slgr %r2,%r2 # no last carry to return + j .Lexit +.L2: lg %r6,0(%r1,%r3) # .L2 -> carry from last sub + slg %r6,0(%r1,%r4) + brc 4,.L4 + slgr %r6,%r0 # no carry yet, add carry from last sub + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brc 11,.L1 # new carry ? +.L3: brct %r5,.L2 + lgr %r2,%r0 # return last carry + j .Lexit +.L4: slgr %r6,%r0 # already a carry, add carry from last sub + stg %r6,0(%r1,%r2) + la %r1,8(%r1) + brct %r5,.L2 + lgr %r2,%r0 # return last carry +.Lexit: lg %r6,48(%r15) # restore register 6 + br %r14 +END(__mpn_sub_n) diff --git a/REORG.TODO/sysdeps/s390/s390-64/sysdep.h b/REORG.TODO/sysdeps/s390/s390-64/sysdep.h new file mode 100644 index 0000000000..a4dfc67178 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/sysdep.h @@ -0,0 +1,94 @@ +/* Assembler macros for 64 bit S/390. + Copyright (C) 2001-2017 Free Software Foundation, Inc. + Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <sysdeps/generic/sysdep.h> + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +#define ALIGNARG(log2) 1<<log2 +#define ASM_SIZE_DIRECTIVE(name) .size name,.-name; + + +/* Define an entry point visible from C. */ +#define ENTRY(name) \ + .globl C_SYMBOL_NAME(name); \ + .type C_SYMBOL_NAME(name),@function; \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + cfi_startproc; \ + CALL_MCOUNT + +#undef END +#define END(name) \ + cfi_endproc; \ + ASM_SIZE_DIRECTIVE(name) \ + +/* If compiled for profiling, call `mcount' at the start of each function. */ +#ifdef PROF +#ifdef PIC +#define CALL_MCOUNT \ + lgr 0,14 ; larl 1,0f ; brasl 14,_mcount@PLT ; lgr 14,0 ; \ + .data ; .align 4 ; 0: .long 0 ; .text ; +#else +#define CALL_MCOUNT \ + lgr 0,14 ; larl 1,0f ; brasl 14,_mcount ; lgr 14,0 ; \ + .data ; .align 4 ; 0: .long 0 ; .text ; +#endif +#else +#define CALL_MCOUNT /* Do nothing. */ +#endif + +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +#define syscall_error __syscall_error +#define mcount _mcount + +#undef PSEUDO +#define PSEUDO(name, syscall_name, args) \ +lose: SYSCALL_PIC_SETUP \ + jg JUMPTARGET(syscall_error); \ + .globl syscall_error; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + jm lose + +#undef PSEUDO_END +#define PSEUDO_END(name) \ + END (name) + +#undef JUMPTARGET +#ifdef PIC +#define JUMPTARGET(name) name##@PLT +#define SYSCALL_PIC_SETUP \ + larl %r12,_GLOBAL_OFFSET_TABLE_ +#else +#define JUMPTARGET(name) name +#define SYSCALL_PIC_SETUP /* Nothing. */ +#endif + +/* Local label name for asm code. */ +#ifndef L +#define L(name) .L##name +#endif + +#endif /* __ASSEMBLER__ */ diff --git a/REORG.TODO/sysdeps/s390/s390-64/tls-macros.h b/REORG.TODO/sysdeps/s390/s390-64/tls-macros.h new file mode 100644 index 0000000000..d70ea6ce0c --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/tls-macros.h @@ -0,0 +1,88 @@ +#define TLS_LE(x) \ + ({ unsigned long __offset; \ + __asm__ ("bras %0,1f\n" \ + "0:\t.quad " #x "@ntpoff\n" \ + "1:\tlg %0,0(%0)" \ + : "=a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) + +#ifdef PIC +# define TLS_IE(x) \ + ({ unsigned long __offset, __got; \ + __asm__ ("bras %0,0f\n\t" \ + ".quad " #x "@gotntpoff\n" \ + "0:\tlarl %1,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %0,0(%0)\n\t" \ + "lg %0,0(%0,%1):tls_load:" #x "\n" \ + : "=&a" (__offset), "=&a" (__got) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +#else +# define TLS_IE(x) \ + ({ unsigned long __offset; \ + __asm__ ("bras %0,1f\n" \ + "0:\t.quad " #x "@indntpoff\n" \ + "1:\t lg %0,0(%0)\n\t" \ + "lg %0,0(%0):tls_load:" #x \ + : "=&a" (__offset) : : "cc" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +#endif + +#ifdef PIC +# define TLS_LD(x) \ + ({ unsigned long __offset, __save12; \ + __asm__ ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsldm\n\t" \ + ".quad " #x "@dtpoff\n" \ + "1:\tlgr %1,%%r12\n\t" \ + "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \ + "lg %0,8(%0)\n\t" \ + "algr %0,%%r2\n\t" \ + "lgr %%r12,%1" \ + : "=&a" (__offset), "=&a" (__save12) \ + : : "cc", "0", "1", "2", "3", "4", "5", "14" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +#else +# define TLS_LD(x) \ + ({ unsigned long __offset; \ + __asm__ ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsldm\n\t" \ + ".quad " #x "@dtpoff\n" \ + "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_ldcall:" #x "\n\t" \ + "lg %0,8(%0)\n\t" \ + "algr %0,%%r2" \ + : "=&a" (__offset) \ + : : "cc", "0", "1", "2", "3", "4", "5", "12", "14" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +#endif + +#ifdef PIC +# define TLS_GD(x) \ + ({ unsigned long __offset, __save12; \ + __asm__ ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsgd\n" \ + "1:\tlgr %1,%%r12\n\t" \ + "larl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \ + "lgr %0,%%r2\n\t" \ + "lgr %%r12,%1" \ + : "=&a" (__offset), "=&a" (__save12) \ + : : "cc", "0", "1", "2", "3", "4", "5", "14" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +#else +# define TLS_GD(x) \ + ({ unsigned long __offset; \ + __asm__ ("bras %0,1f\n" \ + "0:\t.quad " #x "@tlsgd\n" \ + "1:\tlarl %%r12,_GLOBAL_OFFSET_TABLE_\n\t" \ + "lg %%r2,0(%0)\n\t" \ + "brasl %%r14,__tls_get_offset@plt:tls_gdcall:" #x "\n\t" \ + "lgr %0,%%r2" \ + : "=&a" (__offset) \ + : : "cc", "0", "1", "2", "3", "4", "5", "12", "14" ); \ + (int *) (__builtin_thread_pointer() + __offset); }) +#endif diff --git a/REORG.TODO/sysdeps/s390/s390-64/tst-audit.h b/REORG.TODO/sysdeps/s390/s390-64/tst-audit.h new file mode 100644 index 0000000000..67a93f51f1 --- /dev/null +++ b/REORG.TODO/sysdeps/s390/s390-64/tst-audit.h @@ -0,0 +1,25 @@ +/* Definitions for testing PLT entry/exit auditing. S/390 64-bit version. + + Copyright (C) 2012-2017 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <http://www.gnu.org/licenses/>. */ + +#define pltenter la_s390_64_gnu_pltenter +#define pltexit la_s390_64_gnu_pltexit +#define La_regs La_s390_64_regs +#define La_retval La_s390_64_retval +#define int_retval lrv_r2 |