occlum/tools/toolchains/golang/0001-adapt-golang-to-occlum-libos.patch
LI Qing 6d72e10fc1 Add Golang toolchain and the demo
This commit provides a modified Go runtime in Docker image.
Now we can build a Go program using `occlum-go`, then run it
in SGX enclaves by Occlum.
The Golang demo demonstrates how to build and run a web server
program written in Go.
2020-05-15 03:02:42 +00:00

638 lines
16 KiB
Diff

From 4c7e5586d109eba46c4f067699ae652d722270a0 Mon Sep 17 00:00:00 2001
From: "jeffery.wsj" <jeffery.wsj@alibaba-inc.com>
Date: Fri, 8 May 2020 18:06:37 +0800
Subject: [PATCH] adapt golang to occlum libos:
1. hook heap malloc
2. hook all syscall based on amd64 linux platform
3. hook vdso call
---
src/runtime/malloc.go | 76 ++++++++++-----------
src/runtime/os_linux.go | 4 ++
src/runtime/sys_linux_amd64.go | 3 +
src/runtime/sys_linux_amd64.s | 116 +++++++++++++++++++++------------
src/runtime/textflag.h | 11 ++++
src/syscall/asm_linux_amd64.s | 24 +++++--
6 files changed, 150 insertions(+), 84 deletions(-)
create mode 100644 src/runtime/sys_linux_amd64.go
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index d768054198..0d7166397d 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -610,43 +610,45 @@ func (h *mheap) sysAlloc(n uintptr) (v unsafe.Pointer, size uintptr) {
goto mapped
}
- // Try to grow the heap at a hint address.
- for h.arenaHints != nil {
- hint := h.arenaHints
- p := hint.addr
- if hint.down {
- p -= n
- }
- if p+n < p {
- // We can't use this, so don't ask.
- v = nil
- } else if arenaIndex(p+n-1) >= 1<<arenaBits {
- // Outside addressable heap. Can't use.
- v = nil
- } else {
- v = sysReserve(unsafe.Pointer(p), n)
- }
- if p == uintptr(v) {
- // Success. Update the hint.
- if !hint.down {
- p += n
- }
- hint.addr = p
- size = n
- break
- }
- // Failed. Discard this hint and try the next.
- //
- // TODO: This would be cleaner if sysReserve could be
- // told to only return the requested address. In
- // particular, this is already how Windows behaves, so
- // it would simplify things there.
- if v != nil {
- sysFree(v, n, nil)
- }
- h.arenaHints = hint.next
- h.arenaHintAlloc.free(unsafe.Pointer(hint))
- }
+ if occlumentry == 0 {
+ // Try to grow the heap at a hint address.
+ for h.arenaHints != nil {
+ hint := h.arenaHints
+ p := hint.addr
+ if hint.down {
+ p -= n
+ }
+ if p+n < p {
+ // We can't use this, so don't ask.
+ v = nil
+ } else if arenaIndex(p+n-1) >= 1<<arenaBits {
+ // Outside addressable heap. Can't use.
+ v = nil
+ } else {
+ v = sysReserve(unsafe.Pointer(p), n)
+ }
+ if p == uintptr(v) {
+ // Success. Update the hint.
+ if !hint.down {
+ p += n
+ }
+ hint.addr = p
+ size = n
+ break
+ }
+ // Failed. Discard this hint and try the next.
+ //
+ // TODO: This would be cleaner if sysReserve could be
+ // told to only return the requested address. In
+ // particular, this is already how Windows behaves, so
+ // it would simplify things there.
+ if v != nil {
+ sysFree(v, n, nil)
+ }
+ h.arenaHints = hint.next
+ h.arenaHintAlloc.free(unsafe.Pointer(hint))
+ }
+ }
if size == 0 {
if raceenabled {
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
index d4a9bd4ff5..87fb5fffb3 100644
--- a/src/runtime/os_linux.go
+++ b/src/runtime/os_linux.go
@@ -178,6 +178,7 @@ const (
_AT_HWCAP = 16 // hardware capability bit vector
_AT_RANDOM = 25 // introduced in 2.6.29
_AT_HWCAP2 = 26 // hardware capability bit vector 2
+ _AT_OCCLUM = 48 // gnu syscall ABI entry address
)
var procAuxv = []byte("/proc/self/auxv\x00")
@@ -253,6 +254,9 @@ func sysauxv(auxv []uintptr) int {
case _AT_PAGESZ:
physPageSize = val
+
+ case _AT_OCCLUM:
+ occlumentry = val
}
archauxv(tag, val)
diff --git a/src/runtime/sys_linux_amd64.go b/src/runtime/sys_linux_amd64.go
new file mode 100644
index 0000000000..c9369b6661
--- /dev/null
+++ b/src/runtime/sys_linux_amd64.go
@@ -0,0 +1,3 @@
+package runtime
+
+var occlumentry uintptr = 0x0
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
index 5c300f553d..db9c9ab55b 100644
--- a/src/runtime/sys_linux_amd64.s
+++ b/src/runtime/sys_linux_amd64.s
@@ -33,12 +33,14 @@
#define SYS_exit 60
#define SYS_kill 62
#define SYS_fcntl 72
+#define SYS_gettimeofday 96
#define SYS_sigaltstack 131
#define SYS_arch_prctl 158
#define SYS_gettid 186
#define SYS_futex 202
#define SYS_sched_getaffinity 204
#define SYS_epoll_create 213
+#define SYS_clock_gettime 228
#define SYS_exit_group 231
#define SYS_epoll_ctl 233
#define SYS_tgkill 234
@@ -50,7 +52,7 @@
TEXT runtime·exit(SB),NOSPLIT,$0-4
MOVL code+0(FP), DI
MOVL $SYS_exit_group, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
// func exitThread(wait *uint32)
@@ -60,7 +62,7 @@ TEXT runtime·exitThread(SB),NOSPLIT,$0-8
MOVL $0, (AX)
MOVL $0, DI // exit code
MOVL $SYS_exit, AX
- SYSCALL
+ SYSCALL_ENHANCE
// We may not even have a stack any more.
INT $3
JMP 0(PC)
@@ -72,7 +74,7 @@ TEXT runtime·open(SB),NOSPLIT,$0-20
MOVL mode+8(FP), DX
MOVL perm+12(FP), R10
MOVL $SYS_openat, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $-1, AX
@@ -82,7 +84,7 @@ TEXT runtime·open(SB),NOSPLIT,$0-20
TEXT runtime·closefd(SB),NOSPLIT,$0-12
MOVL fd+0(FP), DI
MOVL $SYS_close, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $-1, AX
@@ -94,7 +96,7 @@ TEXT runtime·write(SB),NOSPLIT,$0-28
MOVQ p+8(FP), SI
MOVL n+16(FP), DX
MOVL $SYS_write, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $-1, AX
@@ -106,7 +108,7 @@ TEXT runtime·read(SB),NOSPLIT,$0-28
MOVQ p+8(FP), SI
MOVL n+16(FP), DX
MOVL $SYS_read, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $-1, AX
@@ -127,35 +129,35 @@ TEXT runtime·usleep(SB),NOSPLIT,$16
MOVQ SP, DI
MOVL $0, SI
MOVL $SYS_nanosleep, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
TEXT runtime·gettid(SB),NOSPLIT,$0-4
MOVL $SYS_gettid, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+0(FP)
RET
TEXT runtime·raise(SB),NOSPLIT,$0
MOVL $SYS_getpid, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, R12
MOVL $SYS_gettid, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, SI // arg 2 tid
MOVL R12, DI // arg 1 pid
MOVL sig+0(FP), DX // arg 3
MOVL $SYS_tgkill, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
TEXT runtime·raiseproc(SB),NOSPLIT,$0
MOVL $SYS_getpid, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, DI // arg 1 pid
MOVL sig+0(FP), SI // arg 2
MOVL $SYS_kill, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
TEXT runtime·setitimer(SB),NOSPLIT,$0-24
@@ -163,7 +165,7 @@ TEXT runtime·setitimer(SB),NOSPLIT,$0-24
MOVQ new+8(FP), SI
MOVQ old+16(FP), DX
MOVL $SYS_setittimer, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
TEXT runtime·mincore(SB),NOSPLIT,$0-28
@@ -171,12 +173,29 @@ TEXT runtime·mincore(SB),NOSPLIT,$0-28
MOVQ n+8(FP), SI
MOVQ dst+16(FP), DX
MOVL $SYS_mincore, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+24(FP)
RET
// func walltime() (sec int64, nsec int32)
TEXT runtime·walltime(SB),NOSPLIT,$0-12
+ CMPQ runtime·occlumentry(SB), $0x0
+ JBE start
+ MOVQ SP, BP
+ SUBQ $16, SP // Space for results
+ ANDQ $~15, SP // Align for C code
+ MOVQ $SYS_clock_gettime, AX
+ MOVQ $0, DI
+ LEAQ ret+0(SP), SI
+ CALL *runtime·occlumentry(SB)
+ MOVQ 0(SP), AX
+ MOVQ 8(SP), DX
+ MOVQ BP, SP
+ MOVQ AX, sec+0(FP)
+ MOVL DX, nsec+8(FP)
+ RET
+
+start:
// We don't know how much stack space the VDSO code will need,
// so switch to g0.
// In particular, a kernel configured with CONFIG_OPTIMIZE_INLINING=n
@@ -234,8 +253,24 @@ fallback:
RET
TEXT runtime·nanotime(SB),NOSPLIT,$0-8
- // Switch to g0 stack. See comment above in runtime·walltime.
-
+ CMPQ runtime·occlumentry(SB), $0x0
+ JBE start
+ MOVQ SP, BP
+ SUBQ $16, SP // Space for results
+ ANDQ $~15, SP // Align for C code
+ MOVQ $SYS_clock_gettime, AX
+ MOVQ $1, DI
+ LEAQ ret+0(SP), SI
+ CALL *runtime·occlumentry(SB)
+ MOVQ 0(SP), AX // sec
+ MOVQ 8(SP), DX // nsec
+ IMULQ $1000000000, AX
+ ADDQ DX, AX
+ MOVQ BP, SP
+ MOVQ AX, ret+0(FP)
+ RET
+start:
+ // Switch to g0 stack. See comment above in runtime·walltime.
MOVQ SP, BP // Save old SP; BP unchanged by C code.
get_tls(CX)
@@ -297,7 +332,7 @@ TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
MOVQ old+16(FP), DX
MOVL size+24(FP), R10
MOVL $SYS_rt_sigprocmask, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $0xf1, 0xf1 // crash
@@ -309,7 +344,7 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
MOVQ old+16(FP), DX
MOVQ size+24(FP), R10
MOVL $SYS_rt_sigaction, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+32(FP)
RET
@@ -447,7 +482,7 @@ sigtrampnog:
// https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup
TEXT runtime·sigreturn(SB),NOSPLIT,$0
MOVQ $SYS_rt_sigreturn, AX
- SYSCALL
+ SYSCALL_ENHANCE
INT $3 // not reached
TEXT runtime·sysMmap(SB),NOSPLIT,$0
@@ -459,7 +494,7 @@ TEXT runtime·sysMmap(SB),NOSPLIT,$0
MOVL off+28(FP), R9
MOVL $SYS_mmap, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS ok
NOTQ AX
@@ -494,7 +529,7 @@ TEXT runtime·sysMunmap(SB),NOSPLIT,$0
MOVQ addr+0(FP), DI
MOVQ n+8(FP), SI
MOVQ $SYS_munmap, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $0xf1, 0xf1 // crash
@@ -518,7 +553,7 @@ TEXT runtime·madvise(SB),NOSPLIT,$0
MOVQ n+8(FP), SI
MOVL flags+16(FP), DX
MOVQ $SYS_madvise, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+24(FP)
RET
@@ -532,7 +567,7 @@ TEXT runtime·futex(SB),NOSPLIT,$0
MOVQ addr2+24(FP), R8
MOVL val3+32(FP), R9
MOVL $SYS_futex, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+40(FP)
RET
@@ -550,7 +585,7 @@ TEXT runtime·clone(SB),NOSPLIT,$0
MOVQ fn+32(FP), R12
MOVL $SYS_clone, AX
- SYSCALL
+ SYSCALL_ENHANCE
// In parent, return.
CMPQ AX, $0
@@ -569,7 +604,7 @@ TEXT runtime·clone(SB),NOSPLIT,$0
// Initialize m->procid to Linux tid
MOVL $SYS_gettid, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVQ AX, m_procid(R8)
// Set FS to point at m->tls.
@@ -589,14 +624,14 @@ nog:
// It shouldn't return. If it does, exit that thread.
MOVL $111, DI
MOVL $SYS_exit, AX
- SYSCALL
+ SYSCALL_ENHANCE
JMP -3(PC) // keep exiting
TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
MOVQ new+0(FP), DI
MOVQ old+8(FP), SI
MOVQ $SYS_sigaltstack, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $0xf1, 0xf1 // crash
@@ -613,7 +648,7 @@ TEXT runtime·settls(SB),NOSPLIT,$32
MOVQ DI, SI
MOVQ $0x1002, DI // ARCH_SET_FS
MOVQ $SYS_arch_prctl, AX
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS 2(PC)
MOVL $0xf1, 0xf1 // crash
@@ -621,7 +656,7 @@ TEXT runtime·settls(SB),NOSPLIT,$32
TEXT runtime·osyield(SB),NOSPLIT,$0
MOVL $SYS_sched_yield, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
@@ -629,7 +664,7 @@ TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
MOVQ len+8(FP), SI
MOVQ buf+16(FP), DX
MOVL $SYS_sched_getaffinity, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+24(FP)
RET
@@ -637,7 +672,7 @@ TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
TEXT runtime·epollcreate(SB),NOSPLIT,$0
MOVL size+0(FP), DI
MOVL $SYS_epoll_create, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+8(FP)
RET
@@ -645,7 +680,7 @@ TEXT runtime·epollcreate(SB),NOSPLIT,$0
TEXT runtime·epollcreate1(SB),NOSPLIT,$0
MOVL flags+0(FP), DI
MOVL $SYS_epoll_create1, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+8(FP)
RET
@@ -656,7 +691,7 @@ TEXT runtime·epollctl(SB),NOSPLIT,$0
MOVL fd+8(FP), DX
MOVQ ev+16(FP), R10
MOVL $SYS_epoll_ctl, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+24(FP)
RET
@@ -669,7 +704,7 @@ TEXT runtime·epollwait(SB),NOSPLIT,$0
MOVL timeout+20(FP), R10
MOVQ $0, R8
MOVL $SYS_epoll_pwait, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+24(FP)
RET
@@ -679,10 +714,9 @@ TEXT runtime·closeonexec(SB),NOSPLIT,$0
MOVQ $2, SI // F_SETFD
MOVQ $1, DX // FD_CLOEXEC
MOVL $SYS_fcntl, AX
- SYSCALL
+ SYSCALL_ENHANCE
RET
-
// int access(const char *name, int mode)
TEXT runtime·access(SB),NOSPLIT,$0
// This uses faccessat instead of access, because Android O blocks access.
@@ -691,7 +725,7 @@ TEXT runtime·access(SB),NOSPLIT,$0
MOVL mode+8(FP), DX
MOVL $0, R10
MOVL $SYS_faccessat, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+16(FP)
RET
@@ -701,7 +735,7 @@ TEXT runtime·connect(SB),NOSPLIT,$0-28
MOVQ addr+8(FP), SI
MOVL len+16(FP), DX
MOVL $SYS_connect, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+24(FP)
RET
@@ -711,7 +745,7 @@ TEXT runtime·socket(SB),NOSPLIT,$0-20
MOVL typ+4(FP), SI
MOVL prot+8(FP), DX
MOVL $SYS_socket, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVL AX, ret+16(FP)
RET
@@ -720,6 +754,6 @@ TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
// Implemented as brk(NULL).
MOVQ $0, DI
MOVL $SYS_brk, AX
- SYSCALL
+ SYSCALL_ENHANCE
MOVQ AX, ret+0(FP)
RET
diff --git a/src/runtime/textflag.h b/src/runtime/textflag.h
index daca36d948..824f069076 100644
--- a/src/runtime/textflag.h
+++ b/src/runtime/textflag.h
@@ -35,3 +35,14 @@
// Function is the top of the call stack. Call stack unwinders should stop
// at this function.
#define TOPFRAME 2048
+
+#define SYSCALL_ENHANCE \
+ CMPQ runtime·occlumentry(SB), $0x0 \
+ JBE 4(PC) \
+ CALL *runtime·occlumentry(SB) \
+ CMPQ runtime·occlumentry(SB), $0x0 \
+ JNE 2(PC) \
+ SYSCALL
+
+#define OCCLUM_GET_TIME_OF_DAY \
+ CALL *runtime·occlumentry(SB)
diff --git a/src/syscall/asm_linux_amd64.s b/src/syscall/asm_linux_amd64.s
index 364815df18..4417768e8a 100644
--- a/src/syscall/asm_linux_amd64.s
+++ b/src/syscall/asm_linux_amd64.s
@@ -5,6 +5,8 @@
#include "textflag.h"
#include "funcdata.h"
+#define SYS_gettimeofday 96
+
//
// System calls for AMD64, Linux
//
@@ -23,7 +25,7 @@ TEXT ·Syscall(SB),NOSPLIT,$0-56
MOVQ $0, R8
MOVQ $0, R9
MOVQ trap+0(FP), AX // syscall entry
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS ok
MOVQ $-1, r1+32(FP)
@@ -49,7 +51,7 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-80
MOVQ a5+40(FP), R8
MOVQ a6+48(FP), R9
MOVQ trap+0(FP), AX // syscall entry
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS ok6
MOVQ $-1, r1+56(FP)
@@ -74,7 +76,7 @@ TEXT ·RawSyscall(SB),NOSPLIT,$0-56
MOVQ $0, R8
MOVQ $0, R9
MOVQ trap+0(FP), AX // syscall entry
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS ok1
MOVQ $-1, r1+32(FP)
@@ -97,7 +99,7 @@ TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
MOVQ a5+40(FP), R8
MOVQ a6+48(FP), R9
MOVQ trap+0(FP), AX // syscall entry
- SYSCALL
+ SYSCALL_ENHANCE
CMPQ AX, $0xfffffffffffff001
JLS ok2
MOVQ $-1, r1+56(FP)
@@ -121,7 +123,7 @@ TEXT ·rawVforkSyscall(SB),NOSPLIT,$0-32
MOVQ $0, R9
MOVQ trap+0(FP), AX // syscall entry
POPQ R12 // preserve return address
- SYSCALL
+ SYSCALL_ENHANCE
PUSHQ R12
CMPQ AX, $0xfffffffffffff001
JLS ok2
@@ -143,18 +145,28 @@ TEXT ·rawSyscallNoError(SB),NOSPLIT,$0-48
MOVQ $0, R8
MOVQ $0, R9
MOVQ trap+0(FP), AX // syscall entry
- SYSCALL
+ SYSCALL_ENHANCE
MOVQ AX, r1+32(FP)
MOVQ DX, r2+40(FP)
RET
// func gettimeofday(tv *Timeval) (err uintptr)
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
+ CMPQ runtime·occlumentry(SB), $0x0
+ JBE start
+ MOVQ tv+0(FP), DI
+ MOVQ $0, SI
+ MOVQ $SYS_gettimeofday, AX
+ OCCLUM_GET_TIME_OF_DAY
+ JMP result
+
+start:
MOVQ tv+0(FP), DI
MOVQ $0, SI
MOVQ runtime·vdsoGettimeofdaySym(SB), AX
CALL AX
+result:
CMPQ AX, $0xfffffffffffff001
JLS ok7
NEGQ AX
--
2.19.1.3.ge56e4f7