mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-12 17:25:49 +00:00
Split the External and Intrinsic handling into seperate functions. This
improves readability of the call handling code significantly, as well as makes it clear which parts are hacky (externals) and which parts are good (call handling). No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31415 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -131,6 +131,8 @@ namespace {
|
|||||||
void visitCastInst(CastInst &CI);
|
void visitCastInst(CastInst &CI);
|
||||||
void visitInstruction(Instruction &I);
|
void visitInstruction(Instruction &I);
|
||||||
|
|
||||||
|
bool visitIntrinsic(CallSite CS, Function* F);
|
||||||
|
bool visitExternal(CallSite CS, Function* F);
|
||||||
void visitCallSite(CallSite CS);
|
void visitCallSite(CallSite CS);
|
||||||
void visitVAArgInst(VAArgInst &I);
|
void visitVAArgInst(VAArgInst &I);
|
||||||
|
|
||||||
@@ -406,8 +408,9 @@ void GraphBuilder::visitGetElementPtrInst(User &GEP) {
|
|||||||
for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP);
|
for (gep_type_iterator I = gep_type_begin(GEP), E = gep_type_end(GEP);
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
if (const StructType *STy = dyn_cast<StructType>(*I)) {
|
if (const StructType *STy = dyn_cast<StructType>(*I)) {
|
||||||
|
const ConstantInt* CUI = cast<ConstantInt>(I.getOperand());
|
||||||
unsigned FieldNo =
|
unsigned FieldNo =
|
||||||
(unsigned)cast<ConstantInt>(I.getOperand())->getZExtValue();
|
CUI->getType()->isSigned() ? CUI->getSExtValue() : CUI->getZExtValue();
|
||||||
Offset += (unsigned)TD.getStructLayout(STy)->MemberOffsets[FieldNo];
|
Offset += (unsigned)TD.getStructLayout(STy)->MemberOffsets[FieldNo];
|
||||||
} else if (isa<PointerType>(*I)) {
|
} else if (isa<PointerType>(*I)) {
|
||||||
if (!isa<Constant>(I.getOperand()) ||
|
if (!isa<Constant>(I.getOperand()) ||
|
||||||
@@ -420,7 +423,9 @@ void GraphBuilder::visitGetElementPtrInst(User &GEP) {
|
|||||||
if (const SequentialType *STy = cast<SequentialType>(*I)) {
|
if (const SequentialType *STy = cast<SequentialType>(*I)) {
|
||||||
CurTy = STy->getElementType();
|
CurTy = STy->getElementType();
|
||||||
if (ConstantInt *CS = dyn_cast<ConstantInt>(GEP.getOperand(i))) {
|
if (ConstantInt *CS = dyn_cast<ConstantInt>(GEP.getOperand(i))) {
|
||||||
Offset += CS->getValue()*TD.getTypeSize(CurTy);
|
Offset +=
|
||||||
|
(CS->getType()->isSigned() ? CS->getSExtValue() : CS->getZExtValue())
|
||||||
|
* TD.getTypeSize(CurTy);
|
||||||
} else {
|
} else {
|
||||||
// Variable index into a node. We must merge all of the elements of the
|
// Variable index into a node. We must merge all of the elements of the
|
||||||
// sequential type here.
|
// sequential type here.
|
||||||
@@ -529,25 +534,21 @@ void GraphBuilder::visitInvokeInst(InvokeInst &II) {
|
|||||||
visitCallSite(&II);
|
visitCallSite(&II);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphBuilder::visitCallSite(CallSite CS) {
|
/// returns true if the intrinsic is handled
|
||||||
Value *Callee = CS.getCalledValue();
|
bool GraphBuilder::visitIntrinsic(CallSite CS, Function *F) {
|
||||||
|
|
||||||
// Special case handling of certain libc allocation functions here.
|
|
||||||
if (Function *F = dyn_cast<Function>(Callee))
|
|
||||||
if (F->isExternal())
|
|
||||||
switch (F->getIntrinsicID()) {
|
switch (F->getIntrinsicID()) {
|
||||||
case Intrinsic::vastart:
|
case Intrinsic::vastart:
|
||||||
getValueDest(*CS.getInstruction()).getNode()->setAllocaNodeMarker();
|
getValueDest(*CS.getInstruction()).getNode()->setAllocaNodeMarker();
|
||||||
return;
|
return true;
|
||||||
case Intrinsic::vacopy:
|
case Intrinsic::vacopy:
|
||||||
getValueDest(*CS.getInstruction()).
|
getValueDest(*CS.getInstruction()).
|
||||||
mergeWith(getValueDest(**(CS.arg_begin())));
|
mergeWith(getValueDest(**(CS.arg_begin())));
|
||||||
return;
|
return true;
|
||||||
case Intrinsic::vaend:
|
case Intrinsic::vaend:
|
||||||
case Intrinsic::dbg_func_start:
|
case Intrinsic::dbg_func_start:
|
||||||
case Intrinsic::dbg_region_end:
|
case Intrinsic::dbg_region_end:
|
||||||
case Intrinsic::dbg_stoppoint:
|
case Intrinsic::dbg_stoppoint:
|
||||||
return; // noop
|
return true; // noop
|
||||||
case Intrinsic::memcpy_i32:
|
case Intrinsic::memcpy_i32:
|
||||||
case Intrinsic::memcpy_i64:
|
case Intrinsic::memcpy_i64:
|
||||||
case Intrinsic::memmove_i32:
|
case Intrinsic::memmove_i32:
|
||||||
@@ -558,57 +559,36 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
|
RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
|
||||||
if (DSNode *N = RetNH.getNode())
|
if (DSNode *N = RetNH.getNode())
|
||||||
N->setModifiedMarker()->setReadMarker();
|
N->setModifiedMarker()->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
case Intrinsic::memset_i32:
|
case Intrinsic::memset_i32:
|
||||||
case Intrinsic::memset_i64:
|
case Intrinsic::memset_i64:
|
||||||
// Mark the memory modified.
|
// Mark the memory modified.
|
||||||
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
|
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
|
||||||
N->setModifiedMarker();
|
N->setModifiedMarker();
|
||||||
return;
|
return true;
|
||||||
default:
|
default:
|
||||||
// Determine if the called function is one of the specified heap
|
DEBUG(std::cerr << "[dsa:local] Unhandled intrinsic: " << F->getName() << "\n");
|
||||||
// allocation functions
|
return false;
|
||||||
for (cl::list<std::string>::iterator AllocFunc = AllocList.begin(),
|
|
||||||
LastAllocFunc = AllocList.end();
|
|
||||||
AllocFunc != LastAllocFunc;
|
|
||||||
++AllocFunc) {
|
|
||||||
if (F->getName() == *(AllocFunc)) {
|
|
||||||
setDestTo(*CS.getInstruction(),
|
|
||||||
createNode()->setHeapNodeMarker()->setModifiedMarker());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if the called function is one of the specified heap
|
/// returns true if the external is a recognized libc function with a
|
||||||
// free functions
|
/// known (and generated) graph
|
||||||
for (cl::list<std::string>::iterator FreeFunc = FreeList.begin(),
|
bool GraphBuilder::visitExternal(CallSite CS, Function *F) {
|
||||||
LastFreeFunc = FreeList.end();
|
if (F->getName() == "calloc"
|
||||||
FreeFunc != LastFreeFunc;
|
|
||||||
++FreeFunc) {
|
|
||||||
if (F->getName() == *(FreeFunc)) {
|
|
||||||
// Mark that the node is written to...
|
|
||||||
if (DSNode *N = getValueDest(*(CS.getArgument(0))).getNode())
|
|
||||||
N->setModifiedMarker()->setHeapNodeMarker();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//gets select localtime ioctl
|
|
||||||
|
|
||||||
if ((F->isExternal() && F->getName() == "calloc")
|
|
||||||
|| F->getName() == "posix_memalign"
|
|| F->getName() == "posix_memalign"
|
||||||
|| F->getName() == "memalign" || F->getName() == "valloc") {
|
|| F->getName() == "memalign" || F->getName() == "valloc") {
|
||||||
setDestTo(*CS.getInstruction(),
|
setDestTo(*CS.getInstruction(),
|
||||||
createNode()->setHeapNodeMarker()->setModifiedMarker());
|
createNode()->setHeapNodeMarker()->setModifiedMarker());
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "realloc") {
|
} else if (F->getName() == "realloc") {
|
||||||
DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
|
DSNodeHandle RetNH = getValueDest(*CS.getInstruction());
|
||||||
if (CS.arg_begin() != CS.arg_end())
|
if (CS.arg_begin() != CS.arg_end())
|
||||||
RetNH.mergeWith(getValueDest(**CS.arg_begin()));
|
RetNH.mergeWith(getValueDest(**CS.arg_begin()));
|
||||||
if (DSNode *N = RetNH.getNode())
|
if (DSNode *N = RetNH.getNode())
|
||||||
N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
|
N->setHeapNodeMarker()->setModifiedMarker()->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "memmove") {
|
} else if (F->getName() == "memmove") {
|
||||||
// Merge the first & second arguments, and mark the memory read and
|
// Merge the first & second arguments, and mark the memory read and
|
||||||
// modified.
|
// modified.
|
||||||
@@ -616,7 +596,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
|
RetNH.mergeWith(getValueDest(**(CS.arg_begin()+1)));
|
||||||
if (DSNode *N = RetNH.getNode())
|
if (DSNode *N = RetNH.getNode())
|
||||||
N->setModifiedMarker()->setReadMarker();
|
N->setModifiedMarker()->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "free") {
|
} else if (F->getName() == "free") {
|
||||||
// Mark that the node is written to...
|
// Mark that the node is written to...
|
||||||
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
|
if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
|
||||||
@@ -641,14 +621,14 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "memchr") {
|
} else if (F->getName() == "memchr") {
|
||||||
DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
|
DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
|
||||||
DSNodeHandle Result = getValueDest(*CS.getInstruction());
|
DSNodeHandle Result = getValueDest(*CS.getInstruction());
|
||||||
RetNH.mergeWith(Result);
|
RetNH.mergeWith(Result);
|
||||||
if (DSNode *N = RetNH.getNode())
|
if (DSNode *N = RetNH.getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "read" || F->getName() == "pipe" ||
|
} else if (F->getName() == "read" || F->getName() == "pipe" ||
|
||||||
F->getName() == "wait" || F->getName() == "time" ||
|
F->getName() == "wait" || F->getName() == "time" ||
|
||||||
F->getName() == "getrusage") {
|
F->getName() == "getrusage") {
|
||||||
@@ -659,7 +639,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setModifiedMarker();
|
N->setModifiedMarker();
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "stat" || F->getName() == "fstat" ||
|
} else if (F->getName() == "stat" || F->getName() == "fstat" ||
|
||||||
F->getName() == "lstat") {
|
F->getName() == "lstat") {
|
||||||
// These functions read their first operand if its a pointer.
|
// These functions read their first operand if its a pointer.
|
||||||
@@ -677,7 +657,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(StatTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(StatTy))
|
||||||
N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
|
N->mergeTypeInfo(PTy->getElementType(), StatBuf.getOffset());
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "strtod" || F->getName() == "strtof" ||
|
} else if (F->getName() == "strtod" || F->getName() == "strtof" ||
|
||||||
F->getName() == "strtold") {
|
F->getName() == "strtold") {
|
||||||
// These functions read the first pointer
|
// These functions read the first pointer
|
||||||
@@ -694,7 +674,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
Link.mergeWith(getValueDest(**CS.arg_begin()));
|
Link.mergeWith(getValueDest(**CS.arg_begin()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "fopen" || F->getName() == "fdopen" ||
|
} else if (F->getName() == "fopen" || F->getName() == "fdopen" ||
|
||||||
F->getName() == "freopen") {
|
F->getName() == "freopen") {
|
||||||
// These functions read all of their pointer operands.
|
// These functions read all of their pointer operands.
|
||||||
@@ -722,7 +702,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
CallSite::arg_iterator compit = CS.arg_end();
|
CallSite::arg_iterator compit = CS.arg_end();
|
||||||
Result.mergeWith(getValueDest(**--compit));
|
Result.mergeWith(getValueDest(**--compit));
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){
|
} else if (F->getName() == "fclose" && CS.arg_end()-CS.arg_begin() ==1){
|
||||||
// fclose reads and deallocates the memory in an unknown way for the
|
// fclose reads and deallocates the memory in an unknown way for the
|
||||||
// file descriptor. It merges the FILE type into the descriptor.
|
// file descriptor. It merges the FILE type into the descriptor.
|
||||||
@@ -733,7 +713,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
||||||
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (CS.arg_end()-CS.arg_begin() == 1 &&
|
} else if (CS.arg_end()-CS.arg_begin() == 1 &&
|
||||||
(F->getName() == "fflush" || F->getName() == "feof" ||
|
(F->getName() == "fflush" || F->getName() == "feof" ||
|
||||||
F->getName() == "fileno" || F->getName() == "clearerr" ||
|
F->getName() == "fileno" || F->getName() == "clearerr" ||
|
||||||
@@ -750,7 +730,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
||||||
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (CS.arg_end()-CS.arg_begin() == 4 &&
|
} else if (CS.arg_end()-CS.arg_begin() == 4 &&
|
||||||
(F->getName() == "fwrite" || F->getName() == "fread")) {
|
(F->getName() == "fwrite" || F->getName() == "fread")) {
|
||||||
// fread writes the first operand, fwrite reads it. They both
|
// fread writes the first operand, fwrite reads it. They both
|
||||||
@@ -770,7 +750,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
else
|
else
|
||||||
N->setModifiedMarker();
|
N->setModifiedMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "fgets" && CS.arg_end()-CS.arg_begin() == 3){
|
} else if (F->getName() == "fgets" && CS.arg_end()-CS.arg_begin() == 3){
|
||||||
// fgets reads and writes the memory for the file descriptor. It
|
// fgets reads and writes the memory for the file descriptor. It
|
||||||
// merges the FILE type into the descriptor, and writes to the
|
// merges the FILE type into the descriptor, and writes to the
|
||||||
@@ -790,7 +770,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
||||||
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "ungetc" || F->getName() == "fputc" ||
|
} else if (F->getName() == "ungetc" || F->getName() == "fputc" ||
|
||||||
F->getName() == "fputs" || F->getName() == "putc" ||
|
F->getName() == "fputs" || F->getName() == "putc" ||
|
||||||
F->getName() == "ftell" || F->getName() == "rewind" ||
|
F->getName() == "ftell" || F->getName() == "rewind" ||
|
||||||
@@ -813,7 +793,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (isPointerType((*AI)->getType()))
|
if (isPointerType((*AI)->getType()))
|
||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "fseek" || F->getName() == "fgetpos" ||
|
} else if (F->getName() == "fseek" || F->getName() == "fgetpos" ||
|
||||||
F->getName() == "fsetpos") {
|
F->getName() == "fsetpos") {
|
||||||
// These functions read and write the memory for the file descriptor,
|
// These functions read and write the memory for the file descriptor,
|
||||||
@@ -832,7 +812,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (isPointerType((*AI)->getType()))
|
if (isPointerType((*AI)->getType()))
|
||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setReadMarker()->setModifiedMarker();
|
N->setReadMarker()->setModifiedMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "printf" || F->getName() == "fprintf" ||
|
} else if (F->getName() == "printf" || F->getName() == "fprintf" ||
|
||||||
F->getName() == "sprintf") {
|
F->getName() == "sprintf") {
|
||||||
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
||||||
@@ -864,7 +844,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "vprintf" || F->getName() == "vfprintf" ||
|
} else if (F->getName() == "vprintf" || F->getName() == "vfprintf" ||
|
||||||
F->getName() == "vsprintf") {
|
F->getName() == "vsprintf") {
|
||||||
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
||||||
@@ -912,7 +892,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "scanf" || F->getName() == "fscanf" ||
|
} else if (F->getName() == "scanf" || F->getName() == "fscanf" ||
|
||||||
F->getName() == "sscanf") {
|
F->getName() == "sscanf") {
|
||||||
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
||||||
@@ -944,7 +924,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setModifiedMarker();
|
N->setModifiedMarker();
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "strtok") {
|
} else if (F->getName() == "strtok") {
|
||||||
// strtok reads and writes the first argument, returning it. It reads
|
// strtok reads and writes the first argument, returning it. It reads
|
||||||
// its second arg. FIXME: strtok also modifies some hidden static
|
// its second arg. FIXME: strtok also modifies some hidden static
|
||||||
@@ -966,7 +946,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
if (const PointerType *PTy = dyn_cast<PointerType>(ArgTy))
|
||||||
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
N->mergeTypeInfo(PTy->getElementType(), H.getOffset());
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "strchr" || F->getName() == "strrchr" ||
|
} else if (F->getName() == "strchr" || F->getName() == "strrchr" ||
|
||||||
F->getName() == "strstr") {
|
F->getName() == "strstr") {
|
||||||
// These read their arguments, and return the first one
|
// These read their arguments, and return the first one
|
||||||
@@ -981,14 +961,14 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
|
|
||||||
if (DSNode *N = H.getNode())
|
if (DSNode *N = H.getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "__assert_fail") {
|
} else if (F->getName() == "__assert_fail") {
|
||||||
for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
|
||||||
AI != E; ++AI)
|
AI != E; ++AI)
|
||||||
if (isPointerType((*AI)->getType()))
|
if (isPointerType((*AI)->getType()))
|
||||||
if (DSNode *N = getValueDest(**AI).getNode())
|
if (DSNode *N = getValueDest(**AI).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "modf" && CS.arg_end()-CS.arg_begin() == 2) {
|
} else if (F->getName() == "modf" && CS.arg_end()-CS.arg_begin() == 2) {
|
||||||
// This writes its second argument, and forces it to double.
|
// This writes its second argument, and forces it to double.
|
||||||
CallSite::arg_iterator compit = CS.arg_end();
|
CallSite::arg_iterator compit = CS.arg_end();
|
||||||
@@ -997,7 +977,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
N->setModifiedMarker();
|
N->setModifiedMarker();
|
||||||
N->mergeTypeInfo(Type::DoubleTy, H.getOffset());
|
N->mergeTypeInfo(Type::DoubleTy, H.getOffset());
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "strcat" || F->getName() == "strncat") {
|
} else if (F->getName() == "strcat" || F->getName() == "strncat") {
|
||||||
//This might be making unsafe assumptions about usage
|
//This might be making unsafe assumptions about usage
|
||||||
//Merge return and first arg
|
//Merge return and first arg
|
||||||
@@ -1008,7 +988,7 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
//and read second pointer
|
//and read second pointer
|
||||||
if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
|
if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
return;
|
return true;
|
||||||
} else if (F->getName() == "strcpy" || F->getName() == "strncpy") {
|
} else if (F->getName() == "strcpy" || F->getName() == "strncpy") {
|
||||||
//This might be making unsafe assumptions about usage
|
//This might be making unsafe assumptions about usage
|
||||||
//Merge return and first arg
|
//Merge return and first arg
|
||||||
@@ -1019,8 +999,38 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
//and read second pointer
|
//and read second pointer
|
||||||
if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
|
if (DSNode *N = getValueDest(**(CS.arg_begin() + 1)).getNode())
|
||||||
N->setReadMarker();
|
N->setReadMarker();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphBuilder::visitCallSite(CallSite CS) {
|
||||||
|
Value *Callee = CS.getCalledValue();
|
||||||
|
|
||||||
|
// Special case handling of certain libc allocation functions here.
|
||||||
|
if (Function *F = dyn_cast<Function>(Callee))
|
||||||
|
if (F->isExternal())
|
||||||
|
if (F->isIntrinsic() && visitIntrinsic(CS, F))
|
||||||
|
return;
|
||||||
|
else {
|
||||||
|
// Determine if the called function is one of the specified heap
|
||||||
|
// allocation functions
|
||||||
|
if (AllocList.end() != std::find(AllocList.begin(), AllocList.end(), F->getName())) {
|
||||||
|
setDestTo(*CS.getInstruction(),
|
||||||
|
createNode()->setHeapNodeMarker()->setModifiedMarker());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if the called function is one of the specified heap
|
||||||
|
// free functions
|
||||||
|
if (FreeList.end() != std::find(FreeList.begin(), FreeList.end(), F->getName())) {
|
||||||
|
// Mark that the node is written to...
|
||||||
|
if (DSNode *N = getValueDest(*(CS.getArgument(0))).getNode())
|
||||||
|
N->setModifiedMarker()->setHeapNodeMarker();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (visitExternal(CS,F))
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
// Unknown function, warn if it returns a pointer type or takes a
|
// Unknown function, warn if it returns a pointer type or takes a
|
||||||
// pointer argument.
|
// pointer argument.
|
||||||
bool Warn = isPointerType(CS.getInstruction()->getType());
|
bool Warn = isPointerType(CS.getInstruction()->getType());
|
||||||
@@ -1036,8 +1046,6 @@ void GraphBuilder::visitCallSite(CallSite CS) {
|
|||||||
<< F->getName() << "' will cause pessimistic results!\n");
|
<< F->getName() << "' will cause pessimistic results!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set up the return value...
|
// Set up the return value...
|
||||||
DSNodeHandle RetVal;
|
DSNodeHandle RetVal;
|
||||||
|
Reference in New Issue
Block a user