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.
