define instructions
This commit is contained in:
parent
6600d02c48
commit
01bff40719
192
Jocaml.java
192
Jocaml.java
|
@ -1,18 +1,177 @@
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.Channels;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Jocaml {
|
||||
private static String TRAILER_MAGIC = "Caml1999X028";
|
||||
private static long MARSHAL_MAGIC_SMALL = 0x8495A6BE;
|
||||
private static long MARSHAL_MAGIC_BIG = 0x8495A6BF;
|
||||
|
||||
private static enum CamlInst {
|
||||
ACC0(0, 0),
|
||||
ACC1(1, 0),
|
||||
ACC2(2, 0),
|
||||
ACC3(3, 0),
|
||||
ACC4(4, 0),
|
||||
ACC5(5, 0),
|
||||
ACC6(6, 0),
|
||||
ACC7(7, 0),
|
||||
ACC(8, 1),
|
||||
PUSH(9, 0),
|
||||
PUSHACC0(10, 0),
|
||||
PUSHACC1(11, 0),
|
||||
PUSHACC2(12, 0),
|
||||
PUSHACC3(13, 0),
|
||||
PUSHACC4(14, 0),
|
||||
PUSHACC5(15, 0),
|
||||
PUSHACC6(16, 0),
|
||||
PUSHACC7(17, 0),
|
||||
PUSHACC(18, 1),
|
||||
POP(19, 1),
|
||||
ASSIGN(20, 1),
|
||||
ENVACC1(21, 0),
|
||||
ENVACC2(22, 0),
|
||||
ENVACC3(23, 0),
|
||||
ENVACC4(24, 0),
|
||||
ENVACC(25, 1),
|
||||
PUSHENVACC1(26, 0),
|
||||
PUSHENVACC2(27, 0),
|
||||
PUSHENVACC3(28, 0),
|
||||
PUSHENVACC4(29, 0),
|
||||
PUSHENVACC(30, 1),
|
||||
PUSH_RETADDR(31, 1),
|
||||
APPLY(32, 1),
|
||||
APPLY1(33, 0),
|
||||
APPLY2(34, 0),
|
||||
APPLY3(35, 0),
|
||||
APPTERM(36, 2),
|
||||
APPTERM1(37, 1),
|
||||
APPTERM2(38, 1),
|
||||
APPTERM3(39, 1),
|
||||
RETURN(40, 1),
|
||||
RESTART(41, 0),
|
||||
GRAB(42, 1),
|
||||
CLOSURE(43, 2),
|
||||
CLOSUREREC(44, 4),
|
||||
OFFSETCLOSUREM2(45, 0),
|
||||
OFFSETCLOSURE0(46, 0),
|
||||
OFFSETCLOSURE2(47, 0),
|
||||
OFFSETCLOSURE(48, 1),
|
||||
PUSHOFFSETCLOSUREM2(49, 0),
|
||||
PUSHOFFSETCLOSURE0(50, 0),
|
||||
PUSHOFFSETCLOSURE2(51, 0),
|
||||
PUSHOFFSETCLOSURE(52, 1),
|
||||
GETGLOBAL(53, 1),
|
||||
PUSHGETGLOBAL(54, 1),
|
||||
GETGLOBALFIELD(55, 2),
|
||||
PUSHGETGLOBALFIELD(56, 2),
|
||||
SETGLOBAL(57, 1),
|
||||
ATOM0(58, 0),
|
||||
ATOM(59, 1),
|
||||
PUSHATOM0(60, 0),
|
||||
PUSHATOM(61, 1),
|
||||
MAKEBLOCK(62, 2),
|
||||
MAKEBLOCK1(63, 1),
|
||||
MAKEBLOCK2(64, 1),
|
||||
MAKEBLOCK3(65, 1),
|
||||
MAKEFLOATBLOCK(66, 1),
|
||||
GETFIELD0(67, 0),
|
||||
GETFIELD1(68, 0),
|
||||
GETFIELD2(69, 0),
|
||||
GETFIELD3(70, 0),
|
||||
GETFIELD(71, 1),
|
||||
GETFLOATFIELD(72, 1),
|
||||
SETFIELD0(73, 0),
|
||||
SETFIELD1(74, 0),
|
||||
SETFIELD2(75, 0),
|
||||
SETFIELD3(76, 0),
|
||||
SETFIELD(77, 1),
|
||||
SETFLOATFIELD(78, 1),
|
||||
VECTLENGTH(79, 0),
|
||||
GETVECTITEM(80, 0),
|
||||
SETVECTITEM(81, 0),
|
||||
GETBYTESCHAR(82, 0),
|
||||
SETBYTESCHAR(83, 0),
|
||||
BRANCH(84, 1),
|
||||
BRANCHIF(85, 1),
|
||||
BRANCHIFNOT(86, 1),
|
||||
SWITCH(87, 2),
|
||||
BOOTNOT(88, 0),
|
||||
PUSHTRAP(89, 1),
|
||||
POPTRAP(90, 0),
|
||||
RAISE(91, 0),
|
||||
CHECK_SIGNALS(92, 0),
|
||||
C_CALL1(93, 1),
|
||||
C_CALL2(94, 1),
|
||||
C_CALL3(95, 1),
|
||||
C_CALL4(96, 1),
|
||||
C_CALL5(97, 1),
|
||||
C_CALLN(98, 2),
|
||||
CONST0(99, 0),
|
||||
CONST1(100, 0),
|
||||
CONST2(101, 0),
|
||||
CONST3(102, 0),
|
||||
CONSTINT(103, 1),
|
||||
PUSHCONST0(104, 0),
|
||||
PUSHCONST1(105, 0),
|
||||
PUSHCONST2(106, 0),
|
||||
PUSHCONST3(107, 0),
|
||||
PUSHCONSTINT(108, 1),
|
||||
NEGINT(109, 0),
|
||||
ADDINT(110, 0),
|
||||
SUBINT(111, 0),
|
||||
MULINT(112, 0),
|
||||
DIVINT(113, 0),
|
||||
MODINT(114, 0),
|
||||
ANDINT(115, 0),
|
||||
ORINT(116, 0),
|
||||
XORINT(117, 0),
|
||||
LSLINT(118, 0),
|
||||
LSRINT(119, 0),
|
||||
ASRINT(120, 0),
|
||||
EQ(121, 0),
|
||||
NEQ(122, 0),
|
||||
LTINT(123, 0),
|
||||
LEINT(124, 0),
|
||||
GTINT(125, 0),
|
||||
GEINT(126, 0),
|
||||
OFFSETINT(127, 1),
|
||||
OFFSETREF(128, 1),
|
||||
ISINT(129, 0),
|
||||
GETMETHOD(130, 0),
|
||||
BEQ(131, 2),
|
||||
BNEQ(132, 2),
|
||||
BLTINT(133, 2),
|
||||
BLEINT(134, 2),
|
||||
BGTINT(135, 2),
|
||||
BGEINT(136, 2),
|
||||
ULTINT(137, 0),
|
||||
UGEINT(138, 0),
|
||||
BULTINT(139, 2),
|
||||
BUGEINT(140, 2),
|
||||
GETPUBMET(141, 2),
|
||||
GETDYNMET(142, 0),
|
||||
STOP(143, 0),
|
||||
EVENT(144, 0),
|
||||
BREAK(145, 0),
|
||||
|
||||
RERAISE(146, 0), // ???
|
||||
RAISE_NOTRACE(147, 0),
|
||||
GETSTRINGCHAR(148, 0);
|
||||
|
||||
public final int code;
|
||||
public final int numArgs;
|
||||
CamlInst(int code, int numArgs) {
|
||||
this.code = code;
|
||||
this.numArgs = numArgs;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CodeOffset {
|
||||
public final int offset;
|
||||
|
||||
|
@ -98,15 +257,15 @@ public class Jocaml {
|
|||
// shared elements
|
||||
case 0x04: {
|
||||
long offset = this.data.get() & (long) 0xff;
|
||||
return shared.get((int) offset);
|
||||
return shared.get(shared.size() - 1 - (int) offset);
|
||||
}
|
||||
case 0x05: {
|
||||
long offset = this.data.getShort() & (long) 0xff;
|
||||
return shared.get((int) offset);
|
||||
return shared.get(shared.size() - 1 - (int) offset);
|
||||
}
|
||||
case 0x06: {
|
||||
long offset = this.data.getInt() & (long) 0xff;
|
||||
return shared.get((int) offset);
|
||||
return shared.get(shared.size() - 1 - (int) offset);
|
||||
}
|
||||
|
||||
// blocks
|
||||
|
@ -223,6 +382,7 @@ public class Jocaml {
|
|||
}
|
||||
|
||||
public void unmarshal() throws Exception {
|
||||
this.data.order(ByteOrder.BIG_ENDIAN);
|
||||
int magic = this.data.getInt(0);
|
||||
if (magic != MARSHAL_MAGIC_SMALL) {
|
||||
throw new Exception("bad marshal magic");
|
||||
|
@ -246,6 +406,27 @@ public class Jocaml {
|
|||
|
||||
System.out.println(objs);
|
||||
}
|
||||
|
||||
public void disassemble() throws Exception {
|
||||
this.data.order(ByteOrder.LITTLE_ENDIAN);
|
||||
this.data.position(0);
|
||||
while (this.data.position() < this.data.capacity()) {
|
||||
int op = this.data.getInt();
|
||||
String rep = null;
|
||||
for (CamlInst inst : CamlInst.values()) {
|
||||
if (inst.code == op) {
|
||||
rep = inst.name();
|
||||
for (int i = 0; i < inst.numArgs; i++) {
|
||||
rep += " " + this.data.getInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rep == null) {
|
||||
rep = "<UNKNOWN " + op + ">";
|
||||
}
|
||||
System.out.println(rep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Section findSection(Section[] sections, String name) {
|
||||
|
@ -295,5 +476,6 @@ public class Jocaml {
|
|||
findSection(sections, "SYMB").unmarshal();
|
||||
findSection(sections, "CRCS").unmarshal();
|
||||
findSection(sections, "DATA").unmarshal();
|
||||
findSection(sections, "CODE").disassemble();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue