58 s32_t leftnum = 0, rightnum = 0;
59 string subname = name;
60 size_t leftpos, rightpos;
61 leftpos = subname.find(
"<");
62 while (leftpos != string::npos)
64 subname = subname.substr(leftpos+1);
65 leftpos = subname.find(
"<");
69 rightpos = subname.find(
">");
70 while (rightpos != string::npos)
72 subname = subname.substr(rightpos+1);
73 rightpos = subname.find(
">");
76 if (leftnum != rightnum)
88 size_t lastRightParen = name.rfind(
")");
89 assert(lastRightParen > 0);
91 s32_t paren_num = 1, pos;
92 for (pos = lastRightParen - 1; pos >= 0; pos--)
101 return name.substr(0, pos);
106 if (name[name.size() - 1] !=
'>')
110 s32_t bracket_num = 1, pos;
111 for (pos = name.size() - 2; pos >= 0; pos--)
113 if (name[pos] ==
'>')
115 if (name[pos] ==
'<')
117 if (bracket_num == 0)
120 return name.substr(0, pos);
125 if (!SVFUtil::isa<GlobalVariable>(val))
127 string valName = val->getName().str();
147 for (
unsigned i = 0; i < thunkPrefixes.size(); i++) {
148 auto prefix = thunkPrefixes[i];
149 if (dname.
className.size() > prefix.size() &&
150 dname.
className.compare(0, prefix.size(), prefix) == 0)
187 char *realname = abi::__cxa_demangle(name.c_str(), 0, 0, &status);
188 if (realname ==
nullptr)
195 string realnameStr = string(realname);
197 if (beforeParenthesis.find(
"::") == string::npos ||
206 size_t colon = beforeBracket.rfind(
"::");
207 if (colon == string::npos)
214 dname.
className = beforeParenthesis.substr(0, colon);
215 dname.
funcName = beforeParenthesis.substr(colon + 2);
227 const Value *loadSrc = loadInst->getPointerOperand();
228 const Type *valTy = loadSrc->getType();
229 const Type *elemTy = valTy;
230 for (
s32_t i = 0; i < 3; ++i)
232 if (
const PointerType *ptrTy = SVFUtil::dyn_cast<PointerType>(elemTy))
233 elemTy = ptrTy->getElementType();
237 if (
const FunctionType *functy = SVFUtil::dyn_cast<FunctionType>(elemTy))
239 const Type *paramty = functy->getParamType(0);
241 if (className.size() > 0)
264 if (LLVMModuleSet::getLLVMModuleSet()->allCTir())
270 if (
const LoadInst *vfuncloadinst = SVFUtil::dyn_cast<LoadInst>(vfunc))
272 const Value *vfuncptr = vfuncloadinst->getPointerOperand();
274 SVFUtil::dyn_cast<GetElementPtrInst>(vfuncptr))
276 if (vfuncptrgepinst->getNumIndices() != 1)
278 const Value *vtbl = vfuncptrgepinst->getPointerOperand();
279 if (SVFUtil::isa<LoadInst>(vtbl))
297 for (
auto &inst: bb) {
298 if (llvm::isa<CallInst>(inst) || llvm::isa<InvokeInst>(inst)
299 || llvm::isa<CallBrInst>(inst)) {
300 CallSite cs(const_cast<Instruction*>(&inst));
339 if (thisPtr1 == thisPtr2)
345 for (
const User *thisU : thisPtr1->users())
347 if (
const StoreInst *store = SVFUtil::dyn_cast<StoreInst>(thisU))
349 for (
const User *storeU : store->getPointerOperand()->users())
351 if (
const LoadInst *load = SVFUtil::dyn_cast<LoadInst>(storeU))
353 if(load->getNextNode() && SVFUtil::isa<CastInst>(load->getNextNode()))
354 return SVFUtil::cast<CastInst>(load->getNextNode()) == (thisPtr2->stripPointerCasts());
366 assert(fun->arg_size() >=1 &&
"argument size >= 1?");
367 const Argument* thisPtr = &*(fun->arg_begin());
381 assert(loadInst !=
nullptr);
382 const Value *vfuncptr = loadInst->getPointerOperand();
384 assert(gepInst !=
nullptr);
385 const Value *vtbl = gepInst->getPointerOperand();
392 assert(vfuncloadinst !=
nullptr);
393 const Value *vfuncptr = vfuncloadinst->getPointerOperand();
396 User::const_op_iterator oi = vfuncptrgepinst->idx_begin();
405 idx_value = idx->getSExtValue();
411 string className =
"";
412 if (
const PointerType *ptrType = SVFUtil::dyn_cast<PointerType>(ty))
414 const Type *elemType = ptrType->getElementType();
415 if (SVFUtil::isa<StructType>(elemType) &&
416 !((SVFUtil::cast<StructType>(elemType))->isLiteral()))
418 string elemTypeName = elemType->getStructName().str();
421 className = elemTypeName.substr(
clsName.size());
425 className = elemTypeName.substr(
structName.size());
434 string className =
"";
436 string vtblName = value->getName().str();
438 char *realname = abi::__cxa_demangle(vtblName.c_str(), 0, 0, &status);
439 if (realname !=
nullptr)
441 string realnameStr = string(realname);
453 if (F->isDeclaration())
455 string funcName = F->getName().str();
463 size_t colon = dname.
className.rfind(
"::");
464 if (colon == string::npos)
481 if (F->isDeclaration())
483 string funcName = F->getName().str();
491 size_t colon = dname.
className.rfind(
"::");
492 if (colon == string::npos)
502 dname.
funcName.compare(0, 1,
"~") == 0 &&
511 string thisPtrClassName;
513 if (
const MDNode *N = inst->getMetadata(
"VCallPtrType"))
515 const MDString &mdstr = SVFUtil::cast<MDString>((N->getOperand(0)));
516 thisPtrClassName = mdstr.getString().str();
518 if (thisPtrClassName.size() == 0)
524 size_t found = thisPtrClassName.find_last_not_of(
"0123456789");
525 if (found != string::npos)
527 if (found != thisPtrClassName.size() - 1 && thisPtrClassName[found] ==
'.')
529 return thisPtrClassName.substr(0, found);
533 return thisPtrClassName;
540 if (
const MDNode *N = inst->getMetadata(
"VCallFunName"))
542 const MDString &mdstr = SVFUtil::cast<MDString>((N->getOperand(0)));
543 funName = mdstr.getString().str();
559 if (classNameOfThisPtr.compare(dname.
className) == 0)
u64_t getVCallIdx(CallSite cs)
llvm::StoreInst StoreInst
llvm::FunctionType FunctionType
const string vtblLabelAfterDemangle
bool isVirtualCallSite(CallSite cs)
llvm::PointerType PointerType
Value * getCalledValue() const
bool isConstructor(const Function *F)
raw_ostream & errs()
Overwrite llvm::errs()
CallBase * getInstruction() const
llvm::ConstantInt ConstantInt
std::string getClassNameFromType(const Type *ty)
bool isDestructor(const Function *F)
const std::string derefMDName
bool isSameThisPtrInConstructor(const Argument *thisPtr1, const Value *thisPtr2)
bool isCPPThunkFunction(const Function *F)
bool VCallInCtorOrDtor(CallSite cs)
static string getBeforeParenthesis(const string &name)
const Argument * getConstructorThisPtr(const Function *fun)
bool isLoadVtblInst(const LoadInst *loadInst)
const Function * getThunkTarget(const Function *F)
std::string getClassNameFromVtblObj(const Value *value)
Value * getArgument(unsigned ArgNo) const
llvm::Instruction Instruction
const Value * getVCallThisPtr(CallSite cs)
static bool isOperOverload(const string name)
llvm::Argument Argument
LLVM Aliases and constants.
bool isValVtbl(const Value *val)
const string vtblLabelBeforeDemangle
llvm::GetElementPtrInst GetElementPtrInst
std::string getBeforeBrackets(const std::string &name)
static void handleThunkFunction(cppUtil::DemangledName &dname)
bool paramHasAttr(unsigned ArgNo, llvm::Attribute::AttrKind Kind) const
const string NVThunkFunLabel
Function * getCaller() const
const Value * getVCallVtblPtr(CallSite cs)
std::string getClassNameOfThisPtr(CallSite cs)
Function * getCalledFunction() const
struct DemangledName demangle(const std::string &name)
std::string getFunNameOfVCallSite(CallSite cs)
const string vfunPreLabel
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const string VThunkFuncLabel