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/questions/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