I want to use LLVM to make a dynamic fault injection. My primary goal is to modify the value of a particular register in a particular instruction and do, for example, bit flipping on that register.
I’ve studying some tutorials and codes about LLVM but I’m still not sure how to begin with. I know that I need to program a LLVM pass that iterates over blocks and check which instruction modify to later check which operand in that instruction modify. Is that the correct?
I’ve seen some examples but all of them seem very complicated (a lot of code) to understand for a beginner like me. I wonder if there is an easier example to understand or if you can provide me with one to start with.
Thank you very much for your help!
Examples that I haven’t understood:
By dynamic, do you mean that you want to change which faults are injected while the program is running, or is it sufficient to recompile the program and rerun it when you want to inject new faults? Also, are you wanting to inject faults at the LLVM IR level, or do you want to inject faults after the program’s machine code has been generated (e.g., you want to inject faults into a particular register)? The answers to these questions will determine whether you need to write an LLVM IR pass or an LLVM MachineFunction pass (or whether you really want to be modifying a dynamic binary translator like QEMU/Valgrind instead of using LLVM). I think the first three documents to read are: 1) How to Write an LLVM Pass 2) The LLVM Programmer’s Manual 3) The LLVM Language Reference Manual The first document explains how to add a new analysis/transform to the compiler. The second explains some of the utility functions and idioms that you will see in existing LLVM code. The third describes (in gory detail) the LLVM IR instruction set. Regards, John Criswell
If I understand correctly, you need to first traverse the module, function, bbs and then detect the instructions that you want to modify. You can use the getOpcode() or getOpcodeName() to detect the instruction that you want to modify. Then you need to know which operand you want to modify. You can use getOperand(i) to get the ith operand of one instruction, and then use setOperand(i, new_value) to set the new operand. You can see the examples from the links in your email.
But all these are done in IR level. In the assembly, these instructions could be deleted/modified/optimized.