forked from OSchip/llvm-project
[sanitizer] Add hexagon support to sanitizer-common
Adds build support for hexagon linux to sanitizer common.
This commit is contained in:
parent
c64d1855b9
commit
9ea59e1cd0
|
@ -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})
|
||||
|
|
|
@ -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 "";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue