Skip to content

Commit

Permalink
Merge branch 'SVF-tools:master' into 0822WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonZhongZexin authored Sep 11, 2023
2 parents f75671d + 0a64d8a commit 1568fc6
Show file tree
Hide file tree
Showing 22 changed files with 708 additions and 477 deletions.
1 change: 1 addition & 0 deletions .github/workflows/svf-lib_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ jobs:
cp -rf $GITHUB_WORKSPACE/svf/include SVF-${osVersion}/svf
cp -rf $GITHUB_WORKSPACE/svf-llvm/include SVF-${osVersion}/svf-llvm
cp -f $GITHUB_WORKSPACE/Release-build/svf-llvm/libSvfLLVM.a SVF-${osVersion}/Release-build/svf-llvm/libSvfLLVM.a
cp -f $GITHUB_WORKSPACE/Release-build/svf-llvm/extapi.bc SVF-${osVersion}/Release-build/svf-llvm/extapi.bc
cp -f $GITHUB_WORKSPACE/Release-build/svf/libSvfCore.a SVF-${osVersion}/Release-build/svf/libSvfCore.a
cp -rf $GITHUB_WORKSPACE/Release-build/include SVF-${osVersion}/Release-build
git add .
Expand Down
4 changes: 4 additions & 0 deletions svf-llvm/include/SVF-LLVM/BasicTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ typedef llvm::BinaryOperator BinaryOperator;
typedef llvm::UnaryOperator UnaryOperator;
typedef llvm::UndefValue UndefValue;

// Related to Switch Case
typedef std::pair<const BasicBlock*, const ConstantInt*> SuccBBAndCondValPair;
typedef std::vector<SuccBBAndCondValPair> SuccBBAndCondValPairVec;

// LLVM Intrinsic Instructions
#if LLVM_VERSION_MAJOR >= 13
typedef llvm::IntrinsicInst IntrinsicInst;
Expand Down
70 changes: 68 additions & 2 deletions svf-llvm/include/SVF-LLVM/LLVMUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ inline const PointerType *getRefTypeOfHeapAllocOrStatic(const CallBase* cs)
if (const PointerType *argType = SVFUtil::dyn_cast<PointerType>(arg->getType()))
refType = SVFUtil::dyn_cast<PointerType>(getPtrElementType(argType));
}
// Case 2: heap/static object held by return value.
// Case 2: heap object held by return value.
else
{
assert((SVFUtil::isStaticExtCall(svfcs) || SVFUtil::isHeapAllocExtCallViaRet(svfcs))
assert(SVFUtil::isHeapAllocExtCallViaRet(svfcs)
&& "Must be heap alloc via ret, or static allocation site");
refType = SVFUtil::dyn_cast<PointerType>(cs->getType());
}
Expand Down Expand Up @@ -377,6 +377,23 @@ std::vector<const Function *> getCalledFunctions(const Function *F);
std::vector<std::string> getFunAnnotations(const Function* fun);
void removeFunAnnotations(std::vector<Function*>& removedFuncList);

inline u32_t SVFType2ByteSize(const SVFType* type)
{
const llvm::Type* llvm_rhs = LLVMModuleSet::getLLVMModuleSet()->getLLVMType(type);
u32_t llvm_rhs_size = LLVMUtil::getTypeSizeInBytes(llvm_rhs->getPointerElementType());
u32_t llvm_elem_size = -1;
if (llvm_rhs->getPointerElementType()->isArrayTy() && llvm_rhs_size > 0)
{
size_t array_len = llvm_rhs->getPointerElementType()->getArrayNumElements();
llvm_elem_size = llvm_rhs_size / array_len;
}
else
{
llvm_elem_size =llvm_rhs_size;
}
return llvm_elem_size;
}

inline void removeUnusedFuncsAndAnnotations(std::vector<Function*> removedFuncList)
{
/// Remove unused function annotations in extapi.bc
Expand Down Expand Up @@ -502,6 +519,55 @@ std::string llvmToString(const T& val)
llvm::raw_string_ostream(str) << val;
return str;
}

/**
* See more: https://github.com/SVF-tools/SVF/pull/1191
*
* Given the code:
*
* switch (a) {
* case 0: printf("0\n"); break;
* case 1:
* case 2:
* case 3: printf("a >=1 && a <= 3\n"); break;
* case 4:
* case 6:
* case 7: printf("a >= 4 && a <=7\n"); break;
* default: printf("a < 0 || a > 7"); break;
* }
*
* Generate the IR:
*
* switch i32 %0, label %sw.default [
* i32 0, label %sw.bb
* i32 1, label %sw.bb1
* i32 2, label %sw.bb1
* i32 3, label %sw.bb1
* i32 4, label %sw.bb3
* i32 6, label %sw.bb3
* i32 7, label %sw.bb3
* ]
*
* We can get every case basic block and related case value:
* [
* {%sw.default, -1},
* {%sw.bb, 0},
* {%sw.bb1, 1},
* {%sw.bb1, 2},
* {%sw.bb1, 3},
* {%sw.bb3, 4},
* {%sw.bb3, 6},
* {%sw.bb3, 7},
* ]
* Note: default case value is nullptr
*/
void getSuccBBandCondValPairVec(const SwitchInst &switchInst, SuccBBAndCondValPairVec &vec);

/**
* Note: default case value is nullptr
*/
s64_t getCaseValue(const SwitchInst &switchInst, SuccBBAndCondValPair &succBB2CondVal);

} // End namespace LLVMUtil

} // End namespace SVF
Expand Down
39 changes: 37 additions & 2 deletions svf-llvm/lib/LLVMUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ const std::string structName = "struct.";
*/
bool LLVMUtil::isObject(const Value* ref)
{
if (SVFUtil::isa<Instruction>(ref) && SVFUtil::isStaticExtCall(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast<Instruction>(ref))) )
return true;
if (SVFUtil::isa<Instruction>(ref) && SVFUtil::isHeapAllocExtCallViaRet(LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(SVFUtil::cast<Instruction>(ref))))
return true;
if (SVFUtil::isa<GlobalVariable>(ref))
Expand Down Expand Up @@ -1154,6 +1152,43 @@ s32_t LLVMUtil::getVCallIdx(const CallBase* cs)
return idx_value;
}

