summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-07-11 22:59:43 -0400
committerRich Felker <dalias@aerifal.cx>2012-07-11 22:59:43 -0400
commitb58f738bcb5877c83aef49129b40827a1d5ae4c7 (patch)
treecc439c14a5bf7b0c3d61920fd1d4a536c323a4cc /src/thread
parent2b3cc04a8d383a56a7031e98a7e4da36958d943a (diff)
downloadmusl-b58f738bcb5877c83aef49129b40827a1d5ae4c7.tar.gz
musl-b58f738bcb5877c83aef49129b40827a1d5ae4c7.tar.bz2
musl-b58f738bcb5877c83aef49129b40827a1d5ae4c7.tar.xz
musl-b58f738bcb5877c83aef49129b40827a1d5ae4c7.zip
fix mips clone() on real linux kernel
the old code worked in qemu app-level emulation, but not on real kernels where the clone syscall does not copy the register values to the new thread. save arguments on the new thread stack instead.
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/mips/clone.s11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/thread/mips/clone.s b/src/thread/mips/clone.s
index a7c2d907..fab90dc3 100644
--- a/src/thread/mips/clone.s
+++ b/src/thread/mips/clone.s
@@ -2,9 +2,10 @@
.global __clone
.type __clone,@function
__clone:
- # Save function pointer and argument pointer
- move $25, $4
- move $8, $7
+ # Save function pointer and argument pointer on new thread stack
+ subu $5, $5, 16
+ sw $4, 0($5)
+ sw $7, 4($5)
# Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
move $4, $6
lw $6, 16($sp)
@@ -21,6 +22,8 @@ __clone:
nop
jr $ra
nop
-1: move $4, $8
+1: lw $25, 0($sp)
+ lw $4, 4($sp)
jr $25
+ addu $sp, $sp, 16
nop