Merge pull request #6 from pbst/patch

Fix crashes
This commit is contained in:
hexcoder
2019-06-17 15:16:48 +02:00
committed by GitHub
2 changed files with 16 additions and 9 deletions

View File

@ -184,6 +184,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const
Value *Str1P = callInst->getArgOperand(0), *Str2P = callInst->getArgOperand(1); Value *Str1P = callInst->getArgOperand(0), *Str2P = callInst->getArgOperand(1);
StringRef Str1, Str2, ConstStr; StringRef Str1, Str2, ConstStr;
std::string TmpConstStr;
Value *VarStr; Value *VarStr;
bool HasStr1 = getConstantStringInfo(Str1P, Str1); bool HasStr1 = getConstantStringInfo(Str1P, Str1);
getConstantStringInfo(Str2P, Str2); getConstantStringInfo(Str2P, Str2);
@ -202,21 +203,20 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, const
} }
if (HasStr1) { if (HasStr1) {
ConstStr = Str1; TmpConstStr = Str1.str();
VarStr = Str2P; VarStr = Str2P;
constLen = isMemcmp ? sizedLen : GetStringLength(Str1P); constLen = isMemcmp ? sizedLen : GetStringLength(Str1P);
} }
else { else {
ConstStr = Str2; TmpConstStr = Str2.str();
VarStr = Str1P; VarStr = Str1P;
constLen = isMemcmp ? sizedLen : GetStringLength(Str2P); constLen = isMemcmp ? sizedLen : GetStringLength(Str2P);
} }
/* bugfix thanks to pbst */ /* properly handle zero terminated C strings by adding the terminating 0 to
/* ignore terminating '\0' in string for strcmp */ * the StringRef (in comparison to std::string a StringRef has built-in
if (!isSizedcmp && constLen > 0) { * runtime bounds checking, which makes debugging easier) */
constLen--; TmpConstStr.append("\0", 1); ConstStr = StringRef(TmpConstStr);
}
if (isSizedcmp && constLen > sizedLen) { if (isSizedcmp && constLen > sizedLen) {
constLen = sizedLen; constLen = sizedLen;

View File

@ -87,6 +87,7 @@ BasicBlock* SplitSwitchesTransform::switchConvert(CaseVector Cases, std::vector<
std::vector<uint8_t> setSizes; std::vector<uint8_t> setSizes;
std::vector<std::set<uint8_t>> byteSets(BytesInValue, std::set<uint8_t>()); std::vector<std::set<uint8_t>> byteSets(BytesInValue, std::set<uint8_t>());
assert(ValTypeBitWidth >= 8 && ValTypeBitWidth <= 64);
/* for each of the possible cases we iterate over all bytes of the values /* 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 */ * 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 smallestIndex = 0;
unsigned smallestSize = 257; unsigned smallestSize = 257;
for(unsigned i = 0; i < byteSets.size(); i++) { 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 */ /* this is the value we are switching on */
Value *Val = SI->getCondition(); Value *Val = SI->getCondition();
BasicBlock* Default = SI->getDefaultDest(); BasicBlock* Default = SI->getDefaultDest();
unsigned bitw = Val->getType()->getIntegerBitWidth();
/* If there is only the default destination, don't bother with the code below. */ errs() << "switch: " << SI->getNumCases() << " cases " << bitw << " bit\n";
if (!SI->getNumCases()) {
/* 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; continue;
} }