summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-09-12 19:51:26 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-09-12 19:51:26 +0000
commit0e8364e91254c5cb410a47472557981cb56d961f (patch)
tree3346a1f2609d4a5bc4d91dd39a4c1ff4fc76e3c7
parent63e3a29ff3e4050e615a56127b7789cdc15f520f (diff)
downloadbcm5719-llvm-0e8364e91254c5cb410a47472557981cb56d961f.tar.gz
bcm5719-llvm-0e8364e91254c5cb410a47472557981cb56d961f.zip
[UBSan] Don't overflow when calculating memory range that should be dumped
llvm-svn: 217703
-rw-r--r--compiler-rt/lib/ubsan/ubsan_diag.cc22
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_diag.cc b/compiler-rt/lib/ubsan/ubsan_diag.cc
index cb9349f3222..4a03aa38577 100644
--- a/compiler-rt/lib/ubsan/ubsan_diag.cc
+++ b/compiler-rt/lib/ubsan/ubsan_diag.cc
@@ -193,24 +193,34 @@ static Range *upperBound(MemoryLocation Loc, Range *Ranges,
return Best;
}
+static inline uptr subtractNoOverflow(uptr LHS, uptr RHS) {
+ return (LHS < RHS) ? 0 : LHS - RHS;
+}
+
+static inline uptr addNoOverflow(uptr LHS, uptr RHS) {
+ const uptr Limit = (uptr)-1;
+ return (LHS > Limit - RHS) ? Limit : LHS + RHS;
+}
+
/// Render a snippet of the address space near a location.
static void renderMemorySnippet(const Decorator &Decor, MemoryLocation Loc,
Range *Ranges, unsigned NumRanges,
const Diag::Arg *Args) {
- const unsigned BytesToShow = 32;
- const unsigned MinBytesNearLoc = 4;
-
// Show at least the 8 bytes surrounding Loc.
- MemoryLocation Min = Loc - MinBytesNearLoc, Max = Loc + MinBytesNearLoc;
+ const unsigned MinBytesNearLoc = 4;
+ MemoryLocation Min = subtractNoOverflow(Loc, MinBytesNearLoc);
+ MemoryLocation Max = addNoOverflow(Loc, MinBytesNearLoc);
+ MemoryLocation OrigMin = Min;
for (unsigned I = 0; I < NumRanges; ++I) {
Min = __sanitizer::Min(Ranges[I].getStart().getMemoryLocation(), Min);
Max = __sanitizer::Max(Ranges[I].getEnd().getMemoryLocation(), Max);
}
// If we have too many interesting bytes, prefer to show bytes after Loc.
+ const unsigned BytesToShow = 32;
if (Max - Min > BytesToShow)
- Min = __sanitizer::Min(Max - BytesToShow, Loc - MinBytesNearLoc);
- Max = Min + BytesToShow;
+ Min = __sanitizer::Min(Max - BytesToShow, OrigMin);
+ Max = addNoOverflow(Min, BytesToShow);
// Emit data.
for (uptr P = Min; P != Max; ++P) {
OpenPOWER on IntegriCloud