am 5cf1f229
: Merge "pthread_exit should call __NR_exit with status 0."
* commit '5cf1f229620d02c0ca266c9e03418fdeefd85191': pthread_exit should call __NR_exit with status 0.
This commit is contained in:
commit
58b8f22566
6 changed files with 20 additions and 24 deletions
|
@ -29,7 +29,7 @@
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
|
||||||
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode)
|
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int status)
|
||||||
ENTRY(_exit_with_stack_teardown)
|
ENTRY(_exit_with_stack_teardown)
|
||||||
mov lr, r2
|
mov lr, r2
|
||||||
ldr r7, =__NR_munmap
|
ldr r7, =__NR_munmap
|
||||||
|
|
|
@ -30,14 +30,14 @@
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
/* void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode) */
|
// void _exit_with_stack_teardown(void * stackBase, int stackSize, int status)
|
||||||
|
|
||||||
.type _exit_with_stack_teardown, @function
|
.type _exit_with_stack_teardown, @function
|
||||||
.global _exit_with_stack_teardown
|
.global _exit_with_stack_teardown
|
||||||
.align 4
|
.align 4
|
||||||
.ent _exit_with_stack_teardown
|
.ent _exit_with_stack_teardown
|
||||||
_exit_with_stack_teardown:
|
_exit_with_stack_teardown:
|
||||||
move $s0,$a2 /* preserve retCode for exit() call */
|
move $s0,$a2 /* preserve status for exit() call */
|
||||||
|
|
||||||
li $v0,__NR_munmap
|
li $v0,__NR_munmap
|
||||||
syscall /* the stack is destroyed by this call */
|
syscall /* the stack is destroyed by this call */
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
|
|
||||||
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode)
|
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int status)
|
||||||
ENTRY(_exit_with_stack_teardown)
|
ENTRY(_exit_with_stack_teardown)
|
||||||
// We can trash %ebx here since this call should never return.
|
// We can trash %ebx here since this call should never return.
|
||||||
// We can also take advantage of the fact that the linux syscall trap
|
// We can also take advantage of the fact that the linux syscall trap
|
||||||
// handler saves all the registers, so we don't need a stack to keep
|
// handler saves all the registers, so we don't need a stack to keep
|
||||||
// the retCode argument for exit while doing the munmap */
|
// the status argument for exit while doing the munmap */
|
||||||
mov 4(%esp), %ebx // stackBase
|
mov 4(%esp), %ebx // stackBase
|
||||||
mov 8(%esp), %ecx // stackSize
|
mov 8(%esp), %ecx // stackSize
|
||||||
mov $__NR_munmap, %eax
|
mov $__NR_munmap, %eax
|
||||||
|
@ -14,7 +14,7 @@ ENTRY(_exit_with_stack_teardown)
|
||||||
|
|
||||||
// If munmap failed, we ignore the failure and exit anyway.
|
// If munmap failed, we ignore the failure and exit anyway.
|
||||||
|
|
||||||
mov %edx, %ebx // retCode
|
mov %edx, %ebx // status
|
||||||
movl $__NR_exit, %eax
|
movl $__NR_exit, %eax
|
||||||
int $0x80
|
int $0x80
|
||||||
|
|
||||||
|
|
|
@ -29,17 +29,17 @@
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
#include <machine/asm.h>
|
#include <machine/asm.h>
|
||||||
|
|
||||||
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode)
|
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int status)
|
||||||
ENTRY(_exit_with_stack_teardown)
|
ENTRY(_exit_with_stack_teardown)
|
||||||
// We take advantage of the fact that the linux syscall trap
|
// We take advantage of the fact that the linux syscall trap
|
||||||
// handler saves all the registers, so we don't need to save
|
// handler saves all the registers, so we don't need to save
|
||||||
// the retCode argument for exit(2) while doing the munmap(2).
|
// the status argument for exit(2) while doing the munmap(2).
|
||||||
mov $__NR_munmap, %eax
|
mov $__NR_munmap, %eax
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
// If munmap failed, ignore the failure and exit anyway.
|
// If munmap failed, ignore the failure and exit anyway.
|
||||||
|
|
||||||
mov %rdx, %rdi // retCode
|
mov %rdx, %rdi // status
|
||||||
mov $__NR_exit, %eax
|
mov $__NR_exit, %eax
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
|
|
|
@ -39,21 +39,17 @@ extern int __bionic_clone(unsigned long clone_flags,
|
||||||
int (*fn)(void *),
|
int (*fn)(void *),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
extern void _exit_thread(int retCode);
|
extern void _exit_thread(int status);
|
||||||
|
|
||||||
/* this function is called from the __bionic_clone
|
/* this function is called from the __bionic_clone
|
||||||
* assembly fragment to call the thread function
|
* assembly fragment to call the thread function
|
||||||
* then exit. */
|
* then exit. */
|
||||||
extern void
|
extern void __bionic_clone_entry(int (*fn)(void*), void* arg) {
|
||||||
__bionic_clone_entry( int (*fn)(void *), void *arg )
|
int status = (*fn)(arg);
|
||||||
{
|
_exit_thread(status);
|
||||||
int ret = (*fn)(arg);
|
|
||||||
_exit_thread(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) {
|
||||||
clone(int (*fn)(void *), void *child_stack, int flags, void* arg, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
va_list args;
|
||||||
int *parent_tidptr = NULL;
|
int *parent_tidptr = NULL;
|
||||||
void *new_tls = NULL;
|
void *new_tls = NULL;
|
||||||
|
|
|
@ -44,8 +44,8 @@
|
||||||
extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex);
|
extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex);
|
||||||
extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex);
|
extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex);
|
||||||
|
|
||||||
extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode);
|
extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int status);
|
||||||
extern void _exit_thread(int retCode);
|
extern void _exit_thread(int status);
|
||||||
|
|
||||||
int __futex_wake_ex(volatile void *ftx, int pshared, int val)
|
int __futex_wake_ex(volatile void *ftx, int pshared, int val)
|
||||||
{
|
{
|
||||||
|
@ -143,15 +143,15 @@ void pthread_exit(void * retval)
|
||||||
|
|
||||||
sigfillset(&mask);
|
sigfillset(&mask);
|
||||||
sigdelset(&mask, SIGSEGV);
|
sigdelset(&mask, SIGSEGV);
|
||||||
(void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
|
sigprocmask(SIG_SETMASK, &mask, NULL);
|
||||||
|
|
||||||
// destroy the thread stack
|
|
||||||
if (user_stack) {
|
if (user_stack) {
|
||||||
_exit_thread((int)retval);
|
// Cleaning up this thread's stack is the creator's responsibility, not ours.
|
||||||
|
_exit_thread(0);
|
||||||
} else {
|
} else {
|
||||||
// We need to munmap the stack we're running on before calling exit.
|
// We need to munmap the stack we're running on before calling exit.
|
||||||
// That's not something we can do in C.
|
// That's not something we can do in C.
|
||||||
_exit_with_stack_teardown(stack_base, stack_size, (int)retval);
|
_exit_with_stack_teardown(stack_base, stack_size, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue