From f5ba5ffe80c52e448bf162686c21c82f166ab6c0 Mon Sep 17 00:00:00 2001
From: Philipp Bartsch
Date: Thu, 13 Jun 2019 14:42:10 +0000
Subject: [PATCH 1/2] fix zero terminated string issue
In C "strings" are zero terminated. Functions like
strcmp/strncmp/memcmp/... work on them. We have to be careful to not
ignore the last byte.
---
llvm_mode/compare-transform-pass.so.cc | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc
index c89655eab..d9a1f9452 100644
--- a/llvm_mode/compare-transform-pass.so.cc
+++ b/llvm_mode/compare-transform-pass.so.cc
@@ -184,6 +184,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const
Value *Str1P = callInst->getArgOperand(0), *Str2P = callInst->getArgOperand(1);
StringRef Str1, Str2, ConstStr;
+ std::string TmpConstStr;
Value *VarStr;
bool HasStr1 = getConstantStringInfo(Str1P, Str1);
getConstantStringInfo(Str2P, Str2);
@@ -202,21 +203,20 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const
}
if (HasStr1) {
- ConstStr = Str1;
+ TmpConstStr = Str1.str();
VarStr = Str2P;
constLen = isMemcmp ? sizedLen : GetStringLength(Str1P);
}
else {
- ConstStr = Str2;
+ TmpConstStr = Str2.str();
VarStr = Str1P;
constLen = isMemcmp ? sizedLen : GetStringLength(Str2P);
}
- /* bugfix thanks to pbst */
- /* ignore terminating '\0' in string for strcmp */
- if (!isSizedcmp && constLen > 0) {
- constLen--;
- }
+ /* properly handle zero terminated C strings by adding the terminating 0 to
+ * the StringRef (in comparison to std::string a StringRef has built-in
+ * runtime bounds checking, which makes debugging easier) */
+ TmpConstStr.append("\0", 1); ConstStr = StringRef(TmpConstStr);
if (isSizedcmp && constLen > sizedLen) {
constLen = sizedLen;
From 7b5905bda6f632425b7c3b4b8ee698cba65dcd48 Mon Sep 17 00:00:00 2001
From: Philipp Bartsch
Date: Mon, 17 Jun 2019 02:00:14 +0000
Subject: [PATCH 2/2] llvm_mode/split-switches-pass: add checks
Add extra check to allow early exist in trivial cases that would
sometimes lead to crashes.
---
llvm_mode/split-switches-pass.so.cc | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/llvm_mode/split-switches-pass.so.cc b/llvm_mode/split-switches-pass.so.cc
index 45847f885..4c28f34ce 100644
--- a/llvm_mode/split-switches-pass.so.cc
+++ b/llvm_mode/split-switches-pass.so.cc
@@ -87,6 +87,7 @@ BasicBlock* SplitSwitchesTransform::switchConvert(CaseVector Cases, std::vector<
std::vector setSizes;
std::vector> byteSets(BytesInValue, std::set());
+ assert(ValTypeBitWidth >= 8 && ValTypeBitWidth <= 64);
/* for each of the possible cases we iterate over all bytes of the values
* build a set of possible values at each byte position in byteSets */
@@ -98,6 +99,8 @@ BasicBlock* SplitSwitchesTransform::switchConvert(CaseVector Cases, std::vector<
}
}
+ /* find the index of the first byte position that was not yet checked. then
+ * save the number of possible values at that byte position */
unsigned smallestIndex = 0;
unsigned smallestSize = 257;
for(unsigned i = 0; i < byteSets.size(); i++) {
@@ -235,9 +238,13 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
/* this is the value we are switching on */
Value *Val = SI->getCondition();
BasicBlock* Default = SI->getDefaultDest();
+ unsigned bitw = Val->getType()->getIntegerBitWidth();
- /* If there is only the default destination, don't bother with the code below. */
- if (!SI->getNumCases()) {
+ errs() << "switch: " << SI->getNumCases() << " cases " << bitw << " bit\n";
+
+ /* If there is only the default destination or the condition checks 8 bit or less, don't bother with the code below. */
+ if (!SI->getNumCases() || bitw <= 8) {
+ errs() << "skip trivial switch..\n";
continue;
}