@@ -29,7 +29,7 @@ using namespace llvm;
29298: for all original instructions insert after
30309: signature ← signature + random number
3131 * create CFG
32- * checkBeginning
32+ * checkCompileTimeSigAtJump
333310:for all BB in CFG insert at beginning
343411: signature ← signature − subRanPrevVal
353512: if signature != compileTimeSig error()
@@ -38,7 +38,7 @@ using namespace llvm;
383814: if Last Instr. is return instr. and NrIntrBB > 1 then
393915: Calculate needed variables
404016: return Val ← random number
41- 17: adjust Value ← (compileTimeSigBB + Sum{instrMonUpdates}) -
41+ 17: adjust Value ← (compileTimeSigBB + Sum{in%2 = load i32, ptr @signature, align 4
424218: return Val
434319: Insert signature update before return instr.
444420: signature ← signature + adjustValue
@@ -56,62 +56,56 @@ using namespace llvm;
5656// --- INITIALIZE BLOCKS RANDOM ---
5757
5858bool isNotUniqueCompileTimeSig (
59- const int bb_num,
60- const std::unordered_map<BasicBlock*, int > &compileTimeSig
59+ const uint32_t bb_num,
60+ const std::unordered_map<BasicBlock*, uint32_t > &compileTimeSig
6161) {
62- for (const auto &pair : compileTimeSig) {
63- if (pair. second == bb_num) return true ;
62+ for (const auto &[_, other_bb_id] : compileTimeSig) {
63+ if ( other_bb_id == bb_num ) return true ;
6464 }
6565 return false ;
6666}
6767
6868bool isNotUnique (
69- const int bb_num, const int subrun_num ,
70- const std::unordered_map<BasicBlock*, int > &RandomNumBBs,
71- const std::unordered_map<BasicBlock*, int > &SubRanPrevVals
69+ const uint32_t current_id ,
70+ const std::unordered_map<BasicBlock*, uint32_t > &RandomNumBBs,
71+ const std::unordered_map<BasicBlock*, uint32_t > &SubRanPrevVals
7272) {
73-
74- for ( const auto &pair : RandomNumBBs) {
75- if (pair. second + SubRanPrevVals. at (pair. first ) == bb_num + subrun_num ) {
73+ for ( const auto &[other_bb, other_bb_num] : RandomNumBBs) {
74+ uint32_t other_id = static_cast < uint32_t >(other_bb_num) + SubRanPrevVals. at (other_bb);
75+ if ( other_id == current_id ) {
7676 return true ;
7777 }
7878 }
7979
8080 return false ;
8181}
8282
83- void RACFED::initializeBlocksSignatures (Module &Md) {
84- int i = 0 ;
85- srand (static_cast <unsigned >(time (nullptr ))); // compileTimeSig weak random generator
86- int randomBB;
87- int randomSub;
88-
89- for (Function &Fn : Md) {
90- if (shouldCompile (Fn, FuncAnnotations)) {
91- for (BasicBlock &BB : Fn) {
92-
93- do {
94- randomBB = rand ();
95- } while (isNotUniqueCompileTimeSig (randomBB, compileTimeSig));
96-
97- do {
98- randomSub = rand ();
99- } while (isNotUnique (i, randomSub, compileTimeSig, subRanPrevVals));
100-
101- compileTimeSig.insert (std::pair (&BB, randomBB));// not random, guarantees unicity
102- subRanPrevVals.insert (std::pair (&BB, randomSub)); // In this way the sub value is random
103- sumIntraInstruction.insert (std::pair (&BB, 0 ));// assign value to the sum of the instr
104- i++;
105-
106- }
107- }
83+ void RACFED::initializeBlocksSignatures (Module &Md, Function &Fn) {
84+ std::mt19937 rng (0xB00BA5 ); // seed fisso per riproducibilità
85+ std::uniform_int_distribution<uint32_t > dist (1 , 0x7fffffff );
86+ uint32_t randomBB;
87+ uint32_t randomSub;
88+
89+ for (BasicBlock &BB : Fn) {
90+ do {
91+ randomBB = dist (rng);
92+ } while ( isNotUniqueCompileTimeSig (randomBB, compileTimeSig) );
93+
94+ do {
95+ randomSub = dist (rng);
96+ } while ( isNotUnique (
97+ static_cast <uint32_t >(randomBB) + randomSub,
98+ compileTimeSig,
99+ subRanPrevVals) );
100+
101+ compileTimeSig.insert (std::pair (&BB, randomBB));
102+ subRanPrevVals.insert (std::pair (&BB, randomSub));
108103 }
109104}
110105
111106
112107// --- UPDATE SIGNATURE RANDOM ---
113108void originalInstruction (BasicBlock &BB, std::vector<Instruction*> &OrigInstructions) {
114-
115109 for (Instruction &I : BB) {
116110 if (isa<PHINode>(&I)) continue ; // NON è originale
117111 if (I.isTerminator ()) continue ; // NON è originale
@@ -120,28 +114,27 @@ void originalInstruction(BasicBlock &BB, std::vector<Instruction*> &OrigInstruc
120114 }
121115}
122116
123- void RACFED::updateCompileSigRandom (Function &F, Module &Md ) {
117+ void RACFED::updateCompileSigRandom (Module &Md, Function &Fn ) {
124118 LLVMContext &Ctx = Md.getContext ();
125119 GlobalVariable *SigGV = Md.getNamedGlobal (" signature" );
126120 std::mt19937 rng (0xC0FFEE ); // seed fisso per riproducibilità
127121 std::uniform_int_distribution<uint32_t > dist (1 , 0x7fffffff );
128- auto *I32 = Type::getInt32Ty (Ctx);
122+ auto *I64 = Type::getInt64Ty (Ctx);
129123 if (!SigGV) {
130124 SigGV = new GlobalVariable (
131125 Md,
132- I32 ,
126+ I64 ,
133127 /* isConstant=*/ false ,
134128 GlobalValue::ExternalLinkage,
135- ConstantInt::get (I32 , 0 ),
129+ ConstantInt::get (I64 , 0 ),
136130 " signature" );
137131 }
138132
139- for (auto &BB: F ){
133+ for (auto &BB: Fn ){
140134 std::vector<Instruction*> OrigInstructions;
141135 originalInstruction (BB, OrigInstructions);
142136
143- if (OrigInstructions.size () <= 2 )
144- continue ;
137+ if (OrigInstructions.size () <= 2 ) continue ;
145138
146139 uint64_t partial_sum;
147140
@@ -158,7 +151,7 @@ void RACFED::updateCompileSigRandom(Function &F, Module &Md) {
158151 IRBuilder<> B (InsertPt);
159152
160153 // signature = signature + randomConstant
161- uint32_t K = dist (rng);
154+ uint64_t K = dist (rng);
162155
163156 try {
164157 partial_sum = K + sumIntraInstruction.at (&BB);
@@ -168,15 +161,76 @@ void RACFED::updateCompileSigRandom(Function &F, Module &Md) {
168161
169162 sumIntraInstruction.insert (std::pair (&BB, partial_sum));
170163
171- Value *OldSig = B.CreateLoad (I32 , SigGV);
172- Value *Add = B.CreateAdd (OldSig, ConstantInt::get (I32 , K), " sig_add" );
164+ Value *OldSig = B.CreateLoad (I64 , SigGV);
165+ Value *Add = B.CreateAdd (OldSig, ConstantInt::get (I64 , K), " sig_add" );
173166 B.CreateStore (Add, SigGV);
174167 }
175168 }
169+
176170}
177171
178172// --- CREATE CFG VERIFICATION ---
179173
174+ void RACFED::checkCompileTimeSigAtJump (Module &Md, Function &Fn) {
175+ auto *IntType = llvm::Type::getInt64Ty (Md.getContext ());
176+
177+ BasicBlock *ErrBB = BasicBlock::Create (Fn.getContext (), " ErrBB" , &Fn);
178+ IRBuilder<> ErrB (ErrBB);
179+
180+ IRBuilder<> B (&*(Fn.front ().getFirstInsertionPt ()));
181+
182+ Value *RuntimeSig = B.CreateAlloca (IntType);
183+
184+ for (BasicBlock &BB: Fn) {
185+ int randomNumberBB = compileTimeSig.find (&BB)->second ;
186+ int subRanPrevVal = subRanPrevVals.find (&BB)->second ;
187+
188+ // in this case BB is not the first Basic Block of the function, so it has to
189+ // update RuntimeSig and check it
190+ if (!BB.isEntryBlock ()) {
191+ if (isa<LandingPadInst>(BB.getFirstNonPHI ()) ||
192+ BB.getName ().contains_insensitive (" verification" )) {
193+ IRBuilder<> BChecker (&*BB.getFirstInsertionPt ());
194+ BChecker.CreateStore (llvm::ConstantInt::get (IntType, randomNumberBB),
195+ RuntimeSig, true );
196+ } else if (!BB.getName ().contains_insensitive (" errbb" )) {
197+ BasicBlock *NewBB = BasicBlock::Create (
198+ BB.getContext (), " RACFED_Verification_BB" , BB.getParent (), &BB);
199+ IRBuilder<> BChecker (NewBB);
200+
201+ // add instructions for the first runtime signature update
202+ Value *InstrRuntimeSig = BChecker.CreateLoad (IntType, RuntimeSig, true );
203+
204+ Value *RuntimeSignatureVal = BChecker.CreateSub (
205+ InstrRuntimeSig, llvm::ConstantInt::get (IntType, subRanPrevVal));
206+ BChecker.CreateStore (RuntimeSignatureVal, RuntimeSig, true );
207+
208+ // update phi placing them in the new block
209+ while (isa<PHINode>(&BB.front ())) {
210+ Instruction *PhiInst = &BB.front ();
211+ PhiInst->removeFromParent ();
212+ PhiInst->insertBefore (&NewBB->front ());
213+ }
214+
215+ // replace the uses of BB with NewBB
216+ for (BasicBlock &BB_ : *BB.getParent ()) {
217+ if (&BB_ != NewBB) {
218+ BB_.getTerminator ()->replaceSuccessorWith (&BB, NewBB);
219+ }
220+ }
221+
222+ // add instructions for checking the runtime signature
223+ Value *CmpVal =
224+ BChecker.CreateCmp (llvm::CmpInst::ICMP_EQ, RuntimeSignatureVal,
225+ llvm::ConstantInt::get (IntType, randomNumberBB));
226+ BChecker.CreateCondBr (CmpVal, &BB, ErrBB);
227+
228+ // add NewBB and BB into the NewBBs map
229+ NewBBs.insert (std::pair<BasicBlock *, BasicBlock *>(NewBB, &BB));
230+ }
231+ }
232+ }
233+ }
180234
181235
182236void RACFED::createCFGVerificationBB (
@@ -185,59 +239,15 @@ void RACFED::createCFGVerificationBB(
185239 Value &RetSig, BasicBlock &ErrBB
186240) {
187241
188- // checkBeginning () NON ENTRY BLOCK
242+ // checkCompileSigAtJump () NON ENTRY BLOCK
189243 // compileTimeSig - subRunPrevVal
190244 // if compileTimeSig != runtime_sig error()
191245
192- auto *IntType = llvm::Type::getInt32Ty (BB.getContext ());
246+ auto *IntType = llvm::Type::getInt64Ty (BB.getContext ());
193247
194248 int randomNumberBB = RandomNumberBBs.find (&BB)->second ;
195249 int subRanPrevVal = SubRanPrevVals.find (&BB)->second ;
196250
197- // in this case BB is not the first Basic Block of the function, so it has to
198- // update RuntimeSig and check it
199- if (!BB.isEntryBlock ()) {
200- if (isa<LandingPadInst>(BB.getFirstNonPHI ()) ||
201- BB.getName ().contains_insensitive (" verification" )) {
202- IRBuilder<> BChecker (&*BB.getFirstInsertionPt ());
203- BChecker.CreateStore (llvm::ConstantInt::get (IntType, randomNumberBB),
204- &RuntimeSig, true );
205- } else if (!BB.getName ().contains_insensitive (" errbb" )) {
206- BasicBlock *NewBB = BasicBlock::Create (
207- BB.getContext (), " RACFED_Verification_BB" , BB.getParent (), &BB);
208- IRBuilder<> BChecker (NewBB);
209-
210- // add instructions for the first runtime signature update
211- Value *InstrRuntimeSig = BChecker.CreateLoad (IntType, &RuntimeSig, true );
212-
213- Value *RuntimeSignatureVal = BChecker.CreateSub (
214- InstrRuntimeSig, llvm::ConstantInt::get (IntType, subRanPrevVal));
215- BChecker.CreateStore (RuntimeSignatureVal, &RuntimeSig, true );
216-
217- // update phi placing them in the new block
218- while (isa<PHINode>(&BB.front ())) {
219- Instruction *PhiInst = &BB.front ();
220- PhiInst->removeFromParent ();
221- PhiInst->insertBefore (&NewBB->front ());
222- }
223-
224- // replace the uses of BB with NewBB
225- for (BasicBlock &BB_ : *BB.getParent ()) {
226- if (&BB_ != NewBB) {
227- BB_.getTerminator ()->replaceSuccessorWith (&BB, NewBB);
228- }
229- }
230-
231- // add instructions for checking the runtime signature
232- Value *CmpVal =
233- BChecker.CreateCmp (llvm::CmpInst::ICMP_EQ, RuntimeSignatureVal,
234- llvm::ConstantInt::get (IntType, randomNumberBB));
235- BChecker.CreateCondBr (CmpVal, &BB, &ErrBB);
236-
237- // add NewBB and BB into the NewBBs map
238- NewBBs.insert (std::pair<BasicBlock *, BasicBlock *>(NewBB, &BB));
239- }
240- }
241251
242252 // checkReturnVal()
243253 // compute returnValue
@@ -313,6 +323,7 @@ void RACFED::createCFGVerificationBB(
313323 // }
314324}
315325
326+
316327PreservedAnalyses RACFED::run (Module &Md, ModuleAnalysisManager &AM) {
317328 // mappa: istruzione originale -> random r usato per S = S + r
318329 std::unordered_map<llvm::Instruction*, int > InstrUpdates;
@@ -323,10 +334,17 @@ PreservedAnalyses RACFED::run(Module &Md, ModuleAnalysisManager &AM) {
323334 getFuncAnnotations (Md, FuncAnnotations);
324335 LinkageMap linkageMap = mapFunctionLinkageNames ((Md));
325336
326- initializeBlocksSignatures (Md);
337+ for (Function &Fn : Md) {
338+ if (shouldCompile (Fn, FuncAnnotations))
339+ initializeBlocksSignatures (Md, Fn);
340+ }
327341
328- for (Function &F: Md){
329- updateCompileSigRandom (F, Md);
342+ for (Function &Fn: Md) {
343+ updateCompileSigRandom (Md, Fn);
344+ }
345+
346+ for (Function &Fn: Md) {
347+ checkCompileTimeSigAtJump (Md, Fn);
330348 }
331349
332350 // createCFGVerificationBB();
@@ -408,4 +426,4 @@ llvmGetPassPluginInfo() {
408426// }
409427// }
410428// return nullptr;
411- // }
429+ // }
0 commit comments