Skip to content

Commit

Permalink
i#4301: Fix x86-32 Linux stack alignment on exit and try..except (#4302)
Browse files Browse the repository at this point in the history
The recent switch to use 16-byte alignment in aa941e6 #3966 (PR #4265) missed
the assembly code on exit and for try..except for calls to dynamo_process_exit() and dr_setjmp_sigmask().  The stack is adjusted for both here.

A check for exit alignment is added to the cleancall test.

Fixes #4301
  • Loading branch information
SweetVishnya authored May 20, 2020
1 parent 35fd4f8 commit 96dc1d1
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
14 changes: 7 additions & 7 deletions core/arch/x86/x86.asm
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ GLOBAL_LABEL(cleanup_and_terminate:)
mov [4*ARG_SZ + REG_XBP], ARG4
#else
mov REG_XBP, REG_XSP
# if defined(MACOS) && !defined(X64)
# ifdef UNIX
lea REG_XSP, [-3*ARG_SZ + REG_XSP] /* maintain align-16: offset retaddr */
# endif
#endif
Expand Down Expand Up @@ -602,7 +602,7 @@ cat_done_saving_dstack:
/* avoid sygate sysenter version as our stack may be static const at
* that point, caller will take care of sygate hack */
CALLC0(GLOBAL_REF(get_cleanup_and_terminate_global_do_syscall_entry))
#if defined(MACOS) && !defined(X64)
#if defined(UNIX) && !defined(X64)
lea REG_XSP, [-2*ARG_SZ + REG_XSP] /* maintain align-16 w/ 2 pushes below */
#endif
push REG_XBX /* 16-byte aligned again */
Expand Down Expand Up @@ -649,7 +649,7 @@ cat_have_lock:
mov REG_XSI, [2*ARG_SZ + REG_XBP] /* sysnum */
pop REG_XAX /* syscall */
pop REG_XCX /* dstack */
#if defined(MACOS) && !defined(X64)
#if defined(UNIX) && !defined(X64)
lea REG_XSP, [2*ARG_SZ + REG_XSP] /* undo align-16 lea from above */
#endif
mov REG_XBX, REG_XBP /* save for arg access after swapping stacks */
Expand Down Expand Up @@ -680,12 +680,12 @@ cat_no_thread2:
push PTRSZ [3*ARG_SZ + REG_XBX] /* sys_arg1 */
push REG_XAX /* syscall */
push REG_XSI /* sysnum => xsp 16-byte aligned for x64 and x86 */
#if defined(MACOS) && !defined(X64)
#if defined(UNIX) && !defined(X64)
lea REG_XSP, [-2*ARG_SZ + REG_XSP] /* align to 16 for this call */
#endif
/* free dstack and call the EXIT_DR_HOOK */
CALLC1(GLOBAL_REF(dynamo_thread_stack_free_and_exit), REG_XCX) /* pass dstack */
#if defined(MACOS) && !defined(X64)
#if defined(UNIX) && !defined(X64)
lea REG_XSP, [2*ARG_SZ + REG_XSP] /* undo align to 16 */
#endif
/* finally, execute the termination syscall */
Expand Down Expand Up @@ -1791,11 +1791,11 @@ GLOBAL_LABEL(dr_setjmp:)
/* PR 206278: for try/except we need to save the signal mask */
mov REG_XDX, ARG1
push REG_XDX /* preserve */
# if defined(MACOS) && !defined(X64)
# ifndef X64
lea REG_XSP, [-2*ARG_SZ + REG_XSP] /* maintain align-16: ra + push */
# endif
CALLC1(GLOBAL_REF(dr_setjmp_sigmask), REG_XDX)
# if defined(MACOS) && !defined(X64)
# ifndef X64
lea REG_XSP, [2*ARG_SZ + REG_XSP] /* maintain align-16: ra + push */
# endif
pop REG_XDX /* preserve */
Expand Down
7 changes: 7 additions & 0 deletions suite/tests/client-interface/cleancall.dll.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,11 +596,18 @@ thread_start(void *drcontext)
dr_set_tls_field(drcontext, dr_thread_alloc(drcontext, 3 * sizeof(reg_t)));
}

static void
app_exit_event(void)
{
check_stack_alignment();
}

DR_EXPORT void
dr_init(client_id_t id)
{
dr_register_bb_event(bb_event);
dr_register_thread_init_event(thread_start);
dr_register_thread_exit_event(thread_exit);
dr_register_restore_state_event(restore_state_event);
dr_register_exit_event(app_exit_event);
}

0 comments on commit 96dc1d1

Please sign in to comment.