diff options
Diffstat (limited to 'src/pkg/runtime/linux')
| -rw-r--r-- | src/pkg/runtime/linux/386/signal.c | 2 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/amd64/signal.c | 2 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/amd64/sys.s | 22 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/arm/defs.h | 66 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/arm/signal.c | 159 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/arm/sys.s | 39 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/defs_arm.c | 31 | ||||
| -rw-r--r-- | src/pkg/runtime/linux/os.h | 2 |
8 files changed, 211 insertions, 112 deletions
diff --git a/src/pkg/runtime/linux/386/signal.c b/src/pkg/runtime/linux/386/signal.c index c54008302..87e6779b5 100644 --- a/src/pkg/runtime/linux/386/signal.c +++ b/src/pkg/runtime/linux/386/signal.c @@ -70,7 +70,7 @@ sighandler(int32 sig, Siginfo* info, void* context) printf("\n"); if(gotraceback()){ - traceback((void*)sc->eip, (void*)sc->esp, m->curg); + traceback((void*)sc->eip, (void*)sc->esp, 0, m->curg); tracebackothers(m->curg); dumpregs(sc); } diff --git a/src/pkg/runtime/linux/amd64/signal.c b/src/pkg/runtime/linux/amd64/signal.c index dba6fb10d..87a5a638b 100644 --- a/src/pkg/runtime/linux/amd64/signal.c +++ b/src/pkg/runtime/linux/amd64/signal.c @@ -80,7 +80,7 @@ sighandler(int32 sig, Siginfo* info, void* context) printf("\n"); if(gotraceback()){ - traceback((void*)sc->rip, (void*)sc->rsp, (void*)sc->r15); + traceback((void*)sc->rip, (void*)sc->rsp, 0, (void*)sc->r15); tracebackothers((void*)sc->r15); dumpregs(sc); } diff --git a/src/pkg/runtime/linux/amd64/sys.s b/src/pkg/runtime/linux/amd64/sys.s index 78bb39ad6..882ccf1d2 100644 --- a/src/pkg/runtime/linux/amd64/sys.s +++ b/src/pkg/runtime/linux/amd64/sys.s @@ -98,28 +98,6 @@ TEXT notok(SB),7,$0 MOVQ BP, (BP) RET -TEXT ·memclr(SB),7,$0-16 - MOVQ 8(SP), DI // arg 1 addr - MOVL 16(SP), CX // arg 2 count (cannot be zero) - ADDL $7, CX - SHRL $3, CX - MOVQ $0, AX - CLD - REP - STOSQ - RET - -TEXT ·getcallerpc+0(SB),7,$0 - MOVQ x+0(FP),AX // addr of first arg - MOVQ -8(AX),AX // get calling pc - RET - -TEXT ·setcallerpc+0(SB),7,$0 - MOVQ x+0(FP),AX // addr of first arg - MOVQ x+8(FP), BX - MOVQ BX, -8(AX) // set calling pc - RET - // int64 futex(int32 *uaddr, int32 op, int32 val, // struct timespec *timeout, int32 *uaddr2, int32 val2); TEXT futex(SB),7,$0 diff --git a/src/pkg/runtime/linux/arm/defs.h b/src/pkg/runtime/linux/arm/defs.h index caad66989..215983158 100644 --- a/src/pkg/runtime/linux/arm/defs.h +++ b/src/pkg/runtime/linux/arm/defs.h @@ -1,4 +1,4 @@ -// godefs -carm-gcc -f -I/usr/local/google/src/linux-2.6.28/arch/arm/include -f -I/usr/local/google/src/linux-2.6.28/include defs_arm.c +// godefs -carm-gcc -f -I/usr/local/google/src/linux-2.6.28/arch/arm/include -f -I/usr/local/google/src/linux-2.6.28/include -f-D__KERNEL__ -f-D__ARCH_SI_UID_T=int defs_arm.c // MACHINE GENERATED - DO NOT EDIT. @@ -19,9 +19,73 @@ enum { // Types #pragma pack on +typedef struct Sigset Sigset; +struct Sigset { + uint32 sig[2]; +}; + +typedef struct Sigaction Sigaction; +struct Sigaction { + void *sa_handler; + uint32 sa_flags; + void *sa_restorer; + Sigset sa_mask; +}; + typedef struct Timespec Timespec; struct Timespec { int32 tv_sec; int32 tv_nsec; }; + +typedef struct Sigaltstack Sigaltstack; +struct Sigaltstack { + void *ss_sp; + int32 ss_flags; + uint32 ss_size; +}; + +typedef struct Sigcontext Sigcontext; +struct Sigcontext { + uint32 trap_no; + uint32 error_code; + uint32 oldmask; + uint32 arm_r0; + uint32 arm_r1; + uint32 arm_r2; + uint32 arm_r3; + uint32 arm_r4; + uint32 arm_r5; + uint32 arm_r6; + uint32 arm_r7; + uint32 arm_r8; + uint32 arm_r9; + uint32 arm_r10; + uint32 arm_fp; + uint32 arm_ip; + uint32 arm_sp; + uint32 arm_lr; + uint32 arm_pc; + uint32 arm_cpsr; + uint32 fault_address; +}; + +typedef struct Ucontext Ucontext; +struct Ucontext { + uint32 uc_flags; + Ucontext *uc_link; + Sigaltstack uc_stack; + Sigcontext uc_mcontext; + Sigset uc_sigmask; + int32 __unused[30]; + uint32 uc_regspace[128]; +}; + +typedef struct Siginfo Siginfo; +struct Siginfo { + int32 si_signo; + int32 si_errno; + int32 si_code; + uint8 _sifields[4]; +}; #pragma pack off diff --git a/src/pkg/runtime/linux/arm/signal.c b/src/pkg/runtime/linux/arm/signal.c index 240057548..d1d8bc08c 100644 --- a/src/pkg/runtime/linux/arm/signal.c +++ b/src/pkg/runtime/linux/arm/signal.c @@ -7,25 +7,31 @@ #include "signals.h" #include "os.h" -void dumpregs(void) {} -// void -// dumpregs(Sigcontext *r) -// { -// printf("eax %X\n", r->eax); -// printf("ebx %X\n", r->ebx); -// printf("ecx %X\n", r->ecx); -// printf("edx %X\n", r->edx); -// printf("edi %X\n", r->edi); -// printf("esi %X\n", r->esi); -// printf("ebp %X\n", r->ebp); -// printf("esp %X\n", r->esp); -// printf("eip %X\n", r->eip); -// printf("eflags %X\n", r->eflags); -// printf("cs %X\n", r->cs); -// printf("fs %X\n", r->fs); -// printf("gs %X\n", r->gs); -// } - +void +dumpregs(Sigcontext *r) +{ + printf("trap %x\n", r->trap_no); + printf("error %x\n", r->error_code); + printf("oldmask %x\n", r->oldmask); + printf("r0 %x\n", r->arm_r0); + printf("r1 %x\n", r->arm_r1); + printf("r2 %x\n", r->arm_r2); + printf("r3 %x\n", r->arm_r3); + printf("r4 %x\n", r->arm_r4); + printf("r5 %x\n", r->arm_r5); + printf("r6 %x\n", r->arm_r6); + printf("r7 %x\n", r->arm_r7); + printf("r8 %x\n", r->arm_r8); + printf("r9 %x\n", r->arm_r9); + printf("r10 %x\n", r->arm_r10); + printf("fp %x\n", r->arm_fp); + printf("ip %x\n", r->arm_ip); + printf("sp %x\n", r->arm_sp); + printf("lr %x\n", r->arm_lr); + printf("pc %x\n", r->arm_pc); + printf("cpsr %x\n", r->arm_cpsr); + printf("fault %x\n", r->fault_address); +} /* * This assembler routine takes the args from registers, puts them on the stack, @@ -43,70 +49,79 @@ signame(int32 sig) return gostring((byte*)sigtab[sig].name); } -void sighandler(void) {} -// void -// sighandler(int32 sig, Siginfo* info, void* context) -// { -// Ucontext *uc; -// Sigcontext *sc; - -// if(panicking) // traceback already printed -// exit(2); -// panicking = 1; - -// uc = context; -// sc = &uc->uc_mcontext; - -// if(sig < 0 || sig >= NSIG) -// printf("Signal %d\n", sig); -// else -// printf("%s\n", sigtab[sig].name); +void +sighandler(int32 sig, Siginfo *info, void *context) +{ + Ucontext *uc; + Sigcontext *sc; -// printf("Faulting address: %p\n", *(void**)info->_sifields); -// printf("pc=%X\n", sc->eip); -// printf("\n"); + if(sigtab[sig].flags & SigQueue) { + if(sigsend(sig) || (sigtab[sig].flags & SigIgnore)) + return; + exit(2); // SIGINT, SIGTERM, etc + } -// if(gotraceback()){ -// traceback((void*)sc->eip, (void*)sc->esp, m->curg); -// tracebackothers(m->curg); -// dumpregs(sc); -// } + if(panicking) // traceback already printed + exit(2); + panicking = 1; -// breakpoint(); -// exit(2); -// } + if(sig < 0 || sig >= NSIG) + printf("Signal %d\n", sig); + else + printf("%s\n", sigtab[sig].name); + + uc = context; + sc = &uc->uc_mcontext; + + printf("Faulting address: %p\n", sc->fault_address); + printf("PC=%x\n", sc->arm_pc); + printf("\n"); + + if(gotraceback()){ + traceback((void*)sc->arm_pc, (void*)sc->arm_sp, (void*)sc->arm_lr, m->curg); + tracebackothers(m->curg); + printf("\n"); + dumpregs(sc); + } + +// breakpoint(); + exit(2); +} void signalstack(byte *p, int32 n) { -// Sigaltstack st; + Sigaltstack st; -// st.ss_sp = p; -// st.ss_size = n; -// st.ss_flags = 0; -// sigaltstack(&st, nil); + st.ss_sp = p; + st.ss_size = n; + st.ss_flags = 0; + sigaltstack(&st, nil); } void initsig(void) { -// static Sigaction sa; - -// int32 i; -// sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; -// sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; -// sa.sa_restorer = (void*)sigreturn; -// for(i = 0; i<NSIG; i++) { -// if(sigtab[i].flags) { -// if(sigtab[i].flags & SigCatch) -// *(void**)sa._u = (void*)sigtramp; // handler -// else -// *(void**)sa._u = (void*)sigignore; // handler -// if(sigtab[i].flags & SigRestart) -// sa.sa_flags |= SA_RESTART; -// else -// sa.sa_flags &= ~SA_RESTART; -// rt_sigaction(i, &sa, nil, 8); -// } -// } + static Sigaction sa; + + siginit(); + + int32 i; + sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; + sa.sa_mask.sig[0] = 0xFFFFFFFF; + sa.sa_mask.sig[1] = 0xFFFFFFFF; + sa.sa_restorer = (void*)sigreturn; + for(i = 0; i<NSIG; i++) { + if(sigtab[i].flags) { + if(sigtab[i].flags & (SigCatch | SigQueue)) + sa.sa_handler = (void*)sigtramp; + else + sa.sa_handler = (void*)sigignore; + if(sigtab[i].flags & SigRestart) + sa.sa_flags |= SA_RESTART; + else + sa.sa_flags &= ~SA_RESTART; + rt_sigaction(i, &sa, nil, 8); + } + } } diff --git a/src/pkg/runtime/linux/arm/sys.s b/src/pkg/runtime/linux/arm/sys.s index 78c03db3e..f30aed001 100644 --- a/src/pkg/runtime/linux/arm/sys.s +++ b/src/pkg/runtime/linux/arm/sys.s @@ -18,6 +18,9 @@ #define SYS_write (SYS_BASE + 4) #define SYS_gettimeofday (SYS_BASE + 78) #define SYS_clone (SYS_BASE + 120) +#define SYS_rt_sigreturn (SYS_BASE + 173) +#define SYS_rt_sigaction (SYS_BASE + 174) +#define SYS_sigaltstack (SYS_BASE + 186) #define SYS_mmap2 (SYS_BASE + 192) #define SYS_gettid (SYS_BASE + 224) #define SYS_futex (SYS_BASE + 240) @@ -175,3 +178,39 @@ TEXT cacheflush(SB),7,$0 SWI $0 RET +TEXT sigaltstack(SB),7,$0 + MOVW 0(FP), R0 + MOVW 4(FP), R1 + MOVW $SYS_sigaltstack, R7 + SWI $0 + RET + +TEXT sigignore(SB),7,$0 + RET + +TEXT sigreturn(SB),7,$0 + MOVW R0, R0 + B abort(SB) + RET + +TEXT sigtramp(SB),7,$24 + MOVW m_gsignal(m), g + MOVW R0, 4(R13) + MOVW R1, 8(R13) + MOVW R2, 12(R13) + BL sighandler(SB) + RET + +TEXT rt_sigaction(SB),7,$0 + MOVW 0(FP), R0 + MOVW 4(FP), R1 + MOVW 8(FP), R2 + MOVW 12(FP), R3 + MOVW $SYS_rt_sigaction, R7 + SWI $0 + RET + +TEXT sigreturn(SB),7,$0 + MOVW $SYS_rt_sigreturn, R7 + SWI $0 + RET diff --git a/src/pkg/runtime/linux/defs_arm.c b/src/pkg/runtime/linux/defs_arm.c index eaec05154..01d6bfcdc 100644 --- a/src/pkg/runtime/linux/defs_arm.c +++ b/src/pkg/runtime/linux/defs_arm.c @@ -4,8 +4,7 @@ /* * Input to godefs - godefs -carm-gcc -f -I/usr/local/google/src/linux-2.6.28/arch/arm/include -f - -I/usr/local/google/src/linux-2.6.28/include defs_arm.c >arm/defs.h + godefs -carm-gcc -f -I/usr/local/google/src/linux-2.6.28/arch/arm/include -f -I/usr/local/google/src/linux-2.6.28/include -f-D__KERNEL__ -f-D__ARCH_SI_UID_T=int defs_arm.c >arm/defs.h * Another input file for ARM defs.h */ @@ -14,6 +13,7 @@ #include <asm/mman.h> #include <asm/sigcontext.h> #include <asm/ucontext.h> +#include <asm/siginfo.h> /* #include <sys/signal.h> @@ -38,17 +38,18 @@ enum { $SA_SIGINFO = SA_SIGINFO }; - - - -//typedef struct _fpreg $Fpreg; -//typedef struct _fpxreg $Fpxreg; -//typedef struct _xmmreg $Xmmreg; -//typedef struct _fpstate $Fpstate; +typedef sigset_t $Sigset; +typedef struct sigaction $Sigaction; typedef struct timespec $Timespec; -//typedef struct timeval $Timeval; -// typedef struct sigaction $Sigaction; -// typedef siginfo_t $Siginfo; -// typedef struct sigaltstack $Sigaltstack; -// typedef struct sigcontext $Sigcontext; -// typedef struct ucontext $Ucontext; +typedef struct sigaltstack $Sigaltstack; +typedef struct sigcontext $Sigcontext; +typedef struct ucontext $Ucontext; + +struct xsiginfo { + int si_signo; + int si_errno; + int si_code; + char _sifields[4]; +}; + +typedef struct xsiginfo $Siginfo; diff --git a/src/pkg/runtime/linux/os.h b/src/pkg/runtime/linux/os.h index fd6ccffc3..387fd4321 100644 --- a/src/pkg/runtime/linux/os.h +++ b/src/pkg/runtime/linux/os.h @@ -8,3 +8,5 @@ int32 clone(int32, void*, M*, G*, void(*)(void)); struct Sigaction; void rt_sigaction(uintptr, struct Sigaction*, void*, uintptr); + +void sigaltstack(Sigaltstack*, Sigaltstack*); |
