The CFI code in syscall_entry still was not perfect (sorry...) - when
the application uses -fomit-frame-pointer, and %rbp was not set by the
caller, we didn't tell CFI how to restore the caller's %rsp. We need to
do this, with some more trickery :-(

Backtracing a crash in a system call in gdb should now be possible
(I hope) in cases which failed previously.

Signed-off-by: Nadav Har'El <[email protected]>
---
 arch/x64/entry.S | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/arch/x64/entry.S b/arch/x64/entry.S
index 8fdc5a0..dda7358 100644
--- a/arch/x64/entry.S
+++ b/arch/x64/entry.S
@@ -199,9 +199,21 @@ syscall_entry:
     pushq_cfi %rcx
     .cfi_rel_offset %rip, 0
     pushq_cfi %rbp
-    movq %rsp, %rbp
+
+    # Push on the stack the caller's %rsp, before any of our modifications.
+    # We do this just so we can refer to it with CFI and help gdb's DWARF
+    # stack unwinding. This saving not otherwise needed for correct operation
+    # (we anyway restore it below by undoing all our modifications).
+    movq 24(%rsp), %rbp
+    addq $128, %rbp
+    pushq %rbp
+    .cfi_adjust_cfa_offset 8
     .cfi_rel_offset %rsp, 0
-    #
+
+    # Set rbp (frame pointer, for old-style backtracing) to the %rsp before
+    # the above extra push
+    leaq 8(%rsp), %rbp
+
     # 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"
 
@@ -235,15 +247,11 @@ syscall_entry:
     # syscall number from rax as first argument
     movq %rax, %rdi
 
-    # Because we pushed an odd number of 8 bytes after aligning the stack
-    # we need to realign it to 16 bytes:
-    subq $8, %rsp
-    .cfi_adjust_cfa_offset 8
+    # Because we pushed an even number of 8 bytes after aligning the stack,
+    # it is still 16-byte aligned and we don't need to adjust it here.
 
     callq syscall_wrapper
 
-    addq $8, %rsp
-    .cfi_adjust_cfa_offset -8
     popq_cfi %r9
     # in Linux user and kernel return value are in rax so we have nothing to 
do for return values
 
@@ -260,6 +268,10 @@ syscall_entry:
     popq_cfi %rdx
     popq_cfi %rbx
 
+    # skip the caller's %rsp we pushed just for CFI's sake
+    addq $8, %rsp
+    .cfi_adjust_cfa_offset -8
+
     popq_cfi %rbp
     popq_cfi %rcx
 
-- 
2.7.4

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