Skip to content

Commit

Permalink
fix(complete-cg): strip bitcasts
Browse files Browse the repository at this point in the history
We need to strip bitcasts in order to resolve trivial indirect calls.
We modified the code that strips bitcasts to catch all patterns from
the test suite.
  • Loading branch information
caballa committed Sep 15, 2023
1 parent 529356e commit ad688ef
Showing 1 changed file with 10 additions and 13 deletions.
23 changes: 10 additions & 13 deletions lib/seadsa/DsaCompleteCallGraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,28 +65,25 @@ static const Value *findUniqueReturnValue(const Function &F) {
return onlyRetVal;
}

static Value *stripBitCast(Value *V) {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->isCast()) {
return CE->getOperand(0);
}
}
if (BitCastInst *BC = dyn_cast<BitCastInst>(V)) {
return BC->getOperand(0);
}
return V;
}


static void resolveIndirectCallsThroughBitCast(Function &F, CallGraph &seaCg) {
// Resolve trivial indirect calls through bitcasts:
// call void (...) bitcast (void ()* @parse_dir_colors to void (...)*)()
// call i32 bitcast (i32 (...)* @nd_uint to i32 ()*)()
// call i32 (i32, i32)* bitcast (i32 (i32, i32)* (...)* @nd_binfptr to i32 (i32, i32)* ()*)()
//
// This is important because our top-down/bottom-up analyses
// traverse the call graph in a particular order (topological or
// reverse topological). If these edges are missing then the
// propagation can be done "too early" without analyzing the caller
// or callee yet.
auto stripBitCast = [](Value *V) {
if (BitCastInst *BC = dyn_cast<BitCastInst>(V)) {
return BC->getOperand(0);
} else {
return V->stripPointerCasts();
}
};

for (auto &I : llvm::make_range(inst_begin(&F), inst_end(&F))) {
if (!(isa<CallInst>(I) || isa<InvokeInst>(I))) continue;
CallBase &CB = *dyn_cast<CallBase>(&I);
Expand Down

0 comments on commit ad688ef

Please sign in to comment.