diff options
Diffstat (limited to 'src/pkg/runtime/linux')
-rw-r--r-- | src/pkg/runtime/linux/386/defs.h | 1 | ||||
-rw-r--r-- | src/pkg/runtime/linux/386/rt0.s | 10 | ||||
-rw-r--r-- | src/pkg/runtime/linux/386/signal.c | 108 | ||||
-rw-r--r-- | src/pkg/runtime/linux/386/sys.s | 55 | ||||
-rw-r--r-- | src/pkg/runtime/linux/amd64/defs.h | 1 | ||||
-rw-r--r-- | src/pkg/runtime/linux/amd64/rt0.s | 2 | ||||
-rw-r--r-- | src/pkg/runtime/linux/amd64/signal.c | 124 | ||||
-rw-r--r-- | src/pkg/runtime/linux/amd64/sys.s | 96 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/defs.h | 27 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/rt0.s | 2 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/signal.c | 118 | ||||
-rw-r--r-- | src/pkg/runtime/linux/arm/sys.s | 47 | ||||
-rw-r--r-- | src/pkg/runtime/linux/defs.c | 1 | ||||
-rw-r--r-- | src/pkg/runtime/linux/defs2.c | 1 | ||||
-rw-r--r-- | src/pkg/runtime/linux/defs_arm.c | 29 | ||||
-rw-r--r-- | src/pkg/runtime/linux/mem.c | 27 | ||||
-rw-r--r-- | src/pkg/runtime/linux/os.h | 10 | ||||
-rw-r--r-- | src/pkg/runtime/linux/runtime_defs.go | 14 | ||||
-rw-r--r-- | src/pkg/runtime/linux/signals.h | 2 | ||||
-rw-r--r-- | src/pkg/runtime/linux/thread.c | 90 |
20 files changed, 433 insertions, 332 deletions
diff --git a/src/pkg/runtime/linux/386/defs.h b/src/pkg/runtime/linux/386/defs.h index ef8ef05d0..c1f58b2a0 100644 --- a/src/pkg/runtime/linux/386/defs.h +++ b/src/pkg/runtime/linux/386/defs.h @@ -10,6 +10,7 @@ enum { PROT_EXEC = 0x4, MAP_ANON = 0x20, MAP_PRIVATE = 0x2, + MAP_FIXED = 0x10, SA_RESTART = 0x10000000, SA_ONSTACK = 0x8000000, SA_RESTORER = 0x4000000, diff --git a/src/pkg/runtime/linux/386/rt0.s b/src/pkg/runtime/linux/386/rt0.s index 4d2345d8c..0f82d6a1c 100644 --- a/src/pkg/runtime/linux/386/rt0.s +++ b/src/pkg/runtime/linux/386/rt0.s @@ -4,6 +4,14 @@ // Darwin and Linux use the same linkage to main -TEXT _rt0_386_linux(SB),7,$0 +TEXT _rt0_386_linux(SB),7,$0 + // Linux starts the FPU in extended double precision. + // Other operating systems use double precision. + // Change to double precision to match them, + // and to match other hardware that only has double. + PUSHL $0x27F + FLDCW 0(SP) + POPL AX + JMP _rt0_386(SB) diff --git a/src/pkg/runtime/linux/386/signal.c b/src/pkg/runtime/linux/386/signal.c index 6bc95d0d7..0dbfcf9ff 100644 --- a/src/pkg/runtime/linux/386/signal.c +++ b/src/pkg/runtime/linux/386/signal.c @@ -8,41 +8,41 @@ #include "os.h" void -dumpregs(Sigcontext *r) +runtime·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); + runtime·printf("eax %x\n", r->eax); + runtime·printf("ebx %x\n", r->ebx); + runtime·printf("ecx %x\n", r->ecx); + runtime·printf("edx %x\n", r->edx); + runtime·printf("edi %x\n", r->edi); + runtime·printf("esi %x\n", r->esi); + runtime·printf("ebp %x\n", r->ebp); + runtime·printf("esp %x\n", r->esp); + runtime·printf("eip %x\n", r->eip); + runtime·printf("eflags %x\n", r->eflags); + runtime·printf("cs %x\n", r->cs); + runtime·printf("fs %x\n", r->fs); + runtime·printf("gs %x\n", r->gs); } /* * This assembler routine takes the args from registers, puts them on the stack, * and calls sighandler(). */ -extern void sigtramp(void); -extern void sigignore(void); // just returns -extern void sigreturn(void); // calls sigreturn +extern void runtime·sigtramp(void); +extern void runtime·sigignore(void); // just returns +extern void runtime·sigreturn(void); // calls runtime·sigreturn String -signame(int32 sig) +runtime·signame(int32 sig) { if(sig < 0 || sig >= NSIG) - return emptystring; - return gostringnocopy((byte*)sigtab[sig].name); + return runtime·emptystring; + return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name); } void -sighandler(int32 sig, Siginfo* info, void* context) +runtime·sighandler(int32 sig, Siginfo* info, void* context) { Ucontext *uc; Sigcontext *r; @@ -52,7 +52,7 @@ sighandler(int32 sig, Siginfo* info, void* context) uc = context; r = &uc->uc_mcontext; - if((gp = m->curg) != nil && (sigtab[sig].flags & SigPanic)) { + if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { // Make it look like a call to the signal func. // Have to pass arguments out of band since // augmenting the stack frame would break @@ -61,84 +61,84 @@ sighandler(int32 sig, Siginfo* info, void* context) gp->sigcode0 = info->si_code; gp->sigcode1 = ((uintptr*)info)[3]; - // Only push sigpanic if r->eip != 0. + // Only push runtime·sigpanic if r->eip != 0. // If r->eip == 0, probably panicked because of a // call to a nil func. Not pushing that onto sp will - // make the trace look like a call to sigpanic instead. - // (Otherwise the trace will end at sigpanic and we + // make the trace look like a call to runtime·sigpanic instead. + // (Otherwise the trace will end at runtime·sigpanic and we // won't get to see who faulted.) if(r->eip != 0) { sp = (uintptr*)r->esp; *--sp = r->eip; r->esp = (uintptr)sp; } - r->eip = (uintptr)sigpanic; + r->eip = (uintptr)runtime·sigpanic; return; } - if(sigtab[sig].flags & SigQueue) { - if(sigsend(sig) || (sigtab[sig].flags & SigIgnore)) + if(runtime·sigtab[sig].flags & SigQueue) { + if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore)) return; - exit(2); // SIGINT, SIGTERM, etc + runtime·exit(2); // SIGINT, SIGTERM, etc } - if(panicking) // traceback already printed - exit(2); - panicking = 1; + if(runtime·panicking) // traceback already printed + runtime·exit(2); + runtime·panicking = 1; if(sig < 0 || sig >= NSIG) - printf("Signal %d\n", sig); + runtime·printf("Signal %d\n", sig); else - printf("%s\n", sigtab[sig].name); + runtime·printf("%s\n", runtime·sigtab[sig].name); - printf("PC=%X\n", r->eip); - printf("\n"); + runtime·printf("PC=%X\n", r->eip); + runtime·printf("\n"); - if(gotraceback()){ - traceback((void*)r->eip, (void*)r->esp, 0, m->curg); - tracebackothers(m->curg); - dumpregs(r); + if(runtime·gotraceback()){ + runtime·traceback((void*)r->eip, (void*)r->esp, 0, m->curg); + runtime·tracebackothers(m->curg); + runtime·dumpregs(r); } - breakpoint(); - exit(2); + runtime·breakpoint(); + runtime·exit(2); } void -signalstack(byte *p, int32 n) +runtime·signalstack(byte *p, int32 n) { Sigaltstack st; st.ss_sp = p; st.ss_size = n; st.ss_flags = 0; - sigaltstack(&st, nil); + runtime·sigaltstack(&st, nil); } void -initsig(int32 queue) +runtime·initsig(int32 queue) { static Sigaction sa; - siginit(); + runtime·siginit(); int32 i; sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; - sa.sa_restorer = (void*)sigreturn; + sa.sa_restorer = (void*)runtime·sigreturn; for(i = 0; i<NSIG; i++) { - if(sigtab[i].flags) { - if((sigtab[i].flags & SigQueue) != queue) + if(runtime·sigtab[i].flags) { + if((runtime·sigtab[i].flags & SigQueue) != queue) continue; - if(sigtab[i].flags & (SigCatch | SigQueue)) - sa.k_sa_handler = (void*)sigtramp; + if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) + sa.k_sa_handler = (void*)runtime·sigtramp; else - sa.k_sa_handler = (void*)sigignore; - if(sigtab[i].flags & SigRestart) + sa.k_sa_handler = (void*)runtime·sigignore; + if(runtime·sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; else sa.sa_flags &= ~SA_RESTART; - rt_sigaction(i, &sa, nil, 8); + runtime·rt_sigaction(i, &sa, nil, 8); } } } diff --git a/src/pkg/runtime/linux/386/sys.s b/src/pkg/runtime/linux/386/sys.s index 57ffc4aa4..a1505b0b0 100644 --- a/src/pkg/runtime/linux/386/sys.s +++ b/src/pkg/runtime/linux/386/sys.s @@ -8,21 +8,21 @@ #include "386/asm.h" -TEXT exit(SB),7,$0 +TEXT runtime·exit(SB),7,$0 MOVL $252, AX // syscall number MOVL 4(SP), BX INT $0x80 INT $3 // not reached RET -TEXT exit1(SB),7,$0 +TEXT runtime·exit1(SB),7,$0 MOVL $1, AX // exit - exit the current os thread MOVL 4(SP), BX INT $0x80 INT $3 // not reached RET -TEXT write(SB),7,$0 +TEXT runtime·write(SB),7,$0 MOVL $4, AX // syscall - write MOVL 4(SP), BX MOVL 8(SP), CX @@ -30,7 +30,7 @@ TEXT write(SB),7,$0 INT $0x80 RET -TEXT gettime(SB), 7, $32 +TEXT runtime·gettime(SB), 7, $32 MOVL $78, AX // syscall - gettimeofday LEAL 8(SP), BX MOVL $0, CX @@ -47,7 +47,7 @@ TEXT gettime(SB), 7, $32 MOVL BX, (DI) RET -TEXT rt_sigaction(SB),7,$0 +TEXT runtime·rt_sigaction(SB),7,$0 MOVL $174, AX // syscall - rt_sigaction MOVL 4(SP), BX MOVL 8(SP), CX @@ -56,7 +56,7 @@ TEXT rt_sigaction(SB),7,$0 INT $0x80 RET -TEXT sigtramp(SB),7,$40 +TEXT runtime·sigtramp(SB),7,$40 get_tls(CX) // save g @@ -76,7 +76,7 @@ TEXT sigtramp(SB),7,$40 MOVL context+8(FP), BX MOVL BX, 8(SP) - CALL sighandler(SB) + CALL runtime·sighandler(SB) // restore g get_tls(CX) @@ -85,16 +85,16 @@ TEXT sigtramp(SB),7,$40 RET -TEXT sigignore(SB),7,$0 +TEXT runtime·sigignore(SB),7,$0 RET -TEXT sigreturn(SB),7,$0 +TEXT runtime·sigreturn(SB),7,$0 MOVL $173, AX // rt_sigreturn INT $0x80 INT $3 // not reached RET -TEXT ·mmap(SB),7,$0 +TEXT runtime·mmap(SB),7,$0 MOVL $192, AX // mmap2 MOVL 4(SP), BX MOVL 8(SP), CX @@ -110,9 +110,19 @@ TEXT ·mmap(SB),7,$0 INCL AX RET +TEXT runtime·munmap(SB),7,$0 + MOVL $91, AX // munmap + MOVL 4(SP), BX + MOVL 8(SP), CX + INT $0x80 + CMPL AX, $0xfffff001 + JLS 2(PC) + INT $3 + RET + // int32 futex(int32 *uaddr, int32 op, int32 val, // struct timespec *timeout, int32 *uaddr2, int32 val2); -TEXT futex(SB),7,$0 +TEXT runtime·futex(SB),7,$0 MOVL $240, AX // futex MOVL 4(SP), BX MOVL 8(SP), CX @@ -124,7 +134,7 @@ TEXT futex(SB),7,$0 RET // int32 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); -TEXT clone(SB),7,$0 +TEXT runtime·clone(SB),7,$0 MOVL $120, AX // clone MOVL flags+4(SP), BX MOVL stack+8(SP), CX @@ -161,12 +171,12 @@ TEXT clone(SB),7,$0 // In child on new stack. Reload registers (paranoia). MOVL 0(SP), BX // m MOVL 4(SP), DX // g - MOVL 8(SP), CX // fn + MOVL 8(SP), SI // fn MOVL AX, m_procid(BX) // save tid as m->procid // set up ldt 7+id to point at m->tls. - // m->tls is at m+40. newosproc left the id in tls[0]. + // newosproc left the id in tls[0]. LEAL m_tls(BX), BP MOVL 0(BP), DI ADDL $7, DI // m0 is LDT#7. count up. @@ -175,7 +185,7 @@ TEXT clone(SB),7,$0 PUSHL $32 // sizeof tls PUSHL BP // &tls PUSHL DI // tls # - CALL setldt(SB) + CALL runtime·setldt(SB) POPL AX POPL AX POPL AX @@ -186,21 +196,21 @@ TEXT clone(SB),7,$0 MOVL DX, g(AX) MOVL BX, m(AX) - CALL stackcheck(SB) // smashes AX + CALL runtime·stackcheck(SB) // smashes AX, CX MOVL 0(DX), DX // paranoia; check they are not nil MOVL 0(BX), BX // more paranoia; check that stack splitting code works PUSHAL - CALL emptyfunc(SB) + CALL runtime·emptyfunc(SB) POPAL - CALL CX // fn() - CALL exit1(SB) + CALL SI // fn() + CALL runtime·exit1(SB) MOVL $0x1234, 0x1005 RET -TEXT sigaltstack(SB),7,$-8 +TEXT runtime·sigaltstack(SB),7,$-8 MOVL $186, AX // sigaltstack MOVL new+4(SP), BX MOVL old+8(SP), CX @@ -233,7 +243,7 @@ TEXT sigaltstack(SB),7,$-8 #define USEABLE 0x40 // setldt(int entry, int address, int limit) -TEXT setldt(SB),7,$32 +TEXT runtime·setldt(SB),7,$32 MOVL entry+0(FP), BX // entry MOVL address+4(FP), CX // base address @@ -247,8 +257,11 @@ TEXT setldt(SB),7,$32 * To accommodate that rewrite, we translate * the address here and bump the limit to 0xffffffff (no limit) * so that -8(GS) maps to 0(address). + * Also, the final 0(GS) (current 8(CX)) has to point + * to itself, to mimic ELF. */ ADDL $0x8, CX // address + MOVL CX, 0(CX) // set up user_desc LEAL 16(SP), AX // struct user_desc diff --git a/src/pkg/runtime/linux/amd64/defs.h b/src/pkg/runtime/linux/amd64/defs.h index c08e6b25d..3e3d32f0d 100644 --- a/src/pkg/runtime/linux/amd64/defs.h +++ b/src/pkg/runtime/linux/amd64/defs.h @@ -10,6 +10,7 @@ enum { PROT_EXEC = 0x4, MAP_ANON = 0x20, MAP_PRIVATE = 0x2, + MAP_FIXED = 0x10, SA_RESTART = 0x10000000, SA_ONSTACK = 0x8000000, SA_RESTORER = 0x4000000, diff --git a/src/pkg/runtime/linux/amd64/rt0.s b/src/pkg/runtime/linux/amd64/rt0.s index 2190b4414..dac9ae181 100644 --- a/src/pkg/runtime/linux/amd64/rt0.s +++ b/src/pkg/runtime/linux/amd64/rt0.s @@ -4,7 +4,7 @@ // Darwin and Linux use the same linkage to main -TEXT _rt0_amd64_linux(SB),7,$-8 +TEXT _rt0_amd64_linux(SB),7,$-8 MOVQ $_rt0_amd64(SB), AX MOVQ SP, DI JMP AX diff --git a/src/pkg/runtime/linux/amd64/signal.c b/src/pkg/runtime/linux/amd64/signal.c index 63c3a2e6e..e78bbda9d 100644 --- a/src/pkg/runtime/linux/amd64/signal.c +++ b/src/pkg/runtime/linux/amd64/signal.c @@ -8,49 +8,49 @@ #include "os.h" void -dumpregs(Sigcontext *r) +runtime·dumpregs(Sigcontext *r) { - printf("rax %X\n", r->rax); - printf("rbx %X\n", r->rbx); - printf("rcx %X\n", r->rcx); - printf("rdx %X\n", r->rdx); - printf("rdi %X\n", r->rdi); - printf("rsi %X\n", r->rsi); - printf("rbp %X\n", r->rbp); - printf("rsp %X\n", r->rsp); - printf("r8 %X\n", r->r8 ); - printf("r9 %X\n", r->r9 ); - printf("r10 %X\n", r->r10); - printf("r11 %X\n", r->r11); - printf("r12 %X\n", r->r12); - printf("r13 %X\n", r->r13); - printf("r14 %X\n", r->r14); - printf("r15 %X\n", r->r15); - printf("rip %X\n", r->rip); - printf("rflags %X\n", r->eflags); - printf("cs %X\n", (uint64)r->cs); - printf("fs %X\n", (uint64)r->fs); - printf("gs %X\n", (uint64)r->gs); + runtime·printf("rax %X\n", r->rax); + runtime·printf("rbx %X\n", r->rbx); + runtime·printf("rcx %X\n", r->rcx); + runtime·printf("rdx %X\n", r->rdx); + runtime·printf("rdi %X\n", r->rdi); + runtime·printf("rsi %X\n", r->rsi); + runtime·printf("rbp %X\n", r->rbp); + runtime·printf("rsp %X\n", r->rsp); + runtime·printf("r8 %X\n", r->r8 ); + runtime·printf("r9 %X\n", r->r9 ); + runtime·printf("r10 %X\n", r->r10); + runtime·printf("r11 %X\n", r->r11); + runtime·printf("r12 %X\n", r->r12); + runtime·printf("r13 %X\n", r->r13); + runtime·printf("r14 %X\n", r->r14); + runtime·printf("r15 %X\n", r->r15); + runtime·printf("rip %X\n", r->rip); + runtime·printf("rflags %X\n", r->eflags); + runtime·printf("cs %X\n", (uint64)r->cs); + runtime·printf("fs %X\n", (uint64)r->fs); + runtime·printf("gs %X\n", (uint64)r->gs); } /* * This assembler routine takes the args from registers, puts them on the stack, * and calls sighandler(). */ -extern void sigtramp(void); -extern void sigignore(void); // just returns -extern void sigreturn(void); // calls sigreturn +extern void runtime·sigtramp(void); +extern void runtime·sigignore(void); // just returns +extern void runtime·sigreturn(void); // calls runtime·sigreturn String -signame(int32 sig) +runtime·signame(int32 sig) { if(sig < 0 || sig >= NSIG) - return emptystring; - return gostringnocopy((byte*)sigtab[sig].name); + return runtime·emptystring; + return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name); } void -sighandler(int32 sig, Siginfo* info, void* context) +runtime·sighandler(int32 sig, Siginfo* info, void* context) { Ucontext *uc; Mcontext *mc; @@ -62,7 +62,7 @@ sighandler(int32 sig, Siginfo* info, void* context) mc = &uc->uc_mcontext; r = (Sigcontext*)mc; // same layout, more conveient names - if((gp = m->curg) != nil && (sigtab[sig].flags & SigPanic)) { + if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { // Make it look like a call to the signal func. // Have to pass arguments out of band since // augmenting the stack frame would break @@ -71,84 +71,84 @@ sighandler(int32 sig, Siginfo* info, void* context) gp->sigcode0 = info->si_code; gp->sigcode1 = ((uintptr*)info)[2]; - // Only push sigpanic if r->rip != 0. + // Only push runtime·sigpanic if r->rip != 0. // If r->rip == 0, probably panicked because of a // call to a nil func. Not pushing that onto sp will - // make the trace look like a call to sigpanic instead. - // (Otherwise the trace will end at sigpanic and we + // make the trace look like a call to runtime·sigpanic instead. + // (Otherwise the trace will end at runtime·sigpanic and we // won't get to see who faulted.) if(r->rip != 0) { sp = (uintptr*)r->rsp; *--sp = r->rip; r->rsp = (uintptr)sp; } - r->rip = (uintptr)sigpanic; + r->rip = (uintptr)runtime·sigpanic; return; } - if(sigtab[sig].flags & SigQueue) { - if(sigsend(sig) || (sigtab[sig].flags & SigIgnore)) + if(runtime·sigtab[sig].flags & SigQueue) { + if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore)) return; - exit(2); // SIGINT, SIGTERM, etc + runtime·exit(2); // SIGINT, SIGTERM, etc } - if(panicking) // traceback already printed - exit(2); - panicking = 1; + if(runtime·panicking) // traceback already printed + runtime·exit(2); + runtime·panicking = 1; if(sig < 0 || sig >= NSIG) - printf("Signal %d\n", sig); + runtime·printf("Signal %d\n", sig); else - printf("%s\n", sigtab[sig].name); + runtime·printf("%s\n", runtime·sigtab[sig].name); - printf("PC=%X\n", r->rip); - printf("\n"); + runtime·printf("PC=%X\n", r->rip); + runtime·printf("\n"); - if(gotraceback()){ - traceback((void*)r->rip, (void*)r->rsp, 0, (void*)r->r15); - tracebackothers((void*)r->r15); - dumpregs(r); + if(runtime·gotraceback()){ + runtime·traceback((void*)r->rip, (void*)r->rsp, 0, g); + runtime·tracebackothers(g); + runtime·dumpregs(r); } - breakpoint(); - exit(2); + runtime·breakpoint(); + runtime·exit(2); } void -signalstack(byte *p, int32 n) +runtime·signalstack(byte *p, int32 n) { Sigaltstack st; st.ss_sp = p; st.ss_size = n; st.ss_flags = 0; - sigaltstack(&st, nil); + runtime·sigaltstack(&st, nil); } void -initsig(int32 queue) +runtime·initsig(int32 queue) { static Sigaction sa; - siginit(); + runtime·siginit(); int32 i; sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER; sa.sa_mask = 0xFFFFFFFFFFFFFFFFULL; - sa.sa_restorer = (void*)sigreturn; + sa.sa_restorer = (void*)runtime·sigreturn; for(i = 0; i<NSIG; i++) { - if(sigtab[i].flags) { - if((sigtab[i].flags & SigQueue) != queue) + if(runtime·sigtab[i].flags) { + if((runtime·sigtab[i].flags & SigQueue) != queue) continue; - if(sigtab[i].flags & (SigCatch | SigQueue)) - sa.sa_handler = (void*)sigtramp; + if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) + sa.sa_handler = (void*)runtime·sigtramp; else - sa.sa_handler = (void*)sigignore; - if(sigtab[i].flags & SigRestart) + sa.sa_handler = (void*)runtime·sigignore; + if(runtime·sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; else sa.sa_flags &= ~SA_RESTART; - rt_sigaction(i, &sa, nil, 8); + runtime·rt_sigaction(i, &sa, nil, 8); } } } diff --git a/src/pkg/runtime/linux/amd64/sys.s b/src/pkg/runtime/linux/amd64/sys.s index dd0473158..170b659fc 100644 --- a/src/pkg/runtime/linux/amd64/sys.s +++ b/src/pkg/runtime/linux/amd64/sys.s @@ -8,19 +8,19 @@ #include "amd64/asm.h" -TEXT exit(SB),7,$0-8 +TEXT runtime·exit(SB),7,$0-8 MOVL 8(SP), DI MOVL $231, AX // exitgroup - force all os threads to exit SYSCALL RET -TEXT exit1(SB),7,$0-8 +TEXT runtime·exit1(SB),7,$0-8 MOVL 8(SP), DI MOVL $60, AX // exit - exit the current os thread SYSCALL RET -TEXT open(SB),7,$0-16 +TEXT runtime·open(SB),7,$0-16 MOVQ 8(SP), DI MOVL 16(SP), SI MOVL 20(SP), DX @@ -28,7 +28,7 @@ TEXT open(SB),7,$0-16 SYSCALL RET -TEXT write(SB),7,$0-24 +TEXT runtime·write(SB),7,$0-24 MOVL 8(SP), DI MOVQ 16(SP), SI MOVL 24(SP), DX @@ -36,7 +36,7 @@ TEXT write(SB),7,$0-24 SYSCALL RET -TEXT gettime(SB), 7, $32 +TEXT runtime·gettime(SB), 7, $32 LEAQ 8(SP), DI MOVQ $0, SI MOVQ $0xffffffffff600000, AX @@ -51,7 +51,7 @@ TEXT gettime(SB), 7, $32 MOVL BX, (DI) RET -TEXT rt_sigaction(SB),7,$0-32 +TEXT runtime·rt_sigaction(SB),7,$0-32 MOVL 8(SP), DI MOVQ 16(SP), SI MOVQ 24(SP), DX @@ -60,23 +60,38 @@ TEXT rt_sigaction(SB),7,$0-32 SYSCALL RET -TEXT sigtramp(SB),7,$24-16 - MOVQ m_gsignal(m), g +TEXT runtime·sigtramp(SB),7,$64 + get_tls(BX) + + // save g + MOVQ g(BX), BP + MOVQ BP, 40(SP) + + // g = m->gsignal + MOVQ m(BX), BP + MOVQ m_gsignal(BP), BP + MOVQ BP, g(BX) + MOVQ DI, 0(SP) MOVQ SI, 8(SP) MOVQ DX, 16(SP) - CALL sighandler(SB) + CALL runtime·sighandler(SB) + + // restore g + get_tls(BX) + MOVQ 40(SP), BP + MOVQ BP, g(BX) RET -TEXT sigignore(SB),7,$0 +TEXT runtime·sigignore(SB),7,$0 RET -TEXT sigreturn(SB),7,$0 +TEXT runtime·sigreturn(SB),7,$0 MOVL $15, AX // rt_sigreturn SYSCALL INT $3 // not reached -TEXT ·mmap(SB),7,$0 +TEXT runtime·mmap(SB),7,$0 MOVQ 8(SP), DI MOVQ $0, SI MOVQ 16(SP), SI @@ -85,7 +100,7 @@ TEXT ·mmap(SB),7,$0 MOVL 32(SP), R8 MOVL 36(SP), R9 - MOVL $9, AX // syscall entry + MOVL $9, AX // mmap SYSCALL CMPQ AX, $0xfffffffffffff001 JLS 3(PC) @@ -93,14 +108,24 @@ TEXT ·mmap(SB),7,$0 INCQ AX RET -TEXT notok(SB),7,$0 +TEXT runtime·munmap(SB),7,$0 + MOVQ 8(SP), DI + MOVQ 16(SP), SI + MOVQ $11, AX // munmap + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS 2(PC) + CALL runtime·notok(SB) + RET + +TEXT runtime·notok(SB),7,$0 MOVQ $0xf1, BP MOVQ BP, (BP) RET // int64 futex(int32 *uaddr, int32 op, int32 val, // struct timespec *timeout, int32 *uaddr2, int32 val2); -TEXT futex(SB),7,$0 +TEXT runtime·futex(SB),7,$0 MOVQ 8(SP), DI MOVL 16(SP), SI MOVL 20(SP), DX @@ -112,7 +137,7 @@ TEXT futex(SB),7,$0 RET // int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); -TEXT clone(SB),7,$0 +TEXT runtime·clone(SB),7,$0 MOVL flags+8(SP), DI MOVQ stack+16(SP), SI @@ -129,17 +154,24 @@ TEXT clone(SB),7,$0 CMPQ AX, $0 JEQ 2(PC) RET - - // In child, set up new stack + + // In child, on new stack. MOVQ SI, SP - MOVQ R8, m - MOVQ R9, g - CALL stackcheck(SB) - + // Initialize m->procid to Linux tid MOVL $186, AX // gettid SYSCALL - MOVQ AX, m_procid(m) + MOVQ AX, m_procid(R8) + + // Set FS to point at m->tls. + LEAQ m_tls(R8), DI + CALL runtime·settls(SB) + + // In child, set up new stack + get_tls(CX) + MOVQ R8, m(CX) + MOVQ R9, g(CX) + CALL runtime·stackcheck(SB) // Call fn CALL R12 @@ -150,12 +182,26 @@ TEXT clone(SB),7,$0 SYSCALL JMP -3(PC) // keep exiting -TEXT sigaltstack(SB),7,$-8 +TEXT runtime·sigaltstack(SB),7,$-8 MOVQ new+8(SP), DI MOVQ old+16(SP), SI MOVQ $131, AX SYSCALL CMPQ AX, $0xfffffffffffff001 JLS 2(PC) - CALL notok(SB) + CALL runtime·notok(SB) + RET + +// set tls base to DI +TEXT runtime·settls(SB),7,$32 + ADDQ $16, DI // ELF wants to use -16(FS), -8(FS) + + MOVQ DI, SI + MOVQ $0x1002, DI // ARCH_SET_FS + MOVQ $158, AX // arch_prctl + SYSCALL + CMPQ AX, $0xfffffffffffff001 + JLS 2(PC) + CALL runtime·notok(SB) RET + diff --git a/src/pkg/runtime/linux/arm/defs.h b/src/pkg/runtime/linux/arm/defs.h index b13985171..ff43d689a 100644 --- a/src/pkg/runtime/linux/arm/defs.h +++ b/src/pkg/runtime/linux/arm/defs.h @@ -10,6 +10,7 @@ enum { PROT_EXEC = 0x4, MAP_ANON = 0x20, MAP_PRIVATE = 0x2, + MAP_FIXED = 0x10, SA_RESTART = 0x10000000, SA_ONSTACK = 0x8000000, SA_RESTORER = 0x4000000, @@ -44,19 +45,19 @@ enum { SIGIO = 0x1d, SIGPWR = 0x1e, SIGSYS = 0x1f, - FPE_INTDIV = 0x30001, - FPE_INTOVF = 0x30002, - FPE_FLTDIV = 0x30003, - FPE_FLTOVF = 0x30004, - FPE_FLTUND = 0x30005, - FPE_FLTRES = 0x30006, - FPE_FLTINV = 0x30007, - FPE_FLTSUB = 0x30008, - BUS_ADRALN = 0x30001, - BUS_ADRERR = 0x30002, - BUS_OBJERR = 0x30003, - SEGV_MAPERR = 0x30001, - SEGV_ACCERR = 0x30002, + FPE_INTDIV = 0x1, + FPE_INTOVF = 0x2, + FPE_FLTDIV = 0x3, + FPE_FLTOVF = 0x4, + FPE_FLTUND = 0x5, + FPE_FLTRES = 0x6, + FPE_FLTINV = 0x7, + FPE_FLTSUB = 0x8, + BUS_ADRALN = 0x1, + BUS_ADRERR = 0x2, + BUS_OBJERR = 0x3, + SEGV_MAPERR = 0x1, + SEGV_ACCERR = 0x2, }; // Types diff --git a/src/pkg/runtime/linux/arm/rt0.s b/src/pkg/runtime/linux/arm/rt0.s index 024547ddd..8838b4891 100644 --- a/src/pkg/runtime/linux/arm/rt0.s +++ b/src/pkg/runtime/linux/arm/rt0.s @@ -2,5 +2,5 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -TEXT _rt0_arm_linux(SB),7,$0 +TEXT _rt0_arm_linux(SB),7,$0 B _rt0_arm(SB) diff --git a/src/pkg/runtime/linux/arm/signal.c b/src/pkg/runtime/linux/arm/signal.c index a9dccae4a..c65aff913 100644 --- a/src/pkg/runtime/linux/arm/signal.c +++ b/src/pkg/runtime/linux/arm/signal.c @@ -8,49 +8,49 @@ #include "os.h" void -dumpregs(Sigcontext *r) +runtime·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); + runtime·printf("trap %x\n", r->trap_no); + runtime·printf("error %x\n", r->error_code); + runtime·printf("oldmask %x\n", r->oldmask); + runtime·printf("r0 %x\n", r->arm_r0); + runtime·printf("r1 %x\n", r->arm_r1); + runtime·printf("r2 %x\n", r->arm_r2); + runtime·printf("r3 %x\n", r->arm_r3); + runtime·printf("r4 %x\n", r->arm_r4); + runtime·printf("r5 %x\n", r->arm_r5); + runtime·printf("r6 %x\n", r->arm_r6); + runtime·printf("r7 %x\n", r->arm_r7); + runtime·printf("r8 %x\n", r->arm_r8); + runtime·printf("r9 %x\n", r->arm_r9); + runtime·printf("r10 %x\n", r->arm_r10); + runtime·printf("fp %x\n", r->arm_fp); + runtime·printf("ip %x\n", r->arm_ip); + runtime·printf("sp %x\n", r->arm_sp); + runtime·printf("lr %x\n", r->arm_lr); + runtime·printf("pc %x\n", r->arm_pc); + runtime·printf("cpsr %x\n", r->arm_cpsr); + runtime·printf("fault %x\n", r->fault_address); } /* * This assembler routine takes the args from registers, puts them on the stack, * and calls sighandler(). */ -extern void sigtramp(void); -extern void sigignore(void); // just returns -extern void sigreturn(void); // calls sigreturn +extern void runtime·sigtramp(void); +extern void runtime·sigignore(void); // just returns +extern void runtime·sigreturn(void); // calls runtime·sigreturn String -signame(int32 sig) +runtime·signame(int32 sig) { if(sig < 0 || sig >= NSIG) - return emptystring; - return gostringnocopy((byte*)sigtab[sig].name); + return runtime·emptystring; + return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name); } void -sighandler(int32 sig, Siginfo *info, void *context) +runtime·sighandler(int32 sig, Siginfo *info, void *context) { Ucontext *uc; Sigcontext *r; @@ -59,7 +59,7 @@ sighandler(int32 sig, Siginfo *info, void *context) uc = context; r = &uc->uc_mcontext; - if((gp = m->curg) != nil && (sigtab[sig].flags & SigPanic)) { + if((gp = m->curg) != nil && (runtime·sigtab[sig].flags & SigPanic)) { // Make it look like a call to the signal func. // Have to pass arguments out of band since // augmenting the stack frame would break @@ -75,75 +75,75 @@ sighandler(int32 sig, Siginfo *info, void *context) // old link register is more useful in the stack trace. if(r->arm_pc != 0) r->arm_lr = r->arm_pc; - r->arm_pc = (uintptr)sigpanic; + r->arm_pc = (uintptr)runtime·sigpanic; return; } - if(sigtab[sig].flags & SigQueue) { - if(sigsend(sig) || (sigtab[sig].flags & SigIgnore)) + if(runtime·sigtab[sig].flags & SigQueue) { + if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore)) return; - exit(2); // SIGINT, SIGTERM, etc + runtime·exit(2); // SIGINT, SIGTERM, etc } - if(panicking) // traceback already printed - exit(2); - panicking = 1; + if(runtime·panicking) // traceback already printed + runtime·exit(2); + runtime·panicking = 1; if(sig < 0 || sig >= NSIG) - printf("Signal %d\n", sig); + runtime·printf("Signal %d\n", sig); else - printf("%s\n", sigtab[sig].name); + runtime·printf("%s\n", runtime·sigtab[sig].name); - printf("PC=%x\n", r->arm_pc); - printf("\n"); + runtime·printf("PC=%x\n", r->arm_pc); + runtime·printf("\n"); - if(gotraceback()){ - traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, m->curg); - tracebackothers(m->curg); - printf("\n"); - dumpregs(r); + if(runtime·gotraceback()){ + runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, m->curg); + runtime·tracebackothers(m->curg); + runtime·printf("\n"); + runtime·dumpregs(r); } // breakpoint(); - exit(2); + runtime·exit(2); } void -signalstack(byte *p, int32 n) +runtime·signalstack(byte *p, int32 n) { Sigaltstack st; st.ss_sp = p; st.ss_size = n; st.ss_flags = 0; - sigaltstack(&st, nil); + runtime·sigaltstack(&st, nil); } void -initsig(int32 queue) +runtime·initsig(int32 queue) { static Sigaction sa; - siginit(); + runtime·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; + sa.sa_restorer = (void*)runtime·sigreturn; for(i = 0; i<NSIG; i++) { - if(sigtab[i].flags) { - if((sigtab[i].flags & SigQueue) != queue) + if(runtime·sigtab[i].flags) { + if((runtime·sigtab[i].flags & SigQueue) != queue) continue; - if(sigtab[i].flags & (SigCatch | SigQueue)) - sa.sa_handler = (void*)sigtramp; + if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) + sa.sa_handler = (void*)runtime·sigtramp; else - sa.sa_handler = (void*)sigignore; - if(sigtab[i].flags & SigRestart) + sa.sa_handler = (void*)runtime·sigignore; + if(runtime·sigtab[i].flags & SigRestart) sa.sa_flags |= SA_RESTART; else sa.sa_flags &= ~SA_RESTART; - rt_sigaction(i, &sa, nil, 8); + runtime·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 f30aed001..b25cf81aa 100644 --- a/src/pkg/runtime/linux/arm/sys.s +++ b/src/pkg/runtime/linux/arm/sys.s @@ -25,11 +25,12 @@ #define SYS_gettid (SYS_BASE + 224) #define SYS_futex (SYS_BASE + 240) #define SYS_exit_group (SYS_BASE + 248) +#define SYS_munmap (SYS_BASE + 91) #define ARM_BASE (SYS_BASE + 0x0f0000) #define SYS_ARM_cacheflush (ARM_BASE + 2) -TEXT write(SB),7,$0 +TEXT runtime·write(SB),7,$0 MOVW 0(FP), R0 MOVW 4(FP), R1 MOVW 8(FP), R2 @@ -37,7 +38,7 @@ TEXT write(SB),7,$0 SWI $0 RET -TEXT exit(SB),7,$-4 +TEXT runtime·exit(SB),7,$-4 MOVW 0(FP), R0 MOVW $SYS_exit_group, R7 SWI $0 @@ -45,7 +46,7 @@ TEXT exit(SB),7,$-4 MOVW $1002, R1 MOVW R0, (R1) // fail hard -TEXT exit1(SB),7,$-4 +TEXT runtime·exit1(SB),7,$-4 MOVW 0(FP), R0 MOVW $SYS_exit, R7 SWI $0 @@ -53,7 +54,7 @@ TEXT exit1(SB),7,$-4 MOVW $1003, R1 MOVW R0, (R1) // fail hard -TEXT ·mmap(SB),7,$0 +TEXT runtime·mmap(SB),7,$0 MOVW 0(FP), R0 MOVW 4(FP), R1 MOVW 8(FP), R2 @@ -64,7 +65,14 @@ TEXT ·mmap(SB),7,$0 SWI $0 RET -TEXT gettime(SB),7,$32 +TEXT runtime·munmap(SB),7,$0 + MOVW 0(FP), R0 + MOVW 4(FP), R1 + MOVW $SYS_munmap, R7 + SWI $0 + RET + +TEXT runtime·gettime(SB),7,$32 /* dummy version - return 0,0 */ MOVW $0, R1 MOVW 0(FP), R0 @@ -93,7 +101,7 @@ TEXT gettime(SB),7,$32 // int32 futex(int32 *uaddr, int32 op, int32 val, // struct timespec *timeout, int32 *uaddr2, int32 val2); -TEXT futex(SB),7,$0 +TEXT runtime·futex(SB),7,$0 MOVW 4(SP), R0 MOVW 8(SP), R1 MOVW 12(SP), R2 @@ -106,7 +114,7 @@ TEXT futex(SB),7,$0 // int32 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void)); -TEXT clone(SB),7,$0 +TEXT runtime·clone(SB),7,$0 MOVW flags+0(FP), R0 MOVW stack+4(FP), R1 MOVW $0, R2 // parent tid ptr @@ -139,7 +147,7 @@ TEXT clone(SB),7,$0 MOVW $1234, R1 CMP R0, R1 BEQ 2(PC) - B abort(SB) + BL runtime·abort(SB) MOVW 0(R13), m MOVW 4(R13), g @@ -148,7 +156,7 @@ TEXT clone(SB),7,$0 MOVW 0(m), R0 MOVW 0(g), R0 - BL emptyfunc(SB) // fault if stack check is wrong + BL runtime·emptyfunc(SB) // fault if stack check is wrong // Initialize m->procid to Linux tid MOVW $SYS_gettid, R7 @@ -162,7 +170,7 @@ TEXT clone(SB),7,$0 MOVW $0, R0 MOVW R0, 4(R13) - BL exit1(SB) + BL runtime·exit1(SB) // It shouldn't return MOVW $1234, R0 @@ -170,7 +178,7 @@ TEXT clone(SB),7,$0 MOVW R0, (R1) -TEXT cacheflush(SB),7,$0 +TEXT runtime·cacheflush(SB),7,$0 MOVW 0(FP), R0 MOVW 4(FP), R1 MOVW $0, R2 @@ -178,30 +186,25 @@ TEXT cacheflush(SB),7,$0 SWI $0 RET -TEXT sigaltstack(SB),7,$0 +TEXT runtime·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) +TEXT runtime·sigignore(SB),7,$0 RET -TEXT sigtramp(SB),7,$24 +TEXT runtime·sigtramp(SB),7,$24 MOVW m_gsignal(m), g MOVW R0, 4(R13) MOVW R1, 8(R13) MOVW R2, 12(R13) - BL sighandler(SB) + BL runtime·sighandler(SB) RET -TEXT rt_sigaction(SB),7,$0 +TEXT runtime·rt_sigaction(SB),7,$0 MOVW 0(FP), R0 MOVW 4(FP), R1 MOVW 8(FP), R2 @@ -210,7 +213,7 @@ TEXT rt_sigaction(SB),7,$0 SWI $0 RET -TEXT sigreturn(SB),7,$0 +TEXT runtime·sigreturn(SB),7,$0 MOVW $SYS_rt_sigreturn, R7 SWI $0 RET diff --git a/src/pkg/runtime/linux/defs.c b/src/pkg/runtime/linux/defs.c index f3bdb61fa..2044fd60c 100644 --- a/src/pkg/runtime/linux/defs.c +++ b/src/pkg/runtime/linux/defs.c @@ -27,6 +27,7 @@ enum { $MAP_ANON = MAP_ANONYMOUS, $MAP_PRIVATE = MAP_PRIVATE, + $MAP_FIXED = MAP_FIXED, $SA_RESTART = SA_RESTART, $SA_ONSTACK = SA_ONSTACK, diff --git a/src/pkg/runtime/linux/defs2.c b/src/pkg/runtime/linux/defs2.c index 4cfe4a7ed..3c0b110fc 100644 --- a/src/pkg/runtime/linux/defs2.c +++ b/src/pkg/runtime/linux/defs2.c @@ -47,6 +47,7 @@ enum { $MAP_ANON = MAP_ANONYMOUS, $MAP_PRIVATE = MAP_PRIVATE, + $MAP_FIXED = MAP_FIXED, $SA_RESTART = SA_RESTART, $SA_ONSTACK = SA_ONSTACK, diff --git a/src/pkg/runtime/linux/defs_arm.c b/src/pkg/runtime/linux/defs_arm.c index 2b197272c..a5897d6d0 100644 --- a/src/pkg/runtime/linux/defs_arm.c +++ b/src/pkg/runtime/linux/defs_arm.c @@ -31,6 +31,7 @@ enum { $MAP_ANON = MAP_ANONYMOUS, $MAP_PRIVATE = MAP_PRIVATE, + $MAP_FIXED = MAP_FIXED, $SA_RESTART = SA_RESTART, $SA_ONSTACK = SA_ONSTACK, @@ -67,22 +68,22 @@ enum { $SIGIO = SIGIO, $SIGPWR = SIGPWR, $SIGSYS = SIGSYS, + + $FPE_INTDIV = FPE_INTDIV & 0xFFFF, + $FPE_INTOVF = FPE_INTOVF & 0xFFFF, + $FPE_FLTDIV = FPE_FLTDIV & 0xFFFF, + $FPE_FLTOVF = FPE_FLTOVF & 0xFFFF, + $FPE_FLTUND = FPE_FLTUND & 0xFFFF, + $FPE_FLTRES = FPE_FLTRES & 0xFFFF, + $FPE_FLTINV = FPE_FLTINV & 0xFFFF, + $FPE_FLTSUB = FPE_FLTSUB & 0xFFFF, - $FPE_INTDIV = FPE_INTDIV, - $FPE_INTOVF = FPE_INTOVF, - $FPE_FLTDIV = FPE_FLTDIV, - $FPE_FLTOVF = FPE_FLTOVF, - $FPE_FLTUND = FPE_FLTUND, - $FPE_FLTRES = FPE_FLTRES, - $FPE_FLTINV = FPE_FLTINV, - $FPE_FLTSUB = FPE_FLTSUB, - - $BUS_ADRALN = BUS_ADRALN, - $BUS_ADRERR = BUS_ADRERR, - $BUS_OBJERR = BUS_OBJERR, + $BUS_ADRALN = BUS_ADRALN & 0xFFFF, + $BUS_ADRERR = BUS_ADRERR & 0xFFFF, + $BUS_OBJERR = BUS_OBJERR & 0xFFFF, - $SEGV_MAPERR = SEGV_MAPERR, - $SEGV_ACCERR = SEGV_ACCERR, + $SEGV_MAPERR = SEGV_MAPERR & 0xFFFF, + $SEGV_ACCERR = SEGV_ACCERR & 0xFFFF, }; typedef sigset_t $Sigset; diff --git a/src/pkg/runtime/linux/mem.c b/src/pkg/runtime/linux/mem.c index 7f837bd45..e750f97ea 100644 --- a/src/pkg/runtime/linux/mem.c +++ b/src/pkg/runtime/linux/mem.c @@ -4,26 +4,26 @@ #include "malloc.h" void* -SysAlloc(uintptr n) +runtime·SysAlloc(uintptr n) { void *p; mstats.sys += n; - p = runtime_mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); + p = runtime·mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); if(p < (void*)4096) { if(p == (void*)EACCES) { - printf("mmap: access denied\n"); - printf("If you're running SELinux, enable execmem for this process.\n"); - } else { - printf("mmap: errno=%p\n", p); + runtime·printf("mmap: access denied\n"); + runtime·printf("If you're running SELinux, enable execmem for this process.\n"); + runtime·exit(2); } - exit(2); + runtime·printf("mmap: errno=%p\n", p); + runtime·throw("mmap"); } return p; } void -SysUnused(void *v, uintptr n) +runtime·SysUnused(void *v, uintptr n) { USED(v); USED(n); @@ -31,10 +31,13 @@ SysUnused(void *v, uintptr n) } void -SysFree(void *v, uintptr n) +runtime·SysFree(void *v, uintptr n) { - USED(v); - USED(n); - // TODO(rsc): call munmap + mstats.sys -= n; + runtime·munmap(v, n); } +void +runtime·SysMemInit(void) +{ +} diff --git a/src/pkg/runtime/linux/os.h b/src/pkg/runtime/linux/os.h index 8ca26b748..772ade7da 100644 --- a/src/pkg/runtime/linux/os.h +++ b/src/pkg/runtime/linux/os.h @@ -3,11 +3,11 @@ // license that can be found in the LICENSE file. // Linux-specific system calls -int32 futex(uint32*, int32, uint32, Timespec*, uint32*, uint32); -int32 clone(int32, void*, M*, G*, void(*)(void)); +int32 runtime·futex(uint32*, int32, uint32, Timespec*, uint32*, uint32); +int32 runtime·clone(int32, void*, M*, G*, void(*)(void)); struct Sigaction; -void rt_sigaction(uintptr, struct Sigaction*, void*, uintptr); +void runtime·rt_sigaction(uintptr, struct Sigaction*, void*, uintptr); -void sigaltstack(Sigaltstack*, Sigaltstack*); -void sigpanic(void); +void runtime·sigaltstack(Sigaltstack*, Sigaltstack*); +void runtime·sigpanic(void); diff --git a/src/pkg/runtime/linux/runtime_defs.go b/src/pkg/runtime/linux/runtime_defs.go new file mode 100644 index 000000000..86de13316 --- /dev/null +++ b/src/pkg/runtime/linux/runtime_defs.go @@ -0,0 +1,14 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// OS-Specific Go definitions of internal structures. Master is runtime.h + +package runtime + +type lock struct { + key uint32 + sema uint32 +} + +type note lock diff --git a/src/pkg/runtime/linux/signals.h b/src/pkg/runtime/linux/signals.h index 788f68240..1fc5f8c87 100644 --- a/src/pkg/runtime/linux/signals.h +++ b/src/pkg/runtime/linux/signals.h @@ -8,7 +8,7 @@ #define Q SigQueue #define P SigPanic -SigTab sigtab[] = { +SigTab runtime·sigtab[] = { /* 0 */ 0, "SIGNONE: no trap", /* 1 */ Q+R, "SIGHUP: terminal line hangup", /* 2 */ Q+R, "SIGINT: interrupt", diff --git a/src/pkg/runtime/linux/thread.c b/src/pkg/runtime/linux/thread.c index a849125f9..979260ba1 100644 --- a/src/pkg/runtime/linux/thread.c +++ b/src/pkg/runtime/linux/thread.c @@ -6,7 +6,7 @@ #include "defs.h" #include "os.h" -extern SigTab sigtab[]; +extern SigTab runtime·sigtab[]; // Linux futex. // @@ -48,7 +48,7 @@ futexsleep(uint32 *addr, uint32 val) // as an errno. Libpthread ignores the return value // here, and so can we: as it says a few lines up, // spurious wakeups are allowed. - futex(addr, FUTEX_WAIT, val, &longtime, nil, 0); + runtime·futex(addr, FUTEX_WAIT, val, &longtime, nil, 0); } // If any procs are sleeping on addr, wake up at least one. @@ -57,7 +57,7 @@ futexwakeup(uint32 *addr) { int64 ret; - ret = futex(addr, FUTEX_WAKE, 1, nil, nil, 0); + ret = runtime·futex(addr, FUTEX_WAKE, 1, nil, nil, 0); if(ret >= 0) return; @@ -66,11 +66,11 @@ futexwakeup(uint32 *addr) // EAGAIN or EINTR, but if it does, it would be // safe to loop and call futex again. - prints("futexwakeup addr="); - ·printpointer(addr); - prints(" returned "); - ·printint(ret); - prints("\n"); + runtime·prints("futexwakeup addr="); + runtime·printpointer(addr); + runtime·prints(" returned "); + runtime·printint(ret); + runtime·prints("\n"); *(int32*)0x1006 = 0x1006; } @@ -83,7 +83,7 @@ futexwakeup(uint32 *addr) // The uncontended case runs entirely in user space. // When contention is detected, we defer to the kernel (futex). // -// A reminder: compare-and-swap cas(addr, old, new) does +// A reminder: compare-and-swap runtime·cas(addr, old, new) does // if(*addr == old) { *addr = new; return 1; } // else return 0; // but atomically. @@ -96,7 +96,7 @@ futexlock(Lock *l) again: v = l->key; if((v&1) == 0){ - if(cas(&l->key, v, v|1)){ + if(runtime·cas(&l->key, v, v|1)){ // Lock wasn't held; we grabbed it. return; } @@ -104,7 +104,7 @@ again: } // Lock was held; try to add ourselves to the waiter count. - if(!cas(&l->key, v, v+2)) + if(!runtime·cas(&l->key, v, v+2)) goto again; // We're accounted for, now sleep in the kernel. @@ -122,8 +122,8 @@ again: for(;;){ v = l->key; if(v < 2) - throw("bad lock key"); - if(cas(&l->key, v, v-2)) + runtime·throw("bad lock key"); + if(runtime·cas(&l->key, v, v-2)) break; } @@ -140,8 +140,8 @@ futexunlock(Lock *l) again: v = l->key; if((v&1) == 0) - throw("unlock of unlocked lock"); - if(!cas(&l->key, v, v&~1)) + runtime·throw("unlock of unlocked lock"); + if(!runtime·cas(&l->key, v, v&~1)) goto again; // If there were waiters, wake one. @@ -150,25 +150,25 @@ again: } void -lock(Lock *l) +runtime·lock(Lock *l) { if(m->locks < 0) - throw("lock count"); + runtime·throw("lock count"); m->locks++; futexlock(l); } void -unlock(Lock *l) +runtime·unlock(Lock *l) { m->locks--; if(m->locks < 0) - throw("lock count"); + runtime·throw("lock count"); futexunlock(l); } void -destroylock(Lock *l) +runtime·destroylock(Lock*) { } @@ -186,20 +186,20 @@ destroylock(Lock *l) // you unlock the lock. void -noteclear(Note *n) +runtime·noteclear(Note *n) { n->lock.key = 0; // memset(n, 0, sizeof *n) futexlock(&n->lock); } void -notewakeup(Note *n) +runtime·notewakeup(Note *n) { futexunlock(&n->lock); } void -notesleep(Note *n) +runtime·notesleep(Note *n) { futexlock(&n->lock); futexunlock(&n->lock); // Let other sleepers find out too. @@ -230,7 +230,7 @@ enum }; void -newosproc(M *m, G *g, void *stk, void (*fn)(void)) +runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) { int32 ret; int32 flags; @@ -248,50 +248,58 @@ newosproc(M *m, G *g, void *stk, void (*fn)(void)) m->tls[0] = m->id; // so 386 asm can find it if(0){ - printf("newosproc stk=%p m=%p g=%p fn=%p clone=%p id=%d/%d ostk=%p\n", - stk, m, g, fn, clone, m->id, m->tls[0], &m); + runtime·printf("newosproc stk=%p m=%p g=%p fn=%p clone=%p id=%d/%d ostk=%p\n", + stk, m, g, fn, runtime·clone, m->id, m->tls[0], &m); } - ret = clone(flags, stk, m, g, fn); + ret = runtime·clone(flags, stk, m, g, fn); if(ret < 0) *(int32*)123 = 123; } void -osinit(void) +runtime·osinit(void) { } +void +runtime·goenvs(void) +{ + runtime·goenvs_unix(); +} + // Called to initialize a new m (including the bootstrap m). void -minit(void) +runtime·minit(void) { // Initialize signal handling. - m->gsignal = malg(32*1024); // OS X wants >=8K, Linux >=2K - signalstack(m->gsignal->stackguard, 32*1024); + m->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K + runtime·signalstack(m->gsignal->stackguard, 32*1024); } void -sigpanic(void) +runtime·sigpanic(void) { switch(g->sig) { case SIGBUS: if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000) - panicstring("invalid memory address or nil pointer dereference"); - break; + runtime·panicstring("invalid memory address or nil pointer dereference"); + runtime·printf("unexpected fault address %p\n", g->sigcode1); + runtime·throw("fault"); case SIGSEGV: - if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR) && g->sigcode1 < 0x1000) - panicstring("invalid memory address or nil pointer dereference"); - break; + if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000) + runtime·panicstring("invalid memory address or nil pointer dereference"); + runtime·printf("unexpected fault address %p\n", g->sigcode1); + runtime·throw("fault"); case SIGFPE: switch(g->sigcode0) { case FPE_INTDIV: - panicstring("integer divide by zero"); + runtime·panicstring("integer divide by zero"); case FPE_INTOVF: - panicstring("integer overflow"); + runtime·panicstring("integer overflow"); } - panicstring("floating point error"); + runtime·panicstring("floating point error"); } - panicstring(sigtab[g->sig].name); + runtime·panicstring(runtime·sigtab[g->sig].name); } |