diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2012-07-19 15:58:17 +0200 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2012-07-19 15:58:17 +0200 |
commit | 46f85fc22637213e4a97b306f40a64ae09f82f18 (patch) | |
tree | 0ffbc10b9faf12886e941bbe1e9e600e94a415ce /sysdeps/unix/sysv | |
parent | 08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96 (diff) | |
download | glibc-46f85fc22637213e4a97b306f40a64ae09f82f18.tar.gz glibc-46f85fc22637213e4a97b306f40a64ae09f82f18.tar.xz glibc-46f85fc22637213e4a97b306f40a64ae09f82f18.zip |
S/390: Fix uc_link == NULL handling for makecontext
Diffstat (limited to 'sysdeps/unix/sysv')
6 files changed, 89 insertions, 20 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/Makefile b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile index 3216804f7b..626a96f04f 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/Makefile +++ b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile @@ -21,3 +21,7 @@ sysdep_routines += framestate shared-only-routines += framestate endif endif + +ifeq ($(subdir),stdlib) +sysdep_routines += __makecontext_ret +endif diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S new file mode 100644 index 0000000000..ab172bb72e --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S @@ -0,0 +1,48 @@ +/* Copyright (C) 2012 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> + +ENTRY(__makecontext_ret) + basr %r14,%r7 + ltr %r8,%r8 /* Check whether uc_link is 0. */ + jz 1f + lr %r2,%r8 + br %r9 +1: lhi %r2,0 /* EXIT return value. */ + basr %r13,0 +2: +#ifdef PIC + l %r12,4f-2b(%r13) + la %r12,0(%r12,%r13) /* GOT pointer in r12 after this. */ + l %r1,3f-2b(%r13) + bas %r14,0(%r1,%r12) + .align 4 +3: + .long HIDDEN_JUMPTARGET (exit)@GOTOFF +4: + .long _GLOBAL_OFFSET_TABLE_-2b +#else + l %r1,3f-2b(%r13) + basr %r14,%r1 + .align 4 +3: + .long HIDDEN_JUMPTARGET (exit) +#endif + .align 2 + j .+2 /* Trap if exit returns for some reason. */ +END(__makecontext_ret) diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c b/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c index 7eb2712ece..407676b488 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c +++ b/sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c @@ -80,10 +80,10 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) sp -= 24; *sp = 0; - /* Pass (*func) to __start_context in %r7. */ + /* Pass (*func) to __makecontext_ret in %r7. */ ucp->uc_mcontext.gregs[7] = (long int) func; - /* Pass ucp->uc_link to __start_context in %r8. */ + /* Pass ucp->uc_link to __makecontext_ret in %r8. */ ucp->uc_mcontext.gregs[8] = (long int) ucp->uc_link; /* Pass address of setcontext in %r9. */ @@ -93,12 +93,4 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) ucp->uc_mcontext.gregs[15] = (long int) sp; } -asm (".text\n" - ".type __makecontext_ret,@function\n" - "__makecontext_ret:\n" - " basr %r14,%r7\n" - " lr %r2,%r8\n" - " br %r9\n" - ".size __makecontext_ret, .-__makecontext_ret"); - weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/Makefile b/sysdeps/unix/sysv/linux/s390/s390-64/Makefile index 1f6ad21064..6795734747 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/Makefile +++ b/sysdeps/unix/sysv/linux/s390/s390-64/Makefile @@ -12,3 +12,7 @@ sysdep_routines += framestate shared-only-routines += framestate endif endif + +ifeq ($(subdir),stdlib) +sysdep_routines += __makecontext_ret +endif diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S new file mode 100644 index 0000000000..cbd88e170d --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S @@ -0,0 +1,29 @@ +/* Copyright (C) 2012 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> + +ENTRY(__makecontext_ret) + basr %r14,%r7 + ltgr %r8,%r8 /* Check whether uc_link is 0. */ + jz 1f + lgr %r2,%r8 + br %r9 +1: lghi %r2,0 + brasl %r14,HIDDEN_JUMPTARGET (exit) + j .+2 /* Trap if exit returns. */ +END(__makecontext_ret) diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c b/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c index dcc63a2354..17e5dba3c2 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c +++ b/sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c @@ -80,10 +80,10 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) sp -= 20; *sp = 0; - /* Pass (*func) to __start_context in %r7. */ + /* Pass (*func) to __makecontext_ret in %r7. */ ucp->uc_mcontext.gregs[7] = (long int) func; - /* Pass ucp->uc_link to __start_context in %r8. */ + /* Pass ucp->uc_link to __makecontext_ret in %r8. */ ucp->uc_mcontext.gregs[8] = (long int) ucp->uc_link; /* Pass address of setcontext in %r9. */ @@ -93,12 +93,4 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) ucp->uc_mcontext.gregs[15] = (long int) sp; } -asm (".text\n" - ".type __makecontext_ret,@function\n" - "__makecontext_ret:\n" - " basr %r14,%r7\n" - " lgr %r2,%r8\n" - " br %r9\n" - ".size __makecontext_ret, .-__makecontext_ret"); - weak_alias (__makecontext, makecontext) |