RVPin is a powerful Dynamic Binary Instrumentation (DBI) tool for RISC-V programs. It allows you to analyze and modify RISC-V programs while they're running, making it perfect for debugging, profiling, and program analysis.
Dynamic Binary Instrumentation (DBI) is a technique that allows you to add code to a program while it's running. This is useful for:
- Counting how many times each instruction is used
- Tracking which functions are called
- Monitoring system calls
- Finding memory leaks and bugs
- And much more!
- Instruction Analysis: Track and analyze RISC-V instructions as they execute
- Instrumentation API: Easy-to-use API for adding your own analysis code
- Built-in Tools: Ready-to-use tools for common tasks:
- Instruction Counter: See which instructions are used most often
- System Call Tracer: Monitor interactions with the operating system
Before you start, make sure you have:
-
C++ Development Tools:
- A C++17 compatible compiler (GCC or Clang)
- CMake (version 3.10 or higher)
- Make
-
RISC-V Toolchain:
- RISC-V GNU Toolchain for compiling test programs
- Instructions for installing the toolchain:
# On Ubuntu/Debian: sudo apt-get install gcc-riscv64-linux-gnu # On macOS with Homebrew: brew install riscv-tools
-
Python:
- Python 3.6 or higher
- Required for running the setup scripts
git clone https://github.com/iamkarthikbk/rvpin.git
cd rvpin
# Make the script executable
chmod +x scripts/setup.sh
# Run the setup script
./scripts/setup.sh
This script will:
- Download necessary RISC-V instruction definitions
- Generate the instruction encoding files
- Build the project
# Create build directory
mkdir -p build
cd build
# Configure and build
cmake ..
make
Count how many times each RISC-V instruction is used in a program:
# First, build the hello world test program
make hello
# Then run the instruction counter
./instruction_counter ./hello
You should see output like this:
Instruction Count Summary:
-------------------------
addi : 6
ecall : 2
auipc : 1
-------------------------
Total Instructions: 9
Monitor system calls made by a program:
./syscall_tracer ./hello
You can create your own analysis tools using RVPin's API. Here's a simple example:
#include "core/engine.hpp"
class MyTool {
public:
void onBeforeInstruction(const rvpin::Instruction& inst) {
// Your analysis code here
// This runs before each instruction
}
};
int main(int argc, char* argv[]) {
auto& engine = rvpin::Engine::getInstance();
// Initialize the engine with the target program
if (!engine.initialize(argc - 1, argv + 1)) {
return 1;
}
// Create your tool
MyTool tool;
// Register callbacks
engine.registerBeforeInstruction(
[&tool](const rvpin::Instruction& inst) {
tool.onBeforeInstruction(inst);
});
// Run the instrumented program
return engine.run();
}
src/core/
: Core instrumentation engineengine.cpp
: Main instrumentation enginedecoder.cpp
: RISC-V instruction decoderinstruction.cpp
: Instruction representation
examples/
: Example toolsinstruction_counter.cpp
: Count instruction usagesyscall_tracer.cpp
: Track system calls
scripts/
: Setup and utility scriptssetup.sh
: Project setup scriptgenerate_encoding.py
: Generate instruction encodings
Contributions are welcome! Whether it's:
- Bug fixes
- New features
- Documentation improvements
- Tool improvements
Please feel free to:
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
If you encounter any issues or have questions:
- Check the Issues page
- Open a new issue if needed
- Provide as much detail as possible about your problem
The cache analyzer visualization requires Python 3.9+ and several dependencies. Install them using:
pip install -r requirements.txt
The cache analyzer visualization requires Python 3.9+ and several dependencies. Install them using:
pip install -r requirements.txt