* [ARM] getcontext routines v2 @ 2012-02-24 1:34 Michael Hope 2012-02-24 15:39 ` Carlos O'Donell 0 siblings, 1 reply; 9+ messages in thread From: Michael Hope @ 2012-02-24 1:34 UTC (permalink / raw) To: libc-ports This is an implementation of getcontext, makecontext, setcontext and swapcontext for ARM Linux and continues on from Dave Gilbert's original version[1]. The changes in this version are: * Use the GNU coding style * Use ucontext_i.sym to pull constants and struct offsets into the assembly code * Match the style of the MIPS and Tile implementations These routines survive basic testing. A full GLIBC, QEMU, and GNU pth test run is under way. -- Michael [1] http://sourceware.org/ml/libc-ports/2011-12/msg00047.html diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile index d91b968..a981736 100644 --- a/sysdeps/unix/sysv/linux/arm/Makefile +++ b/sysdeps/unix/sysv/linux/arm/Makefile @@ -20,3 +20,7 @@ endif ifeq ($(subdir),resource) sysdep_routines += oldgetrlimit64 endif + +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S new file mode 100644 index 0000000..11a49e3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S @@ -0,0 +1,114 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <rtld-global-offsets.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int getcontext (ucontext_t *ucp) */ + +ENTRY(__getcontext) + /* No need to save r0-r3, d0-d7, or d16-d31. */ + add r1, r0, #MCONTEXT_ARM_R4 + stmia r1, {r4-r11} + + /* Save R13 separately as Thumb can't STM it. */ + str r13, [r0, #MCONTEXT_ARM_SP] + str r14, [r0, #MCONTEXT_ARM_LR] + /* Return to LR */ + str r14, [r0, #MCONTEXT_ARM_PC] + /* Return zero */ + mov r2, #0 + str r2, [r0, #MCONTEXT_ARM_R0] + + /* Save ucontext_t * across the next call. */ + mov r4, r0 + + /* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ + mov r0, #SIG_BLOCK + mov r1, #0 + add r2, r4, #UCONTEXT_SIGMASK + bl PLTJMP(__sigprocmask) + + /* Store FP regs. Much of the FP code is copied from arm/eabi/setjmp.S. */ + +#ifdef PIC + ldr r2, 1f + ldr r1, Lrtld_global_ro +0: add r2, pc, r2 + ldr r2, [r2, r1] + ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr r2, Lhwcap + ldr r2, [r2, #0] +#endif + + add r0, r4, #UCONTEXT_REGSPACE + + tst r2, #HWCAP_ARM_VFP + beq Lno_vfp + + /* Store the VFP registers. + Don't use VFP instructions directly because this code + is used in non-VFP multilibs. */ + /* Following instruction is vstmia r0!, {d8-d15}. */ + stc p11, cr8, [r0], #64 + /* Store the floating-point status register. */ + /* Following instruction is vmrs r1, fpscr. */ + mrc p10, 7, r1, cr1, cr0, 0 + str r1, [r0], #4 +Lno_vfp: + + tst r2, #HWCAP_ARM_IWMMXT + beq Lno_iwmmxt + + /* Save the call-preserved iWMMXt registers. */ + /* Following instructions are wstrd wr10, [r0], #8 (etc.) */ + stcl p1, cr10, [r0], #8 + stcl p1, cr11, [r0], #8 + stcl p1, cr12, [r0], #8 + stcl p1, cr13, [r0], #8 + stcl p1, cr14, [r0], #8 + stcl p1, cr15, [r0], #8 +Lno_iwmmxt: + + /* Restore the clobbered R4 and LR. */ + ldr r14, [r4, #MCONTEXT_ARM_LR] + ldr r4, [r4, #MCONTEXT_ARM_R4] + + mov r0, #0 + + DO_RET(r14) + +END(__getcontext) + +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif + + +weak_alias(__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c new file mode 100644 index 0000000..a4c8233 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c @@ -0,0 +1,75 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stdarg.h> +#include <ucontext.h> + +extern void __setcontext_orexit_r4 (void); + +/* Number of arguments that go in registers. */ +#define NREG_ARGS 4 + +/* Take a context previously prepared via getcontext() and set to + call func() with the given int only args. */ +void +makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + unsigned long *funcstack; + va_list vl; + unsigned long *regptr; + unsigned int reg; + int misaligned; + + /* Start at the top of stack. */ + funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + + /* Ensure the stack stays eight byte aligned. */ + misaligned = ((unsigned long) funcstack & 4) != 0; + + if ((argc > NREG_ARGS) && (argc & 1) != 0) + misaligned = !misaligned; + + if (misaligned) + funcstack -= 1; + + va_start (vl, argc); + + /* Reserve space for the on-stack arguments. */ + if (argc > NREG_ARGS) + funcstack -= (argc - NREG_ARGS); + + /* R4 of the context points to the link context, and ends up being passed + to __setcontext_orexit_r4 where it ends up either calling setcontext or + if 0 ends up as the conveniently correct param to exit(). */ + ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link; + ucp->uc_mcontext.arm_sp = (unsigned long) funcstack; + ucp->uc_mcontext.arm_lr = (unsigned long) __setcontext_orexit_r4; + ucp->uc_mcontext.arm_pc = (unsigned long) func; + + /* The first four arguments go into registers. */ + regptr = &(ucp->uc_mcontext.arm_r0); + + for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++) + *regptr++ = va_arg (vl, unsigned long); + + /* And the remainder on the stack. */ + for (; reg < argc; reg++) + *funcstack++ = va_arg (vl, unsigned long); + + va_end (vl); +} diff --git a/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S new file mode 100644 index 0000000..6add16a --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S @@ -0,0 +1,103 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <rtld-global-offsets.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int setcontext (const ucontext_t *ucp) */ + +ENTRY(__setcontext) + mov r4, r0 + add r0, r0, #UCONTEXT_REGSPACE + + /* Restore the VFP registers. Copied from arm/eabi/__longjmp.S. */ +#ifdef PIC + ldr r2, 1f + ldr r1, Lrtld_global_ro +0: add r2, pc, r2 + ldr r2, [r2, r1] + ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr r2, Lhwcap + ldr r2, [r2, #0] +#endif + + tst r2, #HWCAP_ARM_VFP + beq Lno_vfp_sc + + /* Following instruction is vldmia r0!, {d8-d15}. */ + ldc p11, cr8, [r0], #64 + /* Restore the floating-point status register. */ + ldr r1, [r0], #4 + /* Following instruction is fmxr fpscr, r1. */ + mcr p10, 7, r1, cr1, cr0, 0 +Lno_vfp_sc: + tst r2, #HWCAP_ARM_IWMMXT + beq Lno_iwmmxt_sc + + /* Restore the call-preserved iWMMXt registers. */ + /* Following instructions are wldrd wr10, [r0], #8 (etc.) */ + ldcl p1, cr10, [r0], #8 + ldcl p1, cr11, [r0], #8 + ldcl p1, cr12, [r0], #8 + ldcl p1, cr13, [r0], #8 + ldcl p1, cr14, [r0], #8 + ldcl p1, cr15, [r0], #8 +Lno_iwmmxt_sc: + + /* Now bring back the signal status. */ + mov r0, #SIG_SETMASK + add r1, r4, #UCONTEXT_SIGMASK + mov r2, #0 + bl PLTJMP(__sigprocmask) + + /* Loading r0-r3 makes makecontext easier. */ + add r14, r4, #MCONTEXT_ARM_R0 + ldmia r14, {r0-r12} + ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)] + add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0) + ldmia r14, {r14, pc} + +END(setcontext) + + /* The function called via a setcontext on a context that makecontext + tweeked returns here (by it's LR), R4 should hold the context we're + supposed to run next, if 0 we exit. */ +ENTRY(__setcontext_orexit_r4) + movs r0, r4 + bne PLTJMP(__setcontext) + + @ New context was 0 - exit + b PLTJMP(_exit) +END(__setcontext_orexit_r4) + +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif + +weak_alias(__setcontext, setcontext) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S new file mode 100644 index 0000000..efb881a --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S @@ -0,0 +1,64 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + +ENTRY(swapcontext) + + /* Have getcontext() do most of the work then fix up + LR afterwards. Save R3 to keep the stack aligned. */ + push {r0,r1,r3,r14} + cfi_adjust_cfa_offset (16) + cfi_rel_offset (r0,0) + cfi_rel_offset (r1,4) + cfi_rel_offset (r3,8) + cfi_rel_offset (r14,12) + + bl __getcontext + mov r4, r0 + + pop {r0,r1,r3,r14} + cfi_adjust_cfa_offset (-16) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r3) + cfi_restore (r14) + + /* Exit if getcontext() failed. */ + cmp r4, #0 + itt ne + movne r0, r4 + RETINSTR(ne, r14) + + /* Fix up LR and the PC. */ + str r13,[r0, #MCONTEXT_ARM_SP] + str r14,[r0, #MCONTEXT_ARM_LR] + str r14,[r0, #MCONTEXT_ARM_PC] + + /* And swap using swapcontext(). */ + mov r0, r1 + b __setcontext + +END(swapcontext) diff --git a/sysdeps/unix/sysv/linux/arm/ucontext_i.sym b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym new file mode 100644 index 0000000..306292f --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym @@ -0,0 +1,30 @@ +#include <inttypes.h> +#include <signal.h> +#include <stddef.h> +#include <sys/ucontext.h> + +SIG_BLOCK +SIG_SETMASK + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) + +UCONTEXT_FLAGS ucontext (uc_flags) +UCONTEXT_LINK ucontext (uc_link) +UCONTEXT_STACK ucontext (uc_stack) +UCONTEXT_MCONTEXT ucontext (uc_mcontext) +UCONTEXT_SIGMASK ucontext (uc_sigmask) + +UCONTEXT_REGSPACE ucontext (uc_regspace) + +MCONTEXT_TRAP_NO mcontext (trap_no) +MCONTEXT_ERROR_CODE mcontext (error_code) +MCONTEXT_OLDMASK mcontext (oldmask) +MCONTEXT_ARM_R0 mcontext (arm_r0) +MCONTEXT_ARM_R4 mcontext (arm_r4) +MCONTEXT_ARM_SP mcontext (arm_sp) +MCONTEXT_ARM_LR mcontext (arm_lr) +MCONTEXT_ARM_PC mcontext (arm_pc) +MCONTEXT_ARM_CPSR mcontext (arm_cpsr) +MCONTEXT_FAULT_ADDRESS mcontext (fault_address) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-02-24 1:34 [ARM] getcontext routines v2 Michael Hope @ 2012-02-24 15:39 ` Carlos O'Donell 2012-02-27 22:03 ` Michael Hope 0 siblings, 1 reply; 9+ messages in thread From: Carlos O'Donell @ 2012-02-24 15:39 UTC (permalink / raw) To: Michael Hope; +Cc: libc-ports On Thu, Feb 23, 2012 at 8:34 PM, Michael Hope <michael.hope@linaro.org> wrote: > This is an implementation of getcontext, makecontext, setcontext and > swapcontext for ARM Linux and continues on from Dave Gilbert's original > version[1]. > > The changes in this version are: > * Use the GNU coding style > * Use ucontext_i.sym to pull constants and struct offsets into the assembly > code > * Match the style of the MIPS and Tile implementations > > These routines survive basic testing. A full GLIBC, QEMU, and GNU pth test > run is under way. I looked over things briefly and the formatting and license looks OK. Do you and Dave have FSF copyright assignments in place? I also have two comments. (1) Is setcontext correctly implemented? Your setcontext doesn't iterate over uc_link, instead you appear to rely on makecontext having set a special return handler and input arguments. The special return handler won't be set of the user manually sets uc_link in the context, which I believe is an allowed operation (only uc_mcontext is forbidden to be modified). I'd be interested in seeing if you pass all of the glibc tests. (2) Please also post a GNU ChangeLog with your patches. Cheers, Carlos. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-02-24 15:39 ` Carlos O'Donell @ 2012-02-27 22:03 ` Michael Hope 2012-02-27 23:06 ` Carlos O'Donell 0 siblings, 1 reply; 9+ messages in thread From: Michael Hope @ 2012-02-27 22:03 UTC (permalink / raw) To: Carlos O'Donell; +Cc: libc-ports On Sat, Feb 25, 2012 at 4:39 AM, Carlos O'Donell <carlos@systemhalted.org> wrote: > On Thu, Feb 23, 2012 at 8:34 PM, Michael Hope <michael.hope@linaro.org> wrote: >> This is an implementation of getcontext, makecontext, setcontext and >> swapcontext for ARM Linux and continues on from Dave Gilbert's original >> version[1]. >> >> The changes in this version are: >> * Use the GNU coding style >> * Use ucontext_i.sym to pull constants and struct offsets into the assembly >> code >> * Match the style of the MIPS and Tile implementations >> >> These routines survive basic testing. A full GLIBC, QEMU, and GNU pth test >> run is under way. > > I looked over things briefly and the formatting and license looks OK. > Do you and Dave have FSF copyright assignments in place? Yes. Linaro has an assignment agreement for GCC, GDB, binutils, and GLIBC under case #664398. > I also have two comments. > > (1) Is setcontext correctly implemented? > > Your setcontext doesn't iterate over uc_link, instead you appear to rely > on makecontext having set a special return handler and input arguments. > > The special return handler won't be set of the user manually sets uc_link > in the context, which I believe is an allowed operation (only uc_mcontext > is forbidden to be modified). It's correct to the specification and matches the MIPS and Tile ports. From IEEE 1003.1:2004: """The uc_link member is used to determine the context that shall be resumed when the context being modified by makecontext() returns. The application shall ensure that the uc_link member is initialized prior to the call to makecontext().""" There's no mention of uc_link being used except when the makecontext() child completes. I've changed the function to __startcontext() to match the other ports and added a weak_alias on __makecontext for consistency. > I'd be interested in seeing if you pass all of the glibc tests. There are no regressions between EGLIBC trunk and trunk + this patch. stdlib/bug-getcontext now passes. The (small) GNU pth testsuite passes. > (2) Please also post a GNU ChangeLog with your patches. Done. -- Michael diff --git a/ChangeLog.arm b/ChangeLog.arm index 9eef7e7..7ecb11b 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,3 +1,13 @@ +2012-02-27 Michael Hope <michael.hope@linaro.org> + + * sysdeps/unix/sysv/linux/arm/eabi/getcontext.S: New file. + * sysdeps/unix/sysv/linux/arm/eabi/makecontext.c: New file. + * sysdeps/unix/sysv/linux/arm/eabi/setcontext.S: New file. + * sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S: New file. + * sysdeps/unix/sysv/linux/arm/ucontext_i.sym: New file. + * sysdeps/unix/sysv/linux/arm/Makefile (gen-as-const-headers): Add + ucontext_i.sym. + 2012-02-17 Aurelien Jarno <aurelien@aurel32.net> * sysdeps/arm/libm-test-ulps: Adjust ULPs for jn tests. diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile index d91b968..a981736 100644 --- a/sysdeps/unix/sysv/linux/arm/Makefile +++ b/sysdeps/unix/sysv/linux/arm/Makefile @@ -20,3 +20,7 @@ endif ifeq ($(subdir),resource) sysdep_routines += oldgetrlimit64 endif + +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S new file mode 100644 index 0000000..11a49e3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S @@ -0,0 +1,114 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <rtld-global-offsets.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int getcontext (ucontext_t *ucp) */ + +ENTRY(__getcontext) + /* No need to save r0-r3, d0-d7, or d16-d31. */ + add r1, r0, #MCONTEXT_ARM_R4 + stmia r1, {r4-r11} + + /* Save R13 separately as Thumb can't STM it. */ + str r13, [r0, #MCONTEXT_ARM_SP] + str r14, [r0, #MCONTEXT_ARM_LR] + /* Return to LR */ + str r14, [r0, #MCONTEXT_ARM_PC] + /* Return zero */ + mov r2, #0 + str r2, [r0, #MCONTEXT_ARM_R0] + + /* Save ucontext_t * across the next call. */ + mov r4, r0 + + /* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ + mov r0, #SIG_BLOCK + mov r1, #0 + add r2, r4, #UCONTEXT_SIGMASK + bl PLTJMP(__sigprocmask) + + /* Store FP regs. Much of the FP code is copied from arm/eabi/setjmp.S. */ + +#ifdef PIC + ldr r2, 1f + ldr r1, Lrtld_global_ro +0: add r2, pc, r2 + ldr r2, [r2, r1] + ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr r2, Lhwcap + ldr r2, [r2, #0] +#endif + + add r0, r4, #UCONTEXT_REGSPACE + + tst r2, #HWCAP_ARM_VFP + beq Lno_vfp + + /* Store the VFP registers. + Don't use VFP instructions directly because this code + is used in non-VFP multilibs. */ + /* Following instruction is vstmia r0!, {d8-d15}. */ + stc p11, cr8, [r0], #64 + /* Store the floating-point status register. */ + /* Following instruction is vmrs r1, fpscr. */ + mrc p10, 7, r1, cr1, cr0, 0 + str r1, [r0], #4 +Lno_vfp: + + tst r2, #HWCAP_ARM_IWMMXT + beq Lno_iwmmxt + + /* Save the call-preserved iWMMXt registers. */ + /* Following instructions are wstrd wr10, [r0], #8 (etc.) */ + stcl p1, cr10, [r0], #8 + stcl p1, cr11, [r0], #8 + stcl p1, cr12, [r0], #8 + stcl p1, cr13, [r0], #8 + stcl p1, cr14, [r0], #8 + stcl p1, cr15, [r0], #8 +Lno_iwmmxt: + + /* Restore the clobbered R4 and LR. */ + ldr r14, [r4, #MCONTEXT_ARM_LR] + ldr r4, [r4, #MCONTEXT_ARM_R4] + + mov r0, #0 + + DO_RET(r14) + +END(__getcontext) + +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif + + +weak_alias(__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c new file mode 100644 index 0000000..66f8456 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c @@ -0,0 +1,74 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <stdarg.h> +#include <ucontext.h> + +/* Number of arguments that go in registers. */ +#define NREG_ARGS 4 + +/* Take a context previously prepared via getcontext() and set to + call func() with the given int only args. */ +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + extern void __startcontext (void); + unsigned long *funcstack; + va_list vl; + unsigned long *regptr; + unsigned int reg; + int misaligned; + + /* Start at the top of stack. */ + funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + + /* Ensure the stack stays eight byte aligned. */ + misaligned = ((unsigned long) funcstack & 4) != 0; + + if ((argc > NREG_ARGS) && (argc & 1) != 0) + misaligned = !misaligned; + + if (misaligned) + funcstack -= 1; + + va_start (vl, argc); + + /* Reserve space for the on-stack arguments. */ + if (argc > NREG_ARGS) + funcstack -= (argc - NREG_ARGS); + + ucp->uc_mcontext.arm_sp = (unsigned long) funcstack; + ucp->uc_mcontext.arm_pc = (unsigned long) func; + + /* Exit to startcontext() with the next context in R4 */ + ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link; + ucp->uc_mcontext.arm_lr = (unsigned long) __startcontext; + + /* The first four arguments go into registers. */ + regptr = &(ucp->uc_mcontext.arm_r0); + + for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++) + *regptr++ = va_arg (vl, unsigned long); + + /* And the remainder on the stack. */ + for (; reg < argc; reg++) + *funcstack++ = va_arg (vl, unsigned long); + + va_end (vl); +} +weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S new file mode 100644 index 0000000..f07af7f --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S @@ -0,0 +1,102 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#include <rtld-global-offsets.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int setcontext (const ucontext_t *ucp) */ + +ENTRY(__setcontext) + mov r4, r0 + add r0, r0, #UCONTEXT_REGSPACE + + /* Restore the VFP registers. Copied from arm/eabi/__longjmp.S. */ +#ifdef PIC + ldr r2, 1f + ldr r1, Lrtld_global_ro +0: add r2, pc, r2 + ldr r2, [r2, r1] + ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr r2, Lhwcap + ldr r2, [r2, #0] +#endif + + tst r2, #HWCAP_ARM_VFP + beq Lno_vfp_sc + + /* Following instruction is vldmia r0!, {d8-d15}. */ + ldc p11, cr8, [r0], #64 + /* Restore the floating-point status register. */ + ldr r1, [r0], #4 + /* Following instruction is fmxr fpscr, r1. */ + mcr p10, 7, r1, cr1, cr0, 0 +Lno_vfp_sc: + tst r2, #HWCAP_ARM_IWMMXT + beq Lno_iwmmxt_sc + + /* Restore the call-preserved iWMMXt registers. */ + /* Following instructions are wldrd wr10, [r0], #8 (etc.) */ + ldcl p1, cr10, [r0], #8 + ldcl p1, cr11, [r0], #8 + ldcl p1, cr12, [r0], #8 + ldcl p1, cr13, [r0], #8 + ldcl p1, cr14, [r0], #8 + ldcl p1, cr15, [r0], #8 +Lno_iwmmxt_sc: + + /* Now bring back the signal status. */ + mov r0, #SIG_SETMASK + add r1, r4, #UCONTEXT_SIGMASK + mov r2, #0 + bl PLTJMP(__sigprocmask) + + /* Loading r0-r3 makes makecontext easier. */ + add r14, r4, #MCONTEXT_ARM_R0 + ldmia r14, {r0-r12} + ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)] + add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0) + ldmia r14, {r14, pc} + +END(setcontext) +weak_alias(__setcontext, setcontext) + + /* Called when a makecontext() context returns. Start the + context in R4 or fall through to exit(). */ +ENTRY(__startcontext) + movs r0, r4 + bne PLTJMP(__setcontext) + + @ New context was 0 - exit + b PLTJMP(_exit) +END(__startcontext) + +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif + diff --git a/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S new file mode 100644 index 0000000..efb881a --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S @@ -0,0 +1,64 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + +ENTRY(swapcontext) + + /* Have getcontext() do most of the work then fix up + LR afterwards. Save R3 to keep the stack aligned. */ + push {r0,r1,r3,r14} + cfi_adjust_cfa_offset (16) + cfi_rel_offset (r0,0) + cfi_rel_offset (r1,4) + cfi_rel_offset (r3,8) + cfi_rel_offset (r14,12) + + bl __getcontext + mov r4, r0 + + pop {r0,r1,r3,r14} + cfi_adjust_cfa_offset (-16) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r3) + cfi_restore (r14) + + /* Exit if getcontext() failed. */ + cmp r4, #0 + itt ne + movne r0, r4 + RETINSTR(ne, r14) + + /* Fix up LR and the PC. */ + str r13,[r0, #MCONTEXT_ARM_SP] + str r14,[r0, #MCONTEXT_ARM_LR] + str r14,[r0, #MCONTEXT_ARM_PC] + + /* And swap using swapcontext(). */ + mov r0, r1 + b __setcontext + +END(swapcontext) diff --git a/sysdeps/unix/sysv/linux/arm/ucontext_i.sym b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym new file mode 100644 index 0000000..306292f --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym @@ -0,0 +1,30 @@ +#include <inttypes.h> +#include <signal.h> +#include <stddef.h> +#include <sys/ucontext.h> + +SIG_BLOCK +SIG_SETMASK + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) + +UCONTEXT_FLAGS ucontext (uc_flags) +UCONTEXT_LINK ucontext (uc_link) +UCONTEXT_STACK ucontext (uc_stack) +UCONTEXT_MCONTEXT ucontext (uc_mcontext) +UCONTEXT_SIGMASK ucontext (uc_sigmask) + +UCONTEXT_REGSPACE ucontext (uc_regspace) + +MCONTEXT_TRAP_NO mcontext (trap_no) +MCONTEXT_ERROR_CODE mcontext (error_code) +MCONTEXT_OLDMASK mcontext (oldmask) +MCONTEXT_ARM_R0 mcontext (arm_r0) +MCONTEXT_ARM_R4 mcontext (arm_r4) +MCONTEXT_ARM_SP mcontext (arm_sp) +MCONTEXT_ARM_LR mcontext (arm_lr) +MCONTEXT_ARM_PC mcontext (arm_pc) +MCONTEXT_ARM_CPSR mcontext (arm_cpsr) +MCONTEXT_FAULT_ADDRESS mcontext (fault_address) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-02-27 22:03 ` Michael Hope @ 2012-02-27 23:06 ` Carlos O'Donell 2012-02-27 23:22 ` Michael Hope 0 siblings, 1 reply; 9+ messages in thread From: Carlos O'Donell @ 2012-02-27 23:06 UTC (permalink / raw) To: Michael Hope; +Cc: libc-ports On Mon, Feb 27, 2012 at 5:03 PM, Michael Hope <michael.hope@linaro.org> wrote: >> I looked over things briefly and the formatting and license looks OK. >> Do you and Dave have FSF copyright assignments in place? > > Yes. Linaro has an assignment agreement for GCC, GDB, binutils, and GLIBC > under case #664398. Excellent. Thanks. >> (1) Is setcontext correctly implemented? > It's correct to the specification and matches the MIPS and Tile ports. From > IEEE 1003.1:2004: I've gone and re-read the standard, and I agree with you. Personally I think there is a QoI issue here, but you meet the standard which is the right thing to do. >> I'd be interested in seeing if you pass all of the glibc tests. > There are no regressions between EGLIBC trunk and trunk + this patch. > stdlib/bug-getcontext now passes. The (small) GNU pth testsuite passes. Perfect. >> (2) Please also post a GNU ChangeLog with your patches. > Done. Thanks. > -- Michael > > diff --git a/ChangeLog.arm b/ChangeLog.arm > index 9eef7e7..7ecb11b 100644 > --- a/ChangeLog.arm > +++ b/ChangeLog.arm > @@ -1,3 +1,13 @@ > +2012-02-27 Michael Hope <michael.hope@linaro.org> > + > + * sysdeps/unix/sysv/linux/arm/eabi/getcontext.S: New file. > + * sysdeps/unix/sysv/linux/arm/eabi/makecontext.c: New file. > + * sysdeps/unix/sysv/linux/arm/eabi/setcontext.S: New file. > + * sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S: New file. > + * sysdeps/unix/sysv/linux/arm/ucontext_i.sym: New file. > + * sysdeps/unix/sysv/linux/arm/Makefile (gen-as-const-headers): Add > + ucontext_i.sym. > + > 2012-02-17 Aurelien Jarno <aurelien@aurel32.net> > > * sysdeps/arm/libm-test-ulps: Adjust ULPs for jn tests. > > diff --git a/sysdeps/unix/sysv/linux/arm/Makefile > b/sysdeps/unix/sysv/linux/arm/Makefile > index d91b968..a981736 100644 > --- a/sysdeps/unix/sysv/linux/arm/Makefile > +++ b/sysdeps/unix/sysv/linux/arm/Makefile > @@ -20,3 +20,7 @@ endif > ifeq ($(subdir),resource) > sysdep_routines += oldgetrlimit64 > endif > + > +ifeq ($(subdir),stdlib) > +gen-as-const-headers += ucontext_i.sym > +endif > diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S > b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S > new file mode 100644 > index 0000000..11a49e3 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S > @@ -0,0 +1,114 @@ > +/* 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, write to the Free > + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA > + 02111-1307 USA. */ > + This should be: ~~~ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ ~~~ We don't use the address form of the license. Please repost the patch with the license change and I'll check it in. Cheers, Carlos. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-02-27 23:06 ` Carlos O'Donell @ 2012-02-27 23:22 ` Michael Hope 2012-03-04 21:17 ` Michael Hope 0 siblings, 1 reply; 9+ messages in thread From: Michael Hope @ 2012-02-27 23:22 UTC (permalink / raw) To: Carlos O'Donell; +Cc: libc-ports On 28/02/12 12:05, Carlos O'Donell wrote: > On Mon, Feb 27, 2012 at 5:03 PM, Michael Hope<michael.hope@linaro.org> wrote: >>> I looked over things briefly and the formatting and license looks OK. >>> Do you and Dave have FSF copyright assignments in place? >> >> Yes. Linaro has an assignment agreement for GCC, GDB, binutils, and GLIBC >> under case #664398. > > Excellent. Thanks. > >>> (1) Is setcontext correctly implemented? >> It's correct to the specification and matches the MIPS and Tile ports. From >> IEEE 1003.1:2004: > > I've gone and re-read the standard, and I agree with you. > > Personally I think there is a QoI issue here, but you meet the > standard which is the right thing to do. Agreed. Being able to change uc_link while in a makecontext() child would be nice. >> +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S >> @@ -0,0 +1,114 @@ >> +/* 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, write to the Free >> + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA >> + 02111-1307 USA. */ >> + > > This should be: > ~~~ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > ~~~ > > We don't use the address form of the license. > > Please repost the patch with the license change and I'll check it in. Updated to match the recent MIPS commits. -- Michael diff --git a/ChangeLog.arm b/ChangeLog.arm index 9eef7e7..7ecb11b 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,3 +1,13 @@ +2012-02-27 Michael Hope <michael.hope@linaro.org> + + * sysdeps/unix/sysv/linux/arm/eabi/getcontext.S: New file. + * sysdeps/unix/sysv/linux/arm/eabi/makecontext.c: New file. + * sysdeps/unix/sysv/linux/arm/eabi/setcontext.S: New file. + * sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S: New file. + * sysdeps/unix/sysv/linux/arm/ucontext_i.sym: New file. + * sysdeps/unix/sysv/linux/arm/Makefile (gen-as-const-headers): Add + ucontext_i.sym. + 2012-02-17 Aurelien Jarno <aurelien@aurel32.net> * sysdeps/arm/libm-test-ulps: Adjust ULPs for jn tests. diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile index d91b968..a981736 100644 --- a/sysdeps/unix/sysv/linux/arm/Makefile +++ b/sysdeps/unix/sysv/linux/arm/Makefile @@ -20,3 +20,7 @@ endif ifeq ($(subdir),resource) sysdep_routines += oldgetrlimit64 endif + +ifeq ($(subdir),stdlib) +gen-as-const-headers += ucontext_i.sym +endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S new file mode 100644 index 0000000..4266287 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/getcontext.S @@ -0,0 +1,113 @@ +/* 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> +#include <rtld-global-offsets.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int getcontext (ucontext_t *ucp) */ + +ENTRY(__getcontext) + /* No need to save r0-r3, d0-d7, or d16-d31. */ + add r1, r0, #MCONTEXT_ARM_R4 + stmia r1, {r4-r11} + + /* Save R13 separately as Thumb can't STM it. */ + str r13, [r0, #MCONTEXT_ARM_SP] + str r14, [r0, #MCONTEXT_ARM_LR] + /* Return to LR */ + str r14, [r0, #MCONTEXT_ARM_PC] + /* Return zero */ + mov r2, #0 + str r2, [r0, #MCONTEXT_ARM_R0] + + /* Save ucontext_t * across the next call. */ + mov r4, r0 + + /* __sigprocmask(SIG_BLOCK, NULL, &(ucontext->uc_sigmask)) */ + mov r0, #SIG_BLOCK + mov r1, #0 + add r2, r4, #UCONTEXT_SIGMASK + bl PLTJMP(__sigprocmask) + + /* Store FP regs. Much of the FP code is copied from arm/eabi/setjmp.S. */ + +#ifdef PIC + ldr r2, 1f + ldr r1, Lrtld_global_ro +0: add r2, pc, r2 + ldr r2, [r2, r1] + ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr r2, Lhwcap + ldr r2, [r2, #0] +#endif + + add r0, r4, #UCONTEXT_REGSPACE + + tst r2, #HWCAP_ARM_VFP + beq Lno_vfp + + /* Store the VFP registers. + Don't use VFP instructions directly because this code + is used in non-VFP multilibs. */ + /* Following instruction is vstmia r0!, {d8-d15}. */ + stc p11, cr8, [r0], #64 + /* Store the floating-point status register. */ + /* Following instruction is vmrs r1, fpscr. */ + mrc p10, 7, r1, cr1, cr0, 0 + str r1, [r0], #4 +Lno_vfp: + + tst r2, #HWCAP_ARM_IWMMXT + beq Lno_iwmmxt + + /* Save the call-preserved iWMMXt registers. */ + /* Following instructions are wstrd wr10, [r0], #8 (etc.) */ + stcl p1, cr10, [r0], #8 + stcl p1, cr11, [r0], #8 + stcl p1, cr12, [r0], #8 + stcl p1, cr13, [r0], #8 + stcl p1, cr14, [r0], #8 + stcl p1, cr15, [r0], #8 +Lno_iwmmxt: + + /* Restore the clobbered R4 and LR. */ + ldr r14, [r4, #MCONTEXT_ARM_LR] + ldr r4, [r4, #MCONTEXT_ARM_R4] + + mov r0, #0 + + DO_RET(r14) + +END(__getcontext) + +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif + + +weak_alias(__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c new file mode 100644 index 0000000..d6ae6f0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/makecontext.c @@ -0,0 +1,73 @@ +/* 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 <stdarg.h> +#include <ucontext.h> + +/* Number of arguments that go in registers. */ +#define NREG_ARGS 4 + +/* Take a context previously prepared via getcontext() and set to + call func() with the given int only args. */ +void +__makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...) +{ + extern void __startcontext (void); + unsigned long *funcstack; + va_list vl; + unsigned long *regptr; + unsigned int reg; + int misaligned; + + /* Start at the top of stack. */ + funcstack = (unsigned long *) (ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size); + + /* Ensure the stack stays eight byte aligned. */ + misaligned = ((unsigned long) funcstack & 4) != 0; + + if ((argc > NREG_ARGS) && (argc & 1) != 0) + misaligned = !misaligned; + + if (misaligned) + funcstack -= 1; + + va_start (vl, argc); + + /* Reserve space for the on-stack arguments. */ + if (argc > NREG_ARGS) + funcstack -= (argc - NREG_ARGS); + + ucp->uc_mcontext.arm_sp = (unsigned long) funcstack; + ucp->uc_mcontext.arm_pc = (unsigned long) func; + + /* Exit to startcontext() with the next context in R4 */ + ucp->uc_mcontext.arm_r4 = (unsigned long) ucp->uc_link; + ucp->uc_mcontext.arm_lr = (unsigned long) __startcontext; + + /* The first four arguments go into registers. */ + regptr = &(ucp->uc_mcontext.arm_r0); + + for (reg = 0; (reg < argc) && (reg < NREG_ARGS); reg++) + *regptr++ = va_arg (vl, unsigned long); + + /* And the remainder on the stack. */ + for (; reg < argc; reg++) + *funcstack++ = va_arg (vl, unsigned long); + + va_end (vl); +} +weak_alias (__makecontext, makecontext) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S new file mode 100644 index 0000000..78003f5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/setcontext.S @@ -0,0 +1,101 @@ +/* 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> +#include <rtld-global-offsets.h> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int setcontext (const ucontext_t *ucp) */ + +ENTRY(__setcontext) + mov r4, r0 + add r0, r0, #UCONTEXT_REGSPACE + + /* Restore the VFP registers. Copied from arm/eabi/__longjmp.S. */ +#ifdef PIC + ldr r2, 1f + ldr r1, Lrtld_global_ro +0: add r2, pc, r2 + ldr r2, [r2, r1] + ldr r2, [r2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr r2, Lhwcap + ldr r2, [r2, #0] +#endif + + tst r2, #HWCAP_ARM_VFP + beq Lno_vfp_sc + + /* Following instruction is vldmia r0!, {d8-d15}. */ + ldc p11, cr8, [r0], #64 + /* Restore the floating-point status register. */ + ldr r1, [r0], #4 + /* Following instruction is fmxr fpscr, r1. */ + mcr p10, 7, r1, cr1, cr0, 0 +Lno_vfp_sc: + tst r2, #HWCAP_ARM_IWMMXT + beq Lno_iwmmxt_sc + + /* Restore the call-preserved iWMMXt registers. */ + /* Following instructions are wldrd wr10, [r0], #8 (etc.) */ + ldcl p1, cr10, [r0], #8 + ldcl p1, cr11, [r0], #8 + ldcl p1, cr12, [r0], #8 + ldcl p1, cr13, [r0], #8 + ldcl p1, cr14, [r0], #8 + ldcl p1, cr15, [r0], #8 +Lno_iwmmxt_sc: + + /* Now bring back the signal status. */ + mov r0, #SIG_SETMASK + add r1, r4, #UCONTEXT_SIGMASK + mov r2, #0 + bl PLTJMP(__sigprocmask) + + /* Loading r0-r3 makes makecontext easier. */ + add r14, r4, #MCONTEXT_ARM_R0 + ldmia r14, {r0-r12} + ldr r13, [r14, #(MCONTEXT_ARM_SP - MCONTEXT_ARM_R0)] + add r14, r14, #(MCONTEXT_ARM_LR - MCONTEXT_ARM_R0) + ldmia r14, {r14, pc} + +END(setcontext) +weak_alias(__setcontext, setcontext) + + /* Called when a makecontext() context returns. Start the + context in R4 or fall through to exit(). */ +ENTRY(__startcontext) + movs r0, r4 + bne PLTJMP(__setcontext) + + @ New context was 0 - exit + b PLTJMP(_exit) +END(__startcontext) + +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif + diff --git a/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S new file mode 100644 index 0000000..09492d0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/swapcontext.S @@ -0,0 +1,63 @@ +/* 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> + +#include "ucontext_i.h" + + .syntax unified + .text + +/* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ + +ENTRY(swapcontext) + + /* Have getcontext() do most of the work then fix up + LR afterwards. Save R3 to keep the stack aligned. */ + push {r0,r1,r3,r14} + cfi_adjust_cfa_offset (16) + cfi_rel_offset (r0,0) + cfi_rel_offset (r1,4) + cfi_rel_offset (r3,8) + cfi_rel_offset (r14,12) + + bl __getcontext + mov r4, r0 + + pop {r0,r1,r3,r14} + cfi_adjust_cfa_offset (-16) + cfi_restore (r0) + cfi_restore (r1) + cfi_restore (r3) + cfi_restore (r14) + + /* Exit if getcontext() failed. */ + cmp r4, #0 + itt ne + movne r0, r4 + RETINSTR(ne, r14) + + /* Fix up LR and the PC. */ + str r13,[r0, #MCONTEXT_ARM_SP] + str r14,[r0, #MCONTEXT_ARM_LR] + str r14,[r0, #MCONTEXT_ARM_PC] + + /* And swap using swapcontext(). */ + mov r0, r1 + b __setcontext + +END(swapcontext) diff --git a/sysdeps/unix/sysv/linux/arm/ucontext_i.sym b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym new file mode 100644 index 0000000..306292f --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/ucontext_i.sym @@ -0,0 +1,30 @@ +#include <inttypes.h> +#include <signal.h> +#include <stddef.h> +#include <sys/ucontext.h> + +SIG_BLOCK +SIG_SETMASK + +-- Offsets of the fields in the ucontext_t structure. +#define ucontext(member) offsetof (ucontext_t, member) +#define mcontext(member) ucontext (uc_mcontext.member) + +UCONTEXT_FLAGS ucontext (uc_flags) +UCONTEXT_LINK ucontext (uc_link) +UCONTEXT_STACK ucontext (uc_stack) +UCONTEXT_MCONTEXT ucontext (uc_mcontext) +UCONTEXT_SIGMASK ucontext (uc_sigmask) + +UCONTEXT_REGSPACE ucontext (uc_regspace) + +MCONTEXT_TRAP_NO mcontext (trap_no) +MCONTEXT_ERROR_CODE mcontext (error_code) +MCONTEXT_OLDMASK mcontext (oldmask) +MCONTEXT_ARM_R0 mcontext (arm_r0) +MCONTEXT_ARM_R4 mcontext (arm_r4) +MCONTEXT_ARM_SP mcontext (arm_sp) +MCONTEXT_ARM_LR mcontext (arm_lr) +MCONTEXT_ARM_PC mcontext (arm_pc) +MCONTEXT_ARM_CPSR mcontext (arm_cpsr) +MCONTEXT_FAULT_ADDRESS mcontext (fault_address) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-02-27 23:22 ` Michael Hope @ 2012-03-04 21:17 ` Michael Hope 2012-03-05 15:59 ` Carlos O'Donell 0 siblings, 1 reply; 9+ messages in thread From: Michael Hope @ 2012-03-04 21:17 UTC (permalink / raw) To: Carlos O'Donell; +Cc: libc-ports On Tue, Feb 28, 2012 at 12:21 PM, Michael Hope <michael.hope@linaro.org> wrote: > On 28/02/12 12:05, Carlos O'Donell wrote: >> >> On Mon, Feb 27, 2012 at 5:03 PM, Michael Hope<michael.hope@linaro.org> >> wrote: >>>> >>>> I looked over things briefly and the formatting and license looks OK. >>>> Do you and Dave have FSF copyright assignments in place? >>> >>> >>> Yes. Linaro has an assignment agreement for GCC, GDB, binutils, and >>> GLIBC >>> under case #664398. >> >> >> Excellent. Thanks. >> >>>> (1) Is setcontext correctly implemented? >>> >>> It's correct to the specification and matches the MIPS and Tile ports. >>> From >>> IEEE 1003.1:2004: >> >> >> I've gone and re-read the standard, and I agree with you. >> >> Personally I think there is a QoI issue here, but you meet the >> standard which is the right thing to do. > > > Agreed. Being able to change uc_link while in a makecontext() child would > be nice. Ping? -- Michael ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-03-04 21:17 ` Michael Hope @ 2012-03-05 15:59 ` Carlos O'Donell 2012-03-05 22:37 ` Joseph S. Myers 0 siblings, 1 reply; 9+ messages in thread From: Carlos O'Donell @ 2012-03-05 15:59 UTC (permalink / raw) To: Joseph S. Myers; +Cc: Michael Hope, libc-ports On Sun, Mar 4, 2012 at 4:17 PM, Michael Hope <michael.hope@linaro.org> wrote: > Ping? http://sourceware.org/ml/libc-ports/2012-02/msg00077.html Joseph, I've reviewed this patch twice and plan to commit this at the end of the day. Do you have any objections? Cheers, Carlos. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-03-05 15:59 ` Carlos O'Donell @ 2012-03-05 22:37 ` Joseph S. Myers 2012-03-06 15:22 ` Carlos O'Donell 0 siblings, 1 reply; 9+ messages in thread From: Joseph S. Myers @ 2012-03-05 22:37 UTC (permalink / raw) To: Carlos O'Donell; +Cc: Michael Hope, libc-ports On Mon, 5 Mar 2012, Carlos O'Donell wrote: > On Sun, Mar 4, 2012 at 4:17 PM, Michael Hope <michael.hope@linaro.org> wrote: > > Ping? > > http://sourceware.org/ml/libc-ports/2012-02/msg00077.html > > Joseph, > > I've reviewed this patch twice and plan to commit this at the end of the day. > > Do you have any objections? I have no objections. -- Joseph S. Myers joseph@codesourcery.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [ARM] getcontext routines v2 2012-03-05 22:37 ` Joseph S. Myers @ 2012-03-06 15:22 ` Carlos O'Donell 0 siblings, 0 replies; 9+ messages in thread From: Carlos O'Donell @ 2012-03-06 15:22 UTC (permalink / raw) To: Joseph S. Myers; +Cc: Michael Hope, libc-ports On Mon, Mar 5, 2012 at 5:37 PM, Joseph S. Myers <joseph@codesourcery.com> wrote: > On Mon, 5 Mar 2012, Carlos O'Donell wrote: > >> On Sun, Mar 4, 2012 at 4:17 PM, Michael Hope <michael.hope@linaro.org> wrote: >> > Ping? >> >> http://sourceware.org/ml/libc-ports/2012-02/msg00077.html >> >> Joseph, >> >> I've reviewed this patch twice and plan to commit this at the end of the day. >> >> Do you have any objections? > > I have no objections. Checked into ports. Thanks for the ping Michael. Cheers, Carlos. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-03-06 15:22 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-02-24 1:34 [ARM] getcontext routines v2 Michael Hope 2012-02-24 15:39 ` Carlos O'Donell 2012-02-27 22:03 ` Michael Hope 2012-02-27 23:06 ` Carlos O'Donell 2012-02-27 23:22 ` Michael Hope 2012-03-04 21:17 ` Michael Hope 2012-03-05 15:59 ` Carlos O'Donell 2012-03-05 22:37 ` Joseph S. Myers 2012-03-06 15:22 ` Carlos O'Donell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).