[sanitizer] Add hexagon support to sanitizer-common

Adds build support for hexagon linux to sanitizer common.
This commit is contained in:
Brian Cain 2021-08-17 14:38:38 -07:00
parent c64d1855b9
commit 9ea59e1cd0
10 changed files with 208 additions and 61 deletions

View File

@ -23,7 +23,8 @@ if(APPLE)
endif()
set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64}
${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9})
${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9}
${HEXAGON})
set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9})
set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64} ${RISCV32} ${RISCV64} ${VE})

View File

@ -697,7 +697,8 @@ enum ModuleArch {
kModuleArchARMV7S,
kModuleArchARMV7K,
kModuleArchARM64,
kModuleArchRISCV64
kModuleArchRISCV64,
kModuleArchHexagon
};
// Sorts and removes duplicates from the container.
@ -764,6 +765,8 @@ inline const char *ModuleArchToString(ModuleArch arch) {
return "arm64";
case kModuleArchRISCV64:
return "riscv64";
case kModuleArchHexagon:
return "hexagon";
}
CHECK(0 && "Invalid module arch");
return "";

View File

@ -177,10 +177,9 @@ typedef long pid_t;
typedef int pid_t;
#endif
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \
SANITIZER_MAC || \
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \
(SANITIZER_SOLARIS && (defined(_LP64) || _FILE_OFFSET_BITS == 64)) || \
(SANITIZER_LINUX && defined(__x86_64__))
(SANITIZER_LINUX && (defined(__x86_64__) || defined(__hexagon__)))
typedef u64 OFF_T;
#else
typedef uptr OFF_T;

View File

@ -158,9 +158,11 @@ namespace __sanitizer {
#include "sanitizer_syscall_linux_aarch64.inc"
#elif SANITIZER_LINUX && defined(__arm__)
#include "sanitizer_syscall_linux_arm.inc"
#else
#include "sanitizer_syscall_generic.inc"
#endif
# elif SANITIZER_LINUX && defined(__hexagon__)
# include "sanitizer_syscall_linux_hexagon.inc"
# else
# include "sanitizer_syscall_generic.inc"
# endif
// --------------- sanitizer_libc.h
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
@ -2097,9 +2099,14 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*pc = ucontext->uc_mcontext.__gregs[REG_PC];
*bp = ucontext->uc_mcontext.__gregs[REG_S0];
*sp = ucontext->uc_mcontext.__gregs[REG_SP];
#else
# error "Unsupported arch"
#endif
# elif defined(__hexagon__)
ucontext_t *ucontext = (ucontext_t *)context;
*pc = ucontext->uc_mcontext.pc;
*bp = ucontext->uc_mcontext.r30;
*sp = ucontext->uc_mcontext.r29;
# else
# error "Unsupported arch"
# endif
}
void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); }

View File

@ -281,11 +281,12 @@
// mandated by the upstream linux community for all new ports. Other ports
// may still use legacy syscalls.
#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
# if (defined(__aarch64__) || defined(__riscv)) && SANITIZER_LINUX
# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
# else
# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
# endif
# if (defined(__aarch64__) || defined(__riscv) || defined(__hexagon__)) && \
SANITIZER_LINUX
# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
# else
# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
# endif
#endif
// udi16 syscalls can only be used when the following conditions are

View File

@ -28,32 +28,32 @@
// are not defined anywhere in userspace headers. Fake them. This seems to work
// fine with newer headers, too.
#include <linux/posix_types.h>
#if defined(__x86_64__) || defined(__mips__)
#include <sys/stat.h>
#else
#define ino_t __kernel_ino_t
#define mode_t __kernel_mode_t
#define nlink_t __kernel_nlink_t
#define uid_t __kernel_uid_t
#define gid_t __kernel_gid_t
#define off_t __kernel_off_t
#define time_t __kernel_time_t
# if defined(__x86_64__) || defined(__mips__) || defined(__hexagon__)
# include <sys/stat.h>
# else
# define ino_t __kernel_ino_t
# define mode_t __kernel_mode_t
# define nlink_t __kernel_nlink_t
# define uid_t __kernel_uid_t
# define gid_t __kernel_gid_t
# define off_t __kernel_off_t
# define time_t __kernel_time_t
// This header seems to contain the definitions of _kernel_ stat* structs.
#include <asm/stat.h>
#undef ino_t
#undef mode_t
#undef nlink_t
#undef uid_t
#undef gid_t
#undef off_t
#endif
# include <asm/stat.h>
# undef ino_t
# undef mode_t
# undef nlink_t
# undef uid_t
# undef gid_t
# undef off_t
# endif
#include <linux/aio_abi.h>
# include <linux/aio_abi.h>
#if !SANITIZER_ANDROID
#include <sys/statfs.h>
#include <linux/perf_event.h>
#endif
# if !SANITIZER_ANDROID
# include <sys/statfs.h>
# include <linux/perf_event.h>
# endif
using namespace __sanitizer;
@ -63,9 +63,9 @@ namespace __sanitizer {
#endif
} // namespace __sanitizer
#if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\
&& !defined(__mips__) && !defined(__s390__)\
&& !defined(__sparc__) && !defined(__riscv)
# if !defined(__powerpc64__) && !defined(__x86_64__) && \
!defined(__aarch64__) && !defined(__mips__) && !defined(__s390__) && \
!defined(__sparc__) && !defined(__riscv) && !defined(__hexagon__)
COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat));
#endif

View File

@ -91,10 +91,10 @@
#if SANITIZER_LINUX
# include <utime.h>
# include <sys/ptrace.h>
#if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
SANITIZER_RISCV64
# include <asm/ptrace.h>
# ifdef __arm__
# if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
defined(__hexagon__) || SANITIZER_RISCV64
# include <asm/ptrace.h>
# ifdef __arm__
typedef struct user_fpregs elf_fpregset_t;
# define ARM_VFPREGS_SIZE_ASAN (32 * 8 /*fpregs*/ + 4 /*fpscr*/)
# if !defined(ARM_VFPREGS_SIZE)
@ -242,12 +242,13 @@ namespace __sanitizer {
defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) || \
defined(__x86_64__) || SANITIZER_RISCV64
#define SIZEOF_STRUCT_USTAT 32
#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \
|| defined(__powerpc__) || defined(__s390__) || defined(__sparc__)
#define SIZEOF_STRUCT_USTAT 20
#else
#error Unknown size of struct ustat
#endif
# elif defined(__arm__) || defined(__i386__) || defined(__mips__) || \
defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \
defined(__hexagon__)
# define SIZEOF_STRUCT_USTAT 20
# else
# error Unknown size of struct ustat
# endif
unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT;
unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
unsigned struct_statvfs64_sz = sizeof(struct statvfs64);

View File

@ -102,7 +102,10 @@ const unsigned struct_kernel_stat64_sz = 104;
#elif SANITIZER_RISCV64
const unsigned struct_kernel_stat_sz = 128;
const unsigned struct_kernel_stat64_sz = 0; // RISCV64 does not use stat64
#endif
# elif defined(__hexagon__)
const unsigned struct_kernel_stat_sz = 128;
const unsigned struct_kernel_stat64_sz = 0;
# endif
struct __sanitizer_perf_event_attr {
unsigned type;
unsigned size;
@ -367,7 +370,7 @@ struct __sanitizer_group {
char **gr_mem;
};
#if defined(__x86_64__) && !defined(_LP64)
# if (defined(__x86_64__) && !defined(_LP64)) || defined(__hexagon__)
typedef long long __sanitizer_time_t;
#else
typedef long __sanitizer_time_t;
@ -475,23 +478,23 @@ struct __sanitizer_dirent {
unsigned short d_reclen;
// more fields that we don't care about
};
#elif SANITIZER_ANDROID || defined(__x86_64__)
# elif SANITIZER_ANDROID || defined(__x86_64__) || defined(__hexagon__)
struct __sanitizer_dirent {
unsigned long long d_ino;
unsigned long long d_off;
unsigned short d_reclen;
// more fields that we don't care about
};
#else
# else
struct __sanitizer_dirent {
uptr d_ino;
uptr d_off;
unsigned short d_reclen;
// more fields that we don't care about
};
#endif
# endif
#if SANITIZER_LINUX && !SANITIZER_ANDROID
# if SANITIZER_LINUX && !SANITIZER_ANDROID
struct __sanitizer_dirent64 {
unsigned long long d_ino;
unsigned long long d_off;
@ -511,8 +514,8 @@ typedef int __sanitizer_clockid_t;
#endif
#if SANITIZER_LINUX
#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \
defined(__mips__)
# if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \
defined(__mips__) || defined(__hexagon__)
typedef unsigned __sanitizer___kernel_uid_t;
typedef unsigned __sanitizer___kernel_gid_t;
#else

View File

@ -22,7 +22,8 @@ namespace __sanitizer {
uptr StackTrace::GetNextInstructionPc(uptr pc) {
#if defined(__sparc__) || defined(__mips__)
return pc + 8;
#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__)
#elif defined(__powerpc__) || defined(__arm__) || defined(__aarch64__) || \
defined(__hexagon__)
return pc + 4;
#elif SANITIZER_RISCV64
// Current check order is 4 -> 2 -> 6 -> 8

View File

@ -0,0 +1,131 @@
//===-- sanitizer_syscall_linux_hexagon.inc ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implementations of internal_syscall and internal_iserror for Linux/hexagon.
//
//===----------------------------------------------------------------------===//
#define SYSCALL(name) __NR_##name
#define __internal_syscall_LL_E(x) \
((union { \
long long ll; \
long l[2]; \
}){.ll = x}) \
.l[0], \
((union { \
long long ll; \
long l[2]; \
}){.ll = x}) \
.l[1]
#define __internal_syscall_LL_O(x) 0, __SYSCALL_LL_E((x))
#define __asm_syscall(...) \
do { \
__asm__ __volatile__("trap0(#1)" : "=r"(r0) : __VA_ARGS__ : "memory"); \
return r0; \
} while (0)
#define __internal_syscall0(n) (__internal_syscall)(n)
static uptr __internal_syscall(long n) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0");
__asm_syscall("r"(r6));
}
#define __internal_syscall1(n, a1) (__internal_syscall)(n, (long)(a1))
static uptr __internal_syscall(long n, long a) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0") = a;
__asm_syscall("r"(r6), "0"(r0));
}
#define __internal_syscall2(n, a1, a2) \
(__internal_syscall)(n, (long)(a1), (long)(a2))
static uptr __internal_syscall(long n, long a, long b) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0") = a;
register u32 r1 __asm__("r1") = b;
__asm_syscall("r"(r6), "0"(r0), "r"(r1));
}
#define __internal_syscall3(n, a1, a2, a3) \
(__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3))
static uptr __internal_syscall(long n, long a, long b, long c) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0") = a;
register u32 r1 __asm__("r1") = b;
register u32 r2 __asm__("r2") = c;
__asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2));
}
#define __internal_syscall4(n, a1, a2, a3, a4) \
(__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4))
static uptr __internal_syscall(long n, long a, long b, long c, long d) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0") = a;
register u32 r1 __asm__("r1") = b;
register u32 r2 __asm__("r2") = c;
register u32 r3 __asm__("r3") = d;
__asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3));
}
#define __internal_syscall5(n, a1, a2, a3, a4, a5) \
(__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4), \
(long)(a5))
static uptr __internal_syscall(long n, long a, long b, long c, long d, long e) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0") = a;
register u32 r1 __asm__("r1") = b;
register u32 r2 __asm__("r2") = c;
register u32 r3 __asm__("r3") = d;
register u32 r4 __asm__("r4") = e;
__asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
}
#define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \
(__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4), \
(long)(a5), (long)(a6))
static uptr __internal_syscall(long n, long a, long b, long c, long d, long e,
long f) {
register u32 r6 __asm__("r6") = n;
register u32 r0 __asm__("r0") = a;
register u32 r1 __asm__("r1") = b;
register u32 r2 __asm__("r2") = c;
register u32 r3 __asm__("r3") = d;
register u32 r4 __asm__("r4") = e;
register u32 r5 __asm__("r5") = f;
__asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
}
#define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n
#define __SYSCALL_NARGS(...) \
__SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, )
#define __SYSCALL_CONCAT_X(a, b) a##b
#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b)
#define __SYSCALL_DISP(b, ...) \
__SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
#define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__)
// Helper function used to avoid clobbering of errno.
bool internal_iserror(uptr retval, int *rverrno) {
if (retval >= (uptr)-4095) {
if (rverrno)
*rverrno = -retval;
return true;
}
return false;
}