Libasan failed to be build for ARM with -mthumb and -fno-omit-frame-pointer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello everyone,
I have a question about the build of ASan's runtime for arm with -mthumb 
and fno-omit-frame-pointer.

So, by default libasan has "-fomit-frame-pointer" option.
The problem occurs when "-fno-omit-frame-pointer" option is adding 
alongside with "-mthumb", the build is failing with error:

../../../../libsanitizer/sanitizer_common/sanitizer_linux.cc: In 
function '__sanitizer::uptr __sanitizer::internal_clone(int (*)(void*), 
void*, int, void*, int*, void*, int*)':
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cc:1134:1: 
error: r7 cannot be used in asm here
  }

And the problem is inside internal_clone function,
I've added reduced test case:

$cat clone.cc

#define __NR_clone 120
#define __NR_exit 1

using uptr = unsigned int;
unsigned int EINVAL = 1;
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, 
void *arg,
                     int *parent_tidptr, void *newtls, int *child_tidptr) {
   unsigned int res;
   if (!fn || !child_stack)
     return -EINVAL;
   child_stack = (char *)child_stack - 2 * sizeof(unsigned int);
   ((unsigned int *)child_stack)[0] = (uptr)fn;
   ((unsigned int *)child_stack)[1] = (uptr)arg;
   register int r0 __asm__("r0") = flags;
   register void *r1 __asm__("r1") = child_stack;
   register int *r2 __asm__("r2") = parent_tidptr;
   register void *r3 __asm__("r3") = newtls;
   register int *r4 __asm__("r4") = child_tidptr;
   register int r7 __asm__("r7") = __NR_clone;

#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
# define ARCH_HAS_BX
#endif
#if __ARM_ARCH > 4
# define ARCH_HAS_BLX
#endif

#ifdef ARCH_HAS_BX
# ifdef ARCH_HAS_BLX
#  define BLX(R) "blx "  #R "\n"
# else
#  define BLX(R) "mov lr, pc; bx " #R "\n"
# endif
#else
# define BLX(R)  "mov lr, pc; mov pc," #R "\n"
#endif

   __asm__ __volatile__(
                        /* %r0 = syscall(%r7 = SYSCALL(clone),
                         *               %r0 = flags,
                         *               %r1 = child_stack,
                         *               %r2 = parent_tidptr,
                         *               %r3  = new_tls,
                         *               %r4 = child_tidptr)
                         */

                        /* Do the system call */
                        "swi 0x0\n"

                        /* if (%r0 != 0)
                         *   return %r0;
                         */
                        "cmp r0, #0\n"
                        "bne 1f\n"

                        /* In the child, now. Call "fn(arg)". */
                        "ldr r0, [sp, #4]\n"
                        "ldr ip, [sp], #8\n"
                        BLX(ip)
                        /* Call _exit(%r0). */
                        "mov r7, %7\n"
                        "swi 0x0\n"
                        "1:\n"
                        "mov %0, r0\n"
                        : "=r"(res)
                        : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), 
"r"(r7),
                          "i"(__NR_exit)
                        : "memory");
   return res;
}

$armv7l-linux-gnueabi-g++ -o clone.s clone.cc -fno-omit-frame-pointer 
-mthumb -S
clone.cc: In function ‘uptr internal_clone(int (*)(void*), void*, int, 
void*, int*, void*, int*)’:
clone.cc:70:1: error: r7 cannot be used in asm here

As far as I understood, r7 register is using for syscall number, r0 for 
return value, and r1 - r6 for syscall arguments, by the way r7 for arm 
with THUMB2 mode is using as frame pointer and it looks like we have a 
conflict in this case.

So, the question is should it be considered as a bug or not, because, 
probably, no one needs libasan with "-mthumb" and 
"-fno-omit-frame-pointer", and by default it works well with 
"-fomit-frame-pointer" ?



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux