[sanitizer] Fix vfork interceptor on i386 w/ dynamic runtime. PLT calls on i386 expect GOT base address in %ebx. This call does not need to go through PLT strictly speaking, but I'd rather avoid future surprises and implement the most general case. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@355125 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S b/lib/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S index d693aa3..ed69381 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S +++ b/lib/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S
@@ -20,15 +20,28 @@ add $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax call *_ZN14__interception10real_vforkE@GOTOFF(%eax) - // Restore return address from the spill area. + // Restore the stack frame. + // 12(%esp) return address + // 8(%esp) spill %ebx + // 4(%esp) spill REAL(vfork) return value + // (%esp) call frame (arg0) for __*_handle_vfork sub $16, %esp + mov %ebx, 8(%esp) mov %eax, 4(%esp) + + // Form GOT address in %ebx. + call .L1$pb +.L1$pb: + pop %ebx +.Ltmp1: + add $_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb), %ebx + + // Restore original return address. call COMMON_INTERCEPTOR_SPILL_AREA mov (%eax), %ecx mov %ecx, 12(%esp) mov 4(%esp), %eax - // Call handle_vfork in the parent process (%rax != 0). test %eax, %eax je .L_exit @@ -39,6 +52,7 @@ .L_exit: mov 4(%esp), %eax + mov 8(%esp), %ebx add $12, %esp ret ASM_SIZE(vfork)