CHAPTER 2. OBFUSCATIONS FOR INTERMEDIATE LANGUAGE 39 irred jump(replace vertex(Jump,Branch) : nil):− exists ({ }; { }∗ ) (entry,Header), exists ({ }; { }∗ ) (Header,Header), exists ({ }; { }∗ ) (entry,Before), exists ({ } ) (Before,Header), not (exists ({ }; { }∗ ) (Header,Before)), exists ({ }; { }∗ ) (Header,InLoop), exists ({ }∗; {not ( ′ is node (Header)) } ) (InLoop,InLoop), all ({ }∗; { ′ def (X), X = expr type(localvar( ),int(true,b32))}; { } ) (entry,Jump), not (exists ({ }; { }∗ ) (Header,Jump)), jump cond(X,C), @vlabel(Jump,instr label(Label,Inst)), outedges(Jump,Edges), @fresh label(NewLabel), @new vertex(instr label(NewLabel : nil,Inst), Edges,Then), new edge(Then,ThenEdge), new edge(InLoop,InLoopEdge), @new vertex(instr label(Label,branch(cond(C),NewLabel)), ThenEdge : InLoopEdge : nil,Branch). Figure 2.10: Code for the irred jump method
CHAPTER 2. OBFUSCATIONS FOR INTERMEDIATE LANGUAGE 40 Finally, we need to find the declaration <strong>of</strong> a local variable (in our case, we look for an integer variable) that occurs before the loop. We bind the node Jump to the node after the declaration. all ({ }∗; { ′ def (X), X = expr type(localvar( ),int(true,b32))}; { } ) (entry,Jump), not (exists ({ }; { }∗ ) (Header,Jump)) Now that we have found a loop and a suitable variable, we are ready to create the jump. We aim to replace the node Jump with a node Branch which is a conditional expression. If the test <strong>of</strong> the conditional is True then we perform the instructions that were at Jump but if the test is False then we jump to InLoop. We create an expression for the test using the predicate jump cond — so jump cond(X,C) uses the variable X to bind C to a representation <strong>of</strong> the condition. For example, here is a predicate that creates X × X ≥ 0: jump cond(X, expr type(applyatom( compare(geq(true)), expr type(applyatom(mul(false,true),X,X), int(true,b32)), expr type(applyatom(ldc(int(true,b32), 0)), int(true,b32))), bool)). We must ensure that the predicate that we build evaluates to True. Since we are replacing the node Jump, we need to know what label Label, instruction Inst and outgoing edges Edges are at Jump. We then create a new node Then (for when the condition is True) which has the label NewLabel and contains the instruction Inst and has outgoing edges Edges. Next we create two new incoming edges: ThenEdge and InLoopEdge. Finally, we can build the node Branch. This node has the same label as Jump and contains a conditional jump — if True we go to the node Then and if False we go to InLoop. If we had nested loops then this specification would be able to produce only a jump from outside the outermost loop. We have to write many conditions just to find a loop — it would be convenient to use a language that includes loops. 2.4 Related Work We briefly summarise some work related to the specifications <strong>of</strong> IL transformations. 2.4.1 Forms <strong>of</strong> IL In Section 2.3.2 we outlined a form <strong>of</strong> IL that replaced stack expressions with assignments which we called EIL. As we discussed in Section 2.3.8, it would