diff --git a/include/seadsa/ownsem.h b/include/seadsa/ownsem.h new file mode 100644 index 00000000..dd3d0af4 --- /dev/null +++ b/include/seadsa/ownsem.h @@ -0,0 +1,15 @@ +#ifndef OWNSEM_H_ +#define OWNSEM_H_ + +#include + +constexpr auto OWNSEM_BUILTIN_NAMES = boost::hana::make_set( + "sea.mkown", "sea.mkshr", "sea.bor_mkbor", "sea.bor_ptr", "sea.bor_mksuc", + "sea.begin_unique", "sea.end_unique", + // "sea.die", // This is not a ptr def operation + "sea.mov", + // Builtin for fat ptr (slot0 and slot1 only) + "sea.set_fatptr_slot", "sea.get_fatptr_slot", "sea.bor_mem2reg", + "sea.mov_mem2reg", "sea.bor_mkbor_part"); + +#endif // OWNSEM_H_ diff --git a/include/seadsa/sea_dsa.h b/include/seadsa/sea_dsa.h index ec2a7c59..9adc7fb8 100644 --- a/include/seadsa/sea_dsa.h +++ b/include/seadsa/sea_dsa.h @@ -26,10 +26,10 @@ extern void sea_dsa_set_external(const void *p); // sea-dsa will collapse the argument's cell extern void sea_dsa_collapse(const void *p); // sea-dsa will return a fresh memory object -extern void *sea_dsa_new() __attribute__((malloc)); +extern void *sea_dsa_new(void) __attribute__((malloc)); // like sea_dsa_new except used for creating a node representation of an // existing memory object -extern void *sea_dsa_mk(); +extern void *sea_dsa_mk(void); // links one cell to another cell. Can be manually extended with // sea_dsa_link_(void *p, unsigned offset, > *p2) in order to // describe what type it is linking to diff --git a/lib/seadsa/DsaLocal.cc b/lib/seadsa/DsaLocal.cc index ac861b65..760b095d 100644 --- a/lib/seadsa/DsaLocal.cc +++ b/lib/seadsa/DsaLocal.cc @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "seadsa/Local.hh" - +#include "seadsa/ownsem.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/Pass.h" @@ -433,6 +433,7 @@ enum class SeadsaFn { LINK, MAKE, ACCESS, + RET_ALIAS_ARG, UNKNOWN }; @@ -458,8 +459,7 @@ class IntraBlockBuilder : public InstVisitor, void visitIntToPtrInst(IntToPtrInst &I); void visitPtrToIntInst(PtrToIntInst &I); void visitBitCastInst(BitCastInst &I); - void visitCmpInst(CmpInst &I) { /* do nothing */ - } + void visitCmpInst(CmpInst &I) { /* do nothing */ } void visitInsertValueInst(InsertValueInst &I); void visitExtractValueInst(ExtractValueInst &I); void visitShuffleVectorInst(ShuffleVectorInst &I); @@ -479,22 +479,28 @@ class IntraBlockBuilder : public InstVisitor, void visitAllocWrapperCall(CallBase &I); void visitAllocationFnCall(CallBase &I); - SeadsaFn getSeaDsaFn(const Function *fn) { if (!fn) return SeadsaFn::UNKNOWN; - SeadsaFn fnType = StringSwitch(fn->getName()) - .Case("sea_dsa_set_modified", SeadsaFn::MODIFY) - .Case("sea_dsa_set_read", SeadsaFn::READ) - .Case("sea_dsa_set_heap", SeadsaFn::HEAP) - .Case("sea_dsa_set_ptrtoint", SeadsaFn::PTR_TO_INT) - .Case("sea_dsa_set_inttoptr", SeadsaFn::INT_TO_PTR) - .Case("sea_dsa_set_extern", SeadsaFn::EXTERN) - .Case("sea_dsa_alias", SeadsaFn::ALIAS) - .Case("sea_dsa_collapse", SeadsaFn::COLLAPSE) - .Case("sea_dsa_mk_seq", SeadsaFn::MAKE_SEQ) - .Case("sea_dsa_mk", SeadsaFn::MAKE) - .Default(SeadsaFn::UNKNOWN); + SeadsaFn fnType = + StringSwitch(fn->getName()) + .Case("sea_dsa_set_modified", SeadsaFn::MODIFY) + .Case("sea_dsa_set_read", SeadsaFn::READ) + .Case("sea_dsa_set_heap", SeadsaFn::HEAP) + .Case("sea_dsa_set_ptrtoint", SeadsaFn::PTR_TO_INT) + .Case("sea_dsa_set_inttoptr", SeadsaFn::INT_TO_PTR) + .Case("sea_dsa_set_extern", SeadsaFn::EXTERN) + .Case("sea_dsa_alias", SeadsaFn::ALIAS) + .Case("sea_dsa_collapse", SeadsaFn::COLLAPSE) + .Case("sea_dsa_mk_seq", SeadsaFn::MAKE_SEQ) + .Case("sea_dsa_mk", SeadsaFn::MAKE) + .Cases("sea.mkown", "sea.mkshr", "sea.bor_mkbor", "sea.bor_ptr", + "sea.bor_mksuc", "sea.begin_unique", "sea.end_unique", + "sea.mov", "sea.set_fatptr_slot", "sea.get_fatptr_slot", + SeadsaFn::RET_ALIAS_ARG) + .Cases("sea.bor_mem2reg", "sea.mov_mem2reg", "sea.bor_mkbor_part", + SeadsaFn::RET_ALIAS_ARG) + .Default(SeadsaFn::UNKNOWN); if (fnType != SeadsaFn::UNKNOWN) return fnType; @@ -517,6 +523,12 @@ class IntraBlockBuilder : public InstVisitor, return n.startswith("sea_dsa_"); } + /// Returns true if \p F is a \p ownsem_ family of functions + static bool isOwnSemFn(const Function *fn) { + if (!fn) return false; + return boost::hana::contains(OWNSEM_BUILTIN_NAMES, fn->getName()); + } + // return function pointer to seadsa::Node setter using seadsaNodeSetterFunc = std::function; @@ -1259,6 +1271,20 @@ void IntraBlockBuilder::visitSeaDsaFnCall(CallBase &I) { return; } + case SeadsaFn::RET_ALIAS_ARG: { + LOG("sea-dsa-ret-alias", llvm::errs() << "In ret-alias\n";); + Value *inp = I.getOperand(0); + seadsa::Cell inpCell = valueCell(*inp); + assert(!m_graph.hasCell(I)); + assert(!inpCell.isNull()); + seadsa::Node *inpNode = inpCell.getNode(); + + seadsa::Node &n = m_graph.mkNode(); + m_graph.mkCell(I, seadsa::Cell(n, 0)); + + n.unify(*inpNode); + return; + } case SeadsaFn::ALIAS: { llvm::SmallVector toMerge; LOG("sea-dsa-alias", llvm::errs() << "In alias\n";); @@ -1445,7 +1471,7 @@ void IntraBlockBuilder::visitCallBase(CallBase &I) { if (m_allocInfo.isAllocWrapper(*callee)) { visitAllocWrapperCall(I); return; - } else if (isSeaDsaFn(callee)) { + } else if (isSeaDsaFn(callee) || isOwnSemFn(callee)) { visitSeaDsaFnCall(I); return; } else if (callee->isDeclaration()) { @@ -1463,7 +1489,6 @@ void IntraBlockBuilder::visitCallBase(CallBase &I) { // a function that does not return a pointer is a noop if (!I.getType()->isPointerTy()) return; - // -- something unexpected. Keep an assert so that we know that something // -- unexpected happened. @@ -1716,10 +1741,9 @@ void BlockBuilderBase::visitCastIntToPtr(const Value &dest) { n.setAlloca(); m_graph.mkCell(dest, seadsa::Cell(n, 0)); if (shouldBeTrackedIntToPtr(dest) && !m_graph.isFlat()) - LOG("dsa-warn", - llvm::errs() - << "WARNING: " << dest << " @ addr " << &dest - << " is (unsoundly) assumed to point to a fresh memory region.\n";); + LOG("dsa-warn", llvm::errs() << "WARNING: " << dest << " @ addr " << &dest + << " is (unsoundly) assumed to point to a " + "fresh memory region.\n";); } void IntraBlockBuilder::visitIntToPtrInst(IntToPtrInst &I) { @@ -1771,8 +1795,8 @@ bool isEscapingPtrToInt(const PtrToIntInst &def) { if (auto *CI = dyn_cast(user)) { const Function *callee = CI->getCalledFunction(); if (callee) { - // callee might not access memory but it can return ptrtoint passed to - // it if (callee->doesNotAccessMemory()) + // callee might not access memory but it can return ptrtoint passed + // to it if (callee->doesNotAccessMemory()) // continue; auto n = callee->getName(); if (n.startswith("__sea_set_extptr_slot") ||