Skip to content

Instantly share code, notes, and snippets.

@Theldus
Last active May 7, 2020 22:59
Show Gist options
  • Save Theldus/489be20bd2d336683042303a9b4a0d32 to your computer and use it in GitHub Desktop.
Save Theldus/489be20bd2d336683042303a9b4a0d32 to your computer and use it in GitHub Desktop.
Makes javap more objdump-like =), enjoy
# Victorique de Blois byte patch v3.0 =), by Theldus
#
# This patch edits the javap source code so that when using the '-c' option, in
# addition to the instruction, the bytes related to it are also emmited, something
# similar to what objdump does. An example of output follows below:
#
# Compiled from "hello.java" (Victorique de Blois, byte dump patch v3.0 by Theldus)
# public class hello {
# public hello();
# Code:
# Offset: PC: Opcode: Bytecode:
# (00335) 0: aload_0 < 2a >
# (00336) 1: invokespecial < b7 00 01 > #1 // Method java/la.. <cut>
# (00339) 4: return < b1 >
#
# public static void main(java.lang.String[]);
# Code:
# Offset: PC: Opcode: Bytecode:
# (00378) 0: getstatic < b2 00 02 > #2 // Field java/lan.. <cut>
# (00381) 3: ldc < 12 03 > #3 // String Hello, W.. <cut>
# (00383) 5: invokevirtual < b6 00 04 > #4 // Method java.. <cut>
# (00386) 8: return < b1 >
# }
#
# OpenJDK tested: openjdk-12-ga.tar.gz
# Link: https://github.com/openjdk/jdk/archive/jdk-12-ga.tar.gz
#
# Build instructions:
#
# Apply this patch:
# cd your-download-path/jdk-jdk-12-ga
# patch -p1 < path-to-your-patch/bytecode.patch
#
# Configure:
# JAVA_HOME=/your/java/path bash configure --disable-warnings-as-errors \
# --with-num-cores=4
#
# Build:
# JAVA_HOME=/your/java/path make images JOBS=4
#
# Binaries will reside in your-download-path/jdk-jdk-12-ga/build/linux*/jdk/bin
#
# ---- Observations: ----
# - It is necessary that the user already have a working OpenJDK installation
# in the system. This will serve as a bootstrap JDK. (at least openjdk-11
# if you're building openjdk-12).
#
# - If used in VM, take note that the build process is very memory hungry.
# (I've successfully build with 4G+)
#
# - The first build takes about 11 min on i7 2600
#
diff -ruN old/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassFile.java jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassFile.java
--- old/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassFile.java 2019-02-19 13:25:11.000000000 -0300
+++ jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/classfile/ClassFile.java 2020-05-07 04:01:45.314908157 -0300
@@ -94,10 +94,57 @@
for (int i = 0; i < fields_count; i++)
fields[i] = new Field(cr);
+ /*
+ * Offset for the first method, adapted from byteLength() xD
+ *
+ * Magic numbers found here:
+ * https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html
+ */
+ int offsetMethod = 4 + // magic
+ 2 + // minor
+ 2 + // major
+ constant_pool.byteLength() +
+ 2 + // access flags
+ 2 + // this_class
+ 2 + // super_class
+ byteLength(interfaces) +
+ byteLength(fields) +
+ 2; // method_count
+
int methods_count = cr.readUnsignedShort();
methods = new Method[methods_count];
- for (int i = 0; i < methods_count; i++)
+ for (int i = 0; i < methods_count; i++) {
methods[i] = new Method(cr);
+
+ offsetMethod += 8; // skip access_flags, name_index, descriptor
+ // index and attributes_count
+ /*
+ * Go through attributes and find the offset
+ * to the very first instruction.
+ */
+ for (Attribute attr : methods[i].attributes) {
+ if (!(attr instanceof Code_attribute)) {
+ offsetMethod += attr.byteLength();
+ } else {
+ Code_attribute code = (Code_attribute) attr;
+
+ /*
+ * Found, let us save our new offset in the method.
+ * Nonetheless, we still need to proceed in order to keep
+ * counting bytes to adjust the analysis for the next
+ * method.
+ *
+ * We are also have guarantee that we have only one
+ * Code_attribute, so this block will not be executed
+ * again until another method.
+ *
+ * 14 = number of bytes until code[]
+ */
+ code.code_offset = offsetMethod + 14;
+ offsetMethod += attr.byteLength();
+ }
+ }
+ }
attributes = new Attributes(cr);
}
diff -ruN old/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Code_attribute.java jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Code_attribute.java
--- old/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Code_attribute.java 2019-02-19 13:25:11.000000000 -0300
+++ jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Code_attribute.java 2020-05-06 23:10:17.524121552 -0300
@@ -130,6 +130,7 @@
};
}
+ public int code_offset;
public final int max_stack;
public final int max_locals;
public final int code_length;
diff -ruN old/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java
--- old/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java 2020-05-07 13:47:06.536362634 -0300
+++ jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java 2020-05-07 00:16:01.014658668 -0300
@@ -152,7 +152,7 @@
Attribute sfa = cf.getAttribute(Attribute.SourceFile);
if (sfa instanceof SourceFile_attribute) {
- println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\"");
+ println("Compiled from \"" + getSourceFile((SourceFile_attribute) sfa) + "\" (Victorique de Blois, byte dump patch v3.0 by Theldus)");
}
if (options.sysInfo || options.verbose) {
@@ -571,6 +571,7 @@
} else if (code != null) {
if (options.showDisassembled) {
println("Code:");
+ println("Offset: PC: Opcode: Bytecode:");
codeWriter.writeInstrs(code);
codeWriter.writeExceptionTable(code);
}
diff -ruN old/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java
--- old/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java 2020-05-07 13:47:06.556362116 -0300
+++ jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java 2020-05-06 23:19:06.453123853 -0300
@@ -105,7 +105,7 @@
try {
for (InstructionDetailWriter w: detailWriters)
w.writeDetails(instr);
- writeInstr(instr);
+ writeInstr(instr, attr);
} catch (ArrayIndexOutOfBoundsException e) {
println(report("error at or after byte " + instr.getPC()));
break;
@@ -116,8 +116,19 @@
w.flush();
}
- public void writeInstr(Instruction instr) {
- print(String.format("%4d: %-13s ", instr.getPC(), instr.getMnemonic()));
+ public void writeInstr(Instruction instr, Code_attribute attr) {
+ print(String.format("(%05d) %4d: %-13s ",
+ instr.getPC() + attr.code_offset, instr.getPC(), instr.getMnemonic()));
+ print("< ");
+ for (int i = 0; i < instr.length(); i++)
+ print(String.format("%02x ", (byte)instr.getByte(i)));
+ print("> ");
+
+ int amountSpaces = (2 + (instr.length()+1) + (instr.length()*2));
+ amountSpaces = 25 - amountSpaces;
+ for (int i = 0; i < amountSpaces; i++)
+ print(" ");
+
// compute the number of indentations for the body of multi-line instructions
// This is 6 (the width of "%4d: "), divided by the width of each indentation level,
// and rounded up to the next integer.
diff -ruN old/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap.properties jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap.properties
--- old/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap.properties 2020-05-07 13:47:06.556362116 -0300
+++ jdk-jdk-12-ga/src/jdk.jdeps/share/classes/com/sun/tools/javap/resources/javap.properties 2020-05-07 00:15:10.056214944 -0300
@@ -23,7 +23,7 @@
err.cant.find.module.ex=Problem finding module {0}: {1}
main.usage.summary=\
-Usage: {0} <options> <classes>\n\
+Usage: {0} <options> <classes> (Victorique de Blois ver)\n\
use --help for a list of possible options
warn.prefix=Warning:
@@ -32,16 +32,16 @@
note.prefix=Note:
main.usage.summary=\
-Usage: {0} <options> <classes>\n\
+Usage: {0} <options> <classes> (Victorique de Blois ver)\n\
use --help for a list of possible options
main.usage=\
-Usage: {0} <options> <classes>\n\
+Usage: {0} <options> <classes> (Victorique de Blois v3.0)\n\
where possible options include:
main.opt.help=\
-\ -? -h --help -help Print this help message
+\ -? -h --help -help Print this
main.opt.version=\
\ -version Version information
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment