-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add support for go1.17 #100
Comments
Note: eggos currently requires Go 1.16. See upstream issue for Go 1.17 support (ref: icexin/eggos#100).
I tried generating a "hello world" eggos kernel using Go 1.17, to debug the boot process. Unexpectedly, it crashes quite early due to ABI changes introduced in Go 1.17. In particular, the crash occurs in an autogenerated wrapper for Dump of assembler code for function github.com/icexin/eggos/kernel.preinit<autogenerated>:
0x00000000002bbe40 <+0>: sub $0x18,%rsp
0x00000000002bbe44 <+4>: mov %rbp,0x10(%rsp)
0x00000000002bbe49 <+9>: lea 0x10(%rsp),%rbp
0x00000000002bbe4e <+14>: mov 0x20(%rsp),%rax
0x00000000002bbe53 <+19>: mov 0x28(%rsp),%rbx
=> 0x00000000002bbe58 <+24>: xorps %xmm15,%xmm15
0x00000000002bbe5c <+28>: mov %fs:0xfffffffffffffff8,%r14
0x00000000002bbe65 <+37>: call 0x2b6c40 <github.com/icexin/eggos/kernel.preinit>
0x00000000002bbe6a <+42>: mov 0x10(%rsp),%rbp
0x00000000002bbe6f <+47>: add $0x18,%rsp
0x00000000002bbe73 <+51>: ret
End of assembler dump.
(gdb) si
[Inferior 1 (process 1) exited normally]
(gdb) The reason for the crash is most likely that the FPU has not yet been initialized; thus causing the instruction |
Notes on the new register-based calling convention introduced Go 1.17 ("ABIInternal"), and how gVisor handles it: |
…ed> function wrappers of Go 1.17 In Go 1.17, when invoking Go functions from asm, <autogenerated> function wrappers are generated to handle the conversion from the old Go ABI (abi0) which is stack based to the new internal register-based Go ABI (abi1). The problem is that the <autogenerated> function wrapper assumes that we are already running in a fully initialized Go environment, with support for SSE instructions and with a configured %fs segment register to handle TLS of G. For context, see the autogenerated function wrapper which is invoked when calling the Go kernel.preinit function from the asm rt0 function. Dump of assembler code for function github.com/icexin/eggos/kernel.preinit<autogenerated>: 0x00000000002bbe40 <+0>: sub $0x18,%rsp 0x00000000002bbe44 <+4>: mov %rbp,0x10(%rsp) 0x00000000002bbe49 <+9>: lea 0x10(%rsp),%rbp 0x00000000002bbe4e <+14>: mov 0x20(%rsp),%rax 0x00000000002bbe53 <+19>: mov 0x28(%rsp),%rbx => 0x00000000002bbe58 <+24>: xorps %xmm15,%xmm15 0x00000000002bbe5c <+28>: mov %fs:0xfffffffffffffff8,%r14 0x00000000002bbe65 <+37>: call 0x2b6c40 <github.com/icexin/eggos/kernel.preinit> 0x00000000002bbe6a <+42>: mov 0x10(%rsp),%rbp 0x00000000002bbe6f <+47>: add $0x18,%rsp 0x00000000002bbe73 <+51>: ret As visible in the disassembly of kernel.preinit<autogenerated>, the XMM15 register is set to zero using XOR (see offset +24), which requires SSE instructions to be initialized. Also, on offset +28, the R14 register is moved into TLS by using the %fs segment register. R14 store G in Go 1.17. To handle this case, we need to initialize %fs to a valid memory location; we use a fake memory location, as no Go routines are running at this point, and later on %fs will be set when the first goroutine is started by thread0Init. Note, this is just a preliminary work to better understand what we must support to handle Go 1.17. We are most likely _not_ going to use this code for the final commit to eggos. This is just to get more intuition into the problem domain. Updates icexin#100.
Go 1.17 implements a new way of passing function arguments and results using registers instead of the stack.
This issue is used to track affected modules and corresponding PRs.
The text was updated successfully, but these errors were encountered: