From daecc9a410a6f23d80daf8ce3afd280fea329e63 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Thu, 18 Nov 2010 14:58:01 +0000 Subject: metag: Add NPTL support Signed-off-by: Markos Chandras Signed-off-by: Bernhard Reutner-Fischer --- libc/sysdeps/linux/metag/clone.S | 50 ++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) (limited to 'libc/sysdeps/linux/metag/clone.S') diff --git a/libc/sysdeps/linux/metag/clone.S b/libc/sysdeps/linux/metag/clone.S index 8fff56710..d9d836338 100644 --- a/libc/sysdeps/linux/metag/clone.S +++ b/libc/sysdeps/linux/metag/clone.S @@ -8,7 +8,17 @@ #include #include -/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ +#define CLONE_VM 0x00000100 +#define CLONE_THREAD 0x00010000 + +#ifdef __PIC__ +#define __CLONE_METAG_LOAD_TP ___metag_load_tp@PLT +#else +#define __CLONE_METAG_LOAD_TP ___metag_load_tp +#endif + +/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, + pid_t *ptid, struct user_desc *tls, pid_t *ctid); */ .text .global __clone @@ -25,8 +35,12 @@ __clone: MOV D0FrT, D1Ar1 ! do the system call - ! get flags MOV D1Ar1, D1Ar3 + MOV D1Ar3, D1Ar5 + MOV D1Ar5, D0Ar6 + MOV D0Ar6, D0Ar4 + GETD D0Ar4, [A0StP+#-4] + ! new sp is already in D0Ar2 MOV D1Re0, #__NR_clone SWITCH #0x440001 @@ -38,14 +52,36 @@ __clone: ! BRKPNT ! We are the child - ! pick the function arg and call address off the stack and execute - MOV D0Ar2, D0FrT - MOV D1Ar1, D0Ar4 - MOV D1RtP, PC +#ifdef RESET_PID + SETL [A0StP++], D0FrT, D1RtP + MOVT D0FrT, #HI(CLONE_THREAD) + ADD D0FrT, D0FrT, #LO(CLONE_THREAD) + ANDS D0FrT, D0FrT, D1Ar1 + BNZ 3f + MOVT D0FrT, #HI(CLONE_VM) + ADD D0FrT, D0FrT, #LO(CLONE_VM) + ANDS D0FrT, D0FrT, D1Ar1 + BZ 1f + MOV D1Ar1, #-1 + BA 2f +1: MOV D1Re0, #__NR_getpid + SWITCH #0x440001 + MOV D1Ar1, D0Re0 +2: CALLR D1RtP, __CLONE_METAG_LOAD_TP + SUB D0Re0, D0Re0, #TLS_PRE_TCB_SIZE + SETD [D0Re0 + #PID], D1Ar1 + SETD [D0Re0 + #TID], D1Ar1 +3: GETL D0FrT, D1RtP, [--A0StP] +#endif + ! Rearrange the function arg and call address from registers + MOV D0Ar2, D0FrT + MOV D1Ar1, D0Ar6 + MOV D1RtP, PC ADD D1RtP, D1RtP, #8 MOV PC, D0Ar2 - ! and we are done, passing the return value through D0Re0 + ! and we are done, passing the return value D0Re0 through D1Ar1 + MOV D1Ar1, D0Re0 #ifdef __PIC__ B _exit@PLT #else -- cgit v1.2.3