Here is a simple implementation of RISC-V instructions interpreter with ELF files' parsing.
There are the following features of the project:
- Firstly ELF file is parsed and checked for correctness.
- The program in ELF file is loaded into virtual memory (paging memory), as it usually OS does.
- The interpreter supports all instructions from RV32I set, except
ECALL,EBREAKandFENCEinstructions.
First of all make sure you have git, cmake, libelf on your device. Then do the following:
git clone https://github.com/Vokerlee/RISC-V-ELF-Interpreter.git
cd RISC-V-ELF-Interpreter
mkdir build
cd build
cmake ..
makeNow you have compiled program in build folder with name RISC-V-Interpreter.
The usage is plain: you are to create ELF file (with RISC-V architecture) and next launch RISC-V-Interpreter as follows:
./RISC-V-Interpreter elf_file_name.outAll information about executed instructions is placed in stdoutstream. It is recommended to redirect stream to another file, using the launch of the program in the following form:
./RISC-V-Interpreter elf_file_name.out > log_instructions.logMind that you cannot use any library while compiling your ELF program, otherwise the interpreter will not work (it doesn't support system calls).
Normally compilers generate ELF files of x86/64 architecture. To change it you are to install another compiler: download and install https://github.com/riscv-collab/riscv-gnu-toolchain RISC-V GNU Compiler Toolchain (mind to disable RVC extension!).] with RV32 configuration.
Now you let's look at an example how to compile a simple program:
int mult(int a, int b);
int main()
{
int a = 19;
int b = 8;
int c = mult(a, b);
return 0;
}
int mult(int a, int b)
{
int result = 0;
while (b != 0)
{
if (b & 0x1 == 0x1)
result += a;
b >>= 1;
a <<= 1;
}
return result;
}riscv32-unknown-elf-gcc -S test_prog.c -o test_prog.s
riscv32-unknown-elf-as test_prog.s -o test_prog.o
riscv32-unknown-elf-ld test_prog.o -o test_prog.outAlso you can use objdump to check for correctness ELF file:
riscv32-unknown-elf-objdump -S test_prog.out > test_prog.dumpDifferent examples of compilation and usage of the program you can see in examples folder.