Ah sorry he does it with rflag and r11

On Mon, Aug 29, 2016 at 7:10 PM, Benoît Canet <[email protected]>
wrote:

>
>
> On Mon, Aug 29, 2016 at 7:08 PM, Avi Kivity <[email protected]> wrote:
>
>>
>>
>> On 08/29/2016 07:49 PM, Nadav Har'El wrote:
>>
>>> GDB uses DWARF CFI meta-instructions to know how to backtrace through
>>> function call frames, and which registers get saved where.
>>>
>>> This patch fixes the CFI instructions in the syscall_entry() assembly
>>> code. After this patch, if we are in system call code we can backtrack
>>> through the syscall_entry() - for example:
>>>
>>>   5  0x000000000059c10b in syscall_wrapper (number=186) at linux.cc:332
>>>   6  0x0000000000480245 in syscall_entry () at arch/x64/entry.S:238
>>>   7  0x0000100000c00bce in main (argc=1, argv=<optimized out>)
>>>      at /home/nyh/osv/tests/tst-syscall.cc:49
>>>   8  0x000000000063526e in osv::application::run_main
>>> (this=0xffffa00003079910,
>>>      path="tests/tst-syscall.so", argc=1, argv=0xffffa00001f88170)
>>>      at core/app.cc:338
>>>
>>> Note how syscall_entry() looks like a normal function - it no longer
>>> pretends to be a "signal frame". In particular, we no longer need to
>>> obey a specific layout of the registers saved on the stack, so I took
>>> this opportunity to remove some of the useless things we saved or
>>> saved multiple times.
>>>
>>> Signed-off-by: Nadav Har'El <[email protected]>
>>> ---
>>>   arch/x64/entry.S | 104 +++++++++++++++++++++---------
>>> -------------------------
>>>   1 file changed, 40 insertions(+), 64 deletions(-)
>>>
>>> diff --git a/arch/x64/entry.S b/arch/x64/entry.S
>>> index e265a30..e3be0bc 100644
>>> --- a/arch/x64/entry.S
>>> +++ b/arch/x64/entry.S
>>> @@ -164,66 +164,43 @@ call_signal_handler_thunk:
>>>   syscall_entry:
>>>       .type syscall_entry, @function
>>>       .cfi_startproc simple
>>>
>>
>> Probably, we need to remove simple here, likely it sets up incorrect
>> references.
>>
>> +    .cfi_undefined rcx # was overwritten with rip by the syscall
>>> instruction
>>>
>>
>> Not .cfi_register1 %rip, %rcx?  So if we trap here, we know who the
>> caller is.
>
>
> From what I understand Nadav does it by hand later when pushing.
>
>>
>>
>> +    .cfi_undefined r11 # was overwritten with rflags by the syscall
>>> instruction
>>>       # There is no ring transition and rflags are left unchanged.
>>>         # Skip the "red zone" allowed by the AMD64 ABI (the caller used a
>>>       # SYSCALL instruction and doesn't know he called a function):
>>>       subq $128, %rsp
>>> +    .cfi_def_cfa %rsp, 0
>>>         # We need to save and restore the caller's %rbp anyway, so let's
>>> also
>>>       # set it up properly for old-style frame-pointer backtracing to
>>> work
>>>       # (e.g., backtrace_safe()). Also need to push the return address
>>> before
>>>       # the rbp to get a normal frame. Our return address is in rcx.
>>> -    pushq %rcx
>>> -    pushq %rbp
>>> +    pushq_cfi %rcx
>>> +    .cfi_rel_offset %rip, 0
>>> +    pushq_cfi %rbp
>>>       movq %rsp, %rbp
>>> +    .cfi_rel_offset %rsp, 0
>>>       #
>>>       # From http://stackoverflow.com/quest
>>> ions/2535989/what-are-the-calling-conventions-for-unix-linux
>>> -system-calls-on-x86-64:
>>>       # "User-level applications use as integer registers for passing
>>> the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9. The kernel interface uses
>>> %rdi, %rsi, %rdx, %r10, %r8 and %r9"
>>>         # FIXME: fpu
>>> -    # build the stack frame by hand
>>> -    pushq %rsp
>>> -    subq $8, %rsp # rip was saved in rcx by the syscall instruction
>>> -    pushq %rax
>>> -    pushq %rbx
>>> -    pushq %rcx # contains rip before syscall instruction
>>> -    pushq %rdx
>>> -    pushq %rsi
>>> -    pushq %rdi
>>> -    pushq %r8
>>> -    pushq %r9
>>> -    pushq %r10
>>> -    pushq %r11 # contains rflags before syscall instruction
>>> -    pushq %r12
>>> -    pushq %r13
>>> -    pushq %r14
>>> -    pushq %r15
>>> -
>>> -    # stack contains a signal_frame
>>> -    .cfi_signal_frame
>>> -    .cfi_def_cfa %rsp, 0
>>> -       .cfi_register rip,rcx # rcx took previous rip value
>>> -       .cfi_register rflags,r11 # r11 took previous rflags value
>>> -       .cfi_undefined rcx # was overwritten with rip by the syscall
>>> instruction
>>> -       .cfi_undefined r11 # was overwritten with rflags by the syscall
>>> instruction
>>> -    .cfi_offset %r15, 0x00
>>> -    .cfi_offset %r14, 0x08
>>> -    .cfi_offset %r13, 0x10
>>> -    .cfi_offset %r12, 0x18
>>> -    .cfi_offset %r11, 0x20
>>> -    .cfi_offset %r10, 0x28
>>> -    .cfi_offset %r9, 0x30
>>> -    .cfi_offset %r8, 0x38
>>> -    .cfi_offset %rbp, 0x40
>>> -    .cfi_offset %rdi, 0x48
>>> -    .cfi_offset %rsi, 0x50
>>> -    .cfi_offset %rdx, 0x58
>>> -    .cfi_offset %rcx, 0x60
>>> -    .cfi_offset %rbx, 0x68
>>> -    .cfi_offset %rax, 0x70
>>> -    .cfi_offset %rip, 0x80
>>> -    .cfi_offset %rsp, 0x98
>>> +    pushq_cfi %rax
>>> +    pushq_cfi %rbx
>>> +    pushq_cfi %rdx
>>> +    pushq_cfi %rsi
>>> +    pushq_cfi %rdi
>>> +    pushq_cfi %r8
>>> +    pushq_cfi %r9
>>> +    pushq_cfi %r10
>>> +    pushq_cfi %r11 # contains rflags before syscall instruction
>>> +    .cfi_rel_offset %rflags, 0
>>> +    pushq_cfi %r12
>>> +    pushq_cfi %r13
>>> +    pushq_cfi %r14
>>> +    pushq_cfi %r15
>>>         # The kernel interface use r10 as fourth argument while the user
>>> interface use rcx
>>>       # so overwrite rcx with r10
>>> @@ -231,7 +208,7 @@ syscall_entry:
>>>         # prepare function call parameter: r9 is on the stack since it's
>>> the seventh param
>>>       # because we shift existing params by one to make room for syscall
>>> number
>>> -    pushq %r9
>>> +    pushq_cfi %r9
>>>       movq %r8, %r9
>>>       movq %rcx, %r8
>>>       movq %rdx, %rcx
>>> @@ -254,34 +231,33 @@ syscall_entry:
>>>       # restore it from 8(%rsp).
>>>       pushq %rsp
>>>       pushq (%rsp)
>>> +    .cfi_adjust_cfa_offset 16
>>>       andq $-0x10, %rsp
>>> +    .cfi_rel_offset %rsp, 8
>>>         callq syscall_wrapper
>>>         movq 8(%rsp), %rsp
>>> +    .cfi_adjust_cfa_offset -16
>>>   -    popq %r9
>>> +    popq_cfi %r9
>>>       # in Linux user and kernel return value are in rax so we have
>>> nothing to do for return values
>>>   -    popq %r15
>>> -    popq %r14
>>> -    popq %r13
>>> -    popq %r12
>>> -    popq %r11
>>> -    popq %r10
>>> -    popq %r9
>>> -    popq %r8
>>> -    popq %rdi
>>> -    popq %rsi
>>> -    popq %rdx
>>> -    popq %rcx
>>> -    popq %rbx
>>> -    addq $8, %rsp  # skip rax emplacement (return value is in rax)
>>> -    addq $8, %rsp  # rip emplacement (rip cannot be popped)
>>> -    popq %rsp
>>> +    popq_cfi %r15
>>> +    popq_cfi %r14
>>> +    popq_cfi %r13
>>> +    popq_cfi %r12
>>> +    popq_cfi %r11
>>> +    popq_cfi %r10
>>> +    popq_cfi %r9
>>> +    popq_cfi %r8
>>> +    popq_cfi %rdi
>>> +    popq_cfi %rsi
>>> +    popq_cfi %rdx
>>> +    popq_cfi %rbx
>>>   -    popq %rbp
>>> -    popq %rcx
>>> +    popq_cfi %rbp
>>> +    popq_cfi %rcx
>>>         addq $128, %rsp    # undo red-zone skip
>>>
>>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "OSv Development" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to