Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: recognize ownsem instrinsic aliases #161

Merged
merged 1 commit into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/seadsa/ownsem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef OWNSEM_H_
#define OWNSEM_H_

#include <boost/hana.hpp>

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_
4 changes: 2 additions & 2 deletions include/seadsa/sea_dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_<type>(void *p, unsigned offset, <type>> *p2) in order to
// describe what type it is linking to
Expand Down
72 changes: 48 additions & 24 deletions lib/seadsa/DsaLocal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -433,6 +433,7 @@ enum class SeadsaFn {
LINK,
MAKE,
ACCESS,
RET_ALIAS_ARG,
UNKNOWN
};

Expand All @@ -458,8 +459,7 @@ class IntraBlockBuilder : public InstVisitor<IntraBlockBuilder>,
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);
Expand All @@ -479,22 +479,28 @@ class IntraBlockBuilder : public InstVisitor<IntraBlockBuilder>,
void visitAllocWrapperCall(CallBase &I);
void visitAllocationFnCall(CallBase &I);


SeadsaFn getSeaDsaFn(const Function *fn) {
if (!fn) return SeadsaFn::UNKNOWN;

SeadsaFn fnType = StringSwitch<SeadsaFn>(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<SeadsaFn>(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;

Expand All @@ -517,6 +523,12 @@ class IntraBlockBuilder : public InstVisitor<IntraBlockBuilder>,
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<seadsa::Node &(seadsa::Node *, bool)>;
Expand Down Expand Up @@ -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<seadsa::Cell, 8> toMerge;
LOG("sea-dsa-alias", llvm::errs() << "In alias\n";);
Expand Down Expand Up @@ -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()) {
Expand All @@ -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.

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1771,8 +1795,8 @@ bool isEscapingPtrToInt(const PtrToIntInst &def) {
if (auto *CI = dyn_cast<const CallInst>(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") ||
Expand Down
Loading