Implements emit_unwind() and other related emitters and provides
unwind_64.S for x86-64.

Signed-off-by: Eduard - Gabriel Munteanu <eduard.munte...@linux360.ro>
---
 arch/x86/Makefile_64 |    3 ++-
 arch/x86/emit-code.c |   27 ++++++++++++++-------------
 arch/x86/unwind_64.S |   41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+), 14 deletions(-)
 create mode 100644 arch/x86/unwind_64.S

diff --git a/arch/x86/Makefile_64 b/arch/x86/Makefile_64
index 94ef588..44723de 100644
--- a/arch/x86/Makefile_64
+++ b/arch/x86/Makefile_64
@@ -11,4 +11,5 @@ ARCH_OBJS = \
        arch/x86/registers_64.o         \
        arch/x86/signal.o               \
        arch/x86/stack-frame.o          \
-       arch/x86/use-def.o
+       arch/x86/use-def.o              \
+       arch/x86/unwind_64.o
diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index 4e2745c..a93eac2 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -340,6 +340,20 @@ void emit_epilog(struct buffer *buf)
        emit_ret(buf);
 }
 
+static void __emit_jmp(struct buffer *buf, unsigned long addr)
+{
+       unsigned long current = (unsigned long)buffer_current(buf);
+       emit(buf, 0xE9);
+       emit_imm32(buf, addr - current - BRANCH_INSN_SIZE);
+}
+
+void emit_unwind(struct buffer *buf)
+{
+       emit_leave(buf);
+       emit_restore_regs(buf);
+       __emit_jmp(buf, (unsigned long)&unwind);
+}
+
 #ifdef CONFIG_X86_32
 
 /************************
@@ -737,19 +751,6 @@ static void emit_restore_regs(struct buffer *buf)
        __emit_pop_reg(buf, REG_EDI);
 }
 
-static void __emit_jmp(struct buffer *buf, unsigned long addr)
-{
-       unsigned long current = (unsigned long)buffer_current(buf);
-       emit(buf, 0xE9);
-       emit_imm32(buf, addr - current - BRANCH_INSN_SIZE);
-}
-
-void emit_unwind(struct buffer *buf)
-{
-       __emit_epilog(buf);
-       __emit_jmp(buf, (unsigned long)&unwind);
-}
-
 static void emit_adc_reg_reg(struct buffer *buf,
                              struct operand *src, struct operand *dest)
 {
diff --git a/arch/x86/unwind_64.S b/arch/x86/unwind_64.S
new file mode 100644
index 0000000..da2c521
--- /dev/null
+++ b/arch/x86/unwind_64.S
@@ -0,0 +1,41 @@
+.global unwind
+.text
+
+/*
+ * unwind - Performs the following:
+ *          1) Resets the stack pointer to point at the end of
+ *             caller's stack frame
+ *          2) Rethrows the exception in caller's context
+ */
+unwind:
+       popq    %rdx    # return address of the method
+       decq    %rdx
+
+       /*
+        * Lookup pointer to compilation unit.
+        */
+       push    %rdx
+       call    get_cu_from_native_addr
+       movq    %rax, %rcx
+       pop     %rdx
+
+       /*
+        * Restore stack pointer. We need to restore space for locals too.
+        */
+       push    %rdx
+       push    %rcx
+       call    cu_frame_locals_offset
+       pop     %rcx
+       pop     %rdx
+
+       movq    %rbp, %rsp
+       subq    %rax, %rsp
+
+       pushq   %rdx    # native ptr
+       pushq   %rbp    # frame
+       pushq   %rcx    # cu
+       call    throw_exception_from
+       addq    $24, %rsp
+
+       pushq %rax
+       ret
-- 
1.6.0.6


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to