Reference1
safecode/include/StackSafety.h: This file defines checks for stack safety.
struct checkStackSafety : public ModulePass {
public :
...
virtual bool runOnModule(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<DataLayout>();
AU.addRequired<EQTDDataStructures>();
AU.setPreservesAll();
}
private :
//
// Tracks the DSNodes that have already been analyzed by an invocation of
// markReachableAllocas().
//
std::set<DSNode *> reachableAllocaNodes;
bool markReachableAllocas(DSNode *DSN, bool start=false);
bool markReachableAllocasInt(DSNode *DSN, bool start=false);
};
}
}
safecode/lib/StackSafety/CheckStackPointer.cpp: Implementation of StackSafety.h
“FixMe: Can this pass get better results by using another DSA pass? It seems this pass may be too conservative by using the Top-Down DSA results.”
runOnModule()
: no changes.
EQTDDataStructures
: An DSA pass that “computes new data structure graphs for each function using the closed graphs for the callers computed by the EQ bottom-up pass.” more
bool
checkStackSafety::runOnModule(Module &M) {
// TDDataStructures *TDDS;
// TDDS = &getAnalysis<TDDataStructures>();
EQTDDataStructures *BUDS;
BUDS = &getAnalysis<EQTDDataStructures>();
//
// Get a pointer to the entry of the program.
//
Function *MainFunc = M.getFunction("main") ? M.getFunction("main")
: M.getFunction ("MAIN__");
//
// Scan each function and look for stack objects which can escape from the
// function.
//
for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) {
Function &F = *MI;
if (&F != MainFunc) {
if (!F.isDeclaration()) {
DSGraph * BUG = BUDS->getDSGraph(F);
//
// If the function can return a pointer, see if a stack object can
// escape via the return value.
//
if (isa<PointerType>(F.getReturnType())) {
for (inst_iterator ii = inst_begin(F), ie = inst_end(&F);
ii != ie;
++ii) {
if (ReturnInst *RI = dyn_cast<ReturnInst>(&*ii)) {
DSNode *DSN = BUG->getNodeForValue(RI).getNode();
if (DSN) {
markReachableAllocas(DSN);
}
}
}
}
//
// Conservatively assume that any stack object reachable from one of
// the incoming arguments is a stack object that is placed there as an
// "output" by this function (or one of its callees).
//
Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end();
for (; AI != AE; ++AI) {
if (isa<PointerType>(AI->getType())) {
DSNode *DSN = BUG->getNodeForValue(AI).getNode();
markReachableAllocas(DSN, true);
}
}
//
// Any stack object that is reachable by a global may also escape the
// function. Scan both for local variables that may alias with globals
// as well as globals that are directly accessed by the function.
//
DSGraph::node_iterator DSNI = BUG->node_begin(), DSNE = BUG->node_end();
for (; DSNI != DSNE; ++DSNI) {
if (DSNI->isGlobalNode()) {
markReachableAllocas(DSNI);
}
}
DSGraph * GlobalGraph = BUG->getGlobalsGraph();
DSNI = GlobalGraph->node_begin(), DSNE = GlobalGraph->node_end();
for (; DSNI != DSNE; ++DSNI) {
if (DSNI->isGlobalNode()) {
markReachableAllocas(DSNI);
}
}
}
}
}
//
// This pass never changes the module; always return false.
//
return false;
}
markReachableAllocasInt(DSNode *DSN, bool start)
: Find all of the DSNodes that alias with stack objects and are reachable from the specified DSNode.
bool
checkStackSafety::markReachableAllocasInt(DSNode *DSN, bool start) {
bool returnValue = false;
reachableAllocaNodes.insert(DSN);
//
// If the initial node is an alloca node, then put it in the reachable set.
//
if (!start && DSN->isAllocaNode()) {
returnValue = true;
AllocaNodes.insert (DSN);
}
//
// Look at the DSNodes reachable from this DSNode. If they alias with the
// stack, put them in the reachable set.
//
DataLayout & TD = getAnalysis<DataLayout>();
for (unsigned i = 0, e = DSN->getSize(); i < e; i += TD.getPointerSize())
if (DSNode *DSNchild = DSN->getLink(i).getNode()) {
if (reachableAllocaNodes.find(DSNchild) != reachableAllocaNodes.end()) {
continue;
} else if (markReachableAllocasInt(DSNchild)) {
returnValue = returnValue || true;
}
}
return returnValue;
}
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?