From 4dde6ac4933ec879bafcafffe898cea51022cd71 Mon Sep 17 00:00:00 2001 From: Andy Ragusa Date: Mon, 14 Aug 2023 12:52:58 -0700 Subject: [PATCH 1/6] Beginning work on Clang 16 upgrade. --- CMakeLists.txt | 33 ++--- cmake/FindClamAV.cmake | 94 -------------- cmake/FindClang.cmake | 177 -------------------------- cmake/FindLLVM.cmake | 173 ------------------------- cmake/Version.cmake | 11 -- libclambcc/CMakeLists.txt | 89 +------------ temp_delete_when_merge/run_opt.sh | 88 +++++++++++++ temp_delete_when_merge/testing/test.c | 43 +++++++ 8 files changed, 153 insertions(+), 555 deletions(-) delete mode 100644 cmake/FindClamAV.cmake delete mode 100644 cmake/FindClang.cmake delete mode 100644 cmake/FindLLVM.cmake delete mode 100644 cmake/Version.cmake create mode 100755 temp_delete_when_merge/run_opt.sh create mode 100644 temp_delete_when_merge/testing/test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f489ac29f..6429d1cb3b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,14 +24,14 @@ project( ClamBCC DESCRIPTION "ClamAV Bytecode Compiler." ) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) -include(Version) +#include(Version) set(PACKAGE_NAME "${PROJECT_NAME}") set(PACKAGE_VERSION "${PROJECT_VERSION}") set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}${VERSION_SUFFIX}") set(PACKAGE_BUGREPORT "https://github.com/Cisco-Talos/clamav-bytecode-compiler/issues") set(PACKAGE_URL "https://www.clamav.net/") -HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH}) +#HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH}) # libtool library versioning rules: http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html set(LIBCLAMBC_CURRENT 1) @@ -40,7 +40,7 @@ set(LIBCLAMBC_AGE 0) math(EXPR LIBCLAMBC_SOVERSION "${LIBCLAMBC_CURRENT} - ${LIBCLAMBC_AGE}") set(LIBCLAMBC_VERSION "${LIBCLAMBC_SOVERSION}.${LIBCLAMBC_AGE}.${LIBCLAMBC_REVISION}") -HexVersion(LIBCLAMBC_VERSION_NUM ${LIBCLAMBC_CURRENT} ${LIBCLAMBC_REVISION} ${LIBCLAMBC_AGE}) +#HexVersion(LIBCLAMBC_VERSION_NUM ${LIBCLAMBC_CURRENT} ${LIBCLAMBC_REVISION} ${LIBCLAMBC_AGE}) # Git optionally used to add commit info into build to differentiate in bug reports. find_package(Git) @@ -103,10 +103,10 @@ if(ENABLE_TESTS) set(Python3_TEST_PACKAGE "pytest;-v") endif() - find_package(ClamAV REQUIRED) + #find_package(ClamAV REQUIRED) endif() -find_package(LLVM 8 REQUIRED) +find_package(LLVM 16 REQUIRED) # Do not disable assertions based on CMAKE_BUILD_TYPE. foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo") @@ -187,13 +187,15 @@ configure_file(clambc-version.h.in clambc-version.h) # Build targets! # +include(AddLLVM) + # The bytecode compiler optimization passes # This is the core of the bytecode compiler add_subdirectory(libclambcc) # The bytecode compiler application # This is really just a python script -add_subdirectory(clambcc) +#add_subdirectory(clambcc) # A tool to generate the runtime interface from the headers #TODO: Finish updating ifacegen to work with modern LLVM @@ -203,7 +205,7 @@ add_subdirectory(clambcc) # # Some of these are copied from ClamAV, some are generated, # and some provide similar interfaces to familiar POSIX API's. -add_subdirectory(headers) +#add_subdirectory(headers) # Documentation (doxygen, manpages) #TODO: @@ -212,17 +214,18 @@ add_subdirectory(headers) # `pandoc -s file.tex -o file.md` mostly-works, but w/ the doxygen integration is insufficient. # add_subdirectory(docs) -if(ENABLE_EXAMPLES) - # Example optimization passes; boilerplate to help compiler devs write new passes. - add_subdirectory( examples ) -endif() +#if(ENABLE_EXAMPLES) +# # Example optimization passes; boilerplate to help compiler devs write new passes. +# add_subdirectory( examples ) +#endif() include(CTest) + add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) -if(ENABLE_TESTS) - # Tests to verify compiler works as intended and that signatures behave as intended. - add_subdirectory( test ) -endif() +#if(ENABLE_TESTS) +# # Tests to verify compiler works as intended and that signatures behave as intended. +# add_subdirectory( test ) +#endif() if(WIN32) # Include the license(s) in the installation diff --git a/cmake/FindClamAV.cmake b/cmake/FindClamAV.cmake deleted file mode 100644 index 0a23a1bd9d..0000000000 --- a/cmake/FindClamAV.cmake +++ /dev/null @@ -1,94 +0,0 @@ -# -# Find the ClamAV programs and headers needed for the test suite. -# -# If found, will set: -# ClamAV_FOUND, ClamAV_VERSION, and -# - clamscan_EXECUTABLE -# - clambc_EXECUTABLE -# - sigtool_EXECUTABLE -# - clambc_headers_DIRECTORY -# -# If you have a custom install location for ClamAV, you can provide a hint -# by settings -DClamAV_HOME= -# - -find_program(clamscan_EXECUTABLE - NAMES clamscan clamscan.exe - HINTS "${ClamAV_HOME}" - PATH_SUFFIXES "bin" -) -if(NOT clamscan_EXECUTABLE AND NOT ClamAV_FIND_QUIETLY) - message("Unable to find clamscan") -endif() - -find_program(clambc_EXECUTABLE - NAMES clambc clambc.exe - HINTS "${ClamAV_HOME}" - PATH_SUFFIXES "bin" -) -if(NOT clambc_EXECUTABLE_EXECUTABLE AND NOT ClamAV_FIND_QUIETLY) - message("Unable to find clambc") -endif() - -find_program(sigtool_EXECUTABLE - NAMES sigtool sigtool.exe - HINTS "${ClamAV_HOME}" - PATH_SUFFIXES "bin" -) -if(NOT sigtool_EXECUTABLE AND NOT ClamAV_FIND_QUIETLY) - message("Unable to find sigtool") -endif() - -if(clamscan_EXECUTABLE AND clambc_EXECUTABLE AND sigtool_EXECUTABLE) - execute_process(COMMAND "${clamscan_EXECUTABLE}" --version - OUTPUT_VARIABLE ClamAV_VERSION_OUTPUT - ERROR_VARIABLE ClamAV_VERSION_ERROR - RESULT_VARIABLE ClamAV_VERSION_RESULT - ) - if(NOT ${ClamAV_VERSION_RESULT} EQUAL 0) - if(NOT ClamAV_FIND_QUIETLY) - message(STATUS "ClamAV not found: Failed to determine version.") - endif() - unset(clamscan_EXECUTABLE) - else() - string(REGEX - MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?(-devel)?" - ClamAV_VERSION "${ClamAV_VERSION_OUTPUT}" - ) - set(ClamAV_VERSION "${ClamAV_VERSION}") - set(ClamAV_FOUND 1) - - # Look for the clambc-headers. E.g.: /lib/clambc-headers/0.104.0 - # - # In the future, the clamav-derived headers for compiling signatures will be - # installed with clamav, and this path will be necessary to find them for running - # the test suite. - find_file(clambc_headers_DIRECTORY - clambc-headers/${ClamAV_VERSION} - HINTS "${ClamAV_HOME}" - PATH_SUFFIXES "lib" - ) - - if(NOT ClamAV_FIND_QUIETLY) - message(STATUS "ClamAV found: ${ClamAV_VERSION}") - message(STATUS " clamscan: ${clamscan_EXECUTABLE}") - message(STATUS " clambc: ${clambc_EXECUTABLE}") - message(STATUS " sigtool: ${sigtool_EXECUTABLE}") - message(STATUS " bc headers: ${clambc_headers_DIRECTORY}") - endif() - - if(NOT clambc_headers_DIRECTORY) - set(clambc_headers_DIRECTORY "") - endif() - endif() - - mark_as_advanced(clamscan_EXECUTABLE clambc_EXECUTABLE sigtool_EXECUTABLE ClamAV_VERSION) -else() - if(ClamAV_FIND_REQUIRED) - message(FATAL_ERROR "ClamAV not found.") - else() - if(NOT ClamAV_FIND_QUIETLY) - message(STATUS "${_msg}") - endif() - endif() -endif() diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake deleted file mode 100644 index 4db126c9ed..0000000000 --- a/cmake/FindClang.cmake +++ /dev/null @@ -1,177 +0,0 @@ -# Detect Clang libraries -# -# Defines the following variables: -# CLANG_FOUND - True if Clang was found -# CLANG_INCLUDE_DIRS - Where to find Clang includes -# CLANG_LIBRARY_DIRS - Where to find Clang libraries -# CLANG_BUILTIN_DIR - Where to find Clang builtin includes -# -# CLANG_CLANG_LIB - Libclang C library -# -# CLANG_CLANGFRONTEND_LIB - Clang Frontend (C++) Library -# CLANG_CLANGDRIVER_LIB - Clang Driver (C++) Library -# ... -# -# CLANG_LIBS - All the Clang C++ libraries -# -# Uses the same include and library paths detected by FindLLVM.cmake -# -# See https://clang.llvm.org/docs/InternalsManual.html for full list of libraries - -#============================================================================= -# Copyright 2014-2015 Kevin Funk -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. - -#============================================================================= - -set(KNOWN_VERSIONS 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8) - -foreach(version ${KNOWN_VERSIONS}) - if(DEFINED Clang_FIND_VERSION AND Clang_FIND_VERSION VERSION_EQUAL version) - find_package(LLVM ${version} PATHS ${LLVM_ROOT}) - else() - find_package(LLVM PATHS ${LLVM_ROOT}) - endif() -endforeach() - -if (${Clang_FIND_REQUIRED}) - if(NOT DEFINED LLVM_FOUND) - message(SEND_ERROR "Could not find LLVM (or Clang for that matter)") - else() - message("Found LLVM version ${LLVM_VERSION}") - endif() -endif() - -set(CLANG_FOUND FALSE) - -if(LLVM_FOUND AND LLVM_LIBRARY_DIRS) - message("Searching for clang libraries...") - macro(FIND_AND_ADD_CLANG_LIB _libname_) - # message("Searching for ${LLVM_LIBRARY_DIRS}/lib${_libname_}-${Clang_FIND_VERSION}.so.1") - string(TOUPPER ${_libname_} _prettylibname_) - find_library(CLANG_${_prettylibname_}_LIB - NAMES - ${_libname_}-${Clang_FIND_VERSION}.so.1 lib${_libname_}-${Clang_FIND_VERSION}.so.1 - ${_libname_}-${Clang_FIND_VERSION} lib${_libname_}-${Clang_FIND_VERSION} - ${_libname_}.so.1 lib${_libname_}.so.1 - ${_libname_} lib${_libname_} - HINTS - ${LLVM_LIBRARY_DIRS} ${ARGN}) - if(CLANG_${_prettylibname_}_LIB) - message("Found ${CLANG_${_prettylibname_}_LIB}") - set(CLANG_LIBS ${CLANG_LIBS} ${CLANG_${_prettylibname_}_LIB}) - endif() - endmacro(FIND_AND_ADD_CLANG_LIB) - - FIND_AND_ADD_CLANG_LIB(clangFrontend) - - # note: On Windows there's 'libclang.dll' instead of 'clang.dll' -> search for 'libclang', too - FIND_AND_ADD_CLANG_LIB(clang NAMES clang libclang clang-${Clang_FIND_VERSION} libclang-${Clang_FIND_VERSION}) # LibClang: high-level C interface - - FIND_AND_ADD_CLANG_LIB(clangDriver) - FIND_AND_ADD_CLANG_LIB(clangCodeGen) - FIND_AND_ADD_CLANG_LIB(clangSema) - FIND_AND_ADD_CLANG_LIB(clangChecker) - FIND_AND_ADD_CLANG_LIB(clangAnalysis) - FIND_AND_ADD_CLANG_LIB(clangRewriteFrontend) - FIND_AND_ADD_CLANG_LIB(clangRewrite) - FIND_AND_ADD_CLANG_LIB(clangAST) - FIND_AND_ADD_CLANG_LIB(clangParse) - FIND_AND_ADD_CLANG_LIB(clangLex) - FIND_AND_ADD_CLANG_LIB(clangBasic) - FIND_AND_ADD_CLANG_LIB(clangARCMigrate) - FIND_AND_ADD_CLANG_LIB(clangEdit) - FIND_AND_ADD_CLANG_LIB(clangFrontendTool) - FIND_AND_ADD_CLANG_LIB(clangSerialization) - FIND_AND_ADD_CLANG_LIB(clangTooling) - FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCheckers) - FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerCore) - FIND_AND_ADD_CLANG_LIB(clangStaticAnalyzerFrontend) - FIND_AND_ADD_CLANG_LIB(clangRewriteCore) -endif() - -if(CLANG_LIBS OR CLANG_CLANG_LIB) - set(CLANG_FOUND TRUE) -else() - message(STATUS "Could not find any Clang libraries in ${LLVM_LIBRARY_DIRS}") -endif() - -if(CLANG_FOUND) - set(CLANG_LIBRARY_DIRS ${LLVM_LIBRARY_DIRS}) - set(CLANG_INCLUDE_DIRS ${LLVM_INCLUDE_DIRS}) - set(CLANG_VERSION ${LLVM_VERSION}) - - # svn version of clang has a svn suffix "8.0.0svn" but installs the header in "8.0.0", without the suffix - string(REPLACE "svn" "" CLANG_VERSION_CLEAN "${CLANG_VERSION}") - # dito for git - string(REPLACE "git" "" CLANG_VERSION_CLEAN "${CLANG_VERSION}") - - find_path(CLANG_BUILTIN_DIR - # cpuid.h because it is defined in ClangSupport constructor as valid clang builtin dir indicator - NAMES "cpuid.h" - PATHS "${CLANG_LIBRARY_DIRS}" - "${CLANG_INCLUDE_DIRS}" - PATH_SUFFIXES "clang/${CLANG_VERSION}/include" - "../../../clang/${CLANG_VERSION}/include" - "clang/${CLANG_VERSION_CLEAN}/include" - "../../../clang/${CLANG_VERSION_CLEAN}/include" - NO_DEFAULT_PATH - ) - - if (NOT CLANG_BUILTIN_DIR) - message(FATAL_ERROR "Could not find Clang builtin directory") - endif() - get_filename_component(CLANG_BUILTIN_DIR ${CLANG_BUILTIN_DIR} ABSOLUTE) - - # check whether llvm-config comes from an install prefix - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --src-root - OUTPUT_VARIABLE _llvmSourceRoot - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(FIND "${LLVM_INCLUDE_DIRS}" "${_llvmSourceRoot}" _llvmIsInstalled) - if (NOT _llvmIsInstalled) - message(STATUS "Detected that llvm-config comes from a build-tree, adding more include directories for Clang") - list(APPEND CLANG_INCLUDE_DIRS - "${LLVM_INSTALL_PREFIX}/tools/clang/include" # build dir - ) - - # check whether the source is from llvm-project.git (currently recommended way to clone the LLVM projects) - # contains all LLVM projects in the top-level directory - get_filename_component(_llvmProjectClangIncludeDir ${_llvmSourceRoot}/../clang/include REALPATH) - if (EXISTS ${_llvmProjectClangIncludeDir}) - message(STATUS " Note: llvm-project.git structure detected, using different include path pointing into source dir") - list(APPEND CLANG_INCLUDE_DIRS "${_llvmProjectClangIncludeDir}") # source dir - else() - list(APPEND CLANG_INCLUDE_DIRS "${_llvmSourceRoot}/tools/clang/include") # source dir - endif() - endif() - - # if the user specified LLVM_ROOT, use that and fail otherwise - if (LLVM_ROOT) - find_program(CLANG_EXECUTABLE NAMES clang HINTS ${LLVM_ROOT}/bin DOC "clang executable" NO_DEFAULT_PATH) - elseif (NOT CLANG_EXECUTABLE) - # find clang, prefer the one with a version suffix, e.g. clang-3.5 - # note: FreeBSD installs clang as clang35 and so on - # note: on some distributions, only 'clang' is shipped, so let's always try to fallback on that - string(REPLACE "." "" Clang_FIND_VERSION_CONCAT ${Clang_FIND_VERSION}) - find_program(CLANG_EXECUTABLE NAMES clang-${Clang_FIND_VERSION} clang${Clang_FIND_VERSION_CONCAT} clang DOC "clang executable") - endif() - - message(STATUS "Found Clang (LLVM version: ${CLANG_VERSION})") - message(STATUS " Include dirs: ${CLANG_INCLUDE_DIRS}") - message(STATUS " Clang libraries: ${CLANG_LIBS}") - message(STATUS " Libclang C library: ${CLANG_CLANG_LIB}") - message(STATUS " Builtin include dir: ${CLANG_BUILTIN_DIR}") - message(STATUS " Clang executable: ${CLANG_EXECUTABLE}") -else() - if(Clang_FIND_REQUIRED) - message(FATAL_ERROR "Could NOT find Clang") - endif() -endif() diff --git a/cmake/FindLLVM.cmake b/cmake/FindLLVM.cmake deleted file mode 100644 index 9e94b2d509..0000000000 --- a/cmake/FindLLVM.cmake +++ /dev/null @@ -1,173 +0,0 @@ -# Find the native LLVM includes and libraries -# -# Defines the following variables -# LLVM_INCLUDE_DIRS - where to find llvm include files -# LLVM_LIBRARY_DIRS - where to find llvm libs -# LLVM_CFLAGS - llvm compiler flags -# LLVM_LFLAGS - llvm linker flags -# LLVM_MODULE_LIBS - list of llvm libs for working with modules. -# LLVM_INSTALL_PREFIX - LLVM installation prefix -# LLVM_FOUND - True if llvm found. -# LLVM_VERSION - Version string ("llvm-config --version") -# -# This module reads hints about search locations from variables -# LLVM_ROOT - Preferred LLVM installation prefix (containing bin/, lib/, ...) -# -# Note: One may specify these as environment variables if they are not specified as -# CMake variables or cache entries. - -#============================================================================= -# Copyright 2014 Kevin Funk -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= - -if(NOT LLVM_ROOT AND DEFINED ENV{LLVM_ROOT}) - file(TO_CMAKE_PATH "$ENV{LLVM_ROOT}" LLVM_ROOT) -endif() - -# if the user specified LLVM_ROOT, use that and fail otherwise -if(LLVM_ROOT) - find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config HINTS ${LLVM_ROOT}/bin DOC "llvm-config executable" NO_DEFAULT_PATH) -elseif(NOT LLVM_CONFIG_EXECUTABLE) - # find llvm-config, prefer the one with a version suffix, e.g. llvm-config-3.5 - # note: FreeBSD installs llvm-config as llvm-config35 and so on - # note: on some distributions, only 'llvm-config' is shipped, so let's always try to fallback on that - string(REPLACE "." "" LLVM_FIND_VERSION_CONCAT_PREFIX ${LLVM_FIND_VERSION}) - list(APPEND LLVM_FIND_VERSION_CONCAT llvm-config${LLVM_FIND_VERSION_CONCAT_PREFIX}) - - foreach(i RANGE 0 9) - list(APPEND LLVM_FIND_VERSION_CONCAT llvm-config${LLVM_FIND_VERSION_CONCAT_PREFIX}${i}) - endforeach() - message("llvm-config list: ${LLVM_FIND_VERSION_CONCAT}") - - find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config-${LLVM_FIND_VERSION} ${LLVM_FIND_VERSION_CONCAT} llvm-config DOC "llvm-config executable") - - # other distributions don't ship llvm-config, but only some llvm-config-VERSION binary - # try to deduce installed LLVM version by looking up llvm-nm in PATH and *then* find llvm-config-VERSION via that - if(NOT LLVM_CONFIG_EXECUTABLE) - find_program(_llvmNmExecutable llvm-nm) - if(_llvmNmExecutable) - execute_process(COMMAND ${_llvmNmExecutable} --version OUTPUT_VARIABLE _out) - string(REGEX REPLACE ".*LLVM version ([^ \n]+).*" "\\1" _versionString "${_out}") - find_program(LLVM_CONFIG_EXECUTABLE NAMES llvm-config-${_versionString} DOC "llvm-config executable") - endif() - endif() -endif() - -set(LLVM_FOUND FALSE) - -if(LLVM_CONFIG_EXECUTABLE) - # verify that we've found the correct version of llvm-config - execute_process(COMMAND ${LLVM_CONFIG_EXECUTABLE} --version - OUTPUT_VARIABLE LLVM_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - - if(NOT LLVM_VERSION) - set(_LLVM_ERROR_MESSAGE "Failed to parse version from ${LLVM_CONFIG_EXECUTABLE}") - unset(LLVM_CONFIG_EXECUTABLE CACHE) - elseif(LLVM_FIND_VERSION VERSION_GREATER LLVM_VERSION) - set(_LLVM_ERROR_MESSAGE "${LLVM_CONFIG_EXECUTABLE} (version ${LLVM_VERSION}) unsuitable: too old for requested version ${LLVM_FIND_VERSION}") - unset(LLVM_CONFIG_EXECUTABLE CACHE) - else() - set(LLVM_FOUND TRUE) - endif() -else() - set(_LLVM_ERROR_MESSAGE "Could NOT find 'llvm-config' executable") -endif() - -if(LLVM_FOUND) - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --includedir - OUTPUT_VARIABLE LLVM_INCLUDE_DIRS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir - OUTPUT_VARIABLE LLVM_LIBRARY_DIRS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --cppflags - OUTPUT_VARIABLE LLVM_CFLAGS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --ldflags - OUTPUT_VARIABLE LLVM_LFLAGS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --libs core bitreader asmparser analysis - OUTPUT_VARIABLE LLVM_MODULE_LIBS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --libfiles - OUTPUT_VARIABLE LLVM_LIBS - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir - OUTPUT_VARIABLE LLVM_LIB_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - #execute_process stores results in a string, and we need a list. - string(REGEX MATCHALL "${LLVM_LIB_DIR}[^ ]*" LLVM_LIBS ${LLVM_LIBS}) - - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --prefix - OUTPUT_VARIABLE LLVM_INSTALL_PREFIX - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - if(NOT ${LLVM_VERSION} VERSION_LESS "3.8.0") - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --shared-mode - OUTPUT_VARIABLE _LLVM_SHARED_MODE - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(_LLVM_SHARED_MODE STREQUAL "shared") - set(LLVM_SHARED_MODE ON) - else() - set(LLVM_SHARED_MODE OFF) - endif() - else() - set(LLVM_SHARED_MODE OFF) - endif() - - # potentially add include dir from binary dir for non-installed LLVM - execute_process( - COMMAND ${LLVM_CONFIG_EXECUTABLE} --src-root - OUTPUT_VARIABLE _llvmSourceRoot - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(FIND "${LLVM_INCLUDE_DIRS}" "${_llvmSourceRoot}" _llvmIsInstalled) - if(NOT _llvmIsInstalled) - list(APPEND LLVM_INCLUDE_DIRS "${LLVM_INSTALL_PREFIX}/include") - endif() -endif() - -if(LLVM_FIND_REQUIRED AND NOT LLVM_FOUND) - message(FATAL_ERROR "Could not find LLVM: ${_LLVM_ERROR_MESSAGE}") -elseif(_LLVM_ERROR_MESSAGE) - message(STATUS "Could not find LLVM: ${_LLVM_ERROR_MESSAGE}") -endif() - -if(LLVM_FOUND) - message(STATUS "Found LLVM (version: ${LLVM_VERSION}): (using ${LLVM_CONFIG_EXECUTABLE})") - message(STATUS " Include dirs: ${LLVM_INCLUDE_DIRS}") - message(STATUS " LLVM libraries: ${LLVM_LIBS}") -endif() diff --git a/cmake/Version.cmake b/cmake/Version.cmake deleted file mode 100644 index 8ac4849c97..0000000000 --- a/cmake/Version.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# Converts a version such as 1.2.255 to 0x0102ff -function(HexVersion version_hex_var major minor patch) - math(EXPR version_dec "${major} * 256 * 256 + ${minor} * 256 + ${patch}") - set(version_hex "0x") - foreach(i RANGE 5 0 -1) - math(EXPR num "(${version_dec} >> (4 * ${i})) & 15") - string(SUBSTRING "0123456789abcdef" ${num} 1 num_hex) - set(version_hex "${version_hex}${num_hex}") - endforeach() - set(${version_hex_var} "${version_hex}" PARENT_SCOPE) -endfunction() diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index 4812a8f87c..f8f5033ee1 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -1,89 +1,8 @@ # Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. -# -# The clambcc object library -# -add_library(clambcc_obj OBJECT) -target_sources(clambcc_obj - PRIVATE - ClamBCLowering/ClamBCLowering.cpp - ClamBCVerifier/ClamBCVerifier.cpp - ClamBCLogicalCompiler/ClamBCLogicalCompiler.cpp - ClamBCRebuild/ClamBCRebuild.cpp - ClamBCTrace/ClamBCTrace.cpp - ClamBCModule/ClamBCModule.cpp - ClamBCWriter/ClamBCWriter.cpp - ClamBCAnalyzer/ClamBCAnalyzer.cpp - Common/ClamBCDiagnostics.cpp - Common/ClamBCUtilities.cpp - Common/ClamBCRegAlloc.cpp - Common/version.c - ClamBCPrepareGEPsForWriter/ClamBCPrepareGEPsForWriter.cpp - ClamBCRemoveSelectInsts/ClamBCRemoveSelectInsts.cpp - ClamBCOutlineEndiannessCalls/ClamBCOutlineEndiannessCalls.cpp - ClamBCChangeMallocArgSize/ClamBCChangeMallocArgSize.cpp - ClamBCRemovePointerPHIs/ClamBCRemovePointerPHIs.cpp - ClamBCConvertIntrinsics/ClamBCConvertIntrinsics.cpp - ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp - ClamBCPreserveABIs/ClamBCPreserveABIs.cpp - ClamBCExtendPHIsTo64Bit/ClamBCExtendPHIsTo64Bit.cpp -) -target_include_directories(clambcc_obj - PRIVATE - ${CMAKE_BINARY_DIR} # For clambc-version.h (generated file) - . # For Common/clambc.h - Common # For clambc.h #TODO: change all passes to use "Common" and then delete this line. - ${LLVM_INCLUDE_DIRS} -) +#add_subdirectory(ClamBCRemoveUndefs) +#add_subdirectory(ClamBCPreserveABIs) +#add_subdirectory(ClamBCAnalyzer) +#add_subdirectory(Common) -set_target_properties(clambcc_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") - -# -# For testing -# -#target_compile_definitions(clambc_obj -DLOG_BEFORE_AFTER=1) - -# -# The clambcc shared library. -# -add_library( clambcc SHARED ) -target_link_libraries( clambcc - PUBLIC - clambcc_obj ) -set_target_properties( clambcc PROPERTIES - VERSION ${LIBCLAMBC_VERSION} - SOVERSION ${LIBCLAMBC_SOVERSION} ) - -target_link_directories(clambcc PRIVATE ${LLVM_LIBRARY_DIRS}) -target_link_libraries(clambcc PUBLIC ${LLVM_LIBS}) - -if(WIN32) - install(TARGETS clambcc 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 clambcc DESTINATION ${CMAKE_INSTALL_LIBDIR}) -endif() diff --git a/temp_delete_when_merge/run_opt.sh b/temp_delete_when_merge/run_opt.sh new file mode 100755 index 0000000000..2c38258716 --- /dev/null +++ b/temp_delete_when_merge/run_opt.sh @@ -0,0 +1,88 @@ +#!/bin/bash + + +#might be useful +#https://stackoverflow.com/questions/67206238/how-to-define-and-read-cli-arguments-for-an-llvm-pass-with-the-new-pass-manager + + + +clang-16 -S \ + -fno-discard-value-names \ + --language=c \ + -emit-llvm \ + -Werror=unused-command-line-argument \ + -Xclang \ + -disable-O0-optnone \ + -o test.ll \ + ../../testing/BC.Img.Exploit.CVE_2017_3124-6335443-1.c \ + -I ../../../build/install/bin/../include \ + -include bytecode.h \ + -D__CLAMBC__ + + +clang-16 -S -emit-llvm -O0 -Xclang -disable-O0-optnone ../../testing/test.c + + + +#opt-16 -S --load-pass-plugin libclambcc/libclambcc.so --passes="my-module-pass,my-function-pass" test.ll -o test.t.ll + +#opt-16 -S --load-pass-plugin libclambcc/libclambcc.so --passes=my-module-pass test.ll -o test.t.ll +#opt-16 -S --load-pass-plugin libclambcc/libclambcc.so --passes=my-function-pass test.ll -o test.t.ll + + + +#opt-16 -S --load-pass-plugin libclambcc/libclambcc.so --load-pass-plugin ./libclambcc/MyModulePass/libclambcc_mymodulepass.so --passes=my-module-pass test.ll -o test.t.ll + + + +#opt-16 -S \ +# --load-pass-plugin libclambcc/libclambcc.so \ +# --load-pass-plugin libclambcc/MyModulePass/libclambcc_mymodulepass.so \ +# --passes="my-module-pass,my-function-pass" test.ll -o test.t.ll +# + + + +#Function Passes and Module Passes can't be mixed. If we are going to have to +#mix them, we need a wrapper to wrap the function pass in a module pass. + + + +#opt-16 -S \ +# --load-pass-plugin libclambcc/MyModulePass/libclambcc_mymodulepass.so \ +# --load-pass-plugin libclambcc/MyModulePass2/libclambcc_mymodulepass2.so \ +# --load-pass-plugin libclambcc/MyFunctionPass/libclambcc_myfunctionpass.so \ +# --passes="my-module-pass2,my-module-pass" test.ll -o test.t.ll +# +# +#opt-16 -S \ +# --load-pass-plugin libclambcc/MyModulePass/libclambcc_mymodulepass.so \ +# --load-pass-plugin libclambcc/MyModulePass2/libclambcc_mymodulepass2.so \ +# --load-pass-plugin libclambcc/MyFunctionPass/libclambcc_myfunctionpass.so \ +# --passes="my-function-pass" test.ll -o test.t.ll +# + + + +#There are warnings about not being able to load libclambccommon.so, but I +#can add print statements to functions in that library and have them print, so ??? +opt-16 -S \ + --load libclambcc/Common/libclambccommon.so \ + --load-pass-plugin libclambcc/ClamBCRemoveUndefs/libclambcremoveundefs.so \ + --load-pass-plugin libclambcc/ClamBCPreserveABIs/libclambcpreserveabis.so \ + --load-pass-plugin libclambcc/ClamBCAnalyzer/libclambcanalyzer.so \ + --passes="-mem2reg"\ + --passes="clambc-remove-undefs,clambc-preserve-abis,default,clambc-preserve-abis" \ + test.ll -o test.t.ll + +#opt-16 -S \ +# --load libclambcc/Common/libclambccommon.so \ +# --load-pass-plugin libclambcc/ClamBCRemoveUndefs/libclambcremoveundefs.so \ +# --load-pass-plugin libclambcc/ClamBCPreserveABIs/libclambcpreserveabis.so \ +# --load-pass-plugin libclambcc/ClamBCAnalyzer/libclambcanalyzer.so \ +# --passes="-mem2reg"\ +# --passes="clambc-remove-undefs,clambc-preserve-abis,default,clambc-preserve-abis,clambc-remove-pointer-phis" \ +# test.ll -o test.t.ll +# + + diff --git a/temp_delete_when_merge/testing/test.c b/temp_delete_when_merge/testing/test.c new file mode 100644 index 0000000000..e2700bb628 --- /dev/null +++ b/temp_delete_when_merge/testing/test.c @@ -0,0 +1,43 @@ +#include + + +void func(int val){ + printf("%s::%d\n", __FUNCTION__, __LINE__); +} + + +typedef struct s *sp; + +static sp func2(){ + return NULL; +} + +const char * const CONST_CP = "hi there"; + +void func3(const char * const val) { + + if (CONST_CP == val){ + printf("val = 'CP'\n"); + } else { + printf("val = '%p'\n", val); + } + +} + + +int main(int argc, char ** argv){ + + const char * val = CONST_CP; + + if (argc > 2){ + func(1); + } else if (1 == argc){ + val = argv[0]; + } + + func3(val); + + return 0; + + +} From a02640e25763073519b06a474dfcafa414319d3c Mon Sep 17 00:00:00 2001 From: Andy Ragusa Date: Mon, 14 Aug 2023 16:22:02 -0700 Subject: [PATCH 2/6] Initial work on ClamBCRemoveUndefs --- libclambcc/CMakeLists.txt | 2 +- libclambcc/ClamBCRemoveUndefs/CMakeLists.txt | 72 +++++++++++++++++++ .../ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp | 69 ++++++++++++++++-- 3 files changed, 137 insertions(+), 6 deletions(-) create mode 100644 libclambcc/ClamBCRemoveUndefs/CMakeLists.txt diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index f8f5033ee1..808dff8cb2 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -1,7 +1,7 @@ # Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. -#add_subdirectory(ClamBCRemoveUndefs) +add_subdirectory(ClamBCRemoveUndefs) #add_subdirectory(ClamBCPreserveABIs) #add_subdirectory(ClamBCAnalyzer) #add_subdirectory(Common) diff --git a/libclambcc/ClamBCRemoveUndefs/CMakeLists.txt b/libclambcc/ClamBCRemoveUndefs/CMakeLists.txt new file mode 100644 index 0000000000..a8403ede67 --- /dev/null +++ b/libclambcc/ClamBCRemoveUndefs/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + +# +# The clambcremoveundefs object library +# +add_library(clambcremoveundefs_obj OBJECT) +target_sources(clambcremoveundefs_obj + PRIVATE + ClamBCRemoveUndefs.cpp +) + +target_include_directories(clambcremoveundefs_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(clambcremoveundefs_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") + +# +# For testing +# +#target_compile_definitions(clambcremoveundefs_obj -DLOG_BEFORE_AFTER=1) + +# +# The clambcremoveundefs shared library. +# +add_library( clambcremoveundefs SHARED ) +target_link_libraries( clambcremoveundefs + PUBLIC + clambcremoveundefs_obj ) +set_target_properties( clambcremoveundefs PROPERTIES + VERSION ${LIBCLAMBC_VERSION} + SOVERSION ${LIBCLAMBC_SOVERSION} ) + +target_link_directories(clambcremoveundefs PRIVATE ${LLVM_LIBRARY_DIRS}) +target_link_libraries(clambcremoveundefs PUBLIC ${LLVM_LIBS}) + +if(WIN32) + install(TARGETS clambcremoveundefs 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 clambcremoveundefs DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + + diff --git a/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp b/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp index 2151b1142f..643e378f9c 100644 --- a/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp +++ b/libclambcc/ClamBCRemoveUndefs/ClamBCRemoveUndefs.cpp @@ -5,6 +5,19 @@ #include "llvm/IR/Instructions.h" #include "llvm/Support/raw_ostream.h" + + +#include "llvm/IR/PassManager.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Support/raw_ostream.h" + + + + + + + #include #include "llvm/IR/LegacyPassManager.h" @@ -32,10 +45,10 @@ namespace store %struct._state* %state, %struct._state** %state.addr, align 8 store i32 %sizeof_state, i32* %sizeof_state.addr, align 4 */ -class ClamBCRemoveUndefs : public ModulePass +struct ClamBCRemoveUndefs : public PassInfoMixin { protected: - llvm::Module *pMod = nullptr; + Module *pMod = nullptr; std::map aborts; bool bChanged = false; @@ -56,10 +69,21 @@ class ClamBCRemoveUndefs : public ModulePass FunctionType *rterrTy = FunctionType::get( Type::getInt32Ty(BB->getContext()), {Type::getInt32Ty(BB->getContext())}, false); +#if 0 Constant *func_abort = BB->getParent()->getParent()->getOrInsertFunction("abort", abrtTy); + Constant *func_rterr = BB->getParent()->getParent()->getOrInsertFunction("bytecode_rt_error", rterrTy); + +#else + llvm::errs() << "<" << __LINE__ << ">" << "Don't know if this will work, remove the ifdef later\n"; + + FunctionCallee func_abort = BB->getParent()->getParent()->getOrInsertFunction("abort", abrtTy); + FunctionCallee func_rterr = + BB->getParent()->getParent()->getOrInsertFunction("bytecode_rt_error", rterrTy); + +#endif BasicBlock *abort = BasicBlock::Create(BB->getContext(), "rterr.trig", BB->getParent()); Constant *PN = ConstantInt::get(Type::getInt32Ty(BB->getContext()), 99); if (MDDbgKind) { @@ -217,13 +241,21 @@ class ClamBCRemoveUndefs : public ModulePass } public: +#if 0 static char ID; - ClamBCRemoveUndefs() - : ModulePass(ID) {} + ClamBCRemoveUndefs() {} +#endif virtual ~ClamBCRemoveUndefs() {} + + + +#if 0 bool runOnModule(Module &m) override +#else + PreservedAnalyses run(Module & m, ModuleAnalysisManager & MAM) +#endif { pMod = &m; @@ -240,13 +272,40 @@ class ClamBCRemoveUndefs : public ModulePass delLst[i]->eraseFromParent(); } - return bChanged; + errs() << "<" << __LINE__ << ">" << "99\% sure this is wrong, since this pass does NOT preserve analyses\n"; + return PreservedAnalyses::all(); } }; // end of struct ClamBCRemoveUndefs } // end of anonymous namespace +#if 0 char ClamBCRemoveUndefs::ID = 0; static RegisterPass X("clambc-remove-undefs", "Remove Undefs", false /* Only looks at CFG */, false /* Analysis Pass */); +#else + +// This part is the new way of registering your pass +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + return { + LLVM_PLUGIN_API_VERSION, "ClamBCRemoveUndefs", "v0.1", + [](PassBuilder &PB) { + PB.registerPipelineParsingCallback( + [](StringRef Name, ModulePassManager &FPM, + ArrayRef) { + if(Name == "clambc-remove-undefs"){ + FPM.addPass(ClamBCRemoveUndefs()); + return true; + } + return false; + } + ); + } + }; +} + + +#endif + From 876e804a09df57d8e6b07636bbc2dda20c3e1593 Mon Sep 17 00:00:00 2001 From: Andy Ragusa Date: Mon, 14 Aug 2023 17:01:56 -0700 Subject: [PATCH 3/6] Initial work to common library --- libclambcc/CMakeLists.txt | 2 +- libclambcc/Common/CMakeLists.txt | 74 +++++++++++++++++++++++++++ libclambcc/Common/ClamBCRegAlloc.cpp | 16 ++++++ libclambcc/Common/ClamBCUtilities.cpp | 7 +++ libclambcc/Common/ClamBCUtilities.h | 2 + 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 libclambcc/Common/CMakeLists.txt diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index 808dff8cb2..49e1c5718a 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -4,5 +4,5 @@ add_subdirectory(ClamBCRemoveUndefs) #add_subdirectory(ClamBCPreserveABIs) #add_subdirectory(ClamBCAnalyzer) -#add_subdirectory(Common) +add_subdirectory(Common) diff --git a/libclambcc/Common/CMakeLists.txt b/libclambcc/Common/CMakeLists.txt new file mode 100644 index 0000000000..1ce211a997 --- /dev/null +++ b/libclambcc/Common/CMakeLists.txt @@ -0,0 +1,74 @@ +# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + +# +# The clambccommon object library +# +add_library(clambccommon_obj OBJECT) +target_sources(clambccommon_obj + PRIVATE + ClamBCDiagnostics.cpp + ClamBCRegAlloc.cpp + ClamBCUtilities.cpp +) + +target_include_directories(clambccommon_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(clambccommon_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") + +# +# For testing +# +#target_compile_definitions(clambccommon_obj -DLOG_BEFORE_AFTER=1) + +# +# The clambccommon shared library. +# +add_library( clambccommon SHARED ) +target_link_libraries( clambccommon + PUBLIC + clambccommon_obj ) +set_target_properties( clambccommon PROPERTIES + VERSION ${LIBCLAMBC_VERSION} + SOVERSION ${LIBCLAMBC_SOVERSION} ) + +target_link_directories(clambccommon PRIVATE ${LLVM_LIBRARY_DIRS}) +target_link_libraries(clambccommon PUBLIC ${LLVM_LIBS}) + +if(WIN32) + install(TARGETS clambccommon 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 clambccommon DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + + diff --git a/libclambcc/Common/ClamBCRegAlloc.cpp b/libclambcc/Common/ClamBCRegAlloc.cpp index 7bd83c011b..ae4fed7c43 100644 --- a/libclambcc/Common/ClamBCRegAlloc.cpp +++ b/libclambcc/Common/ClamBCRegAlloc.cpp @@ -77,7 +77,12 @@ void ClamBCRegAlloc::handlePHI(PHINode *PN) ++It; } while (isa(It)); builder.SetInsertPoint(&*It); +#if 0 LoadInst *LI = builder.CreateLoad(AI, ".phiload"); +#else + llvm::errs() << "<" << __LINE__ << ">" << "There is a chance I'll have to do something like getPoinerOperand->getType or something like that, so leave this in here as a reminder to go look\n" << "\n"; + LoadInst *LI = builder.CreateLoad(AI->getType(), AI, ".phiload"); +#endif builder.SetInstDebugLocation(LI); PN->replaceAllUsesWith(LI); PN->eraseFromParent(); @@ -141,8 +146,19 @@ bool ClamBCRegAlloc::runOnFunction(Function &F) ClamBCStop("Cast from pointer to non-pointer element", BCI); } +#if 0 SrcTy = SPTy->getElementType(); DstTy = DPTy->getElementType(); +#else + + assert (0 && "removed deprecated getPointerElementType calls"); + + + /*Don't expect any issues with this change.*/ + SrcTy = SPTy->getPointerElementType(); + DstTy = DPTy->getPointerElementType(); + +#endif } if (AllocaInst *AI = dyn_cast(BCI->getOperand(0))) { diff --git a/libclambcc/Common/ClamBCUtilities.cpp b/libclambcc/Common/ClamBCUtilities.cpp index 04bfaadfcc..247d1e741f 100644 --- a/libclambcc/Common/ClamBCUtilities.cpp +++ b/libclambcc/Common/ClamBCUtilities.cpp @@ -40,7 +40,14 @@ bool functionRecurses(Function *pFunc, Function *orig, std::vector & for (auto blockIter = bb->begin(), blockEnd = bb->end(); blockIter != blockEnd; blockIter++) { Instruction *inst = llvm::cast(blockIter); if (CallInst *ci = llvm::dyn_cast(inst)) { +#if 0 Value *calledValue = ci->getCalledValue(); +#else + Function * calledValue = ci->getCalledFunction(); + if (nullptr == calledValue){ + assert (0 && "ci->getCalledFunction returned NULL\n"); + } +#endif if (calledValue == orig) { return true; } else if (Function *callee = dyn_cast(calledValue)) { diff --git a/libclambcc/Common/ClamBCUtilities.h b/libclambcc/Common/ClamBCUtilities.h index a010840aa0..63f2c19fc5 100644 --- a/libclambcc/Common/ClamBCUtilities.h +++ b/libclambcc/Common/ClamBCUtilities.h @@ -3,9 +3,11 @@ #include #include +#include #include #include +#include #include "ClamBCDiagnostics.h" From 21b10dbc8f026f7685df9e0661882156d10e63fc Mon Sep 17 00:00:00 2001 From: ragusaa <54862477+ragusaa@users.noreply.github.com> Date: Tue, 15 Aug 2023 11:19:56 -0400 Subject: [PATCH 4/6] ClamBCPreserveABIs. (#28) --- libclambcc/CMakeLists.txt | 2 +- libclambcc/ClamBCPreserveABIs/CMakeLists.txt | 72 ++++++++++++++++++ .../ClamBCPreserveABIs/ClamBCPreserveABIs.cpp | 75 ++++++++++++++++--- 3 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 libclambcc/ClamBCPreserveABIs/CMakeLists.txt diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index 49e1c5718a..850d0a1046 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -2,7 +2,7 @@ add_subdirectory(ClamBCRemoveUndefs) -#add_subdirectory(ClamBCPreserveABIs) +add_subdirectory(ClamBCPreserveABIs) #add_subdirectory(ClamBCAnalyzer) add_subdirectory(Common) diff --git a/libclambcc/ClamBCPreserveABIs/CMakeLists.txt b/libclambcc/ClamBCPreserveABIs/CMakeLists.txt new file mode 100644 index 0000000000..a249e2e2c5 --- /dev/null +++ b/libclambcc/ClamBCPreserveABIs/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + +# +# The clambcpreserveabis object library +# +add_library(clambcpreserveabis_obj OBJECT) +target_sources(clambcpreserveabis_obj + PRIVATE + ClamBCPreserveABIs.cpp +) + +target_include_directories(clambcpreserveabis_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(clambcpreserveabis_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") + +# +# For testing +# +#target_compile_definitions(clambcpreserveabis_obj -DLOG_BEFORE_AFTER=1) + +# +# The clambcpreserveabis shared library. +# +add_library( clambcpreserveabis SHARED ) +target_link_libraries( clambcpreserveabis + PUBLIC + clambcpreserveabis_obj ) +set_target_properties( clambcpreserveabis PROPERTIES + VERSION ${LIBCLAMBC_VERSION} + SOVERSION ${LIBCLAMBC_SOVERSION} ) + +target_link_directories(clambcpreserveabis PRIVATE ${LLVM_LIBRARY_DIRS}) +target_link_libraries(clambcpreserveabis PUBLIC ${LLVM_LIBS}) + +if(WIN32) + install(TARGETS clambcpreserveabis 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 clambcpreserveabis DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + + diff --git a/libclambcc/ClamBCPreserveABIs/ClamBCPreserveABIs.cpp b/libclambcc/ClamBCPreserveABIs/ClamBCPreserveABIs.cpp index d735be0636..595cecb975 100644 --- a/libclambcc/ClamBCPreserveABIs/ClamBCPreserveABIs.cpp +++ b/libclambcc/ClamBCPreserveABIs/ClamBCPreserveABIs.cpp @@ -1,20 +1,25 @@ +#include "Common/clambc.h" +#include "Common/ClamBCUtilities.h" + #include -#include "llvm/IR/Module.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Instructions.h" -#include "llvm/Support/raw_ostream.h" +#include +#include +#include #include -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" +//#include +#include +#include +#include -#include "Common/clambc.h" -#include "Common/ClamBCUtilities.h" #include #include + + + using namespace llvm; namespace @@ -32,7 +37,7 @@ namespace * to fake functions. If it does find it (the second time), it removes those * calls. */ -class ClamBCPreserveABIs : public ModulePass +class ClamBCPreserveABIs : public PassInfoMixin { protected: llvm::Module *pMod = nullptr; @@ -46,9 +51,17 @@ class ClamBCPreserveABIs : public ModulePass return; } FunctionType *pFunctionType = llvm::dyn_cast(pFunc->getType()); +#if 0 std::string newname = pFunc->getName(); +#else + std::string newname( pFunc->getName()); +#endif newname += "_fake"; +#if 0 pFunctionType = llvm::cast(llvm::cast(pFunc->getType())->getElementType()); +#else + pFunctionType = pFunc->getFunctionType(); +#endif Function *fakeFunction = Function::Create(pFunctionType, Function::ExternalLinkage, newname, pFunc->getParent()); fakeFunctions.push_back(fakeFunction); std::vector args; @@ -127,18 +140,28 @@ class ClamBCPreserveABIs : public ModulePass } public: +#if 0 static char ID; ClamBCPreserveABIs() : ModulePass(ID) {} +#endif virtual ~ClamBCPreserveABIs() {} +#if 0 bool runOnModule(Module &m) override +#else + virtual PreservedAnalyses run(Module & m, ModuleAnalysisManager & MAM) +#endif { pMod = &m; if (removeFakeFunctions()) { +#if 0 return bChanged; +#else + return PreservedAnalyses::none(); +#endif } for (auto i = pMod->begin(), e = pMod->end(); i != e; i++) { @@ -151,19 +174,51 @@ class ClamBCPreserveABIs : public ModulePass /*Set the linkage type to external so that the optimizer cannot remove the arguments.*/ pFunc->setLinkage(GlobalValue::ExternalLinkage); } - processFunction(pFunc); } writeMetadata(); +#if 0 return bChanged; +#else + if (bChanged){ + return PreservedAnalyses::none(); + } + return PreservedAnalyses::all(); +#endif } }; // end of struct ClamBCPreserveABIs } // end of anonymous namespace +#if 0 char ClamBCPreserveABIs::ID = 0; static RegisterPass X("clambc-preserve-abis", "Preserve ABIs", false /* Only looks at CFG */, false /* Analysis Pass */); +#else + +// This part is the new way of registering your pass +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + return { + LLVM_PLUGIN_API_VERSION, "ClamBCPreserveABIs", "v0.1", + [](PassBuilder &PB) { + PB.registerPipelineParsingCallback( + [](StringRef Name, ModulePassManager &FPM, + ArrayRef) { + if(Name == "clambc-preserve-abis"){ + FPM.addPass(ClamBCPreserveABIs()); + return true; + } + return false; + } + ); + } + }; +} + + + +#endif From c12ffccec309307bfdaa574a041fa85bc00d60c4 Mon Sep 17 00:00:00 2001 From: ragusaa <54862477+ragusaa@users.noreply.github.com> Date: Tue, 15 Aug 2023 11:20:54 -0400 Subject: [PATCH 5/6] Initial work on ClamBC Analyzer (#29) --- libclambcc/CMakeLists.txt | 2 +- libclambcc/ClamBCAnalyzer/CMakeLists.txt | 72 +++++++++++++++ libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.cpp | 97 ++++++++++++++------ libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.h | 29 ++++-- 4 files changed, 160 insertions(+), 40 deletions(-) create mode 100644 libclambcc/ClamBCAnalyzer/CMakeLists.txt diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index 850d0a1046..f2b2b92eaf 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -3,6 +3,6 @@ add_subdirectory(ClamBCRemoveUndefs) add_subdirectory(ClamBCPreserveABIs) -#add_subdirectory(ClamBCAnalyzer) +add_subdirectory(ClamBCAnalyzer) add_subdirectory(Common) diff --git a/libclambcc/ClamBCAnalyzer/CMakeLists.txt b/libclambcc/ClamBCAnalyzer/CMakeLists.txt new file mode 100644 index 0000000000..03a46bc545 --- /dev/null +++ b/libclambcc/ClamBCAnalyzer/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + +# +# The clambcanalyzer object library +# +add_library(clambcanalyzer_obj OBJECT) +target_sources(clambcanalyzer_obj + PRIVATE + ClamBCAnalyzer.cpp +) + +target_include_directories(clambcanalyzer_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(clambcanalyzer_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") + +# +# For testing +# +#target_compile_definitions(clambcanalyzer_obj -DLOG_BEFORE_AFTER=1) + +# +# The clambcanalyzer shared library. +# +add_library( clambcanalyzer SHARED ) +target_link_libraries( clambcanalyzer + PUBLIC + clambcanalyzer_obj ) +set_target_properties( clambcanalyzer PROPERTIES + VERSION ${LIBCLAMBC_VERSION} + SOVERSION ${LIBCLAMBC_SOVERSION} ) + +target_link_directories(clambcanalyzer PRIVATE ${LLVM_LIBRARY_DIRS}) +target_link_libraries(clambcanalyzer PUBLIC ${LLVM_LIBS}) + +if(WIN32) + install(TARGETS clambcanalyzer 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 clambcanalyzer DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + + diff --git a/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.cpp b/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.cpp index 0527edaa83..60bdd3ca1e 100644 --- a/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.cpp +++ b/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.cpp @@ -37,7 +37,7 @@ using namespace llvm; -extern cl::opt WriteDI; +//extern cl::opt WriteDI; static unsigned getSpecialIndex(StringRef Name) { @@ -67,29 +67,33 @@ static bool compare_lt_functions(Function *A, Function *B) return NA.compare(NB) < 0; } +#if 0 bool ClamBCAnalyzer::runOnModule(Module &M) +#else +PreservedAnalyses ClamBCAnalyzer::run(Module & m, ModuleAnalysisManager & MAM) +#endif { - pMod = &M; + pMod = &m; // Determine bytecode kind, default is 0 (generic). kind = 0; - GlobalVariable *GVKind = M.getGlobalVariable("__clambc_kind"); + GlobalVariable *GVKind = pMod->getGlobalVariable("__clambc_kind"); if (GVKind && GVKind->hasDefinitiveInitializer()) { kind = cast(GVKind->getInitializer())->getValue().getZExtValue(); // GVKind->setLinkage(GlobalValue::InternalLinkage); // Do not set the linkage type to internal, because the optimizer will remove it. if (kind >= 65536) { - ClamBCStop("Bytecode kind cannot be higher than 64k\n", &M); + ClamBCStop("Bytecode kind cannot be higher than 64k\n", pMod); } } - GlobalVariable *G = M.getGlobalVariable("__Copyright"); + GlobalVariable *G = pMod->getGlobalVariable("__Copyright"); if (G && G->hasDefinitiveInitializer()) { Constant *C = G->getInitializer(); // std::string c; StringRef c; if (!getConstantStringInfo(C, c)) { - ClamBCStop("Failed to extract copyright string\n", &M); + ClamBCStop("Failed to extract copyright string\n", pMod); } // copyright = strdup(c.c_str()); copyright = c.str(); @@ -98,18 +102,18 @@ bool ClamBCAnalyzer::runOnModule(Module &M) } // Logical signature created by ClamBCLogicalCompiler. - NamedMDNode *Node = M.getNamedMetadata("clambc.logicalsignature"); + NamedMDNode *Node = pMod->getNamedMetadata("clambc.logicalsignature"); logicalSignature = Node ? cast(Node->getOperand(0)->getOperand(0))->getString() : ""; - Node = M.getNamedMetadata("clambc.virusnames"); + Node = pMod->getNamedMetadata("clambc.virusnames"); virusnames = Node ? cast(Node->getOperand(0)->getOperand(0))->getString() : ""; unsigned tid, fid; // unsigned cid; - startTID = tid = clamav::initTypeIDs(typeIDs, M.getContext()); + startTID = tid = clamav::initTypeIDs(typeIDs, pMod->getContext()); // arrays of [2 x i8] .. [7 x i8] used for struct padding for (unsigned i = 1; i < 8; i++) { - const Type *Ty = llvm::ArrayType::get(llvm::Type::getInt8Ty(M.getContext()), + const Type *Ty = llvm::ArrayType::get(llvm::Type::getInt8Ty(pMod->getContext()), i); typeIDs[Ty] = tid++; extraTypes.push_back(Ty); @@ -118,7 +122,7 @@ bool ClamBCAnalyzer::runOnModule(Module &M) std::vector types; // cid=1; fid = 1; - for (Module::global_iterator I = M.global_begin(); I != M.global_end(); ++I) { + for (Module::global_iterator I = pMod->global_begin(); I != pMod->global_end(); ++I) { GlobalVariable *gv = llvm::cast(I); std::set insts; std::set globs; @@ -136,14 +140,14 @@ bool ClamBCAnalyzer::runOnModule(Module &M) // globals, so introduce helper globals for nested constant expressions. if (CE->getOpcode() != Instruction::GetElementPtr) { if (CE->getOpcode() == Instruction::BitCast) { - GlobalVariable *GV = new GlobalVariable(M, CE->getType(), true, + GlobalVariable *GV = new GlobalVariable(*pMod, CE->getType(), true, GlobalValue::InternalLinkage, CE, I->getName() + "_bc"); CEMap[CE] = GV; continue; } errs() << "UNSUPPORTED: " << *CE << "\n"; - ClamBCStop("Unsupported constant expression", &M); + ClamBCStop("Unsupported constant expression", pMod); } ConstantInt *C0 = dyn_cast(CE->getOperand(1)); ConstantInt *C1 = dyn_cast(CE->getOperand(2)); @@ -152,7 +156,7 @@ bool ClamBCAnalyzer::runOnModule(Module &M) errs() << "UNSUPPORTED: " << *CE << "\n"; ClamBCStop("Unsupported constant expression, nonzero first" " index", - &M); + pMod); } const DataLayout &dataLayout = pMod->getDataLayout(); @@ -164,7 +168,13 @@ bool ClamBCAnalyzer::runOnModule(Module &M) Type *type = CE->getOperand(0)->getType(); if (llvm::isa(type)) { +#if 0 type = llvm::cast(type)->getElementType(); +#else + llvm::errs() << "<" << __LINE__ << ">" << "https://llvm.org/docs/OpaquePointers.html" << "\n"; + llvm::errs() << "<" << __LINE__ << ">" << *CE << "\n"; + assert (0 && "FIGURE OUT WHAT TO DO HERE"); +#endif } uint64_t idx = dataLayout.getIndexedOffsetInType(type, indices); @@ -180,7 +190,7 @@ bool ClamBCAnalyzer::runOnModule(Module &M) CE->replaceAllUsesWith(NewCE); } CE = NewCE; - GlobalVariable *GV = new GlobalVariable(M, CE->getType(), true, + GlobalVariable *GV = new GlobalVariable(*pMod, CE->getType(), true, GlobalValue::InternalLinkage, CE, I->getName() + "_" + Twine(v)); @@ -199,7 +209,7 @@ bool ClamBCAnalyzer::runOnModule(Module &M) // Sort functions. std::vector functions; - for (Module::iterator I = M.begin(), E = M.end(); I != E;) { + for (Module::iterator I = pMod->begin(), E = pMod->end(); I != E;) { Function *F = &*I; ++I; functions.push_back(F); @@ -209,20 +219,20 @@ bool ClamBCAnalyzer::runOnModule(Module &M) for (std::vector::iterator I = functions.begin(), E = functions.end(); I != E; ++I) { - M.getFunctionList().push_back(*I); + pMod->getFunctionList().push_back(*I); } - Function *ep = M.getFunction("entrypoint"); + Function *ep = pMod->getFunction("entrypoint"); if (!ep) { - ClamBCStop("Bytecode must define an entrypoint (with 0 parameters)!\n", &M); + ClamBCStop("Bytecode must define an entrypoint (with 0 parameters)!\n", pMod); } if (ep->getFunctionType()->getNumParams() != 0) { - ClamBCStop("Bytecode must define an entrypoint with 0 parameters!\n", &M); + ClamBCStop("Bytecode must define an entrypoint with 0 parameters!\n", pMod); } unsigned dbgid = 0; - unsigned MDDbgKind = M.getContext().getMDKindID("dbg"); - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { + unsigned MDDbgKind = pMod->getContext().getMDKindID("dbg"); + for (Module::iterator I = pMod->begin(), E = pMod->end(); I != E; ++I) { Function &F = *I; if (F.isDeclaration()) { // Don't add prototypes of debug intrinsics @@ -316,7 +326,7 @@ bool ClamBCAnalyzer::runOnModule(Module &M) continue; } DEBUGERR << *STy << "\n"; - ClamBCStop("Bytecode cannot use abstract types (only pointers to them)!", &M); + ClamBCStop("Bytecode cannot use abstract types (only pointers to them)!", pMod); } } if (!typeIDs.count(STy)) { @@ -328,12 +338,13 @@ bool ClamBCAnalyzer::runOnModule(Module &M) } if (tid >= 65536) { - ClamBCStop("Attempted to use more than 64k types", &M); + ClamBCStop("Attempted to use more than 64k types", pMod); } printGlobals(startTID); - return false; + //return false; + return PreservedAnalyses::all(); } void ClamBCAnalyzer::printGlobals(uint16_t stid) @@ -342,7 +353,7 @@ void ClamBCAnalyzer::printGlobals(uint16_t stid) // Describe types maxApi = 0; // std::vector apis; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { + for (Module::iterator I = pMod->begin(), E = pMod->end(); I != E; ++I) { llvm::Function *pFunc = llvm::cast(I); // Skip dead declarations if (I->use_empty()) { @@ -392,20 +403,20 @@ void ClamBCAnalyzer::printGlobals(uint16_t stid) for (StringMap::iterator I = globalsMap.begin(), E = globalsMap.end(); I != E; ++I) { - if (GlobalVariable *GV = M.getGlobalVariable(I->getKey())) { + if (GlobalVariable *GV = pMod->getGlobalVariable(I->getKey())) { specialGlobals.insert(GV); globals[GV] = I->getValue(); if (I->getValue() > maxGlobal) maxGlobal = I->getValue(); } } - if (GlobalVariable *GV = M.getGlobalVariable("__clambc_kind")) { + if (GlobalVariable *GV = pMod->getGlobalVariable("__clambc_kind")) { specialGlobals.insert(GV); } // std::vector globalInits; globalInits.push_back(0); // ConstantPointerNul placeholder - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { + for (Module::global_iterator I = pMod->global_begin(), E = pMod->global_end(); I != E; ++I) { GlobalVariable *pgv = llvm::cast(I); if (specialGlobals.count(pgv)) { continue; @@ -585,14 +596,42 @@ void ClamBCAnalyzer::populateAPIMap() apiMap["bzip2_done"] = id++; } +#if 0 void ClamBCAnalyzer::getAnalysisUsage(AnalysisUsage &AU) const { // Preserve the CFG, we only eliminate PHIs, and introduce some // loads/stores. AU.setPreservesAll(); } +#endif +#if 0 char ClamBCAnalyzer::ID = 0; static RegisterPass X("clambc-analyzer", "ClamAV bytecode register allocator"); const PassInfo *const ClamBCAnalyzerID = &X; +#else + +// This part is the new way of registering your pass +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + return { + LLVM_PLUGIN_API_VERSION, "ClamBCAnalyzer", "v0.1", + [](PassBuilder &PB) { + PB.registerPipelineParsingCallback( + [](StringRef Name, ModulePassManager &FPM, + ArrayRef) { + if(Name == "clambc-analyzer"){ + FPM.addPass(ClamBCAnalyzer()); + return true; + } + return false; + } + ); + } + }; +} + + +#endif + diff --git a/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.h b/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.h index aec37d78cc..3124ccde67 100644 --- a/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.h +++ b/libclambcc/ClamBCAnalyzer/ClamBCAnalyzer.h @@ -24,15 +24,20 @@ #include "Common/clambc.h" -#include -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" +#include +#include +#include +#include +#include #include #include -#include "llvm/Support/raw_ostream.h" +#include + +#include +#include +#include + +#include #include #include @@ -45,7 +50,7 @@ //5. Cannot see where banMap has any functions inserted. Do we need it? //6. Evaluate the TODO in runOnModule. -class ClamBCAnalyzer : public llvm::ModulePass +class ClamBCAnalyzer : public llvm::PassInfoMixin //llvm::ModulePass { protected: typedef llvm::DenseMap TypeMapTy; @@ -76,6 +81,7 @@ class ClamBCAnalyzer : public llvm::ModulePass unsigned maxGlobal = 0; std::vector globalInits; std::vector mds; + bool WriteDI = false; virtual void printGlobals(uint16_t stid); @@ -103,7 +109,7 @@ class ClamBCAnalyzer : public llvm::ModulePass public: static char ID; explicit ClamBCAnalyzer() - : ModulePass(ID) + //: ModulePass(ID) { populateAPIMap(); @@ -118,9 +124,12 @@ class ClamBCAnalyzer : public llvm::ModulePass } ~ClamBCAnalyzer() {} - virtual bool runOnModule(llvm::Module &m) override; + //virtual bool runOnModule(llvm::Module &m) override; + virtual llvm::PreservedAnalyses run(llvm::Module & m, llvm::ModuleAnalysisManager & MAM); +#if 0 virtual void getAnalysisUsage(llvm::AnalysisUsage &au) const override; +#endif virtual uint32_t getTypeID(const llvm::Type *const t) { From 1e3401f0233a0f542961bf2c4be5c19e4d3323af Mon Sep 17 00:00:00 2001 From: Andy Ragusa Date: Thu, 31 Aug 2023 12:29:57 -0700 Subject: [PATCH 6/6] Updated ClamBCRemovePointerPHIs. --- libclambcc/CMakeLists.txt | 1 + .../ClamBCRemovePointerPHIs/CMakeLists.txt | 72 +++++++++++++++++++ .../ClamBCRemovePointerPHIs.cpp | 50 ++++++++++--- libclambcc/Common/clambc.h | 8 +++ temp_delete_when_merge/run_opt.sh | 48 +++++++------ 5 files changed, 148 insertions(+), 31 deletions(-) create mode 100644 libclambcc/ClamBCRemovePointerPHIs/CMakeLists.txt diff --git a/libclambcc/CMakeLists.txt b/libclambcc/CMakeLists.txt index f2b2b92eaf..fc8c04ae00 100644 --- a/libclambcc/CMakeLists.txt +++ b/libclambcc/CMakeLists.txt @@ -5,4 +5,5 @@ add_subdirectory(ClamBCRemoveUndefs) add_subdirectory(ClamBCPreserveABIs) add_subdirectory(ClamBCAnalyzer) add_subdirectory(Common) +add_subdirectory(ClamBCRemovePointerPHIs) diff --git a/libclambcc/ClamBCRemovePointerPHIs/CMakeLists.txt b/libclambcc/ClamBCRemovePointerPHIs/CMakeLists.txt new file mode 100644 index 0000000000..60bbdc45e5 --- /dev/null +++ b/libclambcc/ClamBCRemovePointerPHIs/CMakeLists.txt @@ -0,0 +1,72 @@ +# Copyright (C) 2021 Cisco Systems, Inc. and/or its affiliates. All rights reserved. + +# +# The clambcremovepointerphis object library +# +add_library(clambcremovepointerphis_obj OBJECT) +target_sources(clambcremovepointerphis_obj + PRIVATE + ClamBCRemovePointerPHIs.cpp +) + +target_include_directories(clambcremovepointerphis_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(clambcremovepointerphis_obj PROPERTIES COMPILE_FLAGS "${WARNCXXFLAGS}") + +# +# For testing +# +#target_compile_definitions(clambcremovepointerphis_obj -DLOG_BEFORE_AFTER=1) + +# +# The clambcremovepointerphis shared library. +# +add_library( clambcremovepointerphis SHARED ) +target_link_libraries( clambcremovepointerphis + PUBLIC + clambcremovepointerphis_obj ) +set_target_properties( clambcremovepointerphis PROPERTIES + VERSION ${LIBCLAMBC_VERSION} + SOVERSION ${LIBCLAMBC_SOVERSION} ) + +target_link_directories(clambcremovepointerphis PRIVATE ${LLVM_LIBRARY_DIRS}) +target_link_libraries(clambcremovepointerphis PUBLIC ${LLVM_LIBS}) + +if(WIN32) + install(TARGETS clambcremovepointerphis 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 clambcremovepointerphis DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + + + diff --git a/libclambcc/ClamBCRemovePointerPHIs/ClamBCRemovePointerPHIs.cpp b/libclambcc/ClamBCRemovePointerPHIs/ClamBCRemovePointerPHIs.cpp index 4c8409641c..5275a64ff1 100644 --- a/libclambcc/ClamBCRemovePointerPHIs/ClamBCRemovePointerPHIs.cpp +++ b/libclambcc/ClamBCRemovePointerPHIs/ClamBCRemovePointerPHIs.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include @@ -20,7 +22,7 @@ using namespace llvm; namespace { -class ClambcRemovePointerPHIs : public FunctionPass +class ClamBCRemovePointerPHIs : public PassInfoMixin { protected: Function *pFunc = nullptr; @@ -283,16 +285,22 @@ class ClambcRemovePointerPHIs : public FunctionPass } public: - static char ID; - ClambcRemovePointerPHIs() - : FunctionPass(ID) {} + ClamBCRemovePointerPHIs(){} + virtual ~ClamBCRemovePointerPHIs(){} + +#if 0 bool runOnFunction(Function &F) override +#else + virtual PreservedAnalyses run(Function & F, FunctionAnalysisManager & MAM) +#endif { pFunc = &F; bool ret = false; + llvm::errs() << "<" << __FUNCTION__ << "::" << __LINE__ << "\n"; + std::vector phis = gatherPHIs(); for (size_t i = 0; i < phis.size(); i++) { PHINode *pn = phis[i]; @@ -302,14 +310,40 @@ class ClambcRemovePointerPHIs : public FunctionPass } } - return ret; + if (ret){ + return PreservedAnalyses::none(); + } + return PreservedAnalyses::all(); } -}; // end of class ClambcRemovePointerPHIs +}; // end of class ClamBCRemovePointerPHIs } // end of anonymous namespace -char ClambcRemovePointerPHIs::ID = 0; -static RegisterPass X("clambc-remove-pointer-phis", "Remove PHI Nodes with pointers", +#if 0 +char ClamBCRemovePointerPHIs::ID = 0; +static RegisterPass X("clambc-remove-pointer-phis", "Remove PHI Nodes with pointers", false /* Only looks at CFG */, false /* Analysis Pass */); +#else +// This part is the new way of registering your pass +extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK +llvmGetPassPluginInfo() { + return { + LLVM_PLUGIN_API_VERSION, "ClamBCRemovePointerPHIs", "v0.1", + [](PassBuilder &PB) { + PB.registerPipelineParsingCallback( + [](StringRef Name, FunctionPassManager &FPM, + ArrayRef) { + if(Name == "clambc-remove-pointer-phis"){ + FPM.addPass(ClamBCRemovePointerPHIs()); + return true; + } + return false; + } + ); + } + }; +} + +#endif diff --git a/libclambcc/Common/clambc.h b/libclambcc/Common/clambc.h index 3d790a1f9e..bda3761d9c 100644 --- a/libclambcc/Common/clambc.h +++ b/libclambcc/Common/clambc.h @@ -136,5 +136,13 @@ enum bc_global { #define DEBUGERR llvm::errs() << "<" << __FILE__ << "::" << __FUNCTION__ << "::" << __LINE__ << ">" #endif //DEBUGERR +#ifndef DEBUG_WHERE +#define DEBUG_WHERE llvm::errs() << "<" << __FUNCTION__ << "::" << __LINE__ << ">\n" +#endif + +#ifndef DEBUG_VALUE +#define DEBUG_VALUE(__value__) llvm::errs() << "<" << __FUNCTION__ << "::" << __LINE__ << ">" << *__value__ << "\n"; +#endif + #define BC_START_TID 69 #endif diff --git a/temp_delete_when_merge/run_opt.sh b/temp_delete_when_merge/run_opt.sh index 2c38258716..c6aa8154cd 100755 --- a/temp_delete_when_merge/run_opt.sh +++ b/temp_delete_when_merge/run_opt.sh @@ -6,21 +6,21 @@ -clang-16 -S \ - -fno-discard-value-names \ - --language=c \ - -emit-llvm \ - -Werror=unused-command-line-argument \ - -Xclang \ - -disable-O0-optnone \ - -o test.ll \ - ../../testing/BC.Img.Exploit.CVE_2017_3124-6335443-1.c \ - -I ../../../build/install/bin/../include \ - -include bytecode.h \ - -D__CLAMBC__ +#clang-16 -S \ +# -fno-discard-value-names \ +# --language=c \ +# -emit-llvm \ +# -Werror=unused-command-line-argument \ +# -Xclang \ +# -disable-O0-optnone \ +# -o test.ll \ +# ../../testing/BC.Img.Exploit.CVE_2017_3124-6335443-1.c \ +# -I ../../../build/install/bin/../include \ +# -include bytecode.h \ +## -D__CLAMBC__ -clang-16 -S -emit-llvm -O0 -Xclang -disable-O0-optnone ../../testing/test.c +clang-16 -S -fno-discard-value-names -emit-llvm -O0 -Xclang -disable-O0-optnone ../temp_delete_when_merge/testing/test.c @@ -66,23 +66,25 @@ clang-16 -S -emit-llvm -O0 -Xclang -disable-O0-optnone ../../testing/test.c #There are warnings about not being able to load libclambccommon.so, but I #can add print statements to functions in that library and have them print, so ??? +#opt-16 -S \ +# --load libclambcc/Common/libclambccommon.so \ +# --load-pass-plugin libclambcc/ClamBCRemoveUndefs/libclambcremoveundefs.so \ +# --load-pass-plugin libclambcc/ClamBCPreserveABIs/libclambcpreserveabis.so \ +# --load-pass-plugin libclambcc/ClamBCAnalyzer/libclambcanalyzer.so \ +# --load-pass-plugin libclambcc/ClamBCRemovePointerPHIs/libclambcremovepointerphis.so \ +# --passes="-mem2reg"\ +# --passes="clambc-remove-undefs,clambc-preserve-abis,default,clambc-preserve-abis" \ +# test.ll -o test.t.ll + opt-16 -S \ --load libclambcc/Common/libclambccommon.so \ --load-pass-plugin libclambcc/ClamBCRemoveUndefs/libclambcremoveundefs.so \ --load-pass-plugin libclambcc/ClamBCPreserveABIs/libclambcpreserveabis.so \ --load-pass-plugin libclambcc/ClamBCAnalyzer/libclambcanalyzer.so \ + --load-pass-plugin libclambcc/ClamBCRemovePointerPHIs/libclambcremovepointerphis.so \ --passes="-mem2reg"\ - --passes="clambc-remove-undefs,clambc-preserve-abis,default,clambc-preserve-abis" \ + --passes="clambc-remove-undefs,clambc-preserve-abis,default,clambc-preserve-abis,function(clambc-remove-pointer-phis)" \ test.ll -o test.t.ll -#opt-16 -S \ -# --load libclambcc/Common/libclambccommon.so \ -# --load-pass-plugin libclambcc/ClamBCRemoveUndefs/libclambcremoveundefs.so \ -# --load-pass-plugin libclambcc/ClamBCPreserveABIs/libclambcpreserveabis.so \ -# --load-pass-plugin libclambcc/ClamBCAnalyzer/libclambcanalyzer.so \ -# --passes="-mem2reg"\ -# --passes="clambc-remove-undefs,clambc-preserve-abis,default,clambc-preserve-abis,clambc-remove-pointer-phis" \ -# test.ll -o test.t.ll -#