Index: src/nonsfi/linux/linux_sys_private.c |
diff --git a/src/nonsfi/linux/linux_sys_private.c b/src/nonsfi/linux/linux_sys_private.c |
index a7dc8673ebff81c1e4ea5be949645b82f0524685..cc2afe04918269dab192db32a50e4ac72d5c97e5 100644 |
--- a/src/nonsfi/linux/linux_sys_private.c |
+++ b/src/nonsfi/linux/linux_sys_private.c |
@@ -633,11 +633,6 @@ |
linux_syscall4(__NR_rt_sigprocmask, how, |
(uintptr_t) set, (uintptr_t) oset, |
sizeof(*set))); |
-} |
- |
-int linux_tgkill(int tgid, int tid, int sig) { |
- return errno_value_call( |
- linux_syscall3(__NR_tgkill, tgid, tid, sig)); |
} |
/* |
@@ -775,7 +770,8 @@ |
* Here we reserve 6 * 4 bytes for three purposes described below: |
* 1) At the beginning of the child process, we call fn(arg). To pass |
* the function pointer and arguments, we use |stack| for |arg|, |
- * |stack + 4| for |fn|. |
+ * |stack - 4| for |fn|. Here, we need 4-byte extra memory on top of |
+ * stack for |arg|. |
* 2) Our syscall() implementation reads six 4-byte arguments regardless |
* of its actual arguments. |
* 3) Similar to 2), our clone() implementation reads three 4-byte arguments |
@@ -787,8 +783,8 @@ |
void *stack = (void *) (((uintptr_t) child_stack - sizeof(uintptr_t) * 6) & |
kStackAlignmentMask); |
/* Put |fn| and |arg| on child process's stack. */ |
+ ((uintptr_t *) stack)[-1] = fn; |
((uintptr_t *) stack)[0] = arg; |
- ((uintptr_t *) stack)[1] = fn; |
#if defined(__i386__) |
uint32_t result; |
@@ -808,7 +804,7 @@ |
* Call fn(arg). Note that |arg| is already ready on top |
* of the stack, here. |
*/ |
- "call *4(%%esp)\n" |
+ "call *-4(%%esp)\n" |
/* Then call _exit(2) with the return value. */ |
"mov %%eax, %%ebx\n" |
"mov %[exit_sysno], %%eax\n" |
@@ -844,7 +840,7 @@ |
"mov fp, #0\n" |
/* Load |arg| to r0 register, then call |fn|. */ |
"ldr r0, [sp]\n" |
- "ldr r1, [sp, #4]\n" |
+ "ldr r1, [sp, #-4]\n" |
"blx r1\n" |
/* |
* Then, call _exit(2) with the returned value. |