[PATCH] D12841: [LLVMdev] Compiler-RT - Enabling ThreadSanitizer on PPC64(BE/LE) platforms

Adhemerval Zanella via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 12:41:08 PDT 2015


zatrazz added inline comments.

================
Comment at: lib/sanitizer_common/sanitizer_linux.cc:989
@@ +988,3 @@
+
+  res = clone(fn, child_stack, flags, arg, parent_tidptr, newtls, child_tidptr);
+
----------------
Here is a working clone implementation for powerpc64 if you want to incorporate in your patch.

```
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
                    int *parent_tidptr, void *newtls, int *child_tidptr) {
  long long res;
/* Stack frame offsets.  */
#if _CALL_ELF != 2
#define FRAME_MIN_SIZE         112
#define FRAME_TOC_SAVE         40
#else
#define FRAME_MIN_SIZE         32
#define FRAME_TOC_SAVE         24
#endif
  if (!fn || !child_stack)
    return -EINVAL;
  CHECK_EQ(0, (uptr)child_stack % 16);
  child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
  ((unsigned long long *)child_stack)[0] = (uptr)fn;
  ((unsigned long long *)child_stack)[1] = (uptr)arg;

  register int (*__fn)(void *) __asm__("r3") = fn;
  register void *__cstack      __asm__("r4") = child_stack;
  register int __flags         __asm__("r5") = flags;
  register void * __arg        __asm__("r6") = arg;
  register int * __ptidptr     __asm__("r7") = parent_tidptr;
  register void * __newtls     __asm__("r8") = newtls;
  register int * __ctidptr     __asm__("r9") = child_tidptr;

  __asm__ __volatile__(
            /* fn, arg, child_stack are saved acrVoss the syscall */
            "mr 28, %5\n\t"
            "mr 29, %6\n\t"
            "mr 27, %8\n\t"

            /* syscall
              r3 == flags
              r4 == child_stack
              r5 == parent_tidptr
              r6 == newtls
              r7 == child_tidptr */
            "mr 3, %7\n\t"
            "mr 5, %9\n\t"
            "mr 6, %10\n\t"
            "mr 7, %11\n\t"
            "li 0, %3\n\t"
            "sc\n\t"

            /* Test if syscall was successful */
            "cmpdi  cr1, 3, 0\n\t"
            "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t"
            "bne-   cr1, 1f\n\t"

            /* Do the function call */
            "std   2, %13(1)\n\t"
#if _CALL_ELF != 2
            "ld    0, 0(28)\n\t"
            "ld    2, 8(28)\n\t"
            "mtctr 0\n\t"
#else
            "mr    12, 28\n\t"
            "mtctr 12\n\t"
#endif
            "mr    3, 27\n\t"
            "bctrl\n\t"
            "ld    2, %13(1)\n\t"

            /* Call _exit(r3) */
            "li 0, %4\n\t"
            "sc\n\t"

            /* Return to parent */
            "1:\n\t"
            "mr %0, 3\n\t"
              : "=r" (res)
              : "0" (-1), "i" (EINVAL),
                "i" (__NR_clone), "i" (__NR_exit),
                "r" (__fn), "r" (__cstack), "r" (__flags),
                "r" (__arg), "r" (__ptidptr), "r" (__newtls),
                "r" (__ctidptr), "i" (FRAME_MIN_SIZE), "i" (FRAME_TOC_SAVE)
              : "cr0", "cr1", "memory", "ctr",
                "r0", "r29", "r27", "r28");
  return res;
}

```

Checked on powerpc64le, no regressions found.


http://reviews.llvm.org/D12841





More information about the llvm-commits mailing list