void LLVMUtil::getSuccBBandCondValPairVec(const SwitchInst &switchInst, SuccBBAndCondValPairVec &vec)
{
// get default successor basic block and default case value (nullptr)
vec.push_back({switchInst.getDefaultDest(), nullptr});

// get normal case value and it's successor basic block
for (const auto& cs : switchInst.cases())
vec.push_back({cs.getCaseSuccessor(), cs.getCaseValue()});
}

s64_t LLVMUtil::getCaseValue(const SwitchInst &switchInst, SuccBBAndCondValPair &succBB2CondVal)
{
const BasicBlock* succBB = succBB2CondVal.first;
const ConstantInt* caseValue = succBB2CondVal.second;
s64_t val;
if (caseValue == nullptr || succBB == switchInst.getDefaultDest())
{
/// default case value is set to -1
val = -1;
}
else
{
/// get normal case value
if (caseValue->getBitWidth() <= 64)
{
val = caseValue->getSExtValue();
}
else
{
/// For larger number, we preserve case value just -1 now
/// see more: https://github.com/SVF-tools/SVF/pull/992
val = -1;
}
}
return val;
}

namespace SVF
{
std::string SVFValue::toString() const
Expand Down
19 changes: 10 additions & 9 deletions svf-llvm/lib/SVFIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -946,19 +946,20 @@ void SVFIRBuilder::visitSwitchInst(SwitchInst &inst)
NodeID cond = getValueNode(inst.getCondition());

BranchStmt::SuccAndCondPairVec successors;
for (u32_t i = 0; i < inst.getNumSuccessors(); ++i)

// get case successor basic block and related case value
SuccBBAndCondValPairVec succBB2CondValPairVec;
LLVMUtil::getSuccBBandCondValPairVec(inst, succBB2CondValPairVec);
for (auto &succBB2CaseValue : succBB2CondValPairVec)
{
const Instruction* succInst = &inst.getSuccessor(i)->front();
const ConstantInt* condVal = inst.findCaseDest(inst.getSuccessor(i));
/// default case is set to -1;
s64_t val = -1;
if (condVal && condVal->getBitWidth() <= 64)
val = condVal->getSExtValue();
s64_t val = LLVMUtil::getCaseValue(inst, succBB2CaseValue);
const BasicBlock *succBB = succBB2CaseValue.first;
const Instruction* succInst = &succBB->front();
const SVFInstruction* svfSuccInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(succInst);
const ICFGNode* icfgNode = pag->getICFG()->getICFGNode(svfSuccInst);
successors.push_back(std::make_pair(icfgNode,val));
successors.push_back(std::make_pair(icfgNode, val));
}
addBranchStmt(brinst, cond,successors);
addBranchStmt(brinst, cond, successors);
}

