diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index 5f3e43251a..2cf8b12adf 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -1,6 +1,7 @@ # Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. +add_subdirectory(ClamBCLogicalCompiler) add_subdirectory(ClamBCRemoveUndefs) add_subdirectory(ClamBCPreserveABIs) add_subdirectory(ClamBCAnalyzer) diff --git a/libclambcc/ClamBCLogicalCompiler/CMakeLists.txt b/libclambcc/ClamBCLogicalCompiler/CMakeLists.txt new file mode 100644 index 0000000000..ade02f4c28 --- /dev/null +++ b/libclambcc/ClamBCLogicalCompiler/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + +# +# The clambclogicalcompiler object library +# +add_library(clambclogicalcompiler_obj OBJECT) +target_sources(clambclogicalcompiler_obj + PRIVATE + ClamBCLogicalCompiler.cpp +) + +target_include_directories(clambclogicalcompiler_obj + PRIVATE + ${CMAKE_BINARY_DIR} # For clambc-version.h (generated file) + . # For Common/clambc.h + .. # For clambc.h #TODO: change all passes to use "Common" and then delete this line. + ${LLVM_INCLUDE_DIRS} +) + +set_target_properties(clambclogicalcompiler_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") + +# +# For testing +# +#target_compile_definitions(clambclogicalcompiler_obj -DLOG_BEFORE_AFTER=1) + +# +# The clambclogicalcompiler shared library. +# +add_library( clambclogicalcompiler SHARED ) +target_link_libraries( clambclogicalcompiler + PUBLIC + clambclogicalcompiler_obj ) +set_target_properties( clambclogicalcompiler PROPERTIES + VERSION ${LIBCLAMBC_VERSION} + SOVERSION ${LIBCLAMBC_SOVERSION} ) + +target_link_directories(clambclogicalcompiler PRIVATE ${LLVM_LIBRARY_DIRS}) +target_link_libraries(clambclogicalcompiler PUBLIC ${LLVM_LIBS}) + +if(WIN32) + install(TARGETS clambclogicalcompiler DESTINATION .) + + # Also install shared library (DLL) dependencies + install(CODE [[ + file(GET_RUNTIME_DEPENDENCIES + LIBRARIES + $ + RESOLVED_DEPENDENCIES_VAR _r_deps + UNRESOLVED_DEPENDENCIES_VAR _u_deps + DIRECTORIES + ${LLVM_LIBRARY_DIRS} + ) + foreach(_file ${_r_deps}) + string(TOLOWER ${_file} _file_lower) + if(NOT ${_file_lower} MATCHES "c:[\\/]windows[\\/]system32.*") + file(INSTALL + DESTINATION "${CMAKE_INSTALL_PREFIX}" + TYPE SHARED_LIBRARY + FOLLOW_SYMLINK_CHAIN + FILES "${_file}" + ) + endif() + endforeach() + #message("UNRESOLVED_DEPENDENCIES_VAR: ${_u_deps}") + ]]) +else() + install(TARGETS clambclogicalcompiler DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + + diff --git a/libclambcc/ClamBCLogicalCompiler/ClamBCLogicalCompiler.cpp b/libclambcc/ClamBCLogicalCompiler/ClamBCLogicalCompiler.cpp index 18adfb04ae..ee7171e09c 100644 --- a/libclambcc/ClamBCLogicalCompiler/ClamBCLogicalCompiler.cpp +++ b/libclambcc/ClamBCLogicalCompiler/ClamBCLogicalCompiler.cpp @@ -20,56 +20,59 @@ * MA 02110-1301, USA. */ -#include "ClamBCModule.h" +#include "Common/ClamBCModule.h" +#include "Common/clambc.h" +#include "Common/bytecode_api.h" +#include "Common/ClamBCDiagnostics.h" +#include "Common/ClamBCCommon.h" +#include "Common/ClamBCUtilities.h" + #include -#include "../Common/bytecode_api.h" -#include "clambc.h" -#include "ClamBCDiagnostics.h" -#include "ClamBCModule.h" -#include "ClamBCCommon.h" -#include "ClamBCUtilities.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Analysis/ConstantFolding.h" +#include +#include +#include +#include #include -#include "llvm/Analysis/ValueTracking.h" +#include #include #include #include #include -//#include -#include -#include +#include +#include +#include #include -#include "llvm/Support/Debug.h" +#include #include -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/raw_ostream.h" +#include +#include #include -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Utils/Local.h" -#include "llvm/Transforms/IPO.h" +#include +#include +#include #include -//#include #include #include + #define DEBUG_TYPE "lsigcompiler" using namespace llvm; -namespace +namespace ClamBCLogicalCompiler { -class ClamBCLogicalCompiler : public ModulePass +class ClamBCLogicalCompiler : public PassInfoMixin { public: +#if 0 static char ID; +#endif ClamBCLogicalCompiler() - : ModulePass(ID) {} + /* : ModulePass(ID) */ {} - virtual bool runOnModule(Module &M); + //virtual bool runOnModule(Module &M); + virtual PreservedAnalyses run(Module & m, ModuleAnalysisManager & MAM); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -90,9 +93,9 @@ class ClamBCLogicalCompiler : public ModulePass bool compileVirusNames(Module &M, unsigned kind); }; -char ClamBCLogicalCompiler::ID = 0; -RegisterPass X("clambc-lcompiler", - "ClamAV Logical Compiler"); + + + enum LogicalKind { LOG_SUBSIGNATURE, LOG_AND, @@ -1631,6 +1634,7 @@ bool ClamBCLogicalCompiler::compileVirusNames(Module &M, unsigned kind) bool Valid = true; for (auto I : F->users()) { +#if 0 Value *pv = nullptr; pv = llvm::cast(I); CallSite CS(pv); @@ -1644,14 +1648,48 @@ bool ClamBCLogicalCompiler::compileVirusNames(Module &M, unsigned kind) continue; } assert(CS.arg_size() == 2 && "setvirusname has 2 args"); +#else + CallInst * pCallInst = llvm::cast(I); + if (nullptr == pCallInst){ + assert (0 && "NOT sure how this is possible"); + continue; + } + + if (F != pCallInst->getCalledFunction()){ + + llvm::errs() << "<" << __FUNCTION__ << "::" << __LINE__ << ">NOT SURE HOW THIS IS POSSIBLE\n"; + + /*Not sure how this is possible, either*/ + printDiagnostic("setvirusname can only be directly called", + pCallInst); + Valid = false; + continue; + } +#endif + + if (2 != pCallInst->arg_size()){ + printDiagnostic("setvirusname has 2 args", pCallInst); + Valid = false; + continue; + } + std::string param; llvm::StringRef sr; +#if 0 Value *V = CS.getArgument(0); +#else +#endif + Value * V = llvm::cast(pCallInst->arg_begin()); + if (nullptr == V){ + printDiagnostic("Invalid argument passed to setvirusname", pCallInst); + Valid = false; + continue; + } bool result = getConstantStringInfo(V, sr); param = sr.str(); if (!result) { printDiagnostic("Argument of foundVirus() must be a constant string", - CS.getInstruction()); + pCallInst); Valid = false; continue; } @@ -1662,23 +1700,32 @@ bool ClamBCLogicalCompiler::compileVirusNames(Module &M, unsigned kind) if (!p.empty() && !virusNamesSet.count(p)) { printDiagnostic(Twine("foundVirus called with an undeclared virusname: ", p), - CS.getInstruction()); + pCallInst); Valid = false; continue; } // Add prefix std::string fullname = p.empty() ? virusNamePrefix : virusNamePrefix + "." + p.str(); - IRBuilder<> builder(CS.getInstruction()->getParent()); + IRBuilder<> builder(pCallInst->getParent()); Value *C = builder.CreateGlobalStringPtr(fullname.c_str()); IntegerType *I32Ty = Type::getInt32Ty(M.getContext()); +#if 0 CS.setArgument(0, C); CS.setArgument(1, ConstantInt::get(I32Ty, fullname.size())); +#else + pCallInst->setArgOperand(0, C); + pCallInst->setArgOperand(1, ConstantInt::get(I32Ty, fullname.size())); +#endif } return Valid; } +#if 0 bool ClamBCLogicalCompiler::runOnModule(Module &M) +#else + PreservedAnalyses ClamBCLogicalCompiler::run(Module & M, ModuleAnalysisManager & MAM) +#endif { bool Valid = true; LogicalSignature = ""; @@ -1705,14 +1752,21 @@ bool ClamBCLogicalCompiler::runOnModule(Module &M) GVKind->setConstant(true); } if (!compileVirusNames(M, kind)) { - if (!kind || kind == BC_STARTUP) - return true; + if (!kind || kind == BC_STARTUP) { + // return true; + return PreservedAnalyses::all(); + } Valid = false; } if (F) { +#if 0 LoopInfo &li = getAnalysis(*F).getLoopInfo(); - if (functionHasLoop(F, li)) { +#else + FunctionAnalysisManager &fam = MAM.getResult(M).getManager(); + LoopInfo * li = &fam.getResult(*F); +#endif + if (functionHasLoop(F, *li)) { printDiagnostic("Logical signature: loop/recursion not supported", F); Valid = false; } @@ -1842,13 +1896,45 @@ bool ClamBCLogicalCompiler::runOnModule(Module &M) // diagnostic already printed exit(42); } - return true; + return PreservedAnalyses::none(); } -} // namespace -const PassInfo *const ClamBCLogicalCompilerID = &X; - -llvm::ModulePass *createClamBCLogicalCompiler() +#if 0 +const PassInfo *const ClamBCLogicalCompilerID = &X; llvm::ModulePass *createClamBCLogicalCompiler() { return new ClamBCLogicalCompiler(); } +#endif + + +#if 0 +char ClamBCLogicalCompiler::ID = 0; +RegisterPass X("clambc-lcompiler", + "ClamAV Logical Compiler"); +#else + +// This part is the new way of registering your pass +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + return { + LLVM_PLUGIN_API_VERSION, "ClamBCLogicalCompiler", "v0.1", + [](PassBuilder &PB) { + PB.registerPipelineParsingCallback( + [](StringRef Name, ModulePassManager &FPM, + ArrayRef) { + if(Name == "clambc-lcompiler"){ + FPM.addPass(ClamBCLogicalCompiler()); + return true; + } + return false; + } + ); + } + }; +} +#endif + + +} // namespace + + diff --git a/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp b/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp index 34399303c1..ac7cb2ac0a 100644 --- a/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp +++ b/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp @@ -33,6 +33,15 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include