Message ID | 540963F9.8020204@huawei.com |
---|---|
State | New |
Headers | show |
Hi Wang, I have tested your patch for arm/armhf and NPTL. Works fine. The getpid tests didn't fail anymore. But when I am trying to compile linuxthreads instead of NPTL I get: /adk/uclibc-arm-static/toolchain_qemu-arm_uclibc_arm_eabi/usr/bin/arm-openadk-linux-uclibceabi-gcc -c libc/sysdeps/linux/arm/syscall-eabi.S -o libc/sysdeps/linux/arm/syscall-eabi.os -Wall -Wstrict-prototypes -Wstrict-aliasing -funsigned-char -fno-builtin -fno-asm -msoft-float -mlittle-endian -fno-stack-protector -nostdinc -I./include -I./include -include libc-symbols.h -I./libc/sysdeps/linux/arm -I./libc/sysdeps/linux -I./ldso/ldso/arm -I./ldso/include -I. -Os -funit-at-a-time -fmerge-all-constants -fstrict-aliasing -fno-tree-loop-optimize -fno-tree-dominator-opts -fno-strength-reduce -march=armv7-a -mtune=cortex-a9 -mfloat-abi=soft -fwrapv -fno-ident -fhonour-copts -Os -pipe -g3 -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -marm -I./libpthread/linuxthreads/sysdeps/unix/sysv/linux/arm -I./libpthread/linuxthreads/sysdeps/arm -I./libpthread/linuxthreads/sysdeps/unix/sysv/linux -I./libpthread/linuxthreads/sysdeps/pthread -I./libpthread/linuxthreads -I./libpthread -I./libc/sysdeps/linux/common -isystem /adk/uclibc-arm-static/toolchain_qemu-arm_uclibc_arm_eabi/usr/lib/gcc/arm-openadk-linux-uclibceabi/4.8.3/include-fixed -isystem /adk/uclibc-arm-static/toolchain_qemu-arm_uclibc_arm_eabi/usr/lib/gcc/arm-openadk-linux-uclibceabi/4.8.3/include -I/adk/uclibc-arm-static/target_qemu-arm_uclibc_arm_eabi/usr/include/ -DNDEBUG -fPIC -MT libc/sysdeps/linux/arm/syscall-eabi.os -MD -MP -MF libc/sysdeps/linux/arm/.syscall-eabi.os.dep -D__ASSEMBLER__ -Wa,--noexecstack ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h: Assembler messages: ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:35: Error: bad instruction `extern __inline __attribute__((__always_inline__))__attribute__((__gnu_inline__,__artificial__))long int' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:36: Error: bad instruction `testandset (int*spinlock)' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:37: Error: junk at end of line, first unrecognized character is `{' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:38: Error: bad instruction `register unsigned int movcc pc,lr' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:40: Error: bad instruction `__asm__ __volatile__("swp %0, %1, [%2]"' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:41: Error: junk at end of line, first unrecognized character is `:' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:41: Error: garbage following instruction -- `b __syscall_error(PLT))' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:42: Error: junk at end of line, first unrecognized character is `:' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:44: Error: bad instruction `return movcc pc,lr' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:45: Error: junk at end of line, first unrecognized character is `}' ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:51: Error: bad instruction `register char*stack_pointer __asm__("sp")' Makerules:366: recipe for target 'libc/sysdeps/linux/arm/clone.os' failed Any idea how to fix the bug without breaking linuxthreads? best regards Waldemar
diff --git a/libc/sysdeps/linux/arm/clone.S b/libc/sysdeps/linux/arm/clone.S index 03cd10e..29045ef 100644 --- a/libc/sysdeps/linux/arm/clone.S +++ b/libc/sysdeps/linux/arm/clone.S @@ -19,12 +19,17 @@ /* clone() is even more special than fork() as it mucks with stacks and invokes a function in the right context after its all over. */ +#include <sysdep.h> #define _ERRNO_H #include <features.h> #include <bits/errno.h> #include <sys/syscall.h> #include <bits/arm_asm.h> #include <bits/arm_bx.h> +#include <sysdep-cancel.h> + +#define CLONE_VM 0x00000100 +#define CLONE_THREAD 0x00010000 #if defined(__NR_clone) /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ @@ -87,6 +92,8 @@ __error: .pool #else __clone: +.fnstart +.cantunwind @ sanity check args cmp r0, #0 IT(te, ne) @@ -95,32 +102,58 @@ __clone: beq __error @ insert the args onto the new stack - sub r1, r1, #8 - str r3, [r1, #4] - @ save the function pointer as the 0th element - str r0, [r1] + str r3, [r1, #-4]! + str r0, [r1, #-4]! @ do the system call @ get flags mov r0, r2 +#ifdef RESET_PID + mov ip, r2 +#endif @ new sp is already in r1 - @ load remaining arguments off the stack - stmfd sp!, {r4} - ldr r2, [sp, #4] - ldr r3, [sp, #8] - ldr r4, [sp, #12] - DO_CALL (clone) - movs a1, a1 - IT(t, ne) - ldmnefd sp!, {r4} + push {r4, r7} + cfi_adjust_cfa_offset (8) + cfi_rel_offset (r4, 0) + cfi_rel_offset (r7, 4) + ldr r2, [sp, #8] + ldr r3, [sp, #12] + ldr r4, [sp, #16] + ldr r7, =SYS_ify(clone) + swi 0x0 + cfi_endproc + cmp r0, #0 + beq 1f + pop {r4, r7} blt __error - IT(t, ne) #if defined(__USE_BX__) bxne lr #else movne pc, lr #endif + cfi_startproc +.fnend +PSEUDO_END (__clone) + +1: + .fnstart + .cantunwind +#ifdef RESET_PID + tst ip, #CLONE_THREAD + bne 3f + GET_TLS (lr) + mov r1, r0 + tst ip, #CLONE_VM + ldr r7, =SYS_ify(getpid) + ite ne + movne r0, #-1 + swieq 0x0 + NEGOFF_ADJ_BASE (r1, TID_OFFSET) + str r0, NEGOFF_OFF1 (r1, TID_OFFSET) + str r0, NEGOFF_OFF2 (r1, PID_OFFSET, TID_OFFSET) +3: +#endif @ pick the function arg and call address off the stack and execute ldr r0, [sp, #4] mov lr, pc diff --git a/libc/sysdeps/linux/arm/sysdep.h b/libc/sysdeps/linux/arm/sysdep.h index 64f4040..2d0a9cc 100644 --- a/libc/sysdeps/linux/arm/sysdep.h +++ b/libc/sysdeps/linux/arm/sysdep.h @@ -213,6 +213,42 @@ __local_syscall_error: \ sees the right arguments. */ +#if __ARM_ARCH > 6 || defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6ZK__) +# define ARCH_HAS_HARD_TP +#endif + +# ifdef __thumb2__ +# define NEGOFF_ADJ_BASE(R, OFF) add R, R, $OFF +# define NEGOFF_ADJ_BASE2(D, S, OFF) add D, S, $OFF +# define NEGOFF_OFF1(R, OFF) [R] +# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $((OFFA) - (OFFB))] +# else +# define NEGOFF_ADJ_BASE(R, OFF) +# define NEGOFF_ADJ_BASE2(D, S, OFF) mov D, S +# define NEGOFF_OFF1(R, OFF) [R, $OFF] +# define NEGOFF_OFF2(R, OFFA, OFFB) [R, $OFFA] +# endif + +# ifdef ARCH_HAS_HARD_TP +/* If the cpu has cp15 available, use it. */ +# define GET_TLS(TMP) mrc p15, 0, r0, c13, c0, 3 +# else +/* At this generic level we have no tricks to pull. Call the ABI routine. */ +# define GET_TLS(TMP) \ + push { r1, r2, r3, lr }; \ + cfi_remember_state; \ + cfi_adjust_cfa_offset (16); \ + cfi_rel_offset (r1, 0); \ + cfi_rel_offset (r2, 4); \ + cfi_rel_offset (r3, 8); \ + cfi_rel_offset (lr, 12); \ + bl __aeabi_read_tp; \ + pop { r1, r2, r3, lr }; \ + cfi_restore_state +# endif /* ARCH_HAS_HARD_TP */ + + + #undef DO_CALL #if defined(__ARM_EABI__)