From bef6f8c528318d6d28a8a6dcb66e5dcf22645096 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 25 Jan 2025 10:15:41 -0600 Subject: [PATCH 1/6] git ignore build and 3rd party directories --- .gitignore | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitignore b/.gitignore index 259148f..b8648ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,17 @@ +# Build directories +build/ +out/ +cmake-build-*/ + +# Third party dependencies +3rdparty/ + +# IDE specific files +.idea/ +.vscode/ +*.swp +.DS_Store + # Prerequisites *.d From 6df33301d1da123dc69d634e3dba184f5f9fa67e Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 25 Jan 2025 10:15:57 -0600 Subject: [PATCH 2/6] feat: initial LLVM analyzer project setup - Add CMake build configuration with LLVM dependencies - Create basic analyzer structure with Module iteration - Set up proper compiler paths for Apple Silicon macOS - Include necessary LLVM components (Core, Support, IRReader) --- CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++++++++++++++ include/Analyzer.h | 16 ++++++++++++++++ src/Analyzer.cpp | 24 +++++++++++++++++++++++ src/main.cpp | 33 +++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 include/Analyzer.h create mode 100644 src/Analyzer.cpp create mode 100644 src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..71be7ae --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.13.4) + +# Find brew prefix and LLVM installation +execute_process( + COMMAND brew --prefix llvm + OUTPUT_VARIABLE LLVM_BREW_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Set the C and CXX compilers before the project declaration +set(CMAKE_C_COMPILER "${LLVM_BREW_PATH}/bin/clang") +set(CMAKE_CXX_COMPILER "${LLVM_BREW_PATH}/bin/clang++") + +project(MyLLVMProject) + +# Set LLVM_DIR based on brew installation +set(LLVM_DIR "${LLVM_BREW_PATH}/lib/cmake/llvm") + +message(STATUS "Using LLVM installed at: ${LLVM_BREW_PATH}") + +# Find LLVM package +find_package(LLVM REQUIRED CONFIG) +message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") +message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") + +# LLVM settings +include_directories(${LLVM_INCLUDE_DIRS}) +add_definitions(${LLVM_DEFINITIONS}) + +# Include our own headers +include_directories(${CMAKE_SOURCE_DIR}/include) + +# Create the executable +add_executable(analyzer + src/main.cpp + src/Analyzer.cpp +) + +# Get the LLVM components we need +llvm_map_components_to_libnames(llvm_libs + Core + Support + IRReader + Analysis +) + +# Link against LLVM libraries +target_link_libraries(analyzer ${llvm_libs}) \ No newline at end of file diff --git a/include/Analyzer.h b/include/Analyzer.h new file mode 100644 index 0000000..4d5cde3 --- /dev/null +++ b/include/Analyzer.h @@ -0,0 +1,16 @@ +#ifndef ANALYZER_H +#define ANALYZER_H + +// Remove forward declaration and include the actual header +#include "llvm/IR/Module.h" + +class Analyzer { +public: + explicit Analyzer(llvm::Module *M); // Added semicolon + void analyze(); // Added semicolon + +private: + llvm::Module *module; // Added semicolon +}; // Added semicolon + +#endif // ANALYZER_H \ No newline at end of file diff --git a/src/Analyzer.cpp b/src/Analyzer.cpp new file mode 100644 index 0000000..5e5ffd4 --- /dev/null +++ b/src/Analyzer.cpp @@ -0,0 +1,24 @@ +#include "Analyzer.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include + +Analyzer::Analyzer(llvm::Module *M) : module(M) {} + +void Analyzer::analyze() { + // Count functions and basic blocks + unsigned numFunctions = 0; + unsigned numBasicBlocks = 0; + + for (auto &F : *module) { + numFunctions++; + + for (auto &BB : F) { + numBasicBlocks++; + } + } + + std::cout << "Module Analysis Results:\n" + << "Number of functions: " << numFunctions << "\n" + << "Number of basic blocks: " << numBasicBlocks << "\n"; +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..c40b844 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,33 @@ +#include "Analyzer.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/Support/SourceMgr.h" +#include +#include + +int main(int argc, char **argv) { + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " \n"; + return 1; + } + + // Create LLVM context + llvm::LLVMContext context; + llvm::SMDiagnostic err; + + // Parse the IR file + std::unique_ptr module = + llvm::parseIRFile(argv[1], err, context); + + if (!module) { + err.print(argv[0], llvm::errs()); + return 1; + } + + // Create our analyzer and run it + Analyzer analyzer(module.get()); + analyzer.analyze(); + + return 0; +} \ No newline at end of file From 9fde4b5509fb44b2452bc48bc1f7943439b57d05 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 25 Jan 2025 10:22:24 -0600 Subject: [PATCH 3/6] git ignore windows specific things --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index b8648ea..c8762fb 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,13 @@ cmake-build-*/ *.exe *.out *.app + +# Windows specific +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +*.sln +[Dd]ebug/ +[Rr]elease/ +x64/ +x86/ From d671e01939e50ee2acfa42d3d9ecf1f0bd57903c Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 25 Jan 2025 10:22:46 -0600 Subject: [PATCH 4/6] feat: add windows support --- CMakeLists.txt | 63 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 71be7ae..fea0468 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,22 +1,34 @@ cmake_minimum_required(VERSION 3.13.4) -# Find brew prefix and LLVM installation -execute_process( - COMMAND brew --prefix llvm - OUTPUT_VARIABLE LLVM_BREW_PATH - OUTPUT_STRIP_TRAILING_WHITESPACE -) - -# Set the C and CXX compilers before the project declaration -set(CMAKE_C_COMPILER "${LLVM_BREW_PATH}/bin/clang") -set(CMAKE_CXX_COMPILER "${LLVM_BREW_PATH}/bin/clang++") +# Detect OS and set platform-specific variables +if(WIN32) + # Windows: Try to find LLVM in standard install locations + set(LLVM_DIR "C:/Program Files/LLVM/lib/cmake/llvm" CACHE PATH "LLVM installation directory") + + # Allow user to override LLVM path through environment variable + if(DEFINED ENV{LLVM_DIR}) + set(LLVM_DIR "$ENV{LLVM_DIR}/lib/cmake/llvm") + endif() +else() + # macOS/Linux: Use brew path or system path + execute_process( + COMMAND brew --prefix llvm + OUTPUT_VARIABLE LLVM_BREW_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE BREW_LLVM_RESULT + ) + + if(BREW_LLVM_RESULT EQUAL 0) + set(LLVM_DIR "${LLVM_BREW_PATH}/lib/cmake/llvm") + # Set compilers for macOS + set(CMAKE_C_COMPILER "${LLVM_BREW_PATH}/bin/clang") + set(CMAKE_CXX_COMPILER "${LLVM_BREW_PATH}/bin/clang++") + endif() +endif() project(MyLLVMProject) -# Set LLVM_DIR based on brew installation -set(LLVM_DIR "${LLVM_BREW_PATH}/lib/cmake/llvm") - -message(STATUS "Using LLVM installed at: ${LLVM_BREW_PATH}") +message(STATUS "Looking for LLVM in: ${LLVM_DIR}") # Find LLVM package find_package(LLVM REQUIRED CONFIG) @@ -45,4 +57,25 @@ llvm_map_components_to_libnames(llvm_libs ) # Link against LLVM libraries -target_link_libraries(analyzer ${llvm_libs}) \ No newline at end of file +target_link_libraries(analyzer ${llvm_libs}) + +# Set C++ standard for all targets +set_target_properties(analyzer PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON +) + +# Windows-specific settings +if(MSVC) + # Add Windows-specific compiler flags + target_compile_options(analyzer PRIVATE + /W4 # Warning level 4 + /EHsc # Enable C++ exceptions + ) +else() + # Unix-like compiler flags + target_compile_options(analyzer PRIVATE + -Wall + -Wextra + ) +endif() \ No newline at end of file From 957c1bfbfd469e27346e6b8c427be8321e1e51e3 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 25 Jan 2025 10:23:24 -0600 Subject: [PATCH 5/6] add setup instructions to readme --- README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b5a629..db51863 100644 --- a/README.md +++ b/README.md @@ -1 +1,55 @@ -# MachOCodeGen \ No newline at end of file +# MachOCodeGen + +A tool for analyzing LLVM IR using the LLVM framework. + +## Prerequisites + +### Windows +1. Install LLVM: + ```batch + winget install LLVM + ``` + Or download from [LLVM Releases](https://releases.llvm.org/) + +2. Either: + - Install LLVM to the default location (`C:/Program Files/LLVM`), or + - Set the `LLVM_DIR` environment variable to your LLVM installation path + +### macOS +1. Install LLVM using Homebrew: + ```bash + brew install llvm + ``` + +## Building the Project + +### Windows +```batch +mkdir build +cd build +cmake .. +cmake --build . +``` + +### macOS +```bash +mkdir build +cd build +cmake .. +make +``` + +## Usage + +The analyzer takes an LLVM IR file as input and provides analysis information: + +```bash +./analyzer input.ll +``` + +To generate LLVM IR from C/C++ code: +```bash +clang -S -emit-llvm input.c -o output.ll +``` + +## Project Structure \ No newline at end of file From 3d144004bd0283123b069f25a61fc91279a7cebb Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sat, 25 Jan 2025 10:33:57 -0600 Subject: [PATCH 6/6] add tests, organize includes and add missing LLVM headers --- CMakeLists.txt | 7 ++++--- src/Analyzer.cpp | 2 +- src/main.cpp | 8 +++++++- tests/test.cpp | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 tests/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fea0468..40d370a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,11 +36,12 @@ message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") # LLVM settings -include_directories(${LLVM_INCLUDE_DIRS}) +include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) +link_directories(${LLVM_LIBRARY_DIRS}) add_definitions(${LLVM_DEFINITIONS}) -# Include our own headers -include_directories(${CMAKE_SOURCE_DIR}/include) +# Include our own headers - make this relative to build directory +include_directories("${CMAKE_SOURCE_DIR}/include") # Quote the path # Create the executable add_executable(analyzer diff --git a/src/Analyzer.cpp b/src/Analyzer.cpp index 5e5ffd4..3049f40 100644 --- a/src/Analyzer.cpp +++ b/src/Analyzer.cpp @@ -1,6 +1,6 @@ -#include "Analyzer.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" +#include #include Analyzer::Analyzer(llvm::Module *M) : module(M) {} diff --git a/src/main.cpp b/src/main.cpp index c40b844..e98f96f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,14 @@ -#include "Analyzer.h" +// LLVM includes #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/raw_ostream.h" + +// Local includes +#include "Analyzer.h" + +// Standard includes #include #include diff --git a/tests/test.cpp b/tests/test.cpp new file mode 100644 index 0000000..462e233 --- /dev/null +++ b/tests/test.cpp @@ -0,0 +1,3 @@ +int add(int a, int b) { return a + b; } + +int main() { return add(40, 2); } \ No newline at end of file