📄 processor.java
字号:
eflagsTrap = false; eflagsNestedTask = false; eflagsVirtual8086Mode = false; eflagsResume = false; } else { throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector + EXT, true); } } break; case 0x1c: //Code: Execute-Only, Conforming case 0x1d: //Code: Execute-Only, Conforming, Accessed case 0x1e: //Code: Execute/Read, Conforming case 0x1f: //Code: Execute/Read, Conforming, Accessed { if (!targetSegment.isPresent()) throw new ProcessorException(PROC_EXCEPTION_NP, selector, true); //SAME-PRIVILEGE //check there is room on stack if (hasErrorCode) { if ((ss.getDefaultSizeFlag() && (esp < 16) && (esp > 0)) || !ss.getDefaultSizeFlag() && ((esp & 0xffff) < 16) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } else { if ((ss.getDefaultSizeFlag() && (esp < 12) && (esp > 0)) || !ss.getDefaultSizeFlag() && ((esp & 0xffff) < 12) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } int targetOffset = trapGate.getTargetOffset(); targetSegment.checkAddress(targetOffset); if (ss.getDefaultSizeFlag()) { esp -= 4; ss.setDoubleWord(esp, getEFlags()); esp -= 4; ss.setDoubleWord(esp, cs.getSelector()); esp -= 4; ss.setDoubleWord(esp, eip); if (hasErrorCode) { esp -= 4; ss.setDoubleWord(esp, errorCode); } } else { esp = (esp & ~ 0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, getEFlags()); esp = (esp & ~ 0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, cs.getSelector()); esp = (esp & ~ 0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, eip); if (hasErrorCode) { esp = (esp & ~ 0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, errorCode); } } cs = targetSegment; eip = targetOffset; cs.setRPL(currentPrivilegeLevel); eflagsTrap = false; eflagsNestedTask = false; eflagsVirtual8086Mode = false; eflagsResume = false; } break; } } break; } } public final void handleVirtual8086ModeException(int vector, boolean hasErrorCode, int errorCode) { int savedESP = esp; int savedEIP = eip; Segment savedCS = cs; Segment savedSS = ss; try { followVirtual8086ModeException(vector, hasErrorCode, errorCode, false, false); } catch (ProcessorException e) { e.printStackTrace(); //return cpu to original state esp = savedESP; eip = savedEIP; cs = savedCS; ss = savedSS; if (vector == PROC_EXCEPTION_DF) { System.err.println("Triple-Fault: Unhandleable, machine will halt!"); throw new IllegalStateException("Triple Fault " + e); } else if (e.combinesToDoubleFault(vector)){ System.err.println(vector); handleVirtual8086ModeException(PROC_EXCEPTION_DF, true, 0); } else handleVirtual8086ModeException(e.getVector(), e.hasErrorCode(), e.getErrorCode()); } } public final void handleSoftVirtual8086ModeInterrupt(int vector) { int savedESP = esp; int savedEIP = eip; Segment savedCS = cs; Segment savedSS = ss; if (eflagsIOPrivilegeLevel < 3) throw new ProcessorException(PROC_EXCEPTION_GP, 0, true); else { try { followVirtual8086ModeException(vector, false, 0, false, true); } catch (ProcessorException e) { e.printStackTrace(); //return cpu to original state esp = savedESP; eip = savedEIP; cs = savedCS; ss = savedSS; //if (e.getVector() == PROC_EXCEPTION_DF) { //System.err.println("Triple-Fault: Unhandleable, machine will halt!"); //throw new IllegalStateException("Triple Fault"); //else handleVirtual8086ModeException(e.getVector(), e.hasErrorCode(), e.getErrorCode()); } } } public final void handleHardVirtual8086ModeInterrupt(int vector) { int savedESP = esp; int savedEIP = eip; Segment savedCS = cs; Segment savedSS = ss; try { followVirtual8086ModeException(vector, false, 0, true, false); } catch (ProcessorException e) { //return cpu to original state esp = savedESP; eip = savedEIP; cs = savedCS; ss = savedSS; //if (e.getVector() == PROC_EXCEPTION_DF) { //System.err.println("Triple-Fault: Unhandleable, machine will halt!"); //throw new IllegalStateException("Triple Fault"); //else handleVirtual8086ModeException(e.getVector(), e.hasErrorCode(), e.getErrorCode()); } } private final void followVirtual8086ModeException(int vector, boolean hasErrorCode, int errorCode, boolean hardware, boolean software) { if (vector == PROC_EXCEPTION_PF) setCR2(linearMemory.getLastWalkedAddress()); int selector = vector << 3; //multiply by 8 to get offset into idt int EXT = hardware ? 1 : 0; Segment gate; boolean isSup = linearMemory.isSupervisor(); try { linearMemory.setSupervisor(true); long descriptor = idtr.getQuadWord(selector); gate = SegmentFactory.createProtectedModeSegment(linearMemory, selector, descriptor); } catch (ProcessorException e) { throw new ProcessorException(PROC_EXCEPTION_GP, selector + 2 + EXT, true); } finally { linearMemory.setSupervisor(isSup); } switch (gate.getType()) { default: System.err.println("Invalid Gate Type For Throwing Interrupt: 0x" + Integer.toHexString(gate.getType())); throw new ProcessorException(PROC_EXCEPTION_GP, selector + 2 + EXT, true); case 0x05: //Interrupt Handler: Task Gate System.out.println("Unimplemented Interrupt Handler: Task Gate"); throw new IllegalStateException("Unimplemented Interrupt Handler: Task Gate"); case 0x06: //Interrupt Handler: 16-bit Interrupt Gate System.out.println("Unimplemented Interrupt Handler: 16-bit Interrupt Gate"); throw new IllegalStateException("Unimplemented Interrupt Handler: 16-bit Interrupt Gate"); case 0x07: //Interrupt Handler: 16-bit Trap Gate System.out.println("Unimplemented Interrupt Handler: 16-bit Trap Gate"); throw new IllegalStateException("Unimplemented Interrupt Handler: 16-bit Trap Gate"); case 0x0e: //Interrupt Handler: 32-bit Interrupt Gate { SegmentFactory.InterruptGate32Bit interruptGate = ((SegmentFactory.InterruptGate32Bit)gate); checkGate(gate, selector, software); int targetSegmentSelector = interruptGate.getTargetSegment(); Segment targetSegment; try { targetSegment = getSegment(targetSegmentSelector); } catch (ProcessorException e) { throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector + EXT, true); } if (targetSegment.getDPL() > currentPrivilegeLevel) throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector + EXT, true); switch(targetSegment.getType()) { default: System.err.println(targetSegment); throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector + EXT, true); case 0x18: //Code, Execute-Only case 0x19: //Code, Execute-Only, Accessed case 0x1a: //Code, Execute/Read case 0x1b: //Code, Execute/Read, Accessed { if (!targetSegment.isPresent()) throw new ProcessorException(PROC_EXCEPTION_NP, targetSegmentSelector + EXT, true); if (targetSegment.getDPL() < currentPrivilegeLevel) { if (targetSegment.getDPL() != 0) throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector, true); //INTERRUPT-FROM-VIRTUAL-8086-MODE int newStackSelector = 0; int newESP = 0; if ((tss.getType() & 0x8) != 0) { int tssStackAddress = (targetSegment.getDPL() * 8) + 4; if ((tssStackAddress + 7) > tss.getLimit()) throw new ProcessorException(PROC_EXCEPTION_TS, tss.getSelector(), true); isSup = linearMemory.isSupervisor(); try { linearMemory.setSupervisor(true); newStackSelector = 0xffff & tss.getWord(tssStackAddress + 4); newESP = tss.getDoubleWord(tssStackAddress); } finally { linearMemory.setSupervisor(isSup); } } else { int tssStackAddress = (targetSegment.getDPL() * 4) + 2; if ((tssStackAddress + 4) > tss.getLimit()) throw new ProcessorException(PROC_EXCEPTION_TS, tss.getSelector(), true); newStackSelector = 0xffff & tss.getWord(tssStackAddress + 2); newESP = 0xffff & tss.getWord(tssStackAddress); } Segment newStackSegment = null; try { newStackSegment = getSegment(newStackSelector); } catch (ProcessorException e) { throw new ProcessorException(PROC_EXCEPTION_TS, newStackSelector, true); } if (newStackSegment.getRPL() != targetSegment.getDPL()) throw new ProcessorException(PROC_EXCEPTION_TS, newStackSelector, true); if ((newStackSegment.getDPL() != targetSegment.getDPL()) || ((newStackSegment.getType() & 0x1a) != 0x12)) throw new ProcessorException(PROC_EXCEPTION_TS, newStackSelector, true); if (!(newStackSegment.isPresent())) throw new ProcessorException(PROC_EXCEPTION_SS, newStackSelector, true); if (hasErrorCode) { if ((newStackSegment.getDefaultSizeFlag() && (esp < 40) && (esp > 0)) || !newStackSegment.getDefaultSizeFlag() && ((esp & 0xffff) < 40) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } else { if ((newStackSegment.getDefaultSizeFlag() && (esp < 36) && (esp > 0)) || !newStackSegment.getDefaultSizeFlag() && ((esp & 0xffff) < 36) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } int targetOffset = interruptGate.getTargetOffset(); targetSegment.checkAddress(targetOffset); int oldSS = ss.getSelector() & 0xffff; int oldESP = esp; int oldCS = cs.getSelector() & 0xffff; int oldEIP = eip & 0xffff; ss = newStackSegment; esp = newESP; cs = targetSegment; eip = targetOffset; setCPL(cs.getDPL()); if (ss.getDefaultSizeFlag()) { esp -= 4; ss.setDoubleWord(esp, gs.getSelector() & 0xffff); esp -= 4; ss.setDoubleWord(esp, fs.getSelector() & 0xffff); esp -= 4; ss.setDoubleWord(esp, ds.getSelector() & 0xffff); esp -= 4; ss.setDoubleWord(esp, es.getSelector() & 0xffff); esp -= 4; ss.setDoubleWord(esp, oldSS); esp -= 4; ss.setDoubleWord(esp, oldESP); esp -= 4; ss.setDoubleWord(esp, getEFlags()); esp -= 4; ss.setDoubleWord(esp, oldCS); esp -= 4; ss.setDoubleWord(esp, oldEIP); if (hasErrorCode) { esp -= 4; ss.setDoubleWord(esp, errorCode); } } else { esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, gs.getSelector() & 0xffff); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, fs.getSelector() & 0xffff); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, ds.getSelector() & 0xffff); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, es.getSelector() & 0xffff); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, oldSS); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, oldESP); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, getEFlags()); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, oldCS); esp = (esp & ~0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, oldEIP); if (hasErrorCode) { esp = (esp & ~ 0xffff) | ((esp - 4) & 0xffff); ss.setDoubleWord(esp & 0xffff, errorCode); } } gs = SegmentFactory.NULL_SEGMENT; fs = SegmentFactory.NULL_SEGMENT; ds = SegmentFactory.NULL_SEGMENT; es = SegmentFactory.NULL_SEGMENT; eflagsInterruptEnable = eflagsInterruptEnableSoon = false; eflagsTrap = false; eflagsNestedTask = false; eflagsVirtual8086Mode = false; eflagsResume = false; throw ModeSwitchException.PROTECTED_MODE_EXCEPTION; } else { throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector, true); } } case 0x1c: //Code: Execute-Only, Conforming case 0x1d: //Code: Execute-Only, Conforming, Accessed case 0x1e: //Code: Execute/Read, Conforming case 0x1f: //Code: Execute/Read, Conforming, Accessed if (!targetSegment.isPresent()) throw new ProcessorException(PROC_EXCEPTION_NP, selector, true); throw new ProcessorException(PROC_EXCEPTION_GP, targetSegmentSelector, true); } } case 0x0f: //Interrupt Handler: 32-bit Trap Gate { SegmentFactory.TrapGate32Bit trapGate = ((SegmentFactory.TrapGate32Bit)gate); checkGate(gate, selector, software); int targetSegmentSelector = trapGate.getTargetSegment(); Segment targetSegment; try { targetSegment = getSegment(targetSegmentSelector);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -