[compiler-rt] r222001 - [ASan] Improved stack overflow detection for PowerPC64
Jay Foad
jay.foad at gmail.com
Fri Nov 14 07:30:39 PST 2014
Author: foad
Date: Fri Nov 14 09:30:39 2014
New Revision: 222001
URL: http://llvm.org/viewvc/llvm-project?rev=222001&view=rev
Log:
[ASan] Improved stack overflow detection for PowerPC64
Summary:
AsanOnSIGSEGV has some heuristics for detecting stack overflow, but
they don't cope with a PowerPC store-with-update instruction which
modifies sp and stores to the modified address in one instruction.
This patch adds some PowerPC-specific code to check for this case.
This fixes the last few cases of the stack-overflow test.
Reviewers: kcc, samsonov, eugenis
Reviewed By: eugenis
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D6253
Modified:
compiler-rt/trunk/lib/asan/asan_posix.cc
Modified: compiler-rt/trunk/lib/asan/asan_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=222001&r1=222000&r2=222001&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_posix.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_posix.cc Fri Nov 14 09:30:39 2014
@@ -44,11 +44,37 @@ void AsanOnSIGSEGV(int, void *siginfo, v
// Access at a reasonable offset above SP, or slightly below it (to account
// for x86_64 or PowerPC redzone, ARM push of multiple registers, etc) is
// probably a stack overflow.
+ bool IsStackAccess = addr + 512 > sp && addr < sp + 0xFFFF;
+
+#if __powerpc64__
+ // Large stack frames can be allocated with e.g.
+ // lis r0,-10000
+ // stdux r1,r1,r0 # store sp to [sp-10000] and update sp by -10000
+ // If the store faults then sp will not have been updated, so test above
+ // will not work, becase the fault address will be more than just "slightly"
+ // below sp.
+ if (!IsStackAccess && IsAccessibleMemoryRange(pc, 4)) {
+ u32 inst = *(unsigned *)pc;
+ u32 ra = (inst >> 16) & 0x1F;
+ u32 opcd = inst >> 26;
+ u32 xo = (inst >> 1) & 0x3FF;
+ // Check for store-with-update to sp. The instructions we accept are:
+ // stbu rs,d(ra) stbux rs,ra,rb
+ // sthu rs,d(ra) sthux rs,ra,rb
+ // stwu rs,d(ra) stwux rs,ra,rb
+ // stdu rs,ds(ra) stdux rs,ra,rb
+ // where ra is r1 (the stack pointer).
+ if (ra == 1 &&
+ (opcd == 39 || opcd == 45 || opcd == 37 || opcd == 62 ||
+ (opcd == 31 && (xo == 247 || xo == 439 || xo == 183 || xo == 181))))
+ IsStackAccess = true;
+ }
+#endif // __powerpc64__
+
// We also check si_code to filter out SEGV caused by something else other
// then hitting the guard page or unmapped memory, like, for example,
// unaligned memory access.
- if (addr + 512 > sp && addr < sp + 0xFFFF &&
- (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))
+ if (IsStackAccess && (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))
ReportStackOverflow(pc, sp, bp, context, addr);
else
ReportSIGSEGV("SEGV", pc, sp, bp, context, addr);
More information about the llvm-commits
mailing list