1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.lang.instrument.Instrumentation;
  25 import java.lang.instrument.ClassDefinition;
  26 
  27 import jdk.internal.org.objectweb.asm.ClassWriter;
  28 import jdk.internal.org.objectweb.asm.Label;
  29 import jdk.internal.org.objectweb.asm.MethodVisitor;
  30 import jdk.internal.org.objectweb.asm.Opcodes;
  31 
  32 public class Agent implements Opcodes {
  33 
  34     private static byte[] makeNewMartyr() {
  35         ClassWriter cw = new ClassWriter(0);
  36         MethodVisitor mv;
  37 
  38         cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "Martyr", null, "java/lang/Object", null);
  39         cw.visitSource(null, null);
  40 
  41         {
  42             mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
  43             mv.visitCode();
  44             Label lab0 = new Label();
  45             mv.visitLabel(lab0);
  46             mv.visitLineNumber(1, lab0);
  47             mv.visitVarInsn(ALOAD, 0);
  48             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
  49             mv.visitInsn(RETURN);
  50             mv.visitMaxs(1, 1);
  51             mv.visitEnd();
  52         }
  53 
  54         {
  55             mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null);
  56             mv.visitCode();
  57             Label lab0 = new Label();
  58             mv.visitLabel(lab0);
  59             mv.visitLineNumber(6, lab0);
  60             mv.visitLdcInsn("Redefinition done");
  61             mv.visitInsn(ARETURN);
  62             mv.visitMaxs(1, 1);
  63             mv.visitEnd();
  64         }
  65 
  66         {
  67             mv = cw.visitMethod(ACC_PROTECTED, "finalize", "()V", null, null);
  68             mv.visitCode();
  69             Label lab0 = new Label();
  70             mv.visitLabel(lab0);
  71             mv.visitLineNumber(8, lab0);
  72             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
  73             mv.visitLdcInsn("Finalizer called");
  74             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
  75             mv.visitInsn(RETURN);
  76             mv.visitMaxs(2, 1);
  77             mv.visitEnd();
  78         }
  79 
  80         cw.visitEnd();
  81         return cw.toByteArray();
  82     }
  83 
  84 
  85     public static void premain(String args, Instrumentation inst) throws Exception {
  86         agentmain(args, inst);
  87     }
  88 
  89     public static void agentmain(String args, Instrumentation inst) throws Exception {
  90         ClassDefinition martyrDef =
  91               new ClassDefinition(Class.forName("Martyr"), makeNewMartyr());
  92         inst.redefineClasses(martyrDef);
  93     }
  94 }