summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/linux/amd64
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/linux/amd64')
-rw-r--r--src/pkg/runtime/linux/amd64/defs.h175
-rw-r--r--src/pkg/runtime/linux/amd64/rt0.s9
-rw-r--r--src/pkg/runtime/linux/amd64/signal.c112
-rw-r--r--src/pkg/runtime/linux/amd64/sys.s193
4 files changed, 489 insertions, 0 deletions
diff --git a/src/pkg/runtime/linux/amd64/defs.h b/src/pkg/runtime/linux/amd64/defs.h
new file mode 100644
index 000000000..43b047523
--- /dev/null
+++ b/src/pkg/runtime/linux/amd64/defs.h
@@ -0,0 +1,175 @@
+// godefs -f -m64 defs.c
+
+// MACHINE GENERATED - DO NOT EDIT.
+
+// Constants
+enum {
+ PROT_NONE = 0,
+ PROT_READ = 0x1,
+ PROT_WRITE = 0x2,
+ PROT_EXEC = 0x4,
+ MAP_ANON = 0x20,
+ MAP_PRIVATE = 0x2,
+ SA_RESTART = 0x10000000,
+ SA_ONSTACK = 0x8000000,
+ SA_RESTORER = 0x4000000,
+ SA_SIGINFO = 0x4,
+};
+
+// Types
+#pragma pack on
+
+typedef struct Timespec Timespec;
+struct Timespec {
+ int64 tv_sec;
+ int64 tv_nsec;
+};
+
+typedef struct Timeval Timeval;
+struct Timeval {
+ int64 tv_sec;
+ int64 tv_usec;
+};
+
+typedef struct Sigaction Sigaction;
+struct Sigaction {
+ void *sa_handler;
+ uint64 sa_flags;
+ void *sa_restorer;
+ uint64 sa_mask;
+};
+
+typedef struct Siginfo Siginfo;
+struct Siginfo {
+ int32 si_signo;
+ int32 si_errno;
+ int32 si_code;
+ byte pad0[4];
+ byte _sifields[112];
+};
+#pragma pack off
+// godefs -f -m64 defs1.c
+
+// MACHINE GENERATED - DO NOT EDIT.
+
+// Constants
+
+// Types
+#pragma pack on
+
+typedef struct Usigset Usigset;
+struct Usigset {
+ uint64 __val[16];
+};
+
+typedef struct Fpxreg Fpxreg;
+struct Fpxreg {
+ uint16 significand[4];
+ uint16 exponent;
+ uint16 padding[3];
+};
+
+typedef struct Xmmreg Xmmreg;
+struct Xmmreg {
+ uint32 element[4];
+};
+
+typedef struct Fpstate Fpstate;
+struct Fpstate {
+ uint16 cwd;
+ uint16 swd;
+ uint16 ftw;
+ uint16 fop;
+ uint64 rip;
+ uint64 rdp;
+ uint32 mxcsr;
+ uint32 mxcr_mask;
+ Fpxreg _st[8];
+ Xmmreg _xmm[16];
+ uint32 padding[24];
+};
+
+typedef struct Fpxreg1 Fpxreg1;
+struct Fpxreg1 {
+ uint16 significand[4];
+ uint16 exponent;
+ uint16 padding[3];
+};
+
+typedef struct Xmmreg1 Xmmreg1;
+struct Xmmreg1 {
+ uint32 element[4];
+};
+
+typedef struct Fpstate1 Fpstate1;
+struct Fpstate1 {
+ uint16 cwd;
+ uint16 swd;
+ uint16 ftw;
+ uint16 fop;
+ uint64 rip;
+ uint64 rdp;
+ uint32 mxcsr;
+ uint32 mxcr_mask;
+ Fpxreg1 _st[8];
+ Xmmreg1 _xmm[16];
+ uint32 padding[24];
+};
+
+typedef struct Sigaltstack Sigaltstack;
+struct Sigaltstack {
+ void *ss_sp;
+ int32 ss_flags;
+ byte pad0[4];
+ uint64 ss_size;
+};
+
+typedef struct Mcontext Mcontext;
+struct Mcontext {
+ int64 gregs[23];
+ Fpstate *fpregs;
+ uint64 __reserved1[8];
+};
+
+typedef struct Ucontext Ucontext;
+struct Ucontext {
+ uint64 uc_flags;
+ Ucontext *uc_link;
+ Sigaltstack uc_stack;
+ Mcontext uc_mcontext;
+ Usigset uc_sigmask;
+ Fpstate __fpregs_mem;
+};
+
+typedef struct Sigcontext Sigcontext;
+struct Sigcontext {
+ uint64 r8;
+ uint64 r9;
+ uint64 r10;
+ uint64 r11;
+ uint64 r12;
+ uint64 r13;
+ uint64 r14;
+ uint64 r15;
+ uint64 rdi;
+ uint64 rsi;
+ uint64 rbp;
+ uint64 rbx;
+ uint64 rdx;
+ uint64 rax;
+ uint64 rcx;
+ uint64 rsp;
+ uint64 rip;
+ uint64 eflags;
+ uint16 cs;
+ uint16 gs;
+ uint16 fs;
+ uint16 __pad0;
+ uint64 err;
+ uint64 trapno;
+ uint64 oldmask;
+ uint64 cr2;
+ Fpstate1 *fpstate;
+ uint64 __reserved1[8];
+};
+#pragma pack off
diff --git a/src/pkg/runtime/linux/amd64/rt0.s b/src/pkg/runtime/linux/amd64/rt0.s
new file mode 100644
index 000000000..55be5bcee
--- /dev/null
+++ b/src/pkg/runtime/linux/amd64/rt0.s
@@ -0,0 +1,9 @@
+// Copyright 2009 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.
+
+// Darwin and Linux use the same linkage to main
+
+TEXT _rt0_amd64_linux(SB),7,$-8
+ MOVQ $_rt0_amd64(SB), AX
+ JMP AX
diff --git a/src/pkg/runtime/linux/amd64/signal.c b/src/pkg/runtime/linux/amd64/signal.c
new file mode 100644
index 000000000..55215176d
--- /dev/null
+++ b/src/pkg/runtime/linux/amd64/signal.c
@@ -0,0 +1,112 @@
+// Copyright 2009 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.
+
+#include "runtime.h"
+#include "defs.h"
+#include "signals.h"
+#include "os.h"
+
+void
+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);
+}
+
+/*
+ * 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
+
+void
+sighandler(int32 sig, Siginfo* info, void* context)
+{
+ Ucontext *uc;
+ Mcontext *mc;
+ Sigcontext *sc;
+
+ if(panicking) // traceback already printed
+ exit(2);
+ panicking = 1;
+
+ uc = context;
+ mc = &uc->uc_mcontext;
+ sc = (Sigcontext*)mc; // same layout, more conveient names
+
+ if(sig < 0 || sig >= NSIG)
+ printf("Signal %d\n", sig);
+ else
+ printf("%s\n", sigtab[sig].name);
+
+ printf("Faulting address: %p\n", *(void**)info->_sifields);
+ printf("PC=%X\n", sc->rip);
+ printf("\n");
+
+ if(gotraceback()){
+ traceback((void*)sc->rip, (void*)sc->rsp, (void*)sc->r15);
+ tracebackothers((void*)sc->r15);
+ dumpregs(sc);
+ }
+
+ breakpoint();
+ exit(2);
+}
+
+void
+signalstack(byte *p, int32 n)
+{
+ Sigaltstack st;
+
+ 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)
+ 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/amd64/sys.s b/src/pkg/runtime/linux/amd64/sys.s
new file mode 100644
index 000000000..f90c704fa
--- /dev/null
+++ b/src/pkg/runtime/linux/amd64/sys.s
@@ -0,0 +1,193 @@
+// Copyright 2009 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.
+
+//
+// System calls and other sys.stuff for AMD64, Linux
+//
+
+TEXT exit(SB),7,$0-8
+ MOVL 8(SP), DI
+ MOVL $231, AX // exitgroup - force all os threads to exi
+ SYSCALL
+ RET
+
+TEXT 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
+ MOVQ 8(SP), DI
+ MOVL 16(SP), SI
+ MOVL 20(SP), DX
+ MOVL $2, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT close(SB),7,$0-8
+ MOVL 8(SP), DI
+ MOVL $3, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT fstat(SB),7,$0-16
+ MOVL 8(SP), DI
+ MOVQ 16(SP), SI
+ MOVL $5, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT read(SB),7,$0-24
+ MOVL 8(SP), DI
+ MOVQ 16(SP), SI
+ MOVL 24(SP), DX
+ MOVL $0, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT write(SB),7,$0-24
+ MOVL 8(SP), DI
+ MOVQ 16(SP), SI
+ MOVL 24(SP), DX
+ MOVL $1, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT sys·write(SB),7,$0-24
+ MOVL 8(SP), DI
+ MOVQ 16(SP), SI
+ MOVL 24(SP), DX
+ MOVL $1, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT rt_sigaction(SB),7,$0-32
+ MOVL 8(SP), DI
+ MOVQ 16(SP), SI
+ MOVQ 24(SP), DX
+ MOVQ 32(SP), R10
+ MOVL $13, AX // syscall entry
+ SYSCALL
+ RET
+
+TEXT sigtramp(SB),7,$24-16
+ MOVQ 32(R14), R15 // g = m->gsignal
+ MOVQ DI,0(SP)
+ MOVQ SI,8(SP)
+ MOVQ DX,16(SP)
+ CALL sighandler(SB)
+ RET
+
+TEXT sigignore(SB),7,$0
+ RET
+
+TEXT sigreturn(SB),7,$0
+ MOVL $15, AX // rt_sigreturn
+ SYSCALL
+ INT $3 // not reached
+
+TEXT sys·mmap(SB),7,$0-32
+ MOVQ 8(SP), DI
+ MOVQ $0, SI
+ MOVL 16(SP), SI
+ MOVL 20(SP), DX
+ MOVL 24(SP), R10
+ MOVL 28(SP), R8
+ MOVL 32(SP), R9
+
+ MOVL $9, AX // syscall entry
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ CALL notok(SB)
+ RET
+
+TEXT notok(SB),7,$0
+ MOVQ $0xf1, BP
+ MOVQ BP, (BP)
+ RET
+
+TEXT sys·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 sys·getcallerpc+0(SB),7,$0
+ MOVQ x+0(FP),AX // addr of first arg
+ MOVQ -8(AX),AX // get calling pc
+ RET
+
+TEXT sys·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
+ MOVQ 8(SP), DI
+ MOVL 16(SP), SI
+ MOVL 20(SP), DX
+ MOVQ 24(SP), R10
+ MOVQ 32(SP), R8
+ MOVL 40(SP), R9
+ MOVL $202, AX
+ SYSCALL
+ RET
+
+// int64 clone(int32 flags, void *stack, M *m, G *g, void (*fn)(void));
+TEXT clone(SB),7,$0
+ MOVL flags+8(SP), DI
+ MOVQ stack+16(SP), SI
+
+ // Copy m, g, fn off parent stack for use by child.
+ // Careful: Linux system call clobbers CX and R11.
+ MOVQ m+24(SP), R8
+ MOVQ g+32(SP), R9
+ MOVQ fn+40(SP), R12
+
+ MOVL $56, AX
+ SYSCALL
+
+ // In parent, return.
+ CMPQ AX, $0
+ JEQ 2(PC)
+ RET
+
+ // In child, set up new stack
+ MOVQ SI, SP
+ MOVQ R8, R14 // m
+ MOVQ R9, R15 // g
+
+ // Initialize m->procid to Linux tid
+ MOVL $186, AX // gettid
+ SYSCALL
+ MOVQ AX, 24(R14)
+
+ // Call fn
+ CALL R12
+
+ // It shouldn't return. If it does, exi
+ MOVL $111, DI
+ MOVL $60, AX
+ SYSCALL
+ JMP -3(PC) // keep exiting
+
+TEXT 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)
+ RET