Skip to content

Commit

Permalink
OpaquePtr type mapping, missing subroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
mxHuber committed Jun 17, 2024
1 parent 8f89d1d commit 2bfffa8
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 79 deletions.
5 changes: 2 additions & 3 deletions include/phasar/PhasarLLVM/ControlFlow/Resolver/Resolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#define PHASAR_PHASARLLVM_CONTROLFLOW_RESOLVER_RESOLVER_H_

#include "phasar/PhasarLLVM/Pointer/LLVMAliasInfo.h"
#include "phasar/Utils/OpaquePtrTypeMap.h"
#include "phasar/Utils/IRDBOpaquePtrTypes.h"

#include "llvm/ADT/DenseSet.h"

Expand Down Expand Up @@ -55,6 +55,7 @@ class Resolver {
protected:
const LLVMProjectIRDB *IRDB;
const LLVMVFTableProvider *VTP;
IRDBOpaquePtrTypes OpaquePtrTypes;

Resolver(const LLVMProjectIRDB *IRDB);

Expand All @@ -65,8 +66,6 @@ class Resolver {
public:
using FunctionSetTy = llvm::SmallDenseSet<const llvm::Function *, 4>;

OpaquePtrTypeInfoMap OpaquePtrTypeInfo;

Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP);

virtual ~Resolver() = default;
Expand Down
29 changes: 29 additions & 0 deletions include/phasar/Utils/IRDBOpaquePtrTypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

#include "phasar/PhasarLLVM/DB/LLVMProjectIRDB.h"

#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"

#include <map>

namespace psr {

class IRDBOpaquePtrTypes {
public:
IRDBOpaquePtrTypes(const LLVMProjectIRDB *IRDB);
const llvm::Type *getTypeOfPtr(const llvm::Value *Value);

private:
std::map<const llvm::Value *, const llvm::DIType *> ValueToDIType;
std::map<const llvm::DIType *, const llvm::Value *> DITypeToValue;
std::map<const llvm::DISubprogram *,
std::vector<const llvm::DILocalVariable *>>
SubprogamVars;
std::map<const llvm::Value *, const llvm::Type *> ValueToType;

const llvm::DIType *getBaseType(const llvm::DIDerivedType *DerivedTy);
const llvm::Type *getPtrType(const llvm::Value *Value);
};

} // namespace psr
17 changes: 0 additions & 17 deletions include/phasar/Utils/OpaquePtrTypeMap.h

This file was deleted.

37 changes: 3 additions & 34 deletions lib/PhasarLLVM/ControlFlow/Resolver/Resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
Expand Down Expand Up @@ -73,39 +74,7 @@ const llvm::StructType *psr::getReceiverType(const llvm::CallBase *CallSite,
return nullptr;
}

llvm::DebugInfoFinder DIF;
const auto *M = IRDB->getModule();
// IRDB->dump();

DIF.processModule(*M);

for (const auto &SubP : DIF.subprograms()) {
llvm::outs() << "SubP: " << SubP << "\n";
llvm::outs() << "Name: " << SubP->getName() << "\n";
llvm::outs() << "VirtualIndex: " << SubP->getVirtualIndex() << "\n";
llvm::outs() << "Metadata ID: " << SubP->getMetadataID() << "\n";
}

if (Receiver->getType()->isOpaquePointerTy()) {
/*
OpaquePtrTypeInfoMap OpaquePtrTypeInfo(IRDB);
if (const auto &ReceiverInstr =
llvm::dyn_cast<llvm::Instruction>(Receiver)) {
llvm::outs() << "ReceiverInstr opcode name: "
<< ReceiverInstr->getOpcodeName() << "\n";
for (const auto *Instr : IRDB->getAllInstructions()) {
llvm::outs() << "Instr opcode name: " << Instr->getOpcodeName() <<
"\n"; if (Instr->getOpcodeName() == ReceiverInstr->getOpcodeName()) {
if (const auto *ReceiverTy =
llvm::dyn_cast<llvm::StructType>(Instr->getType())) {
llvm::outs() << "\nReceiverTy\n" << ReceiverTy << "\n";
return ReceiverTy;
}
}
}
} */

return nullptr;
}

Expand Down Expand Up @@ -145,12 +114,12 @@ bool psr::isConsistentCall(const llvm::CallBase *CallSite,
namespace psr {

Resolver::Resolver(const LLVMProjectIRDB *IRDB)
: IRDB(IRDB), VTP(nullptr), OpaquePtrTypeInfo(IRDB) {
: IRDB(IRDB), VTP(nullptr), OpaquePtrTypes(IRDB) {
assert(IRDB != nullptr);
}

Resolver::Resolver(const LLVMProjectIRDB *IRDB, const LLVMVFTableProvider *VTP)
: IRDB(IRDB), VTP(VTP), OpaquePtrTypeInfo(IRDB) {}
: IRDB(IRDB), VTP(VTP), OpaquePtrTypes(IRDB) {}

const llvm::Function *
Resolver::getNonPureVirtualVFTEntry(const llvm::StructType *T, unsigned Idx,
Expand Down
126 changes: 126 additions & 0 deletions lib/Utils/IRDBOpaquePtrTypes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#include "phasar/Utils/IRDBOpaquePtrTypes.h"

#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"

namespace psr {

IRDBOpaquePtrTypes::IRDBOpaquePtrTypes(const LLVMProjectIRDB *IRDB) {
llvm::DebugInfoFinder DIF;
const auto *M = IRDB->getModule();
DIF.processModule(*M);

for (const auto *Instr : IRDB->getAllInstructions()) {
if (Instr->getType()->isOpaquePointerTy()) {
llvm::outs() << "is opaque pointer\n";
}
}

// Map values to DITypes
for (const auto *Instr : IRDB->getAllInstructions()) {
// Check if the current instruction has debug information
if (const auto *DbgDeclare = llvm::dyn_cast<llvm::DbgDeclareInst>(Instr)) {
if (auto *Var = llvm::dyn_cast<llvm::DILocalVariable>(
DbgDeclare->getVariable())) {
for (const auto *DIFType : DIF.types()) {
if (Var->getType() == DIFType) {
ValueToDIType.try_emplace(DbgDeclare->getAddress(), DIFType);
}
}
}
}
}

// Map local variables to their according subprograms
for (const auto *DITy : DIF.types()) {
if (const auto *Var = llvm::dyn_cast<llvm::DILocalVariable>(DITy)) {
llvm::outs() << "cast to localVar successful\n";
if (SubprogamVars.find(Var->getScope()->getSubprogram()) ==
SubprogamVars.end()) {
std::vector<const llvm::DILocalVariable *> InitVector;
SubprogamVars.try_emplace(Var->getScope()->getSubprogram(),
std::move(InitVector));
}
SubprogamVars[Var->getScope()->getSubprogram()].push_back(Var);
}
}

// Map pointers to the type they are pointing to
for (const auto *Instr : IRDB->getAllInstructions()) {
if (const auto *Value = llvm::dyn_cast<llvm::Value>(Instr)) {
if (Value->getType()->isOpaquePointerTy()) {
ValueToType.try_emplace(Value, getPtrType(Value));
}
}
}

llvm::outs() << "ValueToDIType map:\n";
for (const auto &[Key, Val] : ValueToDIType) {
llvm::outs() << "Key: " << *Key << " Value: " << *Val << "\n";
}

llvm::outs() << "DITypeToValue map:\n";
for (const auto &[Key, Val] : DITypeToValue) {
llvm::outs() << "Key: " << *Key << " Value: " << *Val << "\n";
}

llvm::outs() << "\nSubprogamVars map:\n";
for (const auto &[Key, Val] : SubprogamVars) {
llvm::outs() << "Key: " << Key << " Values\n{";
for (const auto &Elem : Val) {
llvm::outs() << Elem << ", ";
}
llvm::outs() << "}\n";
}
llvm::outs() << "\nValueToType map:\n";
for (const auto &[Key, Val] : ValueToType) {
llvm::outs() << "Key: " << Key << " Value: " << Val << "\n";
}
}

const llvm::Type *IRDBOpaquePtrTypes::getTypeOfPtr(const llvm::Value *Value) {
return ValueToType[Value];
}

const llvm::DIType *
IRDBOpaquePtrTypes::getBaseType(const llvm::DIDerivedType *DerivedTy) {
if (const auto *BaseTy =
llvm::dyn_cast<llvm::DIBasicType>(DerivedTy->getBaseType())) {
return BaseTy;
};

if (const auto *CompTy =
llvm::dyn_cast<llvm::DICompositeType>(DerivedTy->getBaseType())) {
return CompTy;
}

// case: getBaseType() is a derived type itself
if (const auto *BaseIsDerivedTy =
llvm::dyn_cast<llvm::DIDerivedType>(DerivedTy->getBaseType())) {
return getBaseType(BaseIsDerivedTy);
}

// case: getBaseType() returns a DISubroutineType, in which we need to
// find the type inside the corresponding subprogram
/*
if (const auto *BaseIsInSubprogram =
llvm::dyn_cast<llvm::DISubroutineType>(DerivedTy)) {
return;
}*/
llvm::report_fatal_error("No base type found");
}

const llvm::Type *IRDBOpaquePtrTypes::getPtrType(const llvm::Value *Value) {
const auto *CorrespondingDIType = ValueToDIType[Value];
if (const auto *DerivedTyTy =
llvm::dyn_cast<llvm::DIDerivedType>(CorrespondingDIType)) {
return DITypeToValue[getBaseType(DerivedTyTy)]->getType();
}
llvm::report_fatal_error("Value is not a derived type");
}

} // namespace psr
25 changes: 0 additions & 25 deletions lib/Utils/OpaquePtrTypeMap.cpp

This file was deleted.

4 changes: 4 additions & 0 deletions test/llvm_test_code/call_graphs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ set(NoMem2regSources
global_ctor_dtor_4.cpp
)

foreach(TEST_SRC ${NoMem2regSources})
generate_ll_file(FILE ${TEST_SRC})
endforeach(TEST_SRC)

foreach(TEST_SRC ${NoMem2regSources})
generate_ll_file(FILE ${TEST_SRC} DEBUG)
endforeach(TEST_SRC)

0 comments on commit 2bfffa8

Please sign in to comment.