Function Decomposer is a tool designed to analyze and refactor C source code by extracting functions, macros, typedefs, and structs into separate files. This modular approach enhances code readability, maintainability, and reusability, facilitating better project organization and collaboration.
- Macro Extraction: Identifies and relocates all macro definitions to a centralized header file.
- Struct and Typedef Extraction: Extracts struct definitions and their corresponding typedefs into a shared header.
- Function Extraction: Separates each function into its own header and source file, maintaining clear boundaries.
- Metadata Generation: Creates a comprehensive
metadata.jsonfile detailing all extracted entities and their original locations. - Recomposition Tool Integration: Provides a recomposition tool to reconstruct the original source file from the extracted components seamlessly.
Before installing and running Function Decomposer, ensure that the following dependencies and tools are installed on your system:
- Git: Version control system.
- C++ Compiler: Supporting C++17 or later (e.g.,
gcc,clang). - CMake: Build system generator (version 3.10 or later recommended).
- Clang and LibTooling: Required for parsing and analyzing C source code.
- JSON Library: For handling JSON metadata (e.g., nlohmann/json).
Follow these step-by-step instructions to set up and build the Function Decomposer tool on your local machine.
Clone the Function Decomposer repository from GitHub to your local machine:
git clone https://github.com/ssrg-vt/Decomposer.git
cd DecomposerCreate a separate build directory to organize build files:
mkdir build
cd buildEnsure all necessary dependencies are installed. Below are instructions for common operating systems.
macOS
Using Homebrew:
brew install git llvm cmake
brew install nlohmann-jsonAdd LLVM to your PATH by adding the following line to your .bash_profile or .zshrc:
export PATH="/usr/local/opt/llvm/bin:$PATH"Apply the changes:
source ~/.bash_profile
# or
source ~/.zshrcUbuntu/Debian
sudo apt-get update
sudo apt-get install git clang llvm cmake build-essential libclang-dev
sudo apt-get install nlohmann-json-devWindows
- Git: Download and install from Git for Windows.
- C++ Compiler: Install Visual Studio with C++ development tools.
- CMake: Download and install from CMake official website.
- Clang and LibTooling: Install via LLVM Releases or use package managers like Chocolatey:
choco install llvm- JSON Library: Use vcpkg to install:
vcpkg install nlohmann-jsonRun CMake to configure the project. Ensure that CMake finds all necessary dependencies.
cmake ..Common CMake Configuration Flags: Specify LLVM Directory (if LLVM is installed in a non-standard location):
cmake -DLLVM_DIR=/path/to/llvm/lib/cmake/llvm ..Enable Debugging Symbols:
cmake -DCMAKE_BUILD_TYPE=Debug ..Compile the project using make (on Unix-like systems) or the appropriate build tool on your platform.
makeAlternatively, for multi-core builds:
make -j$(nproc)Running the Function Decomposer Tool
Assuming the executable is named FunctionDecomposer, execute it with the target C source file as an argument.
./FunctionDecomposer /path/to/your/source_file.cExample:
./FunctionDecomposer ../sample6.c
./FunctionDecomposer ../libm/mathd/acosd.cExpected Output: • Creation of the results/sample6 directory. • Extraction of macros, structs, typedefs, and functions. • Generation of metadata.json in results/sample6/. • Relocation of entities to appropriate files (e.g., types_and_structs.h, individual .c and .h files for functions).
The Function Decomposer tool comes in two versions: 1. New Version (new_fd.cpp): Includes metadata generation. 2. Old Version (old_fd.cpp): Does not include metadata generation.
You can choose which version to use based on your requirements.
To generate the binary out of the decomposed files , follow these steps:
After running the functional decomposer tool and generating the decomposed files.
make CompileDecomposedTo run the binary of the decomposed files
cd generated_bin
./decomposed_binaryTo select the desired version of the decomposer tool, follow these steps:
- Navigate to the Decomposer Source Directory:
cd src/decomposer/- Choose the Appropriate Version: • For Metadata Generation: Copy new_fd.cpp to FunctionDecomposer.cpp:
cp new_fd.cpp FunctionDecomposer.cpp• Without Metadata Generation: Copy old_fd.cpp to FunctionDecomposer.cpp:
cp old_fd.cpp FunctionDecomposer.cpp
- Return to the Build Directory:
cd ../../build- Rebuild the Project to Apply Changes:
makelibm.a - Binary of the non decomposed files and functions in libmCS libm_decomposed.a - Binary of the decomposed files and functions in libmCS
To run the test file test_libmcs on these two binaries do the following -
cd ..
clang test_libmcs.c ./libs/libm_decomposed.a -lm -o test_libmcs_decomposed
./test_libmcs_decomposed > decomposed_output.txt
clang test_libmcs.c ./libs/libm.a -lm -o test_libmcs_oracle
./test_libmcs_oracle > oracle_output.txt
diff -u oracle_output.txt decomposed_output.txt > difference.txtRun the Function Decomposer on your target C source file:
./FunctionDecomposer /path/to/your/source_file.cThis command will: • Analyze the specified C source file. • Extract macros, structs, typedefs, and functions into separate files. • Generate a metadata.json file detailing all extracted entities.
To reconstruct the original source file from the extracted components, use the Recomposition Tool.
Step-by-Step:
- Ensure the Recomposition Tool is Built If the Recomposition Tool is part of the same repository, it should have been built during the make process. Verify its presence:
ls RecompositionToolIf Not Built: Navigate to the tool’s directory and build it using CMake.
cd RecompositionToolDirectory
mkdir build && cd build
cmake ..
make- Execute the Recomposition Tool Run the tool by providing the path to the metadata.json file.
./RecompositionTool ../results/sample6/metadata.jsonExpected Output: • Generation of a recomposed source file, such as recomposed_sample6.c, within the results/sample6/ directory. • Integration of all macros, structs, typedefs, and functions into the recomposed file.
- Verify the Recombined File
ls results/sample6/Expected File:
recomposed_sample6.c
Inspect the recomposed source:
cat results/sample6/recomposed_sample6.c
- (Optional) Compile and Run the Recombined Source To ensure that the recomposed source functions identically to the original:
gcc results/sample6/recomposed_sample6.c -o results/sample6/recomposed_executable
./results/sample6/recomposed_executable