From 46f85fc22637213e4a97b306f40a64ae09f82f18 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Thu, 19 Jul 2012 15:58:17 +0200 Subject: [PATCH] S/390: Fix uc_link == NULL handling for makecontext --- ChangeLog | 15 +++++++ sysdeps/unix/sysv/linux/s390/s390-32/Makefile | 4 ++ .../sysv/linux/s390/s390-32/__makecontext_ret.S | 48 ++++++++++++++++++++++ sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c | 12 +----- sysdeps/unix/sysv/linux/s390/s390-64/Makefile | 4 ++ .../sysv/linux/s390/s390-64/__makecontext_ret.S | 29 +++++++++++++ sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c | 12 +----- 7 files changed, 104 insertions(+), 20 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S create mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S diff --git a/ChangeLog b/ChangeLog index 3dee64d..d96f368 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ 2012-07-19 Andreas Krebbel + * sysdeps/unix/sysv/linux/s390/s390-32/makecontext.c: Move + __makecontext_ret to ... + * sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S: + ... here and call exit if uc_link is NULL. New file. + * sysdeps/unix/sysv/linux/s390/s390-32/Makefile: Add + __makecontext_ret.S. + * sysdeps/unix/sysv/linux/s390/s390-64/makecontext.c: Move + __makecontext_ret to ... + * sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S: + ... here and call exit if uc_link is NULL. New file. + * sysdeps/unix/sysv/linux/s390/s390-64/Makefile: Add + __makecontext_ret.S. + +2012-07-19 Andreas Krebbel + * elf/elf.h (R_390_IRELATIVE): New definition. * sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela): Invoke the resolver function for IFUNC symbols. Support R_390_IRELATIVE. diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/Makefile b/sysdeps/unix/sysv/linux/s390/s390-32/Makefile index 3216804..626a96f 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 0000000..ab172bb --- /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 + . */ + +#include + +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 7eb2712..407676b 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 1f6ad21..6795734 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 0000000..cbd88e1 --- /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 + . */ + +#include + +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 dcc63a2..17e5dba 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) -- 2.7.4