Skip to content
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

draft PR for gaining insight into what is needed for Go 1.17 calling conventions; DO NOT MERGE #104

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Commits on Feb 12, 2022

  1. kernel: invoke sseInit and initFakeFS from rt0 to handle <autogenerat…

    …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.
    mewmew committed Feb 12, 2022
    Configuration menu
    Copy the full SHA
    8cdbd4f View commit details
    Browse the repository at this point in the history
  2. kernel: skip return address of <autogenerated> function wrapper in tr…

    …apret before IRET instruction
    
    NOTE: this commit will ONLY work for Go 1.17, it is not backwards
    compatible with Go 1.16. We should probably find a way to handle
    both (e.g. build tags or a general approach).
    
    To give context, an <autogenerated> function wrapper is generated
    in Go 1.17 for kernel.trapret.
    
    	Dump of assembler code for function github.com/icexin/eggos/kernel.trapret<autogenerated>:
    	=> 0x00000000002bbf60 <+0>:   call   0x2b9e40 <github.com/icexin/eggos/kernel.trapret>
    		0x00000000002bbf65 <+5>:   xorps  %xmm15,%xmm15
    		0x00000000002bbf69 <+9>:   mov    %fs:0xfffffffffffffff8,%r14
    		0x00000000002bbf72 <+18>:  ret
    
    In this autogenerated function, a call to the real kernel.trapret
    is made, which places a return address on the stack. However, the
    trapret function will use IRET to return, so to handle this case,
    we skip the return address pushed onto the stack by the autogenerated
    function by adding 8 (ptr size) to rsp.
    
    We should definitely try to find a better way to handle this situation
    as it seems very fragile and may break in the future if Go changes
    their autogenerated functions.
    
    So, once more, this is mostly to get intuition into the problem domain,
    it is not meant as a solution that should be merged into eggos.
    mewmew committed Feb 12, 2022
    Configuration menu
    Copy the full SHA
    ef26ff1 View commit details
    Browse the repository at this point in the history