private void createLookupFunction(SootMethod m) { // TODO: This should use a virtual method table or interface method table. Function function = FunctionBuilder.lookup(m); mb.addFunction(function); Variable reserved0 = function.newVariable(I8_PTR_PTR); function.add(new Getelementptr(reserved0, function.getParameterRef(0), 0, 4)); Variable reserved1 = function.newVariable(I8_PTR_PTR); function.add(new Getelementptr(reserved1, function.getParameterRef(0), 0, 5)); function.add(new Store(getString(m.getName()), reserved0.ref())); function.add(new Store(getString(getDescriptor(m)), reserved1.ref())); Value lookupFn = sootClass.isInterface() ? BC_LOOKUP_INTERFACE_METHOD : BC_LOOKUP_VIRTUAL_METHOD; List<Value> args = new ArrayList<Value>(); args.add(function.getParameterRef(0)); if (sootClass.isInterface()) { Value info = getInfoStruct(function); args.add(info); } args.add(function.getParameterRef(1)); args.add(getString(m.getName())); args.add(getString(getDescriptor(m))); Value fptr = call(function, lookupFn, args); Variable f = function.newVariable(function.getType()); function.add(new Bitcast(f, fptr, f.getType())); Value result = call(function, f.ref(), function.getParameterRefs()); function.add(new Ret(result)); }
private Function createClassInitWrapperFunction(FunctionRef targetFn) { Function fn = FunctionBuilder.clinitWrapper(targetFn); Value info = getInfoStruct(fn); Variable infoHeader = fn.newVariable(new PointerType(new StructureType(I8_PTR, I32))); fn.add(new Bitcast(infoHeader, info, infoHeader.getType())); Variable infoHeaderFlags = fn.newVariable(new PointerType(I32)); fn.add(new Getelementptr(infoHeaderFlags, infoHeader.ref(), 0, 1)); Variable flags = fn.newVariable(I32); fn.add(new Load(flags, infoHeaderFlags.ref())); Variable initializedFlag = fn.newVariable(I32); fn.add(new And(initializedFlag, flags.ref(), new IntegerConstant(CI_INITIALIZED))); Variable initialized = fn.newVariable(I1); fn.add( new Icmp( initialized, Icmp.Condition.eq, initializedFlag.ref(), new IntegerConstant(CI_INITIALIZED))); Label trueLabel = new Label(); Label falseLabel = new Label(); fn.add( new Br(initialized.ref(), fn.newBasicBlockRef(trueLabel), fn.newBasicBlockRef(falseLabel))); fn.newBasicBlock(trueLabel); Value result = call(fn, targetFn, fn.getParameterRefs()); fn.add(new Ret(result)); fn.newBasicBlock(falseLabel); call(fn, BC_INITIALIZE_CLASS, fn.getParameterRef(0), info); fn.add(new Br(fn.newBasicBlockRef(trueLabel))); return fn; }