On 08/29/2016 08:10 PM, Benoît Canet wrote:
On Mon, Aug 29, 2016 at 7:08 PM, Avi Kivity <[email protected] <mailto:[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] <mailto:[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.
He does, but when you debug between this point and the push, you will have a broken stack trace.
+ .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 <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 GoogleGroups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected] <mailto:osv-dev%[email protected]>. For more options, visit https://groups.google.com/d/optout <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.