/// %ap = alloca %struct.va_list
Expand Down
20 changes: 18 additions & 2 deletions svf-llvm/lib/SVFIRExtAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
const SVFInstruction* svfInst = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);
const SVFCallInst* svfCall = SVFUtil::cast<SVFCallInst>(svfInst);

if (isHeapAllocExtCallViaRet(svfCall) || isStaticExtCall(svfCall))
if (isHeapAllocExtCallViaRet(svfCall))
{
NodeID val = pag->getValueNode(svfInst);
NodeID obj = pag->getObjectNode(svfInst);
Expand Down Expand Up @@ -156,6 +156,8 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
}
else if (isMemcpyExtFun(svfCallee))
{
// Side-effects similar to void *memcpy(void *dest, const void * src, size_t n)
// which copies n characters from memory area 'src' to memory area 'dest'.
if(svfCallee->getName().find("iconv") != std::string::npos)
addComplexConsForExt(cs->getArgOperand(3), cs->getArgOperand(1), nullptr);
else if(svfCallee->getName().find("bcopy") != std::string::npos)
Expand All @@ -169,7 +171,7 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
}
else if(isMemsetExtFun(svfCallee))
{
// this is for memset(void *str, int c, size_t n)
// Side-effects similar to memset(void *str, int c, size_t n)
// which copies the character c (an unsigned char) to the first n characters of the string pointed to, by the argument str
std::vector<AccessPath> dstFields;
const Type *dtype = getBaseTypeAndFlattenedFields(cs->getArgOperand(0), dstFields, cs->getArgOperand(2));
Expand All @@ -187,6 +189,19 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
}
else if(svfCallee->getName().compare("dlsym") == 0)
{
/*
Side-effects of void* dlsym( void* handle, const char* funName),
Locate the function with the name "funName," then add a "copy" edge between the callsite and that function.
dlsym() example:
int main() {
// Open the shared library
void* handle = dlopen("./my_shared_library.so", RTLD_LAZY);
// Find the function address
void (*myFunctionPtr)() = (void (*)())dlsym(handle, "myFunction");
// Call the function
myFunctionPtr();
}
*/
const Value* src = cs->getArgOperand(1);
if(const GetElementPtrInst* gep = SVFUtil::dyn_cast<GetElementPtrInst>(src))
src = stripConstantCasts(gep->getPointerOperand());
Expand All @@ -212,6 +227,7 @@ void SVFIRBuilder::handleExtCall(const CallBase* cs, const SVFFunction* svfCalle
}
else if(svfCallee->getName().find("_ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_") != std::string::npos)
{
// The purpose of this function is to insert a new node into the red-black tree and then rebalance the tree to ensure that the red-black tree properties are maintained.
assert(svfCall->arg_size() == 4 && "_Rb_tree_insert_and_rebalance should have 4 arguments.\n");

// We have vArg3 points to the entry of _Rb_tree_node_base { color; parent; left; right; }.
Expand Down
9 changes: 0 additions & 9 deletions svf-llvm/lib/SymbolTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -750,15 +750,6 @@ void SymbolTableBuilder::initTypeInfo(ObjTypeInfo* typeinfo, const Value* val,
// Heap object, label its field as infinite here
objSize = typeinfo->getMaxFieldOffsetLimit();
}
else if (SVFUtil::isa<Instruction>(val) &&
isStaticExtCall(
LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(
SVFUtil::cast<Instruction>(val))))
{
analyzeStaticObjType(typeinfo,val);
// static object allocated before main, label its field as infinite here
objSize = typeinfo->getMaxFieldOffsetLimit();
}
else if(ArgInProgEntryFunction(val))
{
analyzeStaticObjType(typeinfo,val);
Expand Down
Loading

0 comments on commit 1568fc6

Please sign in to comment.