forked from OSchip/llvm-project
[MSan] Enable MSAN for aarch64
This patch enabled msan for aarch64 with 39-bit VMA and 42-bit VMA. As defined by lib/msan/msan.h the memory layout used is for 39-bit is: 00 0000 0000 - 40 0000 0000: invalid 40 0000 0000 - 43 0000 0000: shadow 43 0000 0000 - 46 0000 0000: origin 46 0000 0000 - 55 0000 0000: invalid 55 0000 0000 - 56 0000 0000: app (low) 56 0000 0000 - 70 0000 0000: invalid 70 0000 0000 - 80 0000 0000: app (high) And for 42-bit VMA: 000 0000 0000 - 100 0000 0000: invalid 100 0000 0000 - 11b 0000 0000: shadow 11b 0000 0000 - 120 0000 0000: invalid 120 0000 0000 - 13b 0000 0000: origin 13b 0000 0000 - 2aa 0000 0000: invalid 2aa 0000 0000 - 2ab 0000 0000: app (low) 2ab 0000 0000 - 3f0 0000 0000: invalid 3f0 0000 0000 - 400 0000 0000: app (high) Most of tests are passing with exception of: * Linux/mallinfo.cc * chained_origin_limits.cc * dlerror.cc * param_tls_limit.cc * signal_stress_test.cc * nonnull-arg.cpp The 'Linux/mallinfo.cc' is due the fact AArch64 returns the sret in 'x8' instead of default first argument 'x1'. So a function prototype that aims to mimic (by using first argument as the return of function) won't work. For GCC one can make a register alias (register var asm ("r8")), but for clang it detects is an unused variable and generate wrong code. The 'chained_origin_limits' is probably due a wrong code generation, since it fails only when origin memory is used (-fsanitize-memory-track-origins=2) and only in the returned code (return buf[50]). The 'signal_streess_test' and 'nonnull-arg' are due currently missing variadic argument handling in memory sanitizer code instrumentation on LLVM side. Both 'dlerror' and 'param_tls_test' are unknown failures that require further investigation. All the failures are XFAIL for aarch64 for now. llvm-svn: 247809
This commit is contained in:
parent
567b9260fa
commit
19074450ee
|
@ -261,7 +261,7 @@ set(ALL_ASAN_SUPPORTED_ARCH ${X86_64} i386 i686 powerpc64 powerpc64le ${ARM32}
|
|||
${ARM64} mips mipsel mips64 mips64el)
|
||||
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64})
|
||||
set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el)
|
||||
set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el)
|
||||
set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64})
|
||||
set(ALL_PROFILE_SUPPORTED_ARCH ${X86_64} i386 i686 ${ARM32} mips mips64
|
||||
mipsel mips64el ${ARM64} powerpc64 powerpc64le)
|
||||
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64})
|
||||
|
|
|
@ -52,6 +52,47 @@ const MappingDesc kMemoryLayout[] = {
|
|||
#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL)
|
||||
#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x002000000000)
|
||||
|
||||
#elif SANITIZER_LINUX && defined(__aarch64__)
|
||||
|
||||
# if SANITIZER_AARCH64_VMA == 39
|
||||
const MappingDesc kMemoryLayout[] = {
|
||||
{0x0000000000ULL, 0x4000000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x4000000000ULL, 0x4300000000ULL, MappingDesc::SHADOW, "shadow"},
|
||||
{0x4300000000ULL, 0x4600000000ULL, MappingDesc::ORIGIN, "origin"},
|
||||
{0x4600000000ULL, 0x5500000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x5500000000ULL, 0x5600000000ULL, MappingDesc::APP, "app"},
|
||||
{0x5600000000ULL, 0x7000000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x7000000000ULL, 0x8000000000ULL, MappingDesc::APP, "app"}
|
||||
};
|
||||
// Maps low and high app ranges to contiguous space with zero base:
|
||||
// Low: 55 0000 0000 - 55 ffff ffff -> 1 0000 0000 - 1 ffff ffff
|
||||
// High: 70 0000 0000 - 7f ffff ffff -> 0 0000 0000 - f ffff ffff
|
||||
# define LINEARIZE_MEM(mem) \
|
||||
(((uptr)(mem) & ~0x7C00000000ULL) ^ 0x100000000ULL)
|
||||
# define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x4000000000ULL)
|
||||
# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x300000000ULL)
|
||||
|
||||
# elif SANITIZER_AARCH64_VMA == 42
|
||||
const MappingDesc kMemoryLayout[] = {
|
||||
{0x00000000000ULL, 0x10000000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x10000000000ULL, 0x11b00000000ULL, MappingDesc::SHADOW, "shadow"},
|
||||
{0x11b00000000ULL, 0x12000000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x12000000000ULL, 0x13b00000000ULL, MappingDesc::ORIGIN, "origin"},
|
||||
{0x13b00000000ULL, 0x2aa00000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x2aa00000000ULL, 0x2ab00000000ULL, MappingDesc::APP, "app"},
|
||||
{0x2ab00000000ULL, 0x3f000000000ULL, MappingDesc::INVALID, "invalid"},
|
||||
{0x3f000000000ULL, 0x40000000000ULL, MappingDesc::APP, "app"},
|
||||
};
|
||||
// Maps low and high app ranges to contigous space with zero base:
|
||||
// 2 aa00 0000 00 - 2 ab00 0000 00: -> 1a00 0000 00 - 1aff ffff ff
|
||||
// 3 f000 0000 00 - 4 0000 0000 00: -> 0000 0000 00 - 0fff ffff ff
|
||||
# define LINEARIZE_MEM(mem) \
|
||||
(((uptr)(mem) & ~0x3E000000000ULL) ^ 0x1000000000ULL)
|
||||
# define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x10000000000ULL)
|
||||
# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL)
|
||||
|
||||
# endif // SANITIZER_AARCH64_VMA
|
||||
|
||||
#elif SANITIZER_LINUX && defined(__powerpc64__)
|
||||
|
||||
const MappingDesc kMemoryLayout[] = {
|
||||
|
|
|
@ -67,6 +67,16 @@ struct MsanMapUnmapCallback {
|
|||
typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,
|
||||
DefaultSizeClassMap,
|
||||
MsanMapUnmapCallback> PrimaryAllocator;
|
||||
#elif defined(__aarch64__)
|
||||
static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
|
||||
static const uptr kRegionSizeLog = 20;
|
||||
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
|
||||
typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
|
||||
typedef CompactSizeClassMap SizeClassMap;
|
||||
|
||||
typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, sizeof(Metadata),
|
||||
SizeClassMap, kRegionSizeLog, ByteMap,
|
||||
MsanMapUnmapCallback> PrimaryAllocator;
|
||||
#endif
|
||||
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
|
||||
typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
|
||||
|
|
|
@ -245,9 +245,15 @@ INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
|
|||
|
||||
#if !SANITIZER_FREEBSD
|
||||
// This function actually returns a struct by value, but we can't unpoison a
|
||||
// temporary! The following is equivalent on all supported platforms, and we
|
||||
// have a test to confirm that.
|
||||
// temporary! The following is equivalent on all supported platforms but
|
||||
// aarch64 (which uses a different register for sret value). We have a test
|
||||
// to confirm that.
|
||||
INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
|
||||
#ifdef __aarch64__
|
||||
uptr r8;
|
||||
asm volatile("mov %0,x8" : "=r" (r8));
|
||||
sret = reinterpret_cast<__sanitizer_mallinfo*>(r8);
|
||||
#endif
|
||||
REAL(memset)(sret, 0, sizeof(*sret));
|
||||
__msan_unpoison(sret, sizeof(*sret));
|
||||
}
|
||||
|
|
|
@ -2301,7 +2301,7 @@ POST_SYSCALL(ni_syscall)(long res) {}
|
|||
PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
|
||||
#if !SANITIZER_ANDROID && \
|
||||
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
|
||||
defined(__powerpc64__))
|
||||
defined(__powerpc64__) || defined(__aarch64__))
|
||||
if (data) {
|
||||
if (request == ptrace_setregs) {
|
||||
PRE_READ((void *)data, struct_user_regs_struct_sz);
|
||||
|
@ -2322,7 +2322,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
|
|||
POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {
|
||||
#if !SANITIZER_ANDROID && \
|
||||
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
|
||||
defined(__powerpc64__))
|
||||
defined(__powerpc64__) || defined(__aarch64__))
|
||||
if (res >= 0 && data) {
|
||||
// Note that this is different from the interceptor in
|
||||
// sanitizer_common_interceptors.inc.
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID
|
||||
#define SANITIZER_INTERCEPT_PTRACE SI_LINUX_NOT_ANDROID && \
|
||||
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
|
||||
defined(__powerpc64__))
|
||||
defined(__powerpc64__) || defined(__aarch64__))
|
||||
#define SANITIZER_INTERCEPT_SETLOCALE SI_NOT_WINDOWS
|
||||
#define SANITIZER_INTERCEPT_GETCWD SI_NOT_WINDOWS
|
||||
#define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
#if SANITIZER_LINUX || SANITIZER_FREEBSD
|
||||
# include <utime.h>
|
||||
# include <sys/ptrace.h>
|
||||
# if defined(__mips64)
|
||||
# if defined(__mips64) || defined(__aarch64__)
|
||||
# include <asm/ptrace.h>
|
||||
# endif
|
||||
#endif
|
||||
|
@ -303,28 +303,42 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
|
|||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
|
||||
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
|
||||
defined(__powerpc64__))
|
||||
defined(__powerpc64__) || defined(__aarch64__))
|
||||
#if defined(__mips64) || defined(__powerpc64__)
|
||||
unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs);
|
||||
unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t);
|
||||
#elif defined(__aarch64__)
|
||||
unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs);
|
||||
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state);
|
||||
#else
|
||||
unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct);
|
||||
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);
|
||||
#endif // __mips64 || __powerpc64__
|
||||
#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__)
|
||||
#endif // __mips64 || __powerpc64__ || __aarch64__
|
||||
#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \
|
||||
defined(__aarch64__)
|
||||
unsigned struct_user_fpxregs_struct_sz = 0;
|
||||
#else
|
||||
unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
|
||||
#endif // __x86_64 || __mips64 || __powerpc64__
|
||||
#endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__
|
||||
|
||||
int ptrace_peektext = PTRACE_PEEKTEXT;
|
||||
int ptrace_peekdata = PTRACE_PEEKDATA;
|
||||
int ptrace_peekuser = PTRACE_PEEKUSER;
|
||||
#if defined(PT_GETREGS) && defined(PT_SETREGS)
|
||||
int ptrace_getregs = PTRACE_GETREGS;
|
||||
int ptrace_setregs = PTRACE_SETREGS;
|
||||
#else
|
||||
int ptrace_getregs = -1;
|
||||
int ptrace_setregs = -1;
|
||||
#endif
|
||||
#if defined(PT_GETFPREGS) && defined(PT_SETFPREGS)
|
||||
int ptrace_getfpregs = PTRACE_GETFPREGS;
|
||||
int ptrace_setfpregs = PTRACE_SETFPREGS;
|
||||
#if defined(PTRACE_GETFPXREGS) && defined(PTRACE_SETFPXREGS)
|
||||
#else
|
||||
int ptrace_getfpregs = -1;
|
||||
int ptrace_setfpregs = -1;
|
||||
#endif
|
||||
#if defined(PT_GETFPXREGS) && defined(PT_SETFPXREGS)
|
||||
int ptrace_getfpxregs = PTRACE_GETFPXREGS;
|
||||
int ptrace_setfpxregs = PTRACE_SETFPXREGS;
|
||||
#else
|
||||
|
|
|
@ -724,7 +724,7 @@ namespace __sanitizer {
|
|||
|
||||
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
|
||||
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
|
||||
defined(__powerpc64__))
|
||||
defined(__powerpc64__) || defined(__aarch64__))
|
||||
extern unsigned struct_user_regs_struct_sz;
|
||||
extern unsigned struct_user_fpregs_struct_sz;
|
||||
extern unsigned struct_user_fpxregs_struct_sz;
|
||||
|
|
|
@ -19,8 +19,7 @@ namespace __sanitizer {
|
|||
|
||||
static const u32 kStackTraceMax = 256;
|
||||
|
||||
#if SANITIZER_LINUX && (defined(__aarch64__) || defined(__sparc__) || \
|
||||
defined(__mips__))
|
||||
#if SANITIZER_LINUX && (defined(__sparc__) || defined(__mips__))
|
||||
# define SANITIZER_CAN_FAST_UNWIND 0
|
||||
#elif SANITIZER_WINDOWS
|
||||
# define SANITIZER_CAN_FAST_UNWIND 0
|
||||
|
|
|
@ -61,6 +61,10 @@
|
|||
|
||||
// RUN: MSAN_OPTIONS=origin_history_size=7,origin_history_per_stack_limit=0 not %run %t >%t.out 2>&1
|
||||
// RUN: FileCheck %s --check-prefix=CHECK7 < %t.out
|
||||
//
|
||||
// AArch64 fails with -fsanitize-memory-track-origins=2 with and invalid access
|
||||
// on 'return buf[50]'.
|
||||
// XFAIL: aarch64
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
|
||||
//
|
||||
// AArch64 shows fails with uninitialized bytes in __interceptor_strcmp from
|
||||
// dlfcn/dlerror.c:107 (glibc).
|
||||
// XFAIL: aarch64
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "test.h"
|
||||
|
||||
bool AddrIsApp(void *p) {
|
||||
uintptr_t addr = (uintptr_t)p;
|
||||
|
@ -18,12 +20,24 @@ bool AddrIsApp(void *p) {
|
|||
return addr >= 0x00e000000000ULL;
|
||||
#elif defined(__powerpc64__)
|
||||
return addr < 0x000100000000ULL || addr >= 0x300000000000ULL;
|
||||
#elif defined(__aarch64__)
|
||||
unsigned long vma = SystemVMA();
|
||||
if (vma == 39)
|
||||
return (addr >= 0x5500000000ULL && addr < 0x5600000000ULL) ||
|
||||
(addr > 0x7000000000ULL);
|
||||
else if (vma == 42)
|
||||
return (addr >= 0x2aa00000000ULL && addr < 0x2ab00000000ULL) ||
|
||||
(addr > 0x3f000000000ULL);
|
||||
else {
|
||||
fprintf(stderr, "unsupported vma: %lu\n", vma);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Large enough to quickly exhaust the entire address space.
|
||||
#if defined(__mips64)
|
||||
#if defined(__mips64) || defined(__aarch64__)
|
||||
const size_t kMapSize = 0x100000000ULL;
|
||||
#else
|
||||
const size_t kMapSize = 0x1000000000ULL;
|
||||
|
|
|
@ -27,6 +27,9 @@ int main(void) {
|
|||
#elif defined (__powerpc64__)
|
||||
uintptr_t hint = 0x2f0000000000ULL;
|
||||
const uintptr_t app_start = 0x300000000000ULL;
|
||||
#elif defined (__aarch64__)
|
||||
uintptr_t hint = 0x4f0000000ULL;
|
||||
const uintptr_t app_start = 0x7000000000ULL;
|
||||
#endif
|
||||
uintptr_t p = (uintptr_t)mmap(
|
||||
(void *)hint, 4096, PROT_WRITE,
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
|
||||
// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t
|
||||
// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t
|
||||
//
|
||||
// AArch64 fails with:
|
||||
// void f801(S<801>): Assertion `__msan_test_shadow(&s, sizeof(s)) == -1' failed
|
||||
// XFAIL: aarch64
|
||||
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#include <assert.h>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
// RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
|
||||
//
|
||||
// AArch64 lacks var args instrumentation.
|
||||
// XFAIL: aarch64
|
||||
|
||||
// Test that va_arg shadow from a signal handler does not leak outside.
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "test.h"
|
||||
|
||||
const char *mem_to_shadow(const char *p) {
|
||||
#if defined(__x86_64__)
|
||||
|
@ -17,6 +19,22 @@ const char *mem_to_shadow(const char *p) {
|
|||
#define LINEARIZE_MEM(mem) \
|
||||
(((uintptr_t)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL)
|
||||
return (char *)(LINEARIZE_MEM(p) + 0x080000000000ULL);
|
||||
#elif defined(__aarch64__)
|
||||
unsigned long vma = SystemVMA();
|
||||
|
||||
#define LINEARIZE_MEM_39(mem) \
|
||||
(((uintptr_t)(mem) & ~0x7C00000000ULL) ^ 0x100000000ULL)
|
||||
#define LINEARIZE_MEM_42(mem) \
|
||||
(((uintptr_t)(mem) & ~0x3E000000000ULL) ^ 0x1000000000ULL)
|
||||
|
||||
if (vma == 39)
|
||||
return (char *)(LINEARIZE_MEM_39(p) + 0x4000000000ULL);
|
||||
else if (vma == 42)
|
||||
return (char *)(LINEARIZE_MEM_42(p) + 0x10000000000ULL);
|
||||
else {
|
||||
fprintf(stderr, "unsupported vma: %lu\n", vma);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
#if __LP64__
|
||||
# define SANITIZER_WORDSIZE 64
|
||||
#else
|
||||
# define SANITIZER_WORDSIZE 32
|
||||
#endif
|
||||
|
||||
// This is a simplified version of GetMaxVirtualAddress function.
|
||||
unsigned long SystemVMA () {
|
||||
#if SANITIZER_WORDSIZE == 64
|
||||
unsigned long vma = (unsigned long)__builtin_frame_address(0);
|
||||
return SANITIZER_WORDSIZE - __builtin_clzll(vma);
|
||||
#else
|
||||
return SANITIZER_WORDSIZE;
|
||||
#endif
|
||||
}
|
|
@ -7,11 +7,17 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
#include <elf.h>
|
||||
#if __mips64
|
||||
#include <asm/ptrace.h>
|
||||
#include <sys/procfs.h>
|
||||
#endif
|
||||
#ifdef __aarch64__
|
||||
// GLIBC 2.20+ sys/user does not include asm/ptrace.h
|
||||
#include <asm/ptrace.h>
|
||||
#endif
|
||||
|
||||
int main(void) {
|
||||
pid_t pid;
|
||||
|
@ -55,6 +61,26 @@ int main(void) {
|
|||
printf("%lx\n", (elf_greg_t)fpregs[32]);
|
||||
#endif // (__powerpc64__ || __mips64)
|
||||
|
||||
#if (__aarch64__)
|
||||
struct iovec regset_io;
|
||||
|
||||
struct user_pt_regs regs;
|
||||
regset_io.iov_base = ®s;
|
||||
regset_io.iov_len = sizeof(regs);
|
||||
res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, (void*)®set_io);
|
||||
assert(!res);
|
||||
if (regs.pc)
|
||||
printf("%llx\n", regs.pc);
|
||||
|
||||
struct user_fpsimd_state fpregs;
|
||||
regset_io.iov_base = &fpregs;
|
||||
regset_io.iov_len = sizeof(fpregs);
|
||||
res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, (void*)®set_io);
|
||||
assert(!res);
|
||||
if (fpregs.fpsr)
|
||||
printf("%x\n", fpregs.fpsr);
|
||||
#endif // (__aarch64__)
|
||||
|
||||
siginfo_t siginfo;
|
||||
res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
|
||||
assert(!res);
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
// RUN: not %run %t 0m 2>&1 | FileCheck %s --check-prefix=METHOD
|
||||
// RUN: not %run %t 0f 2>&1 | FileCheck %s --check-prefix=FUNC
|
||||
// RUN: not %run %t 0v 2>&1 | FileCheck %s --check-prefix=VARIADIC
|
||||
//
|
||||
// AArch64 lacks var args instrumentation.
|
||||
// XFAIL: aarch64
|
||||
|
||||
class C {
|
||||
int *null_;
|
||||
|
@ -40,19 +43,19 @@ int main(int argc, char *argv[]) {
|
|||
case 'c':
|
||||
return C(0x0, arg).value();
|
||||
// CTOR: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:21: runtime error: null pointer passed as argument 2, which is declared to never be null
|
||||
// CTOR-NEXT: {{.*}}nonnull-arg.cpp:16:31: note: nonnull attribute specified here
|
||||
// CTOR-NEXT: {{.*}}nonnull-arg.cpp:19:31: note: nonnull attribute specified here
|
||||
case 'm':
|
||||
return C(0x0, &local).method(arg, 0x0);
|
||||
// METHOD: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:36: runtime error: null pointer passed as argument 1, which is declared to never be null
|
||||
// METHOD-NEXT: {{.*}}nonnull-arg.cpp:19:54: note: nonnull attribute specified here
|
||||
// METHOD-NEXT: {{.*}}nonnull-arg.cpp:22:54: note: nonnull attribute specified here
|
||||
case 'f':
|
||||
return func(arg);
|
||||
// FUNC: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:19: runtime error: null pointer passed as argument 1, which is declared to never be null
|
||||
// FUNC-NEXT: {{.*}}nonnull-arg.cpp:24:16: note: nonnull attribute specified here
|
||||
// FUNC-NEXT: {{.*}}nonnull-arg.cpp:27:16: note: nonnull attribute specified here
|
||||
case 'v':
|
||||
return variadic(42, arg);
|
||||
// VARIADIC: {{.*}}nonnull-arg.cpp:[[@LINE-1]]:27: runtime error: null pointer passed as argument 2, which is declared to never be null
|
||||
// VARIADIC-NEXT: {{.*}}nonnull-arg.cpp:27:16: note: nonnull attribute specified here
|
||||
// VARIADIC-NEXT: {{.*}}nonnull-arg.cpp:30:16: note: nonnull attribute specified here
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue