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.
