diff options
-rw-r--r-- | lib/asan/asan_linux.cc | 7 | ||||
-rw-r--r-- | lib/asan/asan_mapping.h | 5 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.h | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_internal_defs.h | 7 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.h | 24 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace.cc | 27 |
6 files changed, 59 insertions, 15 deletions
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc index a500f978e..39eec3bfd 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cc @@ -74,6 +74,13 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = ucontext->uc_mcontext.gregs[REG_EIP]; *bp = ucontext->uc_mcontext.gregs[REG_EBP]; *sp = ucontext->uc_mcontext.gregs[REG_ESP]; +# elif defined(__powerpc__) || defined(__powerpc64__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.regs->nip; + *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; + // The powerpc{,64}-linux ABIs do not specify r31 as the frame + // pointer, but GCC always uses r31 when we need a frame pointer. + *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; # elif defined(__sparc__) ucontext_t *ucontext = (ucontext_t*)context; uptr *stk_ptr; diff --git a/lib/asan/asan_mapping.h b/lib/asan/asan_mapping.h index 950fb9ce1..1fecaeb35 100644 --- a/lib/asan/asan_mapping.h +++ b/lib/asan/asan_mapping.h @@ -61,6 +61,7 @@ static const u64 kDefaultShadowScale = 3; static const u64 kDefaultShadowOffset32 = 1ULL << 29; static const u64 kDefaultShadowOffset64 = 1ULL << 44; static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. +static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 @@ -80,7 +81,9 @@ extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset; # define SHADOW_OFFSET kDefaultShadowOffset32 # endif # else -# if SANITIZER_MAC +# if defined(__powerpc64__) +# define SHADOW_OFFSET kPPC64_ShadowOffset64 +# elif SANITIZER_MAC # define SHADOW_OFFSET kDefaultShadowOffset64 # else # define SHADOW_OFFSET kDefaultShort64bitShadowOffset diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index 6d00483df..cf8a12d65 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -27,7 +27,11 @@ struct StackTrace; const uptr kWordSize = SANITIZER_WORDSIZE / 8; const uptr kWordSizeInBits = 8 * kWordSize; +#if defined(__powerpc__) || defined(__powerpc64__) +const uptr kCacheLineSize = 128; +#else const uptr kCacheLineSize = 64; +#endif const uptr kMaxPathLength = 512; diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h index df676de3e..daa724be0 100644 --- a/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/lib/sanitizer_common/sanitizer_internal_defs.h @@ -58,6 +58,13 @@ typedef signed long long sptr; // NOLINT typedef unsigned long uptr; // NOLINT typedef signed long sptr; // NOLINT #endif // defined(_WIN64) +#if defined(__x86_64__) +// Since x32 uses ILP32 data model in 64-bit hardware mode, we must use +// 64-bit pointer to unwind stack frame. +typedef unsigned long long uhwptr; // NOLINT +#else +typedef uptr uhwptr; // NOLINT +#endif typedef unsigned char u8; typedef unsigned short u16; // NOLINT typedef unsigned int u32; diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 9ce48ddc9..b9a0fc98c 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -134,23 +134,32 @@ namespace __sanitizer { int gid; int cuid; int cgid; -#ifdef __powerpc64__ +#ifdef __powerpc__ unsigned mode; unsigned __seq; + u64 __unused1; + u64 __unused2; #else unsigned short mode; unsigned short __pad1; unsigned short __seq; unsigned short __pad2; +#if defined(__x86_64__) && !defined(_LP64) + u64 __unused1; + u64 __unused2; +#else + unsigned long __unused1; + unsigned long __unused2; +#endif #endif - uptr __unused1; - uptr __unused2; }; struct __sanitizer_shmid_ds { __sanitizer_ipc_perm shm_perm; #ifndef __powerpc__ uptr shm_segsz; + #elif !defined(__powerpc64__) + uptr __unused0; #endif uptr shm_atime; #ifndef _LP64 @@ -280,17 +289,20 @@ namespace __sanitizer { #endif #if SANITIZER_LINUX -#if defined(_LP64) || defined(__x86_64__) +#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) typedef unsigned __sanitizer___kernel_uid_t; typedef unsigned __sanitizer___kernel_gid_t; - typedef long long __sanitizer___kernel_off_t; #else typedef unsigned short __sanitizer___kernel_uid_t; typedef unsigned short __sanitizer___kernel_gid_t; +#endif +#if defined(__x86_64__) && !defined(_LP64) + typedef long long __sanitizer___kernel_off_t; +#else typedef long __sanitizer___kernel_off_t; #endif -#if defined(__powerpc64__) +#if defined(__powerpc__) typedef unsigned int __sanitizer___kernel_old_uid_t; typedef unsigned int __sanitizer___kernel_old_gid_t; #else diff --git a/lib/sanitizer_common/sanitizer_stacktrace.cc b/lib/sanitizer_common/sanitizer_stacktrace.cc index cbb15533b..de16becca 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace.cc @@ -24,7 +24,10 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) { // Cancel Thumb bit. pc = pc & (~1); #endif -#if defined(__sparc__) +#if defined(__powerpc__) || defined(__powerpc64__) + // PCs are always 4 byte aligned. + return pc - 4; +#elif defined(__sparc__) return pc - 8; #else return pc - 1; @@ -125,21 +128,29 @@ void StackTrace::FastUnwindStack(uptr pc, uptr bp, } trace[0] = pc; size = 1; - uptr *frame = (uptr *)bp; - uptr *prev_frame = frame - 1; + uhwptr *frame = (uhwptr *)bp; + uhwptr *prev_frame = frame - 1; if (stack_top < 4096) return; // Sanity check for stack top. // Avoid infinite loop when frame == frame[0] by using frame > prev_frame. while (frame > prev_frame && - frame < (uptr *)stack_top - 2 && - frame > (uptr *)stack_bottom && + frame < (uhwptr *)stack_top - 2 && + frame > (uhwptr *)stack_bottom && IsAligned((uptr)frame, sizeof(*frame)) && size < max_depth) { - uptr pc1 = frame[1]; + uhwptr pc1 = frame[1]; if (pc1 != pc) { - trace[size++] = pc1; + trace[size++] = (uptr) pc1; } prev_frame = frame; - frame = (uptr*)frame[0]; + frame = (uhwptr *)frame[0]; + } +} + +void StackTrace::PopStackFrames(uptr count) { + CHECK(size >= count); + size -= count; + for (uptr i = 0; i < size; i++) { + trace[i] = trace[i + count]; } } |