libvmcu - Virtual MCU Library

libvmcu is a library for static and dynamic analysis of AVR binaries.
It can be used to create regression tests for embedded systems or to analyze AVR programs on assembly level.
You can build your own tools too.
There is also a Java binding, that supports basic functionality.
Features:
Cycle accurate realtime Simulation
Cycle accurate realtime simulation of the microcontroller including its peripherals.
Decode, Decompose, Disassemble, Analyze
The pipeline offers an interface for each stage: decode, decompose, disassemble and analyze. Stages can either operate on a single opcode or a whole binary.
Combine Static and Dynamic Analysis
Perform a static analysis on your binary to receive additional information, for example which SFRs are used by the program. Then, use this information to improve your dynamic analysis.
No further dependencies
libvmcu comes with no further dependencies, thus allowing easy setup and easy usage.
Examples:
Printing disassembly of an intel hex file
Printing xrefs of potential labels
Extracting details from opcode
Unittest: Testing interrupt frequency of driver/led/led.hex
This library is still a work in progress. That's why I am posting here. I am looking for contributors who are interested in developing bindings, tests and drivers (just to name few examples). Feedback is also always welcome.
https://github.com/Milo-D/libvmcu-Virtual-MCU-Library

libvmcu is a library for static and dynamic analysis of AVR binaries.
It can be used to create regression tests for embedded systems or to analyze AVR programs on assembly level.
You can build your own tools too.
There is also a Java binding, that supports basic functionality.
Features:
Cycle accurate realtime Simulation
Cycle accurate realtime simulation of the microcontroller including its peripherals.
Decode, Decompose, Disassemble, Analyze
The pipeline offers an interface for each stage: decode, decompose, disassemble and analyze. Stages can either operate on a single opcode or a whole binary.
Combine Static and Dynamic Analysis
Perform a static analysis on your binary to receive additional information, for example which SFRs are used by the program. Then, use this information to improve your dynamic analysis.
No further dependencies
libvmcu comes with no further dependencies, thus allowing easy setup and easy usage.
Examples:
Printing disassembly of an intel hex file
C:
int main(void) {
/* ignoring checks for this example */
vmcu_report_t *report = vmcu_analyze_ihex("file.hex");
for(int32_t i = 0; i < report->progsize; i++)
printf("%s\n", report->disassembly[i].mnem);
vmcu_report_dtor(report);
return EXIT_SUCCESS;
}
Printing xrefs of potential labels
C:
int main(void) {
/* ignoring checks for this example */
vmcu_report_t *report = vmcu_analyze_ihex("file.hex");
for(int32_t i = 0; i < report->nlabels; i++) {
vmcu_label_t *lx = &report->labels[i];
printf("0x%04x\tL%d\n\n", lx->addr, lx->id);
for(int32_t j = 0; j < lx->nxrefs; j++) {
vmcu_xref_t *x = &lx->xrefs[j];
printf(" xref from 0x%04x ", x->p->addr);
printf("(%s)\n", x->p->mnem);
}
printf("\n");
}
vmcu_report_dtor(report);
return EXIT_SUCCESS;
}
Output:
Output:
0x0000 L0
xref from 0x0051 (jmp +0 ; PC <- 0x0)
0x0034 L1
xref from 0x0000 (jmp +52 ; PC <- 0x34)
0x0040 L2
xref from 0x0044 (brne -5 ; (Z = 0): PC <- PC - 0x5 + 1)
0x0042 L3
xref from 0x003f (rjmp +2 ; PC <- PC + 0x2 + 1)
0x0049 L4
xref from 0x004c (brne -4 ; (Z = 0): PC <- PC - 0x4 + 1)
0x004a L5
xref from 0x0048 (rjmp +1 ; PC <- PC + 0x1 + 1)
0x0051 L6
xref from 0x0002 (jmp +81 ; PC <- 0x51)
xref from 0x0004 (jmp +81 ; PC <- 0x51)
xref from 0x0006 (jmp +81 ; PC <- 0x51)
xref from 0x0008 (jmp +81 ; PC <- 0x51)
xref from 0x000a (jmp +81 ; PC <- 0x51)
xref from 0x000c (jmp +81 ; PC <- 0x51)
xref from 0x000e (jmp +81 ; PC <- 0x51)
xref from 0x0010 (jmp +81 ; PC <- 0x51)
xref from 0x0012 (jmp +81 ; PC <- 0x51)
xref from 0x0014 (jmp +81 ; PC <- 0x51)
xref from 0x0016 (jmp +81 ; PC <- 0x51)
xref from 0x0018 (jmp +81 ; PC <- 0x51)
xref from 0x001a (jmp +81 ; PC <- 0x51)
xref from 0x001c (jmp +81 ; PC <- 0x51)
xref from 0x001e (jmp +81 ; PC <- 0x51)
xref from 0x0020 (jmp +81 ; PC <- 0x51)
xref from 0x0022 (jmp +81 ; PC <- 0x51)
xref from 0x0024 (jmp +81 ; PC <- 0x51)
xref from 0x0026 (jmp +81 ; PC <- 0x51)
xref from 0x0028 (jmp +81 ; PC <- 0x51)
xref from 0x002a (jmp +81 ; PC <- 0x51)
xref from 0x002e (jmp +81 ; PC <- 0x51)
xref from 0x0030 (jmp +81 ; PC <- 0x51)
xref from 0x0032 (jmp +81 ; PC <- 0x51)
Extracting details from opcode
C:
int main(void) {
vmcu_plain_t p;
vmcu_disassembly_bytes(0xd8e0, &p);
const VMCU_IKEY key = p.key; // VMCU_LDI
const uint32_t opcode = p.opcode; // 0xe0d8 (big endian)
const uint16_t addr = p.addr; // 0x0000 (undefined)
const bool dword = p.dword; // false
const bool exec = p.exec; // true
const char *mnemonic = p.mnem; // ldi r29, 0x08
vmcu_operand_t *src = &p.src;
vmcu_operand_t *dest = &p.dest;
VMCU_OPTYPE src_type = src.type; // VMCU_IMM8
VMCU_OPTYPE dest_type = dest.type; // VMCU_REGISTER
const uint8_t src_val = src.value; // 0x08
const uint8_t dest_val = dest.value; // (r)29
return EXIT_SUCCESS;
}
Unittest: Testing interrupt frequency of driver/led/led.hex
C:
#define TESTFILE "../../driver/led/led.hex"
#define PORTB 0x0025
#define PB5 0x05
#define bit(v, b) ((v & (1 << b)) >> b)
int main(const int argc, const char **argv) {
uint8_t led;
/* ignoring checks for this example */
vmcu_report_t *report = vmcu_analyze_ihex(TESTFILE);
vmcu_system_t *sys = vmcu_system_ctor(report);
do {
vmcu_system_step(sys);
led = vmcu_system_read_data(sys, PORTB);
} while(bit(led, PB5) == 0x00);
const double f = 16000000U;
const double c = sys->cycles;
const double time = (c / f);
assert((0.95 <= time) && (time <= 1.05));
printf("Time between LED toggle: %lf [s]\n", time);
vmcu_report_dtor(report);
vmcu_system_dtor(sys);
return EXIT_SUCCESS;
}
Output:
Time between LED toggle: 1.000021 [s]
This library is still a work in progress. That's why I am posting here. I am looking for contributors who are interested in developing bindings, tests and drivers (just to name few examples). Feedback is also always welcome.
https://github.com/Milo-D/libvmcu-Virtual-MCU-Library