diff options
Diffstat (limited to 'contrib/bug216610/go')
-rw-r--r-- | contrib/bug216610/go/.gitignore | 5 | ||||
-rw-r--r-- | contrib/bug216610/go/fibber/fib.go | 32 | ||||
-rw-r--r-- | contrib/bug216610/go/fibber/fibs_linux_amd64.s | 21 | ||||
-rw-r--r-- | contrib/bug216610/go/fibber/fibs_linux_arm.s | 23 | ||||
-rw-r--r-- | contrib/bug216610/go/go.mod | 5 | ||||
-rw-r--r-- | contrib/bug216610/go/main.go | 29 |
6 files changed, 115 insertions, 0 deletions
diff --git a/contrib/bug216610/go/.gitignore b/contrib/bug216610/go/.gitignore new file mode 100644 index 0000000..ae14305 --- /dev/null +++ b/contrib/bug216610/go/.gitignore @@ -0,0 +1,5 @@ +fib +*.syso +main +go.sum +linkage.go diff --git a/contrib/bug216610/go/fibber/fib.go b/contrib/bug216610/go/fibber/fib.go new file mode 100644 index 0000000..49757cd --- /dev/null +++ b/contrib/bug216610/go/fibber/fib.go @@ -0,0 +1,32 @@ +// Package fibber implements a Fibonacci sequence generator using a C +// coded compute kernel (a .syso file). +package fibber + +import ( + "unsafe" +) + +// State is the native Go form of the C.state structure. +type State struct { + B, A uint32 +} + +// cPtr converts State into a C pointer suitable as an argument for +// sysoCaller. +func (s *State) cPtr() unsafe.Pointer { + return unsafe.Pointer(&s.B) +} + +// NewState initializes a Fibonacci Number sequence generator. Upon +// return s.A=0 and s.B=1 are the first two numbers in the sequence. +func NewState() *State { + s := &State{} + syso__fib_init.call(s.cPtr()) + return s +} + +// Next advances the state to the next number in the sequence. Upon +// return, s.B is the most recently calculated value. +func (s *State) Next() { + syso__fib_next.call(s.cPtr()) +} diff --git a/contrib/bug216610/go/fibber/fibs_linux_amd64.s b/contrib/bug216610/go/fibber/fibs_linux_amd64.s new file mode 100644 index 0000000..5992d09 --- /dev/null +++ b/contrib/bug216610/go/fibber/fibs_linux_amd64.s @@ -0,0 +1,21 @@ +// To transition from a Go call to a C function call, we are skating +// on really thin ice... Ceveat Emptor! +// +// Ref: +// https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/home +// +// This is not strictly needed, but it makes gdb debugging less +// confusing because spacer ends up being an alias for the TEXT +// section start. +TEXT ·spacer(SB),$0 + RET + +#define RINDEX(n) (8*n) + +// Header to this function wrapper is the last time we can voluntarily +// yield to some other goroutine. +TEXT ·syso(SB),$0-16 + MOVQ cFn+RINDEX(0)(FP), SI + MOVQ state+RINDEX(1)(FP), DI + CALL *SI + RET diff --git a/contrib/bug216610/go/fibber/fibs_linux_arm.s b/contrib/bug216610/go/fibber/fibs_linux_arm.s new file mode 100644 index 0000000..39640a5 --- /dev/null +++ b/contrib/bug216610/go/fibber/fibs_linux_arm.s @@ -0,0 +1,23 @@ +// To transition from a Go call to a C function call, we are skating +// on really thin ice... Ceveat Emptor! +// +// Ref: +// https://stackoverflow.com/questions/261419/what-registers-to-save-in-the-arm-c-calling-convention +// +// This is not strictly needed, but it makes gdb debugging less +// confusing because spacer ends up being an alias for the TEXT +// section start. +TEXT ·spacer(SB),$0 + RET + +#define FINDEX(n) (8*n) + +// Header to this function wrapper is the last time we can voluntarily +// yield to some other goroutine. +// +// Conventions: PC == R15, SP == R13, LR == R14, IP (scratch) = R12 +TEXT ·syso(SB),$0-8 + MOVW cFn+0(FP), R14 + MOVW state+4(FP), R0 + BL (R14) + RET diff --git a/contrib/bug216610/go/go.mod b/contrib/bug216610/go/go.mod new file mode 100644 index 0000000..8531994 --- /dev/null +++ b/contrib/bug216610/go/go.mod @@ -0,0 +1,5 @@ +module fib + +go 1.18 + +require kernel.org/pub/linux/libs/security/libcap/psx v1.2.69 diff --git a/contrib/bug216610/go/main.go b/contrib/bug216610/go/main.go new file mode 100644 index 0000000..65121f6 --- /dev/null +++ b/contrib/bug216610/go/main.go @@ -0,0 +1,29 @@ +// Program fib uses the psx package once, and then prints the first +// ten Fibonacci numbers. +package main + +import ( + "fmt" + "log" + "syscall" + + "fib/fibber" + + "kernel.org/pub/linux/libs/security/libcap/psx" +) + +func main() { + pid, _, err := psx.Syscall3(syscall.SYS_GETPID, 0, 0, 0) + if err != 0 { + log.Fatalf("failed to get PID via psx: %v", err) + } + fmt.Print("psx syscall result: PID=") + fmt.Println(pid) + s := fibber.NewState() + fmt.Print("fib: ", s.A, ", ", s.B) + for i := 0; i < 8; i++ { + s.Next() + fmt.Print(", ", s.B) + } + fmt.Println(", ...") +} |