summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/linux
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/linux')
-rw-r--r--src/pkg/runtime/linux/386/defs.h1
-rw-r--r--src/pkg/runtime/linux/386/rt0.s10
-rw-r--r--src/pkg/runtime/linux/386/signal.c108
-rw-r--r--src/pkg/runtime/linux/386/sys.s55
-rw-r--r--src/pkg/runtime/linux/amd64/defs.h1
-rw-r--r--src/pkg/runtime/linux/amd64/rt0.s2
-rw-r--r--src/pkg/runtime/linux/amd64/signal.c124
-rw-r--r--src/pkg/runtime/linux/amd64/sys.s96
-rw-r--r--src/pkg/runtime/linux/arm/defs.h27
-rw-r--r--src/pkg/runtime/linux/arm/rt0.s2
-rw-r--r--src/pkg/runtime/linux/arm/signal.c118
-rw-r--r--src/pkg/runtime/linux/arm/sys.s47
-rw-r--r--src/pkg/runtime/linux/defs.c1
-rw-r--r--src/pkg/runtime/linux/defs2.c1
-rw-r--r--src/pkg/runtime/linux/defs_arm.c29
-rw-r--r--src/pkg/runtime/linux/mem.c27
-rw-r--r--src/pkg/runtime/linux/os.h10
-rw-r--r--src/pkg/runtime/linux/runtime_defs.go14
-rw-r--r--src/pkg/runtime/linux/signals.h2
-rw-r--r--src/pkg/runtime/linux/thread.c90
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);
}