* Implemented [sig]{set,long}jmp() for PPC. No idea, if it is any good,

but it compiles at least. :-)
* Pulled the architecture specific part out of <posix/setjmp.h> into
  <posix/arch/<arch>/arch_setjmp.h>.
* Moved setjmp_save_sigs.c from the x86 specific implementation into a
  "generic" sibling directory, since it is reusable (and actually used
  by the PPC implementation).
* Added generic/longjmp_return.c containing a function __longjmp_return,
  which is invoked at the end of siglongjmp(), resetting the signal mask
  and validating the return value. It is used by the PPC implementation,
  and should also be used by the x86 implementation, but I'll leave that
  to someone who's motivated enough to also test it. :-)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15479 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2005-12-10 22:56:52 +00:00
parent 62b965a65f
commit fe14a904a8
11 changed files with 223 additions and 8 deletions

View File

@ -0,0 +1,10 @@
/*
* Copyright 2005, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _ARCH_SETJMP_H_
#define _ARCH_SETJMP_H_
typedef int __jmp_buf[23];
#endif /* _ARCH_SETJMP_H_ */

View File

@ -0,0 +1,10 @@
/*
* Copyright 2005, Haiku, Inc.
* Distributed under the terms of the MIT License.
*/
#ifndef _ARCH_SETJMP_H_
#define _ARCH_SETJMP_H_
typedef int __jmp_buf[6];
#endif /* _ARCH_SETJMP_H_ */

View File

@ -5,12 +5,17 @@
#ifndef _SETJMP_H_
#define _SETJMP_H_
#include <signal.h>
// include architecture specific definitions
#ifdef __INTEL__
#include <arch/x86/arch_setjmp.h>
#elif __POWERPC__
#include <arch/ppc/arch_setjmp.h>
#endif
typedef struct __jmp_buf {
int regs[6]; /* saved registers, stack & program pointer */
typedef struct __jmp_buf_tag {
__jmp_buf regs; /* saved registers, stack & program pointer */
int mask_was_saved;
sigset_t saved_mask;
} jmp_buf[1];

View File

@ -0,0 +1,23 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include <setjmp.h>
/** This function is called by [sig]longjmp(). The caller has already
set up the registers and stack, so that returning from the function
will return to the place where [sig]setjmp() was invoked. It resets
the signal mask and validates the value supplied to [sig]longjmp().
*/
int __longjmp_return(jmp_buf buffer, int value);
int
__longjmp_return(jmp_buf buffer, int value)
{
if (buffer[0].mask_was_saved)
sigprocmask(SIG_SETMASK, &buffer[0].saved_mask, NULL);
return (value == 0 ? 1 : value);
}

View File

@ -1,9 +1,17 @@
SubDir HAIKU_TOP src system libroot posix arch ppc ;
# TODO: Implement!
local genericSources =
setjmp_save_sigs.c
longjmp_return.c
;
MergeObject posix_arch_$(TARGET_ARCH).o :
setjmp.S
# setjmp_save_sigs.c
# sigsetjmp.S
# siglongjmp.S
sigsetjmp.S
siglongjmp.S
$(genericSources)
;
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;

View File

@ -0,0 +1,15 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include "setjmp_internal.h"
/* int setjmp(jmp_buf buffer) */
FUNCTION(setjmp):
// call __sigsetjmp with saveMask = 0
addi %r4, 0, 0
b __sigsetjmp
#pragma weak _setjmp=setjmp

View File

@ -0,0 +1,47 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#ifndef SETJMP_INTERNAL_H
#define SETJMP_INTERNAL_H
/* PPC function call ABI register use:
r0 - volatile
r1 - stack frame
r2 - reserved
r3-r4 - param passing, return values
r5-r10 - param passing
r11-r12 - volatile
r13 - small data pointer
r14-r30 - local vars
r31 - local vars/environment
*/
/* These are the fields of the __jmp_regs structure */
#define JMP_REGS_R1 0
#define JMP_REGS_R2 4
#define JMP_REGS_R13 8
#define JMP_REGS_R14 12
#define JMP_REGS_R15 16
#define JMP_REGS_R16 20
#define JMP_REGS_R17 24
#define JMP_REGS_R18 28
#define JMP_REGS_R19 32
#define JMP_REGS_R20 36
#define JMP_REGS_R21 40
#define JMP_REGS_R22 44
#define JMP_REGS_R23 48
#define JMP_REGS_R24 52
#define JMP_REGS_R25 56
#define JMP_REGS_R26 60
#define JMP_REGS_R27 64
#define JMP_REGS_R28 68
#define JMP_REGS_R29 72
#define JMP_REGS_R30 76
#define JMP_REGS_R31 80
#define JMP_REGS_LR 84
#define JMP_REGS_CR 88
#define FUNCTION(x) .global x; .type x,@function; x
#endif /* SETJMP_INTERNAL_H */

View File

@ -0,0 +1,45 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include "setjmp_internal.h"
/* int __siglongjmp(jmp_buf buffer, int value) */
FUNCTION(siglongjmp):
FUNCTION(longjmp):
FUNCTION(_longjmp):
// r3: buffer, r4: saveMask
// restore non-volatile general purpose registers
lwz %r1, JMP_REGS_R1(3)
lwz %r2, JMP_REGS_R2(3)
lwz %r13, JMP_REGS_R13(3)
lwz %r14, JMP_REGS_R14(3)
lwz %r15, JMP_REGS_R15(3)
lwz %r16, JMP_REGS_R16(3)
lwz %r17, JMP_REGS_R17(3)
lwz %r18, JMP_REGS_R18(3)
lwz %r19, JMP_REGS_R19(3)
lwz %r20, JMP_REGS_R20(3)
lwz %r21, JMP_REGS_R21(3)
lwz %r22, JMP_REGS_R22(3)
lwz %r23, JMP_REGS_R23(3)
lwz %r24, JMP_REGS_R24(3)
lwz %r25, JMP_REGS_R25(3)
lwz %r26, JMP_REGS_R26(3)
lwz %r27, JMP_REGS_R27(3)
lwz %r28, JMP_REGS_R28(3)
lwz %r29, JMP_REGS_R29(3)
lwz %r30, JMP_REGS_R30(3)
lwz %r31, JMP_REGS_R31(3)
// restore special registers (link, condition)
lwz %r0, JMP_REGS_LR(3)
mtlr %r0
lwz %r0, JMP_REGS_CR(3)
mtcr %r0
b __longjmp_return
#pragma weak longjmp=siglongjmp

View File

@ -0,0 +1,42 @@
/*
* Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. All rights
* reserved. Distributed under the terms of the Haiku License.
*/
#include "setjmp_internal.h"
/* int sigsetjmp(jmp_buf buffer, int saveMask) */
FUNCTION(__sigsetjmp):
FUNCTION(sigsetjmp):
// r3: buffer, r4: saveMask
// store non-volatile general purpose registers
stw %r1, JMP_REGS_R1(3)
stw %r2, JMP_REGS_R2(3)
stw %r13, JMP_REGS_R13(3)
stw %r14, JMP_REGS_R14(3)
stw %r15, JMP_REGS_R15(3)
stw %r16, JMP_REGS_R16(3)
stw %r17, JMP_REGS_R17(3)
stw %r18, JMP_REGS_R18(3)
stw %r19, JMP_REGS_R19(3)
stw %r20, JMP_REGS_R20(3)
stw %r21, JMP_REGS_R21(3)
stw %r22, JMP_REGS_R22(3)
stw %r23, JMP_REGS_R23(3)
stw %r24, JMP_REGS_R24(3)
stw %r25, JMP_REGS_R25(3)
stw %r26, JMP_REGS_R26(3)
stw %r27, JMP_REGS_R27(3)
stw %r28, JMP_REGS_R28(3)
stw %r29, JMP_REGS_R29(3)
stw %r30, JMP_REGS_R30(3)
stw %r31, JMP_REGS_R31(3)
// store special registers (link, condition)
mflr %r0
stw %r0, JMP_REGS_LR(3)
mfcr %r0
stw %r0, JMP_REGS_CR(3)
b __setjmp_save_sigs

View File

@ -1,8 +1,18 @@
SubDir HAIKU_TOP src system libroot posix arch x86 ;
# TODO: siglongjmp.S should use __longjmp_return to restore the signal mask.
local genericSources =
setjmp_save_sigs.c
# longjmp_return.c
;
MergeObject posix_arch_$(TARGET_ARCH).o :
setjmp.S
setjmp_save_sigs.c
sigsetjmp.S
siglongjmp.S
$(genericSources)
;
SEARCH on [ FGristFiles $(genericSources) ]
= [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;