public String getName() { return reference.getFieldName(); }
@Override public String getFieldAlias(FieldReference field) { return makeUnique(knownVirtualAliases, knowVirtualAliasesCounter, "$" + field.getFieldName()); }
private String suggestForStaticField(FieldReference field) { StringBuilder sb = new StringBuilder(); suggestForClass(field.getClassName(), sb); sb.append('_'); sb.append(sanitize(field.getFieldName())); return sb.toString(); }
private Field getJvmField(FieldReference field) { Class<?> cls; try { cls = Class.forName(field.getClassName(), false, classLoader); } catch (ClassNotFoundException e) { throw new RuntimeException("Class not found: " + field.getClassName()); } Field jvmField; try { jvmField = cls.getDeclaredField(field.getFieldName()); } catch (NoSuchFieldException e) { throw new RuntimeException("Field not found: " + field); } jvmField.setAccessible(true); return jvmField; }
default FieldReader resolve(FieldReference field) { return getAncestors(field.getClassName()) .map(cls -> cls.getField(field.getFieldName())) .filter(Objects::nonNull) .findFirst().orElse(null); }
public String forMemberField(FieldReference field) { return memberFieldNames.computeIfAbsent(field, k -> { Set<String> occupied = occupiedClassNames.computeIfAbsent(k.getClassName(), c -> new HashSet<>(Arrays.asList("parent"))); return pickUnoccupied("fld_" + sanitize(field.getFieldName()), occupied); }); }
public FieldReference getCached(FieldReference reference) { FieldReference result = fieldRefenceCache.get(reference); if (result == null) { result = reference; String classNameCached = getCached(reference.getClassName()); String fieldNameCached = getCached(reference.getFieldName()); if (classNameCached != reference.getClassName() || fieldNameCached != reference.getFieldName()) { result = new FieldReference(classNameCached, fieldNameCached); } fieldRefenceCache.put(result, result); } return result; }
public FieldReader resolve(FieldReference field) { return resolve(field.getClassName(), field.getFieldName()); }
@Override DependencyNode createFieldNode(FieldReference field, ValueType type) { DependencyNode node = createNode(type); if (shouldTag) { node.setTag(field.getClassName() + "#" + field.getFieldName()); } return node; }
public int getFieldOffset(FieldReference field) { ValueType type = ValueType.object(field.getClassName()); addClass(type); ClassBinaryData data = binaryDataMap.get(type); return data.fieldLayout.get(field.getFieldName()); }
@Override public String getStaticFieldAlias(FieldReference field) { return makeUnique(knownAliases, knowAliasesCounter, getClassAlias(field.getClassName()) + "_" + field.getFieldName()); }
public ValueType getFieldType(FieldReference fieldReference) { ClassReader cls = classSource.get(fieldReference.getClassName()); FieldReader field = cls.getField(fieldReference.getFieldName()); return field.getType(); }
@Override public void visit(GetFieldInstruction insn) { try { output.writeByte(insn.getInstance() != null ? 24 : 25); output.writeShort(insn.getReceiver().getIndex()); if (insn.getInstance() != null) { output.writeShort(insn.getInstance().getIndex()); } output.writeInt(symbolTable.lookup(insn.getField().getClassName())); output.writeInt(symbolTable.lookup(insn.getField().getFieldName())); output.writeInt(symbolTable.lookup(insn.getFieldType().toString())); } catch (IOException e) { throw new IOExceptionWrapper(e); } }
@Override public void visit(PutFieldInstruction insn) { try { output.writeByte(insn.getInstance() != null ? 26 : 27); if (insn.getInstance() != null) { output.writeShort(insn.getInstance().getIndex()); } output.writeInt(symbolTable.lookup(insn.getField().getClassName())); output.writeInt(symbolTable.lookup(insn.getField().getFieldName())); output.writeInt(symbolTable.lookup(insn.getFieldType().toString())); output.writeShort(insn.getValue().getIndex()); } catch (IOException e) { throw new IOExceptionWrapper(e); } }
@Override public void visit(QualificationExpr expr) { try { output.writeByte(expr.getQualified() != null ? 17 : 18); if (expr.getQualified() != null) { writeExpr(expr.getQualified()); } output.writeInt(symbolTable.lookup(expr.getField().getClassName())); output.writeInt(symbolTable.lookup(expr.getField().getFieldName())); } catch (IOException e) { throw new IOExceptionWrapper(e); } }
private MethodHolder addReader(DependencyAgent agent, ClassReader cls) { MethodHolder readerMethod = new MethodHolder("getAnnotations", ValueType.parse(Annotation[].class)); readerMethod.setLevel(AccessLevel.PUBLIC); ProgramEmitter pe = ProgramEmitter.create(readerMethod, agent.getClassHierarchy()); List<AnnotationReader> annotations = new ArrayList<>(); for (AnnotationReader annot : cls.getAnnotations().all()) { ClassReader annotType = agent.getClassSource().get(annot.getType()); if (annotType == null) { continue; } AnnotationReader retention = annotType.getAnnotations().get(Retention.class.getName()); if (retention != null) { String retentionPolicy = retention.getValue("value").getEnumValue().getFieldName(); if (retentionPolicy.equals("RUNTIME")) { annotations.add(annot); } } } ValueEmitter array = pe.constructArray(Annotation.class, annotations.size()); for (int i = 0; i < annotations.size(); ++i) { array.setElement(i, generateAnnotationInstance(agent, pe, annotations.get(i))); } array.returnValue(); return readerMethod; }
@Override public void visit(GetFieldInstruction insn) { String className = classNameMapper.map(insn.getField().getClassName()); insn.setField(referenceCache.getCached(new FieldReference(className, insn.getField().getFieldName()))); }
private FieldReference getRealField(FieldReference fieldRef) { String initialCls = fieldRef.getClassName(); String cls = fieldRef.getClassName(); while (cls != null) { ClassReader clsReader = classSource.get(cls); if (clsReader != null) { FieldReader fieldReader = clsReader.getField(fieldRef.getFieldName()); if (fieldReader != null) { return fieldReader.getReference(); } } cls = clsReader.getParent(); } return fieldRef; } }
private void transformProgram(Program program) { for (BasicBlock block : program.getBasicBlocks()) { for (Instruction insn : block) { if (!(insn instanceof GetFieldInstruction)) { continue; } GetFieldInstruction getField = (GetFieldInstruction) insn; FieldReference field = getField.getField(); if (field.getClassName().equals("java.lang.System")) { switch (field.getFieldName()) { case "err": case "out": case "in": { InvokeInstruction invoke = new InvokeInstruction(); invoke.setType(InvocationType.SPECIAL); invoke.setMethod(new MethodReference("java.lang.System", field.getFieldName(), getField.getFieldType())); invoke.setReceiver(getField.getReceiver()); invoke.setLocation(insn.getLocation()); insn.replace(invoke); break; } } } } } } }
@Override public void visit(PutFieldInstruction insn) { String className = classNameMapper.map(insn.getField().getClassName()); if (className != insn.getField().getClassName()) { insn.setField(referenceCache.getCached(new FieldReference(className, insn.getField().getFieldName()))); } } @Override