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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.asm; 26 27 public abstract class Disassembler { 28 protected long startPc; 29 protected byte[] code; 30 31 public Disassembler(long startPc, byte[] code) { 32 this.startPc = startPc; 33 this.code = code; 34 } 35 36 public long getStartPC() { 37 return startPc; 38 } 39 40 public byte[] getCode() { 41 return code; 42 } 43 44 public abstract void decode(InstructionVisitor visitor); 45 } | 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.asm; 26 27 import java.io.PrintStream; 28 import java.util.Observer; 29 import java.util.Observable; 30 import sun.jvm.hotspot.code.CodeBlob; 31 import sun.jvm.hotspot.code.NMethod; 32 import sun.jvm.hotspot.debugger.Address; 33 import sun.jvm.hotspot.runtime.VM; 34 35 public class Disassembler { 36 static final int COMMENT_COLUMN = 40; 37 static final String BYTES_COMMENT = ";..."; /* funky byte display comment */ 38 39 private static String libname; 40 private static String options; 41 private static long decode_function; 42 43 static { 44 VM.registerVMInitializedObserver(new Observer() { 45 public void update(Observable o, Object data) { 46 options = ""; 47 libname = null; 48 String cpu = VM.getVM().getCPU(); 49 if (cpu.equals("sparc")) { 50 libname = "hsdis-sparc"; 51 if (VM.getVM().isLP64()) { 52 options = "v9only"; 53 } 54 } else if (cpu.equals("x86")) { 55 libname = "hsdis-i386"; 56 } else if (cpu.equals("amd64")) { 57 libname = "hsdis-amd64"; 58 } else if (cpu.equals("ia64")) { 59 libname = "hsdis-ia64"; 60 } 61 } 62 }); 63 } 64 65 protected long startPc; 66 protected byte[] code; 67 private CodeBlob blob; 68 private NMethod nmethod; 69 70 public static void decode(InstructionVisitor visitor, CodeBlob blob) { 71 decode(visitor, blob, blob.instructionsBegin(), blob.instructionsEnd()); 72 } 73 74 public static void decode(InstructionVisitor visitor, CodeBlob blob, Address begin, Address end) { 75 int codeSize = (int)end.minus(begin); 76 long startPc = VM.getAddressValue(begin); 77 byte[] code = new byte[codeSize]; 78 for (int i = 0; i < code.length; i++) 79 code[i] = begin.getJByteAt(i); 80 Disassembler dis = new Disassembler(startPc, code); 81 dis.decode(visitor); 82 } 83 84 private Disassembler(long startPc, byte[] code) { 85 this.startPc = startPc; 86 this.code = code; 87 88 // Lazily load hsdis 89 if (decode_function == 0) { 90 decode_function = load_library(libname); 91 } 92 } 93 94 private static native long load_library(String hsdis_library_name); 95 96 private native void decode(InstructionVisitor visitor, long pc, byte[] code, 97 String options, long decode_function); 98 99 private void decode(InstructionVisitor visitor) { 100 visitor.prologue(); 101 decode(visitor, startPc, code, options, decode_function); 102 visitor.epilogue(); 103 } 104 105 private boolean match(String event, String tag) { 106 if (!event.startsWith(tag)) 107 return false; 108 int taglen = tag.length(); 109 if (taglen == event.length()) return true; 110 char delim = event.charAt(taglen); 111 return delim == ' ' || delim == '/' || delim == '='; 112 } 113 114 // This is called from the native code to process various markers 115 // in the dissassembly. 116 private long handleEvent(InstructionVisitor visitor, String event, long arg) { 117 if (match(event, "insn")) { 118 try { 119 visitor.beginInstruction(arg); 120 } catch (Throwable e) { 121 e.printStackTrace(); 122 } 123 } else if (match(event, "/insn")) { 124 try { 125 visitor.endInstruction(arg); 126 } catch (Throwable e) { 127 e.printStackTrace(); 128 } 129 } else if (match(event, "addr")) { 130 if (arg != 0) { 131 visitor.printAddress(arg); 132 } 133 return arg; 134 } else if (match(event, "mach")) { 135 // output().printf("[Disassembling for mach='%s']\n", arg); 136 } else { 137 // ignore unrecognized markup 138 } 139 return 0; 140 } 141 142 // This called from the native code to perform printing 143 private void rawPrint(InstructionVisitor visitor, String s) { 144 visitor.print(s); 145 } 146 } |