-
Notifications
You must be signed in to change notification settings - Fork 0
Resilience-aware LLVM-based Compiler
License
MPSLab-ASU/LLVM-r
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
LLVM backend for OpenRISC 1000 ============================== Installation ------------ mkdir build && cd build with autotools: ../configure CC=gcc CXX=g++ --enable-debug-runtime --prefix=/path/to/instdir with cmake: cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/path/to/instdir make install Run tests --------- make check make TESTSUITE=CodeGen/OR1K check make TESTSUITE=MC/OR1K check or bin/llvm-lit -sv -j1 test/CodeGen/OR1K/ TODO (not a complete list) -------------------------- - Handle unconditional branches in AnalyzeBranch - Floating point support - Integrated assembler support - Relocations ============================== Example and guidelines for EDDI, SWIFTR and WholeSafe ------------ There are sample MiBench assembly files with EDDI, SWIFTR and WholeSafe in MiBenchExample/SampleAssembly. For the fault injection experiment, we modified mor1kx core with few features and there are few nop insturction for the simulation. - l.nop 1111 placed at the "Normal" end of each application - l.nop 100 and l.nop 200 placed at start / end of the FI range - l.nop 204 stands for detected dataflow error - As EDDI is error detection scheme, whenever it finds mismatch between two stream it will raise DF error - For WholeSafe, it only raise DF error if register values of three stream are all different; otherwise it will select major value and correct other one - l.nop 205 stands for detected controlflow error in WholeSafe High-level codes for the compilation are in MiBenchExample/HighLevelCodes - For each high-level application, we used definition of all library functions such as printf from mor1kx development and or1k-glibc - Also, we embedded input files as data structure. For example, in sha benchmark, you can find file_data in sha.c But if you want to compile assemblies with each protection technique, here is an example to compile application. (For the explanation we will use sha benchmark. you can find high-level c codes in MiBenchExample/HighLevelCodes/SHA/) 1. Compile C codes to LLVM assembly and link them - YOUR_LLVM_BUILD_DIRECTORY/bin/clang -I OR1K-ELF-DIRECTORY/include/ -target or1k-elf -emit-llvm -S *.c -O3 - YOUR_LLVM_BUILD_DIRECTORY/bin/llvm-link *.ll -o SHA.LL 2. Now we can generate assembly file without protection, or with SWIFTR - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -compat-or1k-delay-filler=false --march=or1k SHA.LL -o SHA.s - This command just generates assembly file without protection - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -enable-SWIFTR-embeddedLib=true -enable-swiftr-jumpRegCheck=true -enable-NEMESIS-CF=false -compat-or1k-delay-filler=true -reserve-22-registers=true --march=or1k SHA.LL -o SHA-SWIFTR.s - This command will generate sha assembly with SWIFTR protection. But we need to do few works by hand (Step 5.) 3. EDDI needs to duplicate whole memory. In same way, WholeSafe needs to triplicate memory. For this, we need to i) place all data (variables and jump table values). ii) duplicate/triplicate them. iii) calculate distance between original memory and replicated memory (in other words, we need to calculate offset for memory operations in EDDI and WholeSafe). i) and ii) build application with register reserving (For EDDI, we need to reserve 18 regs. For WholeSafe, we need to reserve 22 regs) - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -reserve-18-registers=true --march=or1k SHA.LL -o SHA-REG18.s - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -reserve-22-registers=true --march=or1k SHA.LL -o SHA-REG22.s - Then we need to place all data sequentially - Move all jump tables (LJTI) at the end of program - replace all .comm like #from .type tx_buff,@object .comm tx_buff,32,1 ---------------------------------- #to .type tx_buff,@object tx_buff: .long 0 .long 0 .long 0 .long 0 .long 0 .long 0 .long 0 .long 0 - remove all ".section" of data - Then copy all variables and jump tables (once for EDDI and twice for WholeSafe). We also need to rename copied variables (like tx_buff to tx_buff_shadow1/tx_buff_shadow2). - You can find examples of these conversion and replication of data for sha in MiBenchExample/SampleAssembly/EDDI/SHA-EDDI.s and MiBenchExample/SampleAssembly/WHOLESAFE/SHA-WHOLESAFE.s (Note after .data in these assembly) iii) You can calculate them by hand, or just build benchmark with few modification and run them. - For example, you can insert these instructions to the main function of SHA-REG18.s and SHA-REG22.s l.movhi r13, hi(int_handlers_shadow1) l.movhi r23, hi(int_handlers_shadow2) l.movhi r3, hi(int_handlers) l.ori r13, r13, lo(int_handlers_shadow1) l.ori r23, r23, lo(int_handlers_shadow2) l.ori r3, r3, lo(int_handlers) and then you can calculate offset between r3 and r13 - In SHA of our example, offset is 1668 for EDDI and WholeSafe. 4. Now we can generate assembly with EDDI and WholeSafe with offset from step 3. - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -enable-EDDI-INT-SKIPADDR=true -enable-NEMESIS-CF=false -delay-slot-copy-r9-to-r22=true -eddi_offset=-OFFSET_VALUE -compat-or1k-delay-filler=true -reserve-18-registers=true --march=or1k SHA.LL -o SHA-EDDI.s - This command just generates assembly file with WholeSafe. you need to set OFFSET_VALUE from step 3. - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -enable-tzdc-no-store-voting=true -enable-tzdc-wdc=true -enable-tzdc-int-5interleaving=true -enable-tzdc-3sig-with-wdc-int=true -enable-tzdc-jumpRegCheck=true -enable-NEMESIS-CF=false -tzdc-offset=-OFFSET_VALUE -compat-or1k-delay-filler=true -reserve-22-registers=true -enable-tzdc-complexVoting=true --march=or1k SHA.LL -o SHA-WHOLESAFE5.s - This command just generates assembly file with WholeSafe. you need to set OFFSET_VALUE from step 3. - For the example of sha, you can use -1668 like - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -enable-EDDI-INT-SKIPADDR=true -enable-NEMESIS-CF=false -delay-slot-copy-r9-to-r22=true -eddi_offset=-1668 -compat-or1k-delay-filler=true -reserve-18-registers=true --march=or1k SHA.LL -o SHA-EDDI.s - YOUR_LLVM_BUILD_DIRECTORY/bin/llc -enable-tzdc-no-store-voting=true -enable-tzdc-wdc=true -enable-tzdc-int-5interleaving=true -enable-tzdc-3sig-with-wdc-int=true -enable-tzdc-jumpRegCheck=true -enable-NEMESIS-CF=false -tzdc-offset=-1668 -compat-or1k-delay-filler=true -reserve-22-registers=true -enable-tzdc-complexVoting=true --march=or1k SHA.LL -o SHA-WHOLESAFE5.s 5. Finally we can complete assembly file with some modification by hand - For EDDI and WholeSafe, make data sequential (Do same works in step 3, or just use result of step 3) - Find one normal end of application (return or exit instruction of main function), and replace that instruction as l.nop 1111 - You also need to change your simulator/processor to recognize l.nop 1111 as end of program - Insert register copy instructions at the start of memset and main function - For EDDI, l.addi r14, r1, 0 l.addi r15, r2, 0 l.addi r16, r3, 0 l.addi r17, r4, 0 l.addi r18, r5, 0 l.addi r19, r6, 0 l.addi r20, r7, 0 l.addi r21, r8, 0 l.addi r22, r9, 0 l.addi r23, r10, 0 l.addi r24, r11, 0 l.addi r25, r12, 0 l.addi r26, r13, 0 - For WholeSafe and SWIFTR, l.addi r10, r1, 0 l.addi r12, r2, 0 l.addi r13, r3, 0 l.addi r14, r4, 0 l.addi r15, r5, 0 l.addi r16, r6, 0 l.addi r17, r7, 0 l.addi r19, r9, 0 l.addi r8, r11, 0 l.addi r21, r1, 0 l.addi r22, r2, 0 l.addi r23, r3, 0 l.addi r24, r4, 0 l.addi r25, r5, 0 l.addi r26, r6, 0 l.addi r27, r7, 0 l.addi r29, r9, 0 l.addi r31, r11, 0 -Also, for the start of main function in WholeSafe, insert signature initialization l.addi r18, r0, 0 l.addi r20, r0, 0 l.addi r28, r0, 0 - (WholeSafe) we need to insert voting algorithm for critical operation by hand. For sha, only l.nop 4 is critical operation as in our simulation environment l.nop 4 will put character in r3, and this is only one operation for the output. So right before the l.nop 4, insert these instructions l.sfne r3, r13 l.mfspr r30, r0, 16 l.addi r30, r30, 16 l.bf .LBB16_1 l.nop 0 (.LBB16_1 is an error recovery block of sim_putc function. In other application, you need to change it to the recovery block of simputc function) Also, before the end of application (l.nop 1111), insert compare operation between triplicated signatures. Currently we consider unrecoverable CF error if all signatures are different; if only two singatures matches, we consider that it is because of DF error. So replace l.nop 1111 (that we replaced original end of application) like this PREVIOUS l.nop 1111 ----------------------------------- CURRENT l.sfeq r18, r20 l.bf .LBB33_NOTCF l.sfeq r20, r28 l.bf .LBB33_NOTCF l.sfeq r18, r28 l.bf .LBB33_NOTCF l.nop 0 l.nop 204 .LBB33_NOTCF: l.nop 11111 - (EDDI) Similarly, insert comparison before the l.nop 4 l.sfne r3, r16 l.bf .LBB16_1 (.LBB16_1 is an detected error handling block of sim_putc function. In other application, you need to change it to the erorr block of simputc function) Also, currently our LLVM has some bugs with l.nop 2 and l.nop 4. If there are few instructions before l.nop 2 or l.nop 4 like .intel_syntax l.nop 1670 .att_syntax please remove them and #APP l.addi r3,r16,0 #NO_APP also remove them. (note that you should not remove l.nop 2 and l.nop 4) - (SWIFTR) Similar to EDDI, insert these instructions before l.nop 4 l.sfne r3, r13 l.cmov r3, r23, r3 l.cmov r13, r23, r13 Also, please handle bugs with l.nop 2 and l.nop 4. If there are few instructions before l.nop 2 or l.nop 4 like .intel_syntax l.nop 1670 .att_syntax (If it exists, there will be one more. If it does not exist please don't mind) please remove them and also #APP l.addi r3,r13,0 #NO_APP #APP l.addi r3,r23,0 remove them. (note that you should not remove l.nop 2 and l.nop 4) - Finally, please insert l.nop 100 at the start of the main function, and l.nop 200 just before the end of main function (only before normal end) for FI range
About
Resilience-aware LLVM-based Compiler
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published