Advertisement
Dimension

Export.java

Dec 10th, 2011
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 34.33 KB | None | 0 0
  1. package emulator.editor;
  2.  
  3. import java.util.*;
  4. import java.util.Map.Entry;
  5.  
  6. import com.sun.tools.javac.util.ByteBuffer;
  7.  
  8. import emulator.Hypervisor;
  9. import emulator.Hypervisor.Call;
  10. import emulator.code.*;
  11. import emulator.code.Code.Decl;
  12. import emulator.code.Operation.OperationType;
  13. import emulator.editor.ExportStructure.*;
  14. import emulator.editor.CodeOut.*;
  15. import emulator.editor.Context.*;
  16. import emulator.memory.*;
  17. import emulator.memory.Identifier.Stack;
  18. import emulator.memory.Memory.Access;
  19. import emulator.memory.Memory.Access.StructureAccess;
  20.  
  21. public class Export {
  22.     // java: emulate only
  23.     // x86: hypervised(default), native, or emulate
  24.     // preliminary: real mode, future: process/thread, paging, nx
  25.     // TODO: export: microkernel, java, c++ + os api
  26.     // limit tracing functionality
  27.  
  28.     // system code guidelines:
  29.     // compare memory-range behind target address before/after write
  30.     // memory up to fixedMemory is READ-ONLY
  31.     // check bounds on any access
  32.     //
  33.     // only memory manager and hypervisor in level 0
  34.     // disable call gate and interrupt gate
  35.     // disable system management mode (use remote heartbeat)
  36.     // constrain mem / io
  37.     // io only level 0
  38.    
  39.     // non-hypervised code:
  40.     // memory manager/gc
  41.     // hypervisor/process/thread
  42.     // security checks (buffer overflow, page per process, hw/io/usermode-driver)
  43.    
  44.     // bootstrap:
  45.     // 1. initialize protected mode, segments, tables
  46.     // initialize cpu, io, interrupt
  47.     //
  48.     // 2. load memory up to fixed memory from disk
  49.     // use only fixed memory
  50.     //
  51.     // 3. load initial heap from disk (root process & management stacks)
  52.     // start hypervisor
  53.    
  54.     // trace:
  55.     // hypervisor:
  56.     // restore for/for_list/for_loop with variables
  57.     // restore sequence with index (fixed size entries)
  58.     // insert bytecode / procedure: no restore
  59.    
  60.     // NO RESTORE OVER UNMANAGED CODE (only after / before)
  61.    
  62.     // 511 processes
  63.     //      (= 1024 pages / 2 code&data - 1 kernel)
  64.     //      (indefinite threads, are defined in process memory) // TODO indefinite processes, are defined in root process memory
  65.  
  66.     public static final LinkedHashMap<Operation.OperationType, ExportDef> intelExportDef = new LinkedHashMap<Operation.OperationType, ExportDef>();
  67.  
  68.     public static void initIntelExport() {
  69.  
  70.         intelExportDef.put(Operation.OperationType.Control.OP_ENVIRONMENT, new ExportDef(
  71.             // fixed
  72.             new FixedExportScript() {
  73.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  74.                     assert false;
  75.                 }
  76.             },
  77.            
  78.             //hypervised
  79.             new HypervisedExportScript[] {
  80.             new HypervisedExportScript() {
  81.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  82.                    
  83.                 }
  84.             }
  85.             }
  86.         ));
  87.  
  88.         intelExportDef.put(Operation.OperationType.Expression.OP_TRIGGER, new ExportDef(
  89.             // fixed
  90.             new FixedExportScript() {
  91.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  92.                     assert false;
  93.                 }
  94.             },
  95.            
  96.             //hypervised
  97.             new HypervisedExportScript[] {
  98.             new HypervisedExportScript() {
  99.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  100.                    
  101.                 }
  102.             }
  103.             }
  104.         ));
  105.  
  106.         intelExportDef.put(Operation.OperationType.Control.OP_SEQUENCE, new ExportDef(
  107.             // variable decl in unmanaged code only on top of procedure
  108.             // decide if managed only per procedure
  109.  
  110.             // fixed
  111.             new FixedExportScript() {
  112.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  113.                     Vector<Code> code1 = CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("code")))[0]);
  114.  
  115.                     // init
  116.                     //boolean block = code1.size() > 1;
  117.                     //boolean function = context.code.propertyList.containsKey(new Identifier.Property("function"));
  118.                     boolean decl = !context.code.declList.isEmpty();
  119.                     if(decl) {
  120.                         for(Entry<Identifier.Stack, Decl> decl1 : context.code.declList.entrySet()) {
  121.                             //
  122.                         }
  123.                     }
  124.                    
  125.                     Structure.List.Vector structure = (Structure.List.Vector) Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("code")))[0];
  126.                     for(Code code2 : code1) {
  127.                         fixedExportCode(new CodeContext.CodeContextNew(context, code2), intelExport, exportContext);
  128.                     }
  129.                 }
  130.             },
  131.            
  132.             //hypervised
  133.             new HypervisedExportScript[] {
  134.             new HypervisedExportScript() { // 0
  135.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  136.                     /*int size2 = call.declInitList.size();
  137.                    
  138.                     if(call.step2 >= size2) {
  139.                         call.step2 = 0;
  140.                         call.step = 2;
  141.                     }
  142.                     else {
  143.                         Code.Decl decl = call.declInitList.get(call.step2);
  144.                         assert decl.initType == Code.Decl.InitType.EXPRESSION;
  145.                        
  146.                         Code code2 = (Code) Memory.Process.resolveExecuteItem(context.process, decl.initExpression)[0];
  147.                         Hypervisor.pushExecuteExpression(context.threadStackContext, new Call(new CodeContext.CodeContextNew(context, code2), true));
  148.                     }*/
  149.  
  150.                     // fixed
  151.                     int addr_size2 = 0;
  152.                     int addr_decl = 0;
  153.                    
  154.                     // context
  155.                     int addr_call_step = 0;
  156.                     int addr_call_step2 = 0;
  157.                    
  158.                     // access, resolve in hypervisor (userspace access)
  159.                     int addr_code2 = 0;
  160.                    
  161.                     // offset
  162.                     BytecodeOffset[] off_if1_else1 = new BytecodeOffset[1];
  163.                     BytecodeOffset[] off_if1_end = new BytecodeOffset[1];
  164.  
  165.                     exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_size2));
  166.                     exportContext.procedure.addInstructionList(ExportOpcode.loadInteger(ExportOpcode.sel_ax));
  167.                     exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_call_step2));
  168.                     exportContext.procedure.addInstructionList(ExportOpcode.loadInteger(ExportOpcode.sel_cx));
  169.                     exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeOperator(ExportOpcode.IntelOpcodeOperator.OP_LGC_GTE_S)); // call.step2 >= size2
  170.  
  171.                     exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_if1_else1));
  172.                     exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP_IF_FALSE)); // if(call.step2 >= size2) {
  173.  
  174.                     {
  175.                         exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_call_step2));
  176.                         exportContext.procedure.addInstructionList(ExportOpcode.storeIntegerConstant(0)); // call.step2 = 0;
  177.                        
  178.                         exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_call_step));
  179.                         exportContext.procedure.addInstructionList(ExportOpcode.storeIntegerConstant(2)); // call.step = 2;
  180.                     }
  181.                    
  182.                     exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_if1_end));
  183.                     exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP)); // else {
  184.                     off_if1_else1[0] = getOffset(intelExport, exportContext); // else {
  185.                    
  186.                     {
  187.                        
  188.                     }
  189.  
  190.                     off_if1_end[0] = getOffset(intelExport, exportContext); // }
  191.                 }
  192.             },
  193.             new HypervisedExportScript() { // 1
  194.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  195.                     /*int size2 = call.declInitList.size();
  196.                    
  197.                     assert call.step2 < size2;
  198.                    
  199.                     {
  200.                         Code.Decl decl = call.declInitList.get(call.step2);
  201.                         assert decl.initType == Code.Decl.InitType.EXPRESSION;
  202.                        
  203.                         Object[] access2 = Memory.Process.resolveItem(context.process, decl.access);
  204.                        
  205.                         access2[0] = Hypervisor.popEvaluate(context.threadStackContext);
  206.                     }
  207.                    
  208.                     call.step2++;
  209.                     call.step = 0;*/
  210.                 }
  211.             },
  212.             new HypervisedExportScript() { // 2
  213.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  214.                     /*int size2 = ((Structure.List.Vector) Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("code")))[0]).size();
  215.                    
  216.                     if(call.step2 >= size2) {
  217.                         call.step = -1;
  218.                     }
  219.                     else {
  220.                         Code code2 = (Code) Memory.Process.resolveExecuteItem(context.process, new Access.MultipleAccess(context.code.codeList.get(new Identifier.Property("code")), new StructureAccess(new Identifier.Property("index", call.step2))))[0];
  221.                         Hypervisor.pushExecute(context.threadStackContext, new Call(new CodeContext.CodeContextNew(context, code2), false));
  222.                        
  223.                         call.step2++;
  224.                         call.step = 2;
  225.                     }*/
  226.                 }
  227.             }
  228.             }
  229.         ));
  230.  
  231.         intelExportDef.put(Operation.OperationType.Control.OP_FOR_STEP, new ExportDef(
  232.             // fixed
  233.             new FixedExportScript() {
  234.                 public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
  235.                     // fixed
  236.                     //int addr_condition = 0; // inline
  237.                     int addr_step = 0;
  238.                     //resolveFixedVariableAddress(access, intelExport);
  239.                    
  240.                     // context
  241.                    
  242.                     // offset
  243.                     BytecodeOffset[] off_loop1_start = new BytecodeOffset[1];
  244.                     BytecodeOffset[] off_loop1_end = new BytecodeOffset[1];
  245.  
  246.                     // init
  247.                     boolean decl = !context.code.declList.isEmpty();
  248.                     if(decl) {
  249.                         for(Entry<Identifier.Stack, Decl> decl1 : context.code.declList.entrySet()) {
  250.                             //
  251.                         }
  252.                     }
  253.  
  254.                     off_loop1_start[0] = getOffset(intelExport, exportContext);
  255.                     { // execute cond
  256.                         Code code1 = (Code) Memory.Process.resolveExecuteItem(context.process, context.code.dataList.get(new Identifier.Property("cond")))[0];
  257.                         fixedExportCode(new CodeContext.CodeContextNew(context, (Code) code1), intelExport, exportContext);
  258.                     }
  259.                     //exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_valueStack_0));
  260.                     exportContext.procedure.addInstructionList(ExportOpcode.loadInteger(ExportOpcode.sel_ax));
  261.                     exportContext.procedure.addInstructionList(ExportOpcode.castIntegerBoolean(ExportOpcode.sel_ax));
  262.                    
  263.                     exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_loop1_end));
  264.                     exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP_IF_FALSE)); //
  265.  
  266.                     {
  267.                        
  268.                     }
  269.                    
  270.                     { // execute step
  271.                         Code code1 = (Code) Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("step")))[0];
  272.                         fixedExportCode(new CodeContext.CodeContextNew(context, (Code) code1), intelExport, exportContext);
  273.                     }
  274.                    
  275.                     exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_loop1_start));
  276.                     exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP)); // }
  277.                     off_loop1_end[0] = getOffset(intelExport, exportContext);
  278.                 }
  279.             },
  280.            
  281.             //hypervised
  282.             new HypervisedExportScript[] {
  283.             }
  284.         ));
  285.     }
  286.  
  287.     public static class ExportDef {
  288.         public FixedExportScript fixedExportScript;
  289.         public HypervisedExportScript[] hypervisedExportScript;
  290.  
  291.         public ExportDef(FixedExportScript fixedExportScript, HypervisedExportScript[] hypervisedExportScript) {
  292.             this.fixedExportScript = fixedExportScript;
  293.             this.hypervisedExportScript = hypervisedExportScript;
  294.         };
  295.     }
  296.  
  297.     public static abstract class FixedExportScript {
  298.         public abstract void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext);
  299.     }
  300.  
  301.     public static abstract class HypervisedExportScript {
  302.         public abstract void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext);
  303.     }
  304.    
  305.     // Layout ===================0
  306.  
  307.     public static final int userspacePageCount1 = 0x3FA; // of size: 4mb (0x00400000)
  308.     public static final int userspacePageCount2 = 0x000FE800; // of size: 4kb (0x1000)
  309.     // 4gb =
  310.     //       4mb(0x00400000)  // low memory, hypervisor, management
  311.     //     + 20mb(0x01400000) // mapped io
  312.     //     + (0xFE800000)     // userspace memory, smallest memory allocation to process: 4kb (0x1000)
  313.     // 0xFE800000 = 4mb(0x00400000) * 0x3FA
  314.     // 0xFE800000 = 4kb(0x1000) * 0x000FE800
  315.  
  316.     // TODO
  317.     public static int interruptProxyPageCount = 0;
  318.     public static int fixedCodePageCount = 0;
  319.     public static int hypervisedCodePageCount = 0;
  320.     public static int fixedMemoryPageCount = 0;
  321.    
  322.     public static class IntelInstruction {
  323.         public int byteOffset = -1;
  324.         public byte[] bytecode; // add only if != null
  325.         public boolean locate = false; // locate bytes 1 .. 4
  326.         public boolean locateLocal = true;
  327.         public BytecodeOffset[] offset; // address relative to procedure start
  328.     }
  329.    
  330.     public static class BytecodeOffset {
  331.         //public int startAddress = -1;
  332.         //public Vector<IntelProcedure> procedureList;
  333.        
  334.         public int procedureIndex = -1;
  335.         public int instructionIndex = -1;
  336.     }
  337.    
  338.     public static class IntelProcedure {
  339.         public int byteAddress = -1;
  340.         public int byteLength = -1;
  341.  
  342.         public final Vector<IntelInstruction> instructionList = new Vector<IntelInstruction>();
  343.        
  344.         public void addInstructionList(IntelInstruction[] instructionList1) {
  345.             for(IntelInstruction instruction : instructionList1) {
  346.                 if(instruction != null && instruction.bytecode != null)
  347.                     instructionList.add(instruction);
  348.             }
  349.         }
  350.     }
  351.    
  352.     public static class LookupTable {
  353.         public int itemSize = -1;
  354.         public int itemCount = -1;
  355.         public int tableSize = -1;
  356.         public byte[][] itemList;
  357.     }
  358.    
  359.     public static class MemoryImage {
  360.         public int start = -1;
  361.         public int size = -1;
  362.         public int end = -1;
  363.         public byte[] image;
  364.        
  365.         public MemoryImage(int start, int size) {
  366.             this.start = start;
  367.             this.size = size;
  368.         }
  369.     }
  370.    
  371.     public static class IntelExport {
  372.  
  373.         public static class FixedMemoryLayout {// address, size
  374.             // boot state (execute once)
  375.             // return stack index
  376.             // evaluate stack index
  377.             // fild tmp int32 constant
  378.             // fld tmp float80 constant TODO
  379.             // 8 return addresses (call stack)
  380.             // 8 evaluate stack
  381.             // 8 resolve temp
  382.             // 64 variables, parameters
  383.         }
  384.         public final FixedMemoryLayout fixedMemoryLayout = new FixedMemoryLayout();
  385.        
  386.         // fixed procedures: (import java, list variables, no recursion)
  387.         // schedule
  388.         // find free mem slot
  389.         // find free page
  390.         // ...
  391.        
  392.         public static class MemoryLayout {// address, size
  393.             // 0 .. 0x00100000 read only, no execute
  394.             public final MemoryImage interruptVectorTable =             new MemoryImage(0, 0x400);
  395.             public final MemoryImage bios1 =                            new MemoryImage(0x400, 0x100);
  396.            
  397.             public final MemoryImage bootstrapCode2 =                   new MemoryImage(0x500, -1);
  398.             public final MemoryImage bootstrapCode1 =                   new MemoryImage(0x7C00, 0x200); // TODO mbr 0x6000 ?
  399.  
  400.             public final MemoryImage biosX =                            new MemoryImage(0x00080000, 0x00020000); // TODO ebda 0x0009FC00 ?
  401.             public final MemoryImage vga =                              new MemoryImage(0x000A0000, 0x00020000);
  402.             public final MemoryImage bios2 =                            new MemoryImage(0x000C0000, 0x00040000);
  403.  
  404.             // 0x00100000 ..  execute, code before data
  405.             // code, read only
  406.             public final MemoryImage bootstrapCode3 =                   new MemoryImage(0x00100000, -1);// read-only, abort on second time execution
  407.  
  408.             public final MemoryImage interruptProxyList =               new MemoryImage(-1, 0x1000 * interruptProxyPageCount);
  409.             public final MemoryImage fixedCodeList =                    new MemoryImage(-1, 0x1000 * fixedCodePageCount);// non-hypervised procedures
  410.            
  411.             // code cache
  412.             public final MemoryImage hypervisedCodeList =               new MemoryImage(-1, 0x1000 * hypervisedCodePageCount);// hypervised procedures
  413.  
  414.             // data
  415.             public final MemoryImage interruptDescriptorTableRegister = new MemoryImage(-1, 6);
  416.             public final MemoryImage globalDescriptorTableRegister =    new MemoryImage(-1, 6);
  417.            
  418.             public final MemoryImage interruptDescriptorTable =         new MemoryImage(-1, 0x100 * 8);
  419.             public final MemoryImage globalDescriptorTable =            new MemoryImage(-1, (userspacePageCount2 + 3) * 8);// hypervisor level 0, separate remaining ram for code / data
  420.             public final MemoryImage pageDirectory =                    new MemoryImage(-1, 0x400 * 4);
  421.             public final MemoryImage pageTable =                        new MemoryImage(-1, 0x400 * 0x400 * 4);
  422.             public final MemoryImage taskStateSegmentTable =                new MemoryImage(-1, -1); // taskCount = coreCount + 1(hypervisor/memoryManagement)
  423.  
  424.             public final MemoryImage fixedMemory =                      new MemoryImage(-1, 0x1000 * fixedMemoryPageCount);
  425.             public final MemoryImage processTable =                     new MemoryImage(-1, 0x1000);// pointers to process root page + management info
  426.             public final MemoryImage pageAllocTable =                   new MemoryImage(-1, 0x1000);// allocated/free
  427.  
  428.             public final MemoryImage processPermissionTable =           new MemoryImage(-1, 0x1000);
  429.             public final MemoryImage processAllocTable =                new MemoryImage(-1, 0x1000);// storage class -> page
  430.             public final MemoryImage pageLoadTable =                    new MemoryImage(-1, 0x1000);// page -> slot
  431.             //public final MemoryImage linkTable =                      new MemoryImage(-1, 0x1000);// page + slot -> link (list)
  432.  
  433.             public final MemoryImage hashtableList =                    new MemoryImage(-1, -1);
  434.             public final MemoryImage hashtableStringPointerList =       new MemoryImage(-1, -1);
  435.             public final MemoryImage hashtableStringList =              new MemoryImage(-1, -1);
  436.  
  437.             public final MemoryImage referenceounterTable =             new MemoryImage(-1, -1); // variable size, tabled bignum
  438.  
  439.             // 0x001FF000 .. 0x00400000 no execute, protect: page fault, segmentation fault
  440.             public final MemoryImage mandatoryStack =                   new MemoryImage(0x001FF000, 0x1000);
  441.  
  442.             // 0x00400000 .. 0xFEC00000 partly execute
  443.             public final MemoryImage userspace =                        new MemoryImage(0x00400000, 0xFE800000);// code and data-stacks from hypervised code, paged
  444.  
  445.             // 0xFEC00000 .. 0xFFFFFFFF no execute
  446.             public final MemoryImage mappedIo =                         new MemoryImage(0xFEC00000, 0x1400000); // TODO ?
  447.         }
  448.         public final MemoryLayout memoryLayout = new MemoryLayout();
  449.         public byte[] mbr;//bootstrapCode1 (load hdd from 0xFF upwards) + partition table
  450.         public byte[] kernelImage;
  451.        
  452.         public final LookupTable interruptVectorTable = new LookupTable();
  453.         public final LookupTable globalDescriptorTable = new LookupTable();
  454.  
  455.         public final Vector<IntelProcedure> fixedProcedureList = new Vector<IntelProcedure>();
  456.         public final HashMap<Identifier.Stack, Integer> fixedVariableList = new HashMap<Identifier.Stack, Integer>();
  457.  
  458.         public final Vector<IntelProcedure> hypervisedProcedureList = new Vector<IntelProcedure>(); // code cache
  459.     }
  460.    
  461.     public static class IntelExportContext {
  462.         public boolean managed = true; // TODO: later: reduce tracing, increase performance
  463.         public int procedureIndex = -1;
  464.         public IntelProcedure procedure;
  465.     }
  466.    
  467.     //====
  468.    
  469.     public static void initInterruptDescriptorTable(LookupTable lookupTable) {
  470.         lookupTable.itemSize = 8;
  471.         lookupTable.itemCount = 0x100;// 256 interrupts
  472.         lookupTable.tableSize = lookupTable.itemSize * lookupTable.itemCount;
  473.         lookupTable.itemList = new byte[lookupTable.itemCount][];
  474.  
  475.         Vector<IntelProcedure> proxyList = new Vector<IntelProcedure>();
  476.         for(int i = 0; i < lookupTable.itemCount; i++) {
  477.             IntelProcedure procedure = new IntelProcedure();
  478.             proxyList.add(procedure);
  479.  
  480.             procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_IRET));
  481.             procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_INVALID_EXECUTE_LOCATION));
  482.         }
  483.        
  484.         for(int i = 0; i < lookupTable.itemCount; i++) {
  485.             InterruptDescriptor structure = new InterruptDescriptor();
  486.             InterruptDescriptor.TypeAttr typeAttr = new InterruptDescriptor.TypeAttr();
  487.             typeAttr.type = InterruptDescriptor.Type.INTERRUPT_GATE;
  488.             typeAttr.storageSegment = false;
  489.             typeAttr.privilege = 0;
  490.             typeAttr.present = true;
  491.  
  492.             structure.write(InterruptDescriptor.Field.SEGMENT, 0);
  493.             structure.write(InterruptDescriptor.Field.OFFSET, 0);
  494.             structure.write(InterruptDescriptor.Field.TYPE_ATTR, typeAttr);
  495.            
  496.             assert structure.structure.length == lookupTable.itemSize;
  497.             lookupTable.itemList[i] = structure.structure;
  498.         }
  499.     }
  500.    
  501.     public static void initGlobalDescriptorTable(LookupTable lookupTable) {
  502.         lookupTable.itemSize = 8;
  503.         lookupTable.itemCount = userspacePageCount2 + 3;
  504.         lookupTable.tableSize = lookupTable.itemSize * lookupTable.itemCount;
  505.         lookupTable.itemList = new byte[lookupTable.itemCount][];
  506.  
  507.         // 0 .. 0x00100000 read only
  508.         {
  509.             GlobalDescriptor structure = new GlobalDescriptor();
  510.             GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
  511.             accessByte.accessed = false;
  512.             accessByte.readable_writable = false;
  513.             accessByte.direction_conforming = false;
  514.             accessByte.executable = false;
  515.             accessByte.privilege = 3;
  516.             accessByte.present = true;
  517.             GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
  518.             flags.size = true;
  519.             flags.granularity = true;
  520.  
  521.             structure.write(GlobalDescriptor.Field.LIMIT, 0x00100000); // 1mb
  522.             structure.write(GlobalDescriptor.Field.BASE, 0);
  523.             structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
  524.             structure.write(GlobalDescriptor.Field.FLAGS, flags);
  525.            
  526.             assert structure.structure.length == lookupTable.itemSize;
  527.             lookupTable.itemList[0] = structure.structure;
  528.         }
  529.        
  530.         // 0x00100000 .. 0x00400000 hypervisor / management
  531.         {
  532.             GlobalDescriptor structure = new GlobalDescriptor();
  533.             GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
  534.             accessByte.accessed = false;
  535.             accessByte.readable_writable = false;
  536.             accessByte.direction_conforming = false;
  537.             accessByte.executable = false;
  538.             accessByte.privilege = 3;
  539.             accessByte.present = true;
  540.             GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
  541.             flags.size = true;
  542.             flags.granularity = true;
  543.  
  544.             structure.write(GlobalDescriptor.Field.LIMIT, 0x00100000); // 1mb
  545.             structure.write(GlobalDescriptor.Field.BASE, 0x00100000);
  546.             structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
  547.             structure.write(GlobalDescriptor.Field.FLAGS, flags);
  548.            
  549.             assert structure.structure.length == lookupTable.itemSize;
  550.             lookupTable.itemList[2] = structure.structure;
  551.         }
  552.        
  553.         // 0x00400000 .. 0xFEC00000 userspace pages (segmentation for nx)
  554.         for(int i = 0; i < userspacePageCount2; i++) {
  555.             GlobalDescriptor structure = new GlobalDescriptor();
  556.             GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
  557.             accessByte.accessed = false;
  558.             accessByte.readable_writable = false;
  559.             accessByte.direction_conforming = false;
  560.             accessByte.executable = false;
  561.             accessByte.privilege = 3;
  562.             accessByte.present = true;
  563.             GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
  564.             flags.size = true;
  565.             flags.granularity = true;
  566.  
  567.             structure.write(GlobalDescriptor.Field.LIMIT, 0x1000); // 4kb
  568.             structure.write(GlobalDescriptor.Field.BASE, 0x00400000 + 0x1000 * i);
  569.             structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
  570.             structure.write(GlobalDescriptor.Field.FLAGS, flags);
  571.            
  572.             assert structure.structure.length == lookupTable.itemSize;
  573.             lookupTable.itemList[i + 3] = structure.structure;
  574.         }
  575.         assert 0x00400000 + 0x1000 * userspacePageCount2 == 0xFEC00000;
  576.        
  577.         // 0xFEC00000 .. 0xFFFFFFFF mapped io
  578.         {
  579.             GlobalDescriptor structure = new GlobalDescriptor();
  580.             GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
  581.             accessByte.accessed = false;
  582.             accessByte.readable_writable = false;
  583.             accessByte.direction_conforming = false;
  584.             accessByte.executable = false;
  585.             accessByte.privilege = 3;
  586.             accessByte.present = true;
  587.             GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
  588.             flags.size = true;
  589.             flags.granularity = true;
  590.  
  591.             structure.write(GlobalDescriptor.Field.LIMIT, 0x1400000); // 20mb
  592.             structure.write(GlobalDescriptor.Field.BASE, 0xFEC00000);
  593.             structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
  594.             structure.write(GlobalDescriptor.Field.FLAGS, flags);
  595.            
  596.             assert structure.structure.length == lookupTable.itemSize;
  597.             lookupTable.itemList[1] = structure.structure;
  598.         }
  599.     }
  600.    
  601.     public static void initPageDirectory(LookupTable lookupTable1, Vector<LookupTable> lookupTableList) {
  602.         assert userspacePageCount2 == userspacePageCount1 * 0x400;
  603.        
  604.         lookupTable1.itemSize = 4;
  605.         lookupTable1.itemCount = userspacePageCount1;
  606.         lookupTable1.tableSize = lookupTable1.itemSize * lookupTable1.itemCount;
  607.         lookupTable1.itemList = new byte[lookupTable1.itemCount][];
  608.        
  609.         for(int i = 0; i < userspacePageCount1; i++) {
  610.             {
  611.                 PageDirectoryEntry structure = new PageDirectoryEntry();
  612.                 PageDirectoryEntry.Flags flags = new PageDirectoryEntry.Flags();
  613.                 flags.present = true;
  614.                 flags.read_write = false;
  615.                 flags.user_supervisor = false;
  616.                 flags.writeThrough = false;
  617.                 flags.cacheDisabled = true;
  618.                 flags.accessed = false;
  619.                 flags.dirty = false;
  620.                 flags.pageSize = false;
  621.                 flags.global = false;
  622.    
  623.                 structure.write(PageDirectoryEntry.Field.FLAGS, flags);
  624.                 structure.write(PageDirectoryEntry.Field.PHYSICAL_ADDRESS, 0);
  625.                
  626.                 assert structure.structure.length == lookupTable1.itemSize;
  627.                 lookupTable1.itemList[i] = structure.structure;
  628.             }
  629.            
  630.             {
  631.                 LookupTable lookupTable2 = new LookupTable();
  632.                 lookupTable2.itemSize = 4;
  633.                 lookupTable2.itemCount = 0x400;
  634.                 lookupTable2.tableSize = lookupTable2.itemSize * lookupTable2.itemCount;
  635.                 lookupTable2.itemList = new byte[lookupTable2.itemCount][];
  636.                
  637.                 for(int j = 0; j < 0x400; j++) {
  638.                     PageDirectoryEntry structure = new PageDirectoryEntry();
  639.                     PageDirectoryEntry.Flags flags = new PageDirectoryEntry.Flags();
  640.                     flags.present = true;
  641.                     flags.read_write = false;
  642.                     flags.user_supervisor = false;
  643.                     flags.writeThrough = false;
  644.                     flags.cacheDisabled = true;
  645.                     flags.accessed = false;
  646.                     flags.dirty = false;
  647.                     flags.pageSize = false;
  648.                     flags.global = false;
  649.        
  650.                     structure.write(PageDirectoryEntry.Field.FLAGS, flags);
  651.                     structure.write(PageDirectoryEntry.Field.PHYSICAL_ADDRESS, 0);
  652.                    
  653.                     assert structure.structure.length == lookupTable2.itemSize;
  654.                     lookupTable2.itemList[j] = structure.structure;
  655.                 }
  656.             }
  657.         }
  658.     }
  659.    
  660.     public static void initTaskSegmentTable(LookupTable lookupTable) {
  661.     }
  662.    
  663.     public static byte[] locateBytecode(Vector<IntelProcedure> procedureList, int startAddress, boolean hypervised) {
  664.         Vector<Byte> buffer = new Vector<Byte>();
  665.  
  666.         // 1: update offset per instruction, update offset per procedure
  667.         {
  668.             int currentAddress = startAddress;
  669.             for(IntelProcedure procedure : procedureList) {
  670.                 procedure.byteAddress = -1;
  671.                 procedure.byteLength = -1;
  672.                
  673.                 if(hypervised) {
  674.                     // jump to hypervisor
  675.                     procedure.addInstructionList(ExportOpcode.loadAddress(1));
  676.                     procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP));
  677.                 }
  678.                 else {
  679.                     // pop callstack and jump
  680.                     procedure.addInstructionList(ExportOpcode.loadAddress(1));
  681.                     procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP));
  682.                 }
  683.                
  684.                 procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_INVALID_EXECUTE_LOCATION));
  685.                
  686.                 int currentOffset = 0;
  687.                 for(IntelInstruction instruction : procedure.instructionList) {
  688.                     instruction.byteOffset = currentOffset;
  689.                     currentOffset += instruction.bytecode.length;
  690.                 }
  691.                 procedure.byteLength = currentOffset;
  692.                 procedure.byteAddress = currentAddress;
  693.                
  694.                 currentAddress += procedure.byteLength;
  695.             }
  696.         }
  697.        
  698.         // 2: update jumps (absolute, fixed address)
  699.         {
  700.             for(IntelProcedure procedure : procedureList) {
  701.                 for(IntelInstruction instruction : procedure.instructionList) {
  702.                     if(instruction.locate) {
  703.                         IntelProcedure procedure1 = procedureList.get(instruction.offset[0].procedureIndex);
  704.                         IntelInstruction instruction1 = procedure1.instructionList.get(instruction.offset[0].instructionIndex);
  705.  
  706.                         assert procedure1 != null;
  707.                         assert instruction1 != null;
  708.                         assert instruction.offset[0].instructionIndex >= 0;
  709.                         assert instruction.offset[0].instructionIndex < procedure1.instructionList.size();
  710.  
  711.                         if(instruction.locateLocal) {
  712.                             assert procedure1 == procedure;
  713.                         }
  714.                         else {
  715.                             assert instruction.offset[0].instructionIndex == 0;
  716.                             assert instruction1.byteOffset == 0;
  717.                         }
  718.                        
  719.                         int physicalAddress = procedure1.byteAddress + instruction1.byteOffset; // procedureAddress + instructionOffset
  720.                        
  721.                         byte[] b = new byte[]{
  722.                                 (byte) ((physicalAddress & 0x000000FF) >>> 0),
  723.                                 (byte) ((physicalAddress & 0x0000FF00) >>> 8),
  724.                                 (byte) ((physicalAddress & 0x00FF0000) >>> 16),
  725.                                 (byte) ((physicalAddress & 0xFF000000) >>> 24),
  726.                         };
  727.  
  728.                         instruction.bytecode[1] = b[0];
  729.                         instruction.bytecode[2] = b[1];
  730.                         instruction.bytecode[3] = b[2];
  731.                         instruction.bytecode[4] = b[3];
  732.                     }
  733.                 }
  734.             }
  735.         }
  736.        
  737.         // 3: append bytecode to buffer
  738.         {
  739.             int currentAddress = startAddress;
  740.             for(IntelProcedure procedure : procedureList) {
  741.                 assert procedure.byteAddress >= 0;
  742.                 assert procedure.byteLength >= 0;
  743.                 assert currentAddress == procedure.byteAddress;
  744.                
  745.                 for(IntelInstruction instruction : procedure.instructionList) {
  746.                     bufferAppend(buffer, instruction.bytecode);
  747.  
  748.                     assert currentAddress == procedure.byteAddress + instruction.byteOffset;
  749.                     currentAddress += instruction.bytecode.length;
  750.                     assert buffer.size() == currentAddress - startAddress;
  751.                 }
  752.                
  753.                 assert currentAddress == procedure.byteAddress + procedure.byteLength;
  754.             }
  755.         }
  756.        
  757.         return bufferOut(buffer);
  758.     }
  759.    
  760.     public static void bufferAppend(Vector<Byte> buffer, byte[] bytecode) {
  761.         for(byte b : bytecode) {
  762.             buffer.add(b);
  763.         }
  764.     }
  765.    
  766.     public static byte[] bufferOut(Vector<Byte> buffer) {
  767.         byte[] out = new byte[buffer.size()];
  768.         int i = 0;
  769.         for(Byte b : buffer) {
  770.             out[i++] = b;
  771.         }
  772.         return out;
  773.     }
  774.    
  775.     public static void fixedExportFunction(CodeContext context, IntelExport intelExport) {
  776.         // procedure only for OP_SEQUENCE marked as function
  777.         // other code objects: inline, multiple export of same contained code object, detect recursion
  778.         // steps: do not exist / use loop
  779.         // non-recursive, non-reentrant
  780.        
  781.         assert context.code == null;
  782.        
  783.         Vector<Code> codeList = new Vector<Code>();
  784.         codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.control, 0))[0]));
  785.         codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.expression, 0))[0]));
  786.        
  787.         // collect variables
  788.         {
  789.             int i = 0;
  790.             for(Code code1 : codeList) {
  791.                 if(!code1.declList.isEmpty()) {
  792.                     assert code1.operationType == OperationType.Control.OP_SEQUENCE
  793.                             || code1.operationType == OperationType.Control.OP_FOR_STEP;
  794.                    
  795.                     for(Identifier.Stack stackId : code1.declList.keySet()) {
  796.                         intelExport.fixedVariableList.put(stackId, i++);
  797.                     }
  798.                 }
  799.             }
  800.            
  801.             assert intelExport.fixedVariableList.size() == i;
  802.         }
  803.        
  804.         {
  805.             int i = 0;
  806.             for(Code code1 : codeList) {
  807.                 assert code1.operationType instanceof OperationType.IExecute;
  808.                
  809.                 if(code1.operationType == OperationType.Control.OP_SEQUENCE
  810.                         && code1.propertyList.containsKey(new Identifier.Property("function"))) {
  811.                     FixedExportScript exportScript1 = intelExportDef.get(code1.operationType).fixedExportScript;
  812.    
  813.                     IntelExportContext exportContext = new IntelExportContext();
  814.                     exportContext.procedure = new IntelProcedure();
  815.                     exportContext.procedureIndex = i++;
  816.                     intelExport.fixedProcedureList.add(exportContext.procedure);
  817.                    
  818.                     exportScript1.exec(context, intelExport, exportContext);
  819.                 }
  820.             }
  821.            
  822.             assert intelExport.fixedProcedureList.size() == i;
  823.         }
  824.     }
  825.    
  826.     public static void fixedExportCode(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {           
  827.         assert context.code.operationType instanceof OperationType.IExecute;
  828.  
  829.         if(context.code.operationType == OperationType.Control.OP_SEQUENCE
  830.                 && context.code.propertyList.containsKey(new Identifier.Property("function"))) { // do not use environment/trigger
  831.            
  832.             // TODO callstack (fixed)
  833.  
  834.             exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(1));
  835.             exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP));
  836.         }
  837.         else {
  838.             FixedExportScript exportScript1 = intelExportDef.get(context.code.operationType).fixedExportScript;
  839.             exportScript1.exec(context, intelExport, exportContext);
  840.         }
  841.     }
  842.    
  843.     public static void hypervisedExport(CodeContext context, IntelExport intelExport) {
  844.         // one procedure for each step of each code object
  845.        
  846.         assert context.code == null;
  847.        
  848.         Vector<Code> codeList = new Vector<Code>();
  849.         codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.control, 0))[0]));
  850.         codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.expression, 0))[0]));
  851.        
  852.         int i = 0;
  853.         for(Code code1 : codeList) {
  854.             assert code1.operationType instanceof OperationType.IExecute;
  855.             HypervisedExportScript[] exportScript1 = intelExportDef.get(code1.operationType).hypervisedExportScript;
  856.             for(HypervisedExportScript exportScript2 : exportScript1) {
  857.                 IntelExportContext exportContext = new IntelExportContext();
  858.                 exportContext.procedure = new IntelProcedure();
  859.                 exportContext.procedureIndex = i++;
  860.                 intelExport.hypervisedProcedureList.add(exportContext.procedure);
  861.                
  862.                 exportScript2.exec(context, intelExport, exportContext);
  863.             }
  864.         }
  865.        
  866.         assert intelExport.hypervisedProcedureList.size() == i;
  867.     }
  868.    
  869.     public static BytecodeOffset getOffset(IntelExport intelExport, IntelExportContext exportContext) {
  870.         BytecodeOffset offset = new BytecodeOffset();
  871.        
  872.         offset.procedureIndex = exportContext.procedureIndex;
  873.         offset.instructionIndex = exportContext.procedure.instructionList.size();
  874.        
  875.         return offset;
  876.     }
  877.    
  878.     public static int resolveFixedVariableAddress(Access access, IntelExport intelExport) {
  879.         assert access instanceof Access.StackAccess;
  880.        
  881.         {
  882.             Access.StackAccess access1 = (Access.StackAccess) access;
  883.             assert access1.offset == 0;
  884.  
  885.             Integer address = intelExport.fixedVariableList.get(access1.stackId);
  886.             assert address != null;
  887.            
  888.             return address;
  889.         }
  890.     }
  891. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement