Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package emulator.editor;
- import java.util.*;
- import java.util.Map.Entry;
- import com.sun.tools.javac.util.ByteBuffer;
- import emulator.Hypervisor;
- import emulator.Hypervisor.Call;
- import emulator.code.*;
- import emulator.code.Code.Decl;
- import emulator.code.Operation.OperationType;
- import emulator.editor.ExportStructure.*;
- import emulator.editor.CodeOut.*;
- import emulator.editor.Context.*;
- import emulator.memory.*;
- import emulator.memory.Identifier.Stack;
- import emulator.memory.Memory.Access;
- import emulator.memory.Memory.Access.StructureAccess;
- public class Export {
- // java: emulate only
- // x86: hypervised(default), native, or emulate
- // preliminary: real mode, future: process/thread, paging, nx
- // TODO: export: microkernel, java, c++ + os api
- // limit tracing functionality
- // system code guidelines:
- // compare memory-range behind target address before/after write
- // memory up to fixedMemory is READ-ONLY
- // check bounds on any access
- //
- // only memory manager and hypervisor in level 0
- // disable call gate and interrupt gate
- // disable system management mode (use remote heartbeat)
- // constrain mem / io
- // io only level 0
- // non-hypervised code:
- // memory manager/gc
- // hypervisor/process/thread
- // security checks (buffer overflow, page per process, hw/io/usermode-driver)
- // bootstrap:
- // 1. initialize protected mode, segments, tables
- // initialize cpu, io, interrupt
- //
- // 2. load memory up to fixed memory from disk
- // use only fixed memory
- //
- // 3. load initial heap from disk (root process & management stacks)
- // start hypervisor
- // trace:
- // hypervisor:
- // restore for/for_list/for_loop with variables
- // restore sequence with index (fixed size entries)
- // insert bytecode / procedure: no restore
- // NO RESTORE OVER UNMANAGED CODE (only after / before)
- // 511 processes
- // (= 1024 pages / 2 code&data - 1 kernel)
- // (indefinite threads, are defined in process memory) // TODO indefinite processes, are defined in root process memory
- public static final LinkedHashMap<Operation.OperationType, ExportDef> intelExportDef = new LinkedHashMap<Operation.OperationType, ExportDef>();
- public static void initIntelExport() {
- intelExportDef.put(Operation.OperationType.Control.OP_ENVIRONMENT, new ExportDef(
- // fixed
- new FixedExportScript() {
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- assert false;
- }
- },
- //hypervised
- new HypervisedExportScript[] {
- new HypervisedExportScript() {
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- }
- }
- }
- ));
- intelExportDef.put(Operation.OperationType.Expression.OP_TRIGGER, new ExportDef(
- // fixed
- new FixedExportScript() {
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- assert false;
- }
- },
- //hypervised
- new HypervisedExportScript[] {
- new HypervisedExportScript() {
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- }
- }
- }
- ));
- intelExportDef.put(Operation.OperationType.Control.OP_SEQUENCE, new ExportDef(
- // variable decl in unmanaged code only on top of procedure
- // decide if managed only per procedure
- // fixed
- new FixedExportScript() {
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- Vector<Code> code1 = CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("code")))[0]);
- // init
- //boolean block = code1.size() > 1;
- //boolean function = context.code.propertyList.containsKey(new Identifier.Property("function"));
- boolean decl = !context.code.declList.isEmpty();
- if(decl) {
- for(Entry<Identifier.Stack, Decl> decl1 : context.code.declList.entrySet()) {
- //
- }
- }
- Structure.List.Vector structure = (Structure.List.Vector) Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("code")))[0];
- for(Code code2 : code1) {
- fixedExportCode(new CodeContext.CodeContextNew(context, code2), intelExport, exportContext);
- }
- }
- },
- //hypervised
- new HypervisedExportScript[] {
- new HypervisedExportScript() { // 0
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- /*int size2 = call.declInitList.size();
- if(call.step2 >= size2) {
- call.step2 = 0;
- call.step = 2;
- }
- else {
- Code.Decl decl = call.declInitList.get(call.step2);
- assert decl.initType == Code.Decl.InitType.EXPRESSION;
- Code code2 = (Code) Memory.Process.resolveExecuteItem(context.process, decl.initExpression)[0];
- Hypervisor.pushExecuteExpression(context.threadStackContext, new Call(new CodeContext.CodeContextNew(context, code2), true));
- }*/
- // fixed
- int addr_size2 = 0;
- int addr_decl = 0;
- // context
- int addr_call_step = 0;
- int addr_call_step2 = 0;
- // access, resolve in hypervisor (userspace access)
- int addr_code2 = 0;
- // offset
- BytecodeOffset[] off_if1_else1 = new BytecodeOffset[1];
- BytecodeOffset[] off_if1_end = new BytecodeOffset[1];
- exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_size2));
- exportContext.procedure.addInstructionList(ExportOpcode.loadInteger(ExportOpcode.sel_ax));
- exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_call_step2));
- exportContext.procedure.addInstructionList(ExportOpcode.loadInteger(ExportOpcode.sel_cx));
- exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeOperator(ExportOpcode.IntelOpcodeOperator.OP_LGC_GTE_S)); // call.step2 >= size2
- exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_if1_else1));
- exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP_IF_FALSE)); // if(call.step2 >= size2) {
- {
- exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_call_step2));
- exportContext.procedure.addInstructionList(ExportOpcode.storeIntegerConstant(0)); // call.step2 = 0;
- exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_call_step));
- exportContext.procedure.addInstructionList(ExportOpcode.storeIntegerConstant(2)); // call.step = 2;
- }
- exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_if1_end));
- exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP)); // else {
- off_if1_else1[0] = getOffset(intelExport, exportContext); // else {
- {
- }
- off_if1_end[0] = getOffset(intelExport, exportContext); // }
- }
- },
- new HypervisedExportScript() { // 1
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- /*int size2 = call.declInitList.size();
- assert call.step2 < size2;
- {
- Code.Decl decl = call.declInitList.get(call.step2);
- assert decl.initType == Code.Decl.InitType.EXPRESSION;
- Object[] access2 = Memory.Process.resolveItem(context.process, decl.access);
- access2[0] = Hypervisor.popEvaluate(context.threadStackContext);
- }
- call.step2++;
- call.step = 0;*/
- }
- },
- new HypervisedExportScript() { // 2
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- /*int size2 = ((Structure.List.Vector) Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("code")))[0]).size();
- if(call.step2 >= size2) {
- call.step = -1;
- }
- else {
- 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];
- Hypervisor.pushExecute(context.threadStackContext, new Call(new CodeContext.CodeContextNew(context, code2), false));
- call.step2++;
- call.step = 2;
- }*/
- }
- }
- }
- ));
- intelExportDef.put(Operation.OperationType.Control.OP_FOR_STEP, new ExportDef(
- // fixed
- new FixedExportScript() {
- public void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- // fixed
- //int addr_condition = 0; // inline
- int addr_step = 0;
- //resolveFixedVariableAddress(access, intelExport);
- // context
- // offset
- BytecodeOffset[] off_loop1_start = new BytecodeOffset[1];
- BytecodeOffset[] off_loop1_end = new BytecodeOffset[1];
- // init
- boolean decl = !context.code.declList.isEmpty();
- if(decl) {
- for(Entry<Identifier.Stack, Decl> decl1 : context.code.declList.entrySet()) {
- //
- }
- }
- off_loop1_start[0] = getOffset(intelExport, exportContext);
- { // execute cond
- Code code1 = (Code) Memory.Process.resolveExecuteItem(context.process, context.code.dataList.get(new Identifier.Property("cond")))[0];
- fixedExportCode(new CodeContext.CodeContextNew(context, (Code) code1), intelExport, exportContext);
- }
- //exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(addr_valueStack_0));
- exportContext.procedure.addInstructionList(ExportOpcode.loadInteger(ExportOpcode.sel_ax));
- exportContext.procedure.addInstructionList(ExportOpcode.castIntegerBoolean(ExportOpcode.sel_ax));
- exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_loop1_end));
- exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP_IF_FALSE)); //
- {
- }
- { // execute step
- Code code1 = (Code) Memory.Process.resolveExecuteItem(context.process, context.code.codeList.get(new Identifier.Property("step")))[0];
- fixedExportCode(new CodeContext.CodeContextNew(context, (Code) code1), intelExport, exportContext);
- }
- exportContext.procedure.addInstructionList(ExportOpcode.loadJumpAddress(off_loop1_start));
- exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP)); // }
- off_loop1_end[0] = getOffset(intelExport, exportContext);
- }
- },
- //hypervised
- new HypervisedExportScript[] {
- }
- ));
- }
- public static class ExportDef {
- public FixedExportScript fixedExportScript;
- public HypervisedExportScript[] hypervisedExportScript;
- public ExportDef(FixedExportScript fixedExportScript, HypervisedExportScript[] hypervisedExportScript) {
- this.fixedExportScript = fixedExportScript;
- this.hypervisedExportScript = hypervisedExportScript;
- };
- }
- public static abstract class FixedExportScript {
- public abstract void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext);
- }
- public static abstract class HypervisedExportScript {
- public abstract void exec(CodeContext context, IntelExport intelExport, IntelExportContext exportContext);
- }
- // Layout ===================0
- public static final int userspacePageCount1 = 0x3FA; // of size: 4mb (0x00400000)
- public static final int userspacePageCount2 = 0x000FE800; // of size: 4kb (0x1000)
- // 4gb =
- // 4mb(0x00400000) // low memory, hypervisor, management
- // + 20mb(0x01400000) // mapped io
- // + (0xFE800000) // userspace memory, smallest memory allocation to process: 4kb (0x1000)
- // 0xFE800000 = 4mb(0x00400000) * 0x3FA
- // 0xFE800000 = 4kb(0x1000) * 0x000FE800
- // TODO
- public static int interruptProxyPageCount = 0;
- public static int fixedCodePageCount = 0;
- public static int hypervisedCodePageCount = 0;
- public static int fixedMemoryPageCount = 0;
- public static class IntelInstruction {
- public int byteOffset = -1;
- public byte[] bytecode; // add only if != null
- public boolean locate = false; // locate bytes 1 .. 4
- public boolean locateLocal = true;
- public BytecodeOffset[] offset; // address relative to procedure start
- }
- public static class BytecodeOffset {
- //public int startAddress = -1;
- //public Vector<IntelProcedure> procedureList;
- public int procedureIndex = -1;
- public int instructionIndex = -1;
- }
- public static class IntelProcedure {
- public int byteAddress = -1;
- public int byteLength = -1;
- public final Vector<IntelInstruction> instructionList = new Vector<IntelInstruction>();
- public void addInstructionList(IntelInstruction[] instructionList1) {
- for(IntelInstruction instruction : instructionList1) {
- if(instruction != null && instruction.bytecode != null)
- instructionList.add(instruction);
- }
- }
- }
- public static class LookupTable {
- public int itemSize = -1;
- public int itemCount = -1;
- public int tableSize = -1;
- public byte[][] itemList;
- }
- public static class MemoryImage {
- public int start = -1;
- public int size = -1;
- public int end = -1;
- public byte[] image;
- public MemoryImage(int start, int size) {
- this.start = start;
- this.size = size;
- }
- }
- public static class IntelExport {
- public static class FixedMemoryLayout {// address, size
- // boot state (execute once)
- // return stack index
- // evaluate stack index
- // fild tmp int32 constant
- // fld tmp float80 constant TODO
- // 8 return addresses (call stack)
- // 8 evaluate stack
- // 8 resolve temp
- // 64 variables, parameters
- }
- public final FixedMemoryLayout fixedMemoryLayout = new FixedMemoryLayout();
- // fixed procedures: (import java, list variables, no recursion)
- // schedule
- // find free mem slot
- // find free page
- // ...
- public static class MemoryLayout {// address, size
- // 0 .. 0x00100000 read only, no execute
- public final MemoryImage interruptVectorTable = new MemoryImage(0, 0x400);
- public final MemoryImage bios1 = new MemoryImage(0x400, 0x100);
- public final MemoryImage bootstrapCode2 = new MemoryImage(0x500, -1);
- public final MemoryImage bootstrapCode1 = new MemoryImage(0x7C00, 0x200); // TODO mbr 0x6000 ?
- public final MemoryImage biosX = new MemoryImage(0x00080000, 0x00020000); // TODO ebda 0x0009FC00 ?
- public final MemoryImage vga = new MemoryImage(0x000A0000, 0x00020000);
- public final MemoryImage bios2 = new MemoryImage(0x000C0000, 0x00040000);
- // 0x00100000 .. execute, code before data
- // code, read only
- public final MemoryImage bootstrapCode3 = new MemoryImage(0x00100000, -1);// read-only, abort on second time execution
- public final MemoryImage interruptProxyList = new MemoryImage(-1, 0x1000 * interruptProxyPageCount);
- public final MemoryImage fixedCodeList = new MemoryImage(-1, 0x1000 * fixedCodePageCount);// non-hypervised procedures
- // code cache
- public final MemoryImage hypervisedCodeList = new MemoryImage(-1, 0x1000 * hypervisedCodePageCount);// hypervised procedures
- // data
- public final MemoryImage interruptDescriptorTableRegister = new MemoryImage(-1, 6);
- public final MemoryImage globalDescriptorTableRegister = new MemoryImage(-1, 6);
- public final MemoryImage interruptDescriptorTable = new MemoryImage(-1, 0x100 * 8);
- public final MemoryImage globalDescriptorTable = new MemoryImage(-1, (userspacePageCount2 + 3) * 8);// hypervisor level 0, separate remaining ram for code / data
- public final MemoryImage pageDirectory = new MemoryImage(-1, 0x400 * 4);
- public final MemoryImage pageTable = new MemoryImage(-1, 0x400 * 0x400 * 4);
- public final MemoryImage taskStateSegmentTable = new MemoryImage(-1, -1); // taskCount = coreCount + 1(hypervisor/memoryManagement)
- public final MemoryImage fixedMemory = new MemoryImage(-1, 0x1000 * fixedMemoryPageCount);
- public final MemoryImage processTable = new MemoryImage(-1, 0x1000);// pointers to process root page + management info
- public final MemoryImage pageAllocTable = new MemoryImage(-1, 0x1000);// allocated/free
- public final MemoryImage processPermissionTable = new MemoryImage(-1, 0x1000);
- public final MemoryImage processAllocTable = new MemoryImage(-1, 0x1000);// storage class -> page
- public final MemoryImage pageLoadTable = new MemoryImage(-1, 0x1000);// page -> slot
- //public final MemoryImage linkTable = new MemoryImage(-1, 0x1000);// page + slot -> link (list)
- public final MemoryImage hashtableList = new MemoryImage(-1, -1);
- public final MemoryImage hashtableStringPointerList = new MemoryImage(-1, -1);
- public final MemoryImage hashtableStringList = new MemoryImage(-1, -1);
- public final MemoryImage referenceounterTable = new MemoryImage(-1, -1); // variable size, tabled bignum
- // 0x001FF000 .. 0x00400000 no execute, protect: page fault, segmentation fault
- public final MemoryImage mandatoryStack = new MemoryImage(0x001FF000, 0x1000);
- // 0x00400000 .. 0xFEC00000 partly execute
- public final MemoryImage userspace = new MemoryImage(0x00400000, 0xFE800000);// code and data-stacks from hypervised code, paged
- // 0xFEC00000 .. 0xFFFFFFFF no execute
- public final MemoryImage mappedIo = new MemoryImage(0xFEC00000, 0x1400000); // TODO ?
- }
- public final MemoryLayout memoryLayout = new MemoryLayout();
- public byte[] mbr;//bootstrapCode1 (load hdd from 0xFF upwards) + partition table
- public byte[] kernelImage;
- public final LookupTable interruptVectorTable = new LookupTable();
- public final LookupTable globalDescriptorTable = new LookupTable();
- public final Vector<IntelProcedure> fixedProcedureList = new Vector<IntelProcedure>();
- public final HashMap<Identifier.Stack, Integer> fixedVariableList = new HashMap<Identifier.Stack, Integer>();
- public final Vector<IntelProcedure> hypervisedProcedureList = new Vector<IntelProcedure>(); // code cache
- }
- public static class IntelExportContext {
- public boolean managed = true; // TODO: later: reduce tracing, increase performance
- public int procedureIndex = -1;
- public IntelProcedure procedure;
- }
- //====
- public static void initInterruptDescriptorTable(LookupTable lookupTable) {
- lookupTable.itemSize = 8;
- lookupTable.itemCount = 0x100;// 256 interrupts
- lookupTable.tableSize = lookupTable.itemSize * lookupTable.itemCount;
- lookupTable.itemList = new byte[lookupTable.itemCount][];
- Vector<IntelProcedure> proxyList = new Vector<IntelProcedure>();
- for(int i = 0; i < lookupTable.itemCount; i++) {
- IntelProcedure procedure = new IntelProcedure();
- proxyList.add(procedure);
- procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_IRET));
- procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_INVALID_EXECUTE_LOCATION));
- }
- for(int i = 0; i < lookupTable.itemCount; i++) {
- InterruptDescriptor structure = new InterruptDescriptor();
- InterruptDescriptor.TypeAttr typeAttr = new InterruptDescriptor.TypeAttr();
- typeAttr.type = InterruptDescriptor.Type.INTERRUPT_GATE;
- typeAttr.storageSegment = false;
- typeAttr.privilege = 0;
- typeAttr.present = true;
- structure.write(InterruptDescriptor.Field.SEGMENT, 0);
- structure.write(InterruptDescriptor.Field.OFFSET, 0);
- structure.write(InterruptDescriptor.Field.TYPE_ATTR, typeAttr);
- assert structure.structure.length == lookupTable.itemSize;
- lookupTable.itemList[i] = structure.structure;
- }
- }
- public static void initGlobalDescriptorTable(LookupTable lookupTable) {
- lookupTable.itemSize = 8;
- lookupTable.itemCount = userspacePageCount2 + 3;
- lookupTable.tableSize = lookupTable.itemSize * lookupTable.itemCount;
- lookupTable.itemList = new byte[lookupTable.itemCount][];
- // 0 .. 0x00100000 read only
- {
- GlobalDescriptor structure = new GlobalDescriptor();
- GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
- accessByte.accessed = false;
- accessByte.readable_writable = false;
- accessByte.direction_conforming = false;
- accessByte.executable = false;
- accessByte.privilege = 3;
- accessByte.present = true;
- GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
- flags.size = true;
- flags.granularity = true;
- structure.write(GlobalDescriptor.Field.LIMIT, 0x00100000); // 1mb
- structure.write(GlobalDescriptor.Field.BASE, 0);
- structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
- structure.write(GlobalDescriptor.Field.FLAGS, flags);
- assert structure.structure.length == lookupTable.itemSize;
- lookupTable.itemList[0] = structure.structure;
- }
- // 0x00100000 .. 0x00400000 hypervisor / management
- {
- GlobalDescriptor structure = new GlobalDescriptor();
- GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
- accessByte.accessed = false;
- accessByte.readable_writable = false;
- accessByte.direction_conforming = false;
- accessByte.executable = false;
- accessByte.privilege = 3;
- accessByte.present = true;
- GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
- flags.size = true;
- flags.granularity = true;
- structure.write(GlobalDescriptor.Field.LIMIT, 0x00100000); // 1mb
- structure.write(GlobalDescriptor.Field.BASE, 0x00100000);
- structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
- structure.write(GlobalDescriptor.Field.FLAGS, flags);
- assert structure.structure.length == lookupTable.itemSize;
- lookupTable.itemList[2] = structure.structure;
- }
- // 0x00400000 .. 0xFEC00000 userspace pages (segmentation for nx)
- for(int i = 0; i < userspacePageCount2; i++) {
- GlobalDescriptor structure = new GlobalDescriptor();
- GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
- accessByte.accessed = false;
- accessByte.readable_writable = false;
- accessByte.direction_conforming = false;
- accessByte.executable = false;
- accessByte.privilege = 3;
- accessByte.present = true;
- GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
- flags.size = true;
- flags.granularity = true;
- structure.write(GlobalDescriptor.Field.LIMIT, 0x1000); // 4kb
- structure.write(GlobalDescriptor.Field.BASE, 0x00400000 + 0x1000 * i);
- structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
- structure.write(GlobalDescriptor.Field.FLAGS, flags);
- assert structure.structure.length == lookupTable.itemSize;
- lookupTable.itemList[i + 3] = structure.structure;
- }
- assert 0x00400000 + 0x1000 * userspacePageCount2 == 0xFEC00000;
- // 0xFEC00000 .. 0xFFFFFFFF mapped io
- {
- GlobalDescriptor structure = new GlobalDescriptor();
- GlobalDescriptor.AccessByte accessByte = new GlobalDescriptor.AccessByte();
- accessByte.accessed = false;
- accessByte.readable_writable = false;
- accessByte.direction_conforming = false;
- accessByte.executable = false;
- accessByte.privilege = 3;
- accessByte.present = true;
- GlobalDescriptor.Flags flags = new GlobalDescriptor.Flags();
- flags.size = true;
- flags.granularity = true;
- structure.write(GlobalDescriptor.Field.LIMIT, 0x1400000); // 20mb
- structure.write(GlobalDescriptor.Field.BASE, 0xFEC00000);
- structure.write(GlobalDescriptor.Field.ACCESS_BYTE, accessByte);
- structure.write(GlobalDescriptor.Field.FLAGS, flags);
- assert structure.structure.length == lookupTable.itemSize;
- lookupTable.itemList[1] = structure.structure;
- }
- }
- public static void initPageDirectory(LookupTable lookupTable1, Vector<LookupTable> lookupTableList) {
- assert userspacePageCount2 == userspacePageCount1 * 0x400;
- lookupTable1.itemSize = 4;
- lookupTable1.itemCount = userspacePageCount1;
- lookupTable1.tableSize = lookupTable1.itemSize * lookupTable1.itemCount;
- lookupTable1.itemList = new byte[lookupTable1.itemCount][];
- for(int i = 0; i < userspacePageCount1; i++) {
- {
- PageDirectoryEntry structure = new PageDirectoryEntry();
- PageDirectoryEntry.Flags flags = new PageDirectoryEntry.Flags();
- flags.present = true;
- flags.read_write = false;
- flags.user_supervisor = false;
- flags.writeThrough = false;
- flags.cacheDisabled = true;
- flags.accessed = false;
- flags.dirty = false;
- flags.pageSize = false;
- flags.global = false;
- structure.write(PageDirectoryEntry.Field.FLAGS, flags);
- structure.write(PageDirectoryEntry.Field.PHYSICAL_ADDRESS, 0);
- assert structure.structure.length == lookupTable1.itemSize;
- lookupTable1.itemList[i] = structure.structure;
- }
- {
- LookupTable lookupTable2 = new LookupTable();
- lookupTable2.itemSize = 4;
- lookupTable2.itemCount = 0x400;
- lookupTable2.tableSize = lookupTable2.itemSize * lookupTable2.itemCount;
- lookupTable2.itemList = new byte[lookupTable2.itemCount][];
- for(int j = 0; j < 0x400; j++) {
- PageDirectoryEntry structure = new PageDirectoryEntry();
- PageDirectoryEntry.Flags flags = new PageDirectoryEntry.Flags();
- flags.present = true;
- flags.read_write = false;
- flags.user_supervisor = false;
- flags.writeThrough = false;
- flags.cacheDisabled = true;
- flags.accessed = false;
- flags.dirty = false;
- flags.pageSize = false;
- flags.global = false;
- structure.write(PageDirectoryEntry.Field.FLAGS, flags);
- structure.write(PageDirectoryEntry.Field.PHYSICAL_ADDRESS, 0);
- assert structure.structure.length == lookupTable2.itemSize;
- lookupTable2.itemList[j] = structure.structure;
- }
- }
- }
- }
- public static void initTaskSegmentTable(LookupTable lookupTable) {
- }
- public static byte[] locateBytecode(Vector<IntelProcedure> procedureList, int startAddress, boolean hypervised) {
- Vector<Byte> buffer = new Vector<Byte>();
- // 1: update offset per instruction, update offset per procedure
- {
- int currentAddress = startAddress;
- for(IntelProcedure procedure : procedureList) {
- procedure.byteAddress = -1;
- procedure.byteLength = -1;
- if(hypervised) {
- // jump to hypervisor
- procedure.addInstructionList(ExportOpcode.loadAddress(1));
- procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP));
- }
- else {
- // pop callstack and jump
- procedure.addInstructionList(ExportOpcode.loadAddress(1));
- procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP));
- }
- procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_INVALID_EXECUTE_LOCATION));
- int currentOffset = 0;
- for(IntelInstruction instruction : procedure.instructionList) {
- instruction.byteOffset = currentOffset;
- currentOffset += instruction.bytecode.length;
- }
- procedure.byteLength = currentOffset;
- procedure.byteAddress = currentAddress;
- currentAddress += procedure.byteLength;
- }
- }
- // 2: update jumps (absolute, fixed address)
- {
- for(IntelProcedure procedure : procedureList) {
- for(IntelInstruction instruction : procedure.instructionList) {
- if(instruction.locate) {
- IntelProcedure procedure1 = procedureList.get(instruction.offset[0].procedureIndex);
- IntelInstruction instruction1 = procedure1.instructionList.get(instruction.offset[0].instructionIndex);
- assert procedure1 != null;
- assert instruction1 != null;
- assert instruction.offset[0].instructionIndex >= 0;
- assert instruction.offset[0].instructionIndex < procedure1.instructionList.size();
- if(instruction.locateLocal) {
- assert procedure1 == procedure;
- }
- else {
- assert instruction.offset[0].instructionIndex == 0;
- assert instruction1.byteOffset == 0;
- }
- int physicalAddress = procedure1.byteAddress + instruction1.byteOffset; // procedureAddress + instructionOffset
- byte[] b = new byte[]{
- (byte) ((physicalAddress & 0x000000FF) >>> 0),
- (byte) ((physicalAddress & 0x0000FF00) >>> 8),
- (byte) ((physicalAddress & 0x00FF0000) >>> 16),
- (byte) ((physicalAddress & 0xFF000000) >>> 24),
- };
- instruction.bytecode[1] = b[0];
- instruction.bytecode[2] = b[1];
- instruction.bytecode[3] = b[2];
- instruction.bytecode[4] = b[3];
- }
- }
- }
- }
- // 3: append bytecode to buffer
- {
- int currentAddress = startAddress;
- for(IntelProcedure procedure : procedureList) {
- assert procedure.byteAddress >= 0;
- assert procedure.byteLength >= 0;
- assert currentAddress == procedure.byteAddress;
- for(IntelInstruction instruction : procedure.instructionList) {
- bufferAppend(buffer, instruction.bytecode);
- assert currentAddress == procedure.byteAddress + instruction.byteOffset;
- currentAddress += instruction.bytecode.length;
- assert buffer.size() == currentAddress - startAddress;
- }
- assert currentAddress == procedure.byteAddress + procedure.byteLength;
- }
- }
- return bufferOut(buffer);
- }
- public static void bufferAppend(Vector<Byte> buffer, byte[] bytecode) {
- for(byte b : bytecode) {
- buffer.add(b);
- }
- }
- public static byte[] bufferOut(Vector<Byte> buffer) {
- byte[] out = new byte[buffer.size()];
- int i = 0;
- for(Byte b : buffer) {
- out[i++] = b;
- }
- return out;
- }
- public static void fixedExportFunction(CodeContext context, IntelExport intelExport) {
- // procedure only for OP_SEQUENCE marked as function
- // other code objects: inline, multiple export of same contained code object, detect recursion
- // steps: do not exist / use loop
- // non-recursive, non-reentrant
- assert context.code == null;
- Vector<Code> codeList = new Vector<Code>();
- codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.control, 0))[0]));
- codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.expression, 0))[0]));
- // collect variables
- {
- int i = 0;
- for(Code code1 : codeList) {
- if(!code1.declList.isEmpty()) {
- assert code1.operationType == OperationType.Control.OP_SEQUENCE
- || code1.operationType == OperationType.Control.OP_FOR_STEP;
- for(Identifier.Stack stackId : code1.declList.keySet()) {
- intelExport.fixedVariableList.put(stackId, i++);
- }
- }
- }
- assert intelExport.fixedVariableList.size() == i;
- }
- {
- int i = 0;
- for(Code code1 : codeList) {
- assert code1.operationType instanceof OperationType.IExecute;
- if(code1.operationType == OperationType.Control.OP_SEQUENCE
- && code1.propertyList.containsKey(new Identifier.Property("function"))) {
- FixedExportScript exportScript1 = intelExportDef.get(code1.operationType).fixedExportScript;
- IntelExportContext exportContext = new IntelExportContext();
- exportContext.procedure = new IntelProcedure();
- exportContext.procedureIndex = i++;
- intelExport.fixedProcedureList.add(exportContext.procedure);
- exportScript1.exec(context, intelExport, exportContext);
- }
- }
- assert intelExport.fixedProcedureList.size() == i;
- }
- }
- public static void fixedExportCode(CodeContext context, IntelExport intelExport, IntelExportContext exportContext) {
- assert context.code.operationType instanceof OperationType.IExecute;
- if(context.code.operationType == OperationType.Control.OP_SEQUENCE
- && context.code.propertyList.containsKey(new Identifier.Property("function"))) { // do not use environment/trigger
- // TODO callstack (fixed)
- exportContext.procedure.addInstructionList(ExportOpcode.loadAddress(1));
- exportContext.procedure.addInstructionList(ExportOpcode.getOpcodeSpecial(ExportOpcode.IntelOpcodeSpecial.OP_JMP));
- }
- else {
- FixedExportScript exportScript1 = intelExportDef.get(context.code.operationType).fixedExportScript;
- exportScript1.exec(context, intelExport, exportContext);
- }
- }
- public static void hypervisedExport(CodeContext context, IntelExport intelExport) {
- // one procedure for each step of each code object
- assert context.code == null;
- Vector<Code> codeList = new Vector<Code>();
- codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.control, 0))[0]));
- codeList.addAll(CodeOut.getOperandList(context.process, Memory.Process.resolveExecuteItem(context.process, new Access.StackAccess(context.stackContext.stackId.expression, 0))[0]));
- int i = 0;
- for(Code code1 : codeList) {
- assert code1.operationType instanceof OperationType.IExecute;
- HypervisedExportScript[] exportScript1 = intelExportDef.get(code1.operationType).hypervisedExportScript;
- for(HypervisedExportScript exportScript2 : exportScript1) {
- IntelExportContext exportContext = new IntelExportContext();
- exportContext.procedure = new IntelProcedure();
- exportContext.procedureIndex = i++;
- intelExport.hypervisedProcedureList.add(exportContext.procedure);
- exportScript2.exec(context, intelExport, exportContext);
- }
- }
- assert intelExport.hypervisedProcedureList.size() == i;
- }
- public static BytecodeOffset getOffset(IntelExport intelExport, IntelExportContext exportContext) {
- BytecodeOffset offset = new BytecodeOffset();
- offset.procedureIndex = exportContext.procedureIndex;
- offset.instructionIndex = exportContext.procedure.instructionList.size();
- return offset;
- }
- public static int resolveFixedVariableAddress(Access access, IntelExport intelExport) {
- assert access instanceof Access.StackAccess;
- {
- Access.StackAccess access1 = (Access.StackAccess) access;
- assert access1.offset == 0;
- Integer address = intelExport.fixedVariableList.get(access1.stackId);
- assert address != null;
- return address;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement