Browse Source

LibELF: Store SSE registers in x86_64 PLT Trampoline

Save and restore XMM registers so userspace programs don't
randomly lose values from calls. This fixes a crash in ScummVM.
Peter 3 years ago
parent
commit
24fdf99d8b
1 changed files with 21 additions and 3 deletions
  1. 21 3
      Userland/Libraries/LibELF/Arch/x86_64/plt_trampoline.S

+ 21 - 3
Userland/Libraries/LibELF/Arch/x86_64/plt_trampoline.S

@@ -10,6 +10,15 @@
 .type _plt_trampoline,@function
 _plt_trampoline: # (object, relocation_index)
      # save flags/registers (https://stackoverflow.com/questions/18024672/what-registers-are-preserved-through-a-linux-x86-64-function-call)
+    subq $128, %rsp
+    movdqu %xmm0, 0x0(%rsp)
+    movdqu %xmm1, 0x10(%rsp)
+    movdqu %xmm2, 0x20(%rsp)
+    movdqu %xmm3, 0x30(%rsp)
+    movdqu %xmm4, 0x40(%rsp)
+    movdqu %xmm5, 0x50(%rsp)
+    movdqu %xmm6, 0x60(%rsp)
+    movdqu %xmm7, 0x70(%rsp)
     pushfq
     pushq %rax
     pushq %rcx
@@ -21,8 +30,8 @@ _plt_trampoline: # (object, relocation_index)
     pushq %r10
     pushq %r11
 
-    movq 80(%rsp), %rdi # object
-    movq 88(%rsp), %rsi # relocation_index
+    movq 208(%rsp), %rdi # object
+    movq 216(%rsp), %rsi # relocation_index
 
     # offset = index * sizeof(Elf64_Rela)
     shlq $3, %rsi
@@ -35,7 +44,7 @@ _plt_trampoline: # (object, relocation_index)
     movq %rbp, %rsp
     popq %rbp
 
-    movq %rax, 88(%rsp) # replace object argument with symbol address
+    movq %rax, 216(%rsp) # replace object argument with symbol address
 
      # restore flags/registers
     popq %r11
@@ -49,6 +58,15 @@ _plt_trampoline: # (object, relocation_index)
     popq %rax
     popfq
 
+    movdqu 0x0(%rsp), %xmm0
+    movdqu 0x10(%rsp), %xmm1
+    movdqu 0x20(%rsp), %xmm2
+    movdqu 0x30(%rsp), %xmm3
+    movdqu 0x40(%rsp), %xmm4
+    movdqu 0x50(%rsp), %xmm5
+    movdqu 0x60(%rsp), %xmm6
+    movdqu 0x70(%rsp), %xmm7
+    addq $128, %rsp
     addq $8, %rsp # remove relocation_index argument
 
     retq