86 u32_t leftnum = 0, rightnum = 0;
88 size_t leftpos, rightpos;
89 leftpos = subname.find(
'<');
90 while (leftpos != std::string::npos)
92 subname = subname.substr(leftpos + 1);
93 leftpos = subname.find(
'<');
97 rightpos = subname.find(
'>');
98 while (rightpos != std::string::npos)
100 subname = subname.substr(rightpos + 1);
101 rightpos = subname.find(
'>');
104 return leftnum != rightnum;
109 size_t lastRightParen =
name.rfind(
')');
110 assert(lastRightParen > 0);
112 s32_t paren_num = 1, pos;
113 for (pos = lastRightParen - 1; pos >= 0; pos--)
115 if (
name[pos] ==
')')
117 if (
name[pos] ==
'(')
122 return name.substr(0, pos);
133 s32_t bracket_num = 1, pos;
134 for (pos =
name.size() - 2; pos >= 0; pos--)
136 if (
name[pos] ==
'>')
138 if (
name[pos] ==
'<')
140 if (bracket_num == 0)
143 return name.substr(0, pos);
161 for (
unsigned i = 0; i < thunkPrefixes.size(); i++)
163 auto prefix = thunkPrefixes[i];
164 if (dname.
className.size() > prefix.size() &&
165 dname.
className.compare(0, prefix.size(), prefix) == 0)
201 char* realname = abi::__cxa_demangle(
name.c_str(), 0, 0, &status);
202 if (realname ==
nullptr)
204 dname.className =
"";
211 if (beforeParenthesis.find(
"::") == std::string::npos ||
214 dname.className =
"";
220 size_t colon = beforeBracket.rfind(
"::");
221 if (colon == std::string::npos)
223 dname.className =
"";
228 dname.className = beforeParenthesis.substr(0, colon);
229 dname.funcName = beforeParenthesis.substr(colon + 2);
248 size_t first = s.find_first_not_of(
' ');
249 size_t last = s.find_last_not_of(
' ');
250 if (first != std::string::npos && last != std::string::npos)
252 s = s.substr(first, (last - first + 1));
261 auto removePointerAndReference = [](
std::string& s)
263 while (!s.empty() && (s.back() ==
'*' || s.back() ==
'&'))
270 char* realname = abi::__cxa_demangle(
name.c_str(), 0, 0, &status);
271 if (realname ==
nullptr)
280 size_t start = realnameStr.find(
'(');
281 size_t end = realnameStr.find(
')');
282 if (start == std::string::npos || end == std::string::npos || start >= end)
288 std::string paramList = realnameStr.substr(start + 1, end - start - 1);
291 std::istringstream ss(paramList);
293 while (std::getline(ss, param,
','))
296 removePointerAndReference(param);
309 char* realname = abi::__cxa_demangle(vtblName.c_str(), 0, 0, &status);
310 if (realname !=
nullptr)
325 const ConstantStruct *vtblStruct = SVFUtil::dyn_cast<ConstantStruct>(vtbl->getOperand(0));
326 assert(vtblStruct &&
"Initializer of a vtable not a struct?");
328 if (vtblStruct->getNumOperands() == 2 &&
329 SVFUtil::isa<ConstantStruct>(vtblStruct->getOperand(0)) &&
330 vtblStruct->getOperand(1)->getType()->isArrayTy())
331 return SVFUtil::cast<ConstantStruct>(vtblStruct->getOperand(0));
338 if (!SVFUtil::isa<GlobalVariable>(val))
356 if (cs->getCalledFunction() !=
nullptr || cs->arg_empty())
361 if (cs->getArgOperand(0)->getType()->isPointerTy() ==
false)
364 const Value* vfunc = cs->getCalledOperand();
365 if (
const LoadInst* vfuncloadinst = SVFUtil::dyn_cast<LoadInst>(vfunc))
367 const Value* vfuncptr = vfuncloadinst->getPointerOperand();
369 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr))
371 if (vfuncptrgepinst->getNumIndices() != 1)
373 const Value* vtbl = vfuncptrgepinst->getPointerOperand();
374 if (SVFUtil::isa<LoadInst>(vtbl))
395 for (
auto& inst : bb)
397 if (
const CallBase* callbase = SVFUtil::dyn_cast<CallBase>(&inst))
403 ret = callbase->getCalledFunction();
413 if (cs->paramHasAttr(0, llvm::Attribute::StructRet))
415 return cs->getArgOperand(1);
419 return cs->getArgOperand(0);
438 const Value* thisPtr2)
440 if (thisPtr1 == thisPtr2)
442 for (
const Value* thisU : thisPtr1->users())
444 if (
const StoreInst* store = SVFUtil::dyn_cast<StoreInst>(thisU))
446 for (
const Value* storeU : store->getPointerOperand()->users())
448 if (
const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(storeU))
450 if (load->getNextNode() &&
451 SVFUtil::isa<CastInst>(load->getNextNode()))
452 return SVFUtil::cast<CastInst>(load->getNextNode()) ==
453 (thisPtr2->stripPointerCasts());
464 "not a constructor?");
465 assert(fun->arg_size() >= 1 &&
"argument size >= 1?");
466 const Argument* thisPtr = &*(fun->arg_begin());
476 size_t colon = dname.
className.rfind(
"::");
477 if (colon == std::string::npos)
491 if (
F->isDeclaration())
511 if (
F->isDeclaration())
526 dname.
funcName.compare(0, 1,
"~") == 0 &&
540 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
541 assert(loadInst !=
nullptr);
542 const Value* vfuncptr = loadInst->getPointerOperand();
544 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
545 assert(gepInst !=
nullptr);
546 const Value* vtbl = gepInst->getPointerOperand();
556 const Function* func = cs->getCaller();
557 for (
const auto &classNameOfThisPtr: classNameOfThisPtrs)
562 if (classNameOfThisPtr.compare(dname.
className) == 0)
573 for(
auto it = ty->element_begin(); it!=ty->element_end(); it++)
576 if (str.find(
vtableType) != std::string::npos)
586 if (!((SVFUtil::cast<StructType>(ty))->isLiteral()))
588 std::string elemTypeName = ty->getStructName().str();
591 className = elemTypeName.substr(
clsName.size());
595 className = elemTypeName.substr(
structName.size());
605 if (
const MDNode* N = inst->getMetadata(
"VCallPtrType"))
607 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
608 thisPtrClassName = mdstr->getString().str();
610 if (thisPtrClassName.size() == 0)
614 thisPtrNames.insert(names.begin(), names.end());
618 std::transform(thisPtrNames.begin(), thisPtrNames.end(), std::inserter(ans, ans.begin()),
621 size_t found = thisPtrName.find_last_not_of(
"0123456789");
622 if (found != std::string::npos)
624 if (found != thisPtrName.size() - 1 &&
625 thisPtrName[found] ==
'.')
627 return thisPtrName.substr(0, found);
638 if (
const MDNode* N = inst->getMetadata(
"VCallFunName"))
640 const MDString* mdstr = SVFUtil::cast<MDString>(N->getOperand(0).get());
641 funName = mdstr->getString().str();
649 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
650 assert(vfuncloadinst !=
nullptr);
651 const Value* vfuncptr = vfuncloadinst->getPointerOperand();
653 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr);
654 User::const_op_iterator oi = vfuncptrgepinst->idx_begin();
655 const ConstantInt* idx = SVFUtil::dyn_cast<ConstantInt>(oi->get());
664 idx_value = (
s32_t)idx->getSExtValue();
674 if (
const GlobalVariable* v = SVFUtil::dyn_cast<GlobalVariable>(val))
678 else if (!v->hasInitializer())
680 return !v->isExternalLinkage(v->getLinkage());
684 StInfo *stInfo = LLVMModuleSet::getLLVMModuleSet()->getSVFType(v->getInitializer()->getType())->getTypeInfo();
686 for (std::vector<const SVFType*>::const_iterator it = fields.begin(), eit = fields.end(); it != eit; ++it)
689 assert(!SVFUtil::isa<SVFFunctionType>(elemTy) &&
"Initializer of a global is a function?");
690 if (SVFUtil::isa<SVFPointerType>(elemTy))
694 return v->isConstant();
708 assert(foo->hasName() &&
"foo does not have a name? possible indirect call");
716 clsNameInBrackets.insert(demangledName.
className);
717 return clsNameInBrackets;
723 assert(!classNames.empty() &&
"empty class names?");
737 typedef std::pair<u32_t, u32_t> StEdIdxPair;
738 std::stack<int> stack;
739 std::vector<StEdIdxPair> innerMostPairs;
740 std::vector<bool> used(input.length(),
false);
742 for (
u32_t i = 0; i < input.length(); ++i)
748 else if (input[i] ==
'>' && i > 0 && input[i - 1] !=
'-')
752 int openIndex = stack.top();
756 bool isInnermost =
true;
757 for (
u32_t j = openIndex + 1; j < i && isInnermost; ++j)
767 innerMostPairs.emplace_back(openIndex, i);
768 used[openIndex] = used[i] =
true;
773 std::vector<std::string> ans(innerMostPairs.size());
774 std::transform(innerMostPairs.begin(), innerMostPairs.end(), ans.begin(), [&input](StEdIdxPair &
p) ->
std::string
776 return input.substr(p.first + 1, p.second - p.first - 1);
788 auto start = std::find_if(str.begin(), str.end(), [](
unsigned char ch)
790 return !std::isspace(ch);
792 auto end = std::find_if(str.rbegin(), str.rend(), [](
unsigned char ch)
794 return !std::isspace(ch);
802 std::vector<std::string> tokens;
803 size_t start = 0, end = 0;
805 while ((end = input.find(delimiter, start)) != std::string::npos)
829 for (
const auto &innermost: innermosts)
831 const std::vector<std::string> &allstrs =
splitAndStrip(innermost,
',');
832 for (
const auto &str: allstrs)
834 size_t spacePos = str.find(
' ');
835 if (spacePos != std::string::npos)
838 ans.insert(str.substr(0, spacePos));
842 size_t starPos = str.find(
'*');
843 if (starPos != std::string::npos)
845 ans.insert(str.substr(0, starPos));
863 if (
const auto *callBase = SVFUtil::dyn_cast<CallBase>(val))
865 const Function *foo = callBase->getCalledFunction();
867 if(!foo)
return false;
870 else if (
const auto *func = SVFUtil::dyn_cast<Function>(val))
885 return foo.compare(0, label.size(), label) == 0;
896 assert(foo->hasName() &&
"foo does not have a name? possible indirect call");
902 return matchedLabel && demangledName.find(
'<') != std::string::npos && demangledName.find(
'>') != std::string::npos;
912 assert(foo->hasName() &&
"foo does not have a name? possible indirect call");
913 return foo->getName().str() ==
dyncast;
923 Value *tgtCast = callBase->getArgOperand(2);
926 assert(leftPos != (
u32_t) std::string::npos &&
"does not find ZTI for dyncast?");
927 u32_t rightPos = leftPos;
928 while (rightPos < valueStr.size() && valueStr[rightPos] !=
' ') rightPos++;
929 const std::string &substr = valueStr.substr(leftPos, rightPos - leftPos);
933 assert(realName !=
"" &&
"real name for dyncast empty?");
939 StructType *classTy = StructType::getTypeByName(LLVMModuleSet::getLLVMModuleSet()->getContext(),
941 return classTy ? classTy : LLVMModuleSet::getLLVMModuleSet()->getTypeInference()->ptrType();
const std::string znst6Label
const std::string znkst23Label
const std::string vtblLabelBeforeDemangle
static void handleThunkFunction(cppUtil::DemangledName &dname)
static bool isOperOverload(const std::string &name)
const std::string VThunkFuncLabel
static std::string getBeforeParenthesis(const std::string &name)
const std::string znkst20Label
const std::string znst5Label
const std::string vtblLabelAfterDemangle
const std::string clsName
const std::string structName
std::vector< std::string > splitAndStrip(const std::string &input, char delimiter)
const std::string znstLabel
std::string stripWhitespaces(const std::string &str)
const std::string zn1Label
const std::string znkstLabel
const std::string znst7Label
const std::string dyncast
const std::string znst12Label
const std::string NVThunkFunLabel
const std::string znkLabel
std::vector< std::string > findInnermostBrackets(const std::string &input)
const std::string vtableType
const std::string ztilabel
const std::string znst14Label
const std::string znk9Label
const std::string znkst5Label
void stripBracketsAndNamespace(cppUtil::DemangledName &dname)
const std::string ztiprefix
const std::string vfunPreLabel
static LLVMModuleSet * getLLVMModuleSet()
ObjTypeInference * getTypeInference()
Set< std::string > & inferThisPtrClsName(const Value *thisPtr)
get or infer the class names of thisptr
std::vector< const SVFType * > & getFlattenFieldTypes()
std::string dumpType(const Type *type)
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
bool isConstantObjSym(const SVFValue *val)
Check whether this value points-to a constant object.
std::string dumpValue(const Value *val)
std::ostream & errs()
Overwrite llvm::errs()
std::string getFunNameOfVCallSite(const CallBase *cs)
std::string getBeforeBrackets(const std::string &name)
const Argument * getConstructorThisPtr(const Function *fun)
std::string extractClsNameFromDynCast(const CallBase *callBase)
extract class name from cpp dyncast function
s32_t getVCallIdx(const CallBase *cs)
const Value * getVCallVtblPtr(const CallBase *cs)
bool isTemplateFunc(const Function *foo)
whether foo is a cpp template function
bool classTyHasVTable(const StructType *ty)
bool isSameThisPtrInConstructor(const Argument *thisPtr1, const Value *thisPtr2)
Set< std::string > getClsNamesInBrackets(const std::string &name)
const Value * getVCallThisPtr(const CallBase *cs)
bool matchesLabel(const std::string &foo, const std::string &label)
whether foo matches the mangler label
std::string getClassNameFromType(const StructType *ty)
struct DemangledName demangle(const std::string &name)
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
bool isCPPThunkFunction(const Function *F)
bool VCallInCtorOrDtor(const CallBase *cs)
bool isClsNameSource(const Value *val)
Set< std::string > extractClsNamesFromTemplate(const std::string &oname)
extract class names from template functions
bool isVirtualCallSite(const CallBase *cs)
const Type * cppClsNameToType(const std::string &className)
const Function * getThunkTarget(const Function *F)
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
bool isConstructor(const Function *F)
std::string getClassNameFromVtblObj(const std::string &vtblName)
Set< std::string > extractClsNamesFromFunc(const Function *foo)
extract class name from the c++ function name, e.g., constructor/destructors
bool isValVtbl(const Value *val)
bool isDestructor(const Function *F)
bool isDynCast(const Function *foo)
whether foo is a cpp dyncast function
llvm::GlobalVariable GlobalVariable
llvm::ConstantStruct ConstantStruct
llvm::StructType StructType
LLVM types.
llvm::GlobalValue GlobalValue
llvm::Value Value
LLVM Basic classes.
llvm::StoreInst StoreInst
llvm::GetElementPtrInst GetElementPtrInst
llvm::ConstantInt ConstantInt
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set