📄 processor.java
字号:
} } 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 < 24) && (esp > 0)) || !newStackSegment.getDefaultSizeFlag() && ((esp & 0xffff) < 24) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } else { if ((newStackSegment.getDefaultSizeFlag() && (esp < 20) && (esp > 0)) || !newStackSegment.getDefaultSizeFlag() && ((esp & 0xffff) < 20) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } int targetOffset = interruptGate.getTargetOffset(); targetSegment.checkAddress(targetOffset); int oldSS = ss.getSelector(); int oldESP = esp; int oldCS = cs.getSelector(); int oldEIP = eip; ss = newStackSegment; esp = newESP; cs = targetSegment; eip = targetOffset; setCPL(cs.getDPL()); if (ss.getDefaultSizeFlag()) { 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, 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); } } eflagsInterruptEnable = eflagsInterruptEnableSoon = false; eflagsTrap = false; eflagsNestedTask = false; eflagsVirtual8086Mode = false; eflagsResume = false; } else if (targetSegment.getDPL() == currentPrivilegeLevel) { //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 = interruptGate.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); eflagsInterruptEnable = eflagsInterruptEnableSoon = false; 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 = interruptGate.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); eflagsInterruptEnable = eflagsInterruptEnableSoon = false; eflagsTrap = false; eflagsNestedTask = false; eflagsVirtual8086Mode = false; eflagsResume = false; } break; } } break; 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); } 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: 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) { //INTER-PRIVILEGE-LEVEL 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 < 24) && (esp > 0)) || !newStackSegment.getDefaultSizeFlag() && ((esp & 0xffff) < 24) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } else { if ((newStackSegment.getDefaultSizeFlag() && (esp < 20) && (esp > 0)) || !newStackSegment.getDefaultSizeFlag() && ((esp & 0xffff) < 20) && ((esp & 0xffff) > 0)) throw new ProcessorException(PROC_EXCEPTION_SS, 0, true); } int targetOffset = trapGate.getTargetOffset(); targetSegment.checkAddress(targetOffset); int oldSS = ss.getSelector(); int oldESP = esp; int oldCS = cs.getSelector(); int oldEIP = eip; ss = newStackSegment; esp = newESP; cs = targetSegment; eip = targetOffset; setCPL(cs.getDPL()); if (ss.getDefaultSizeFlag()) { 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, 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); } } eflagsTrap = false; eflagsNestedTask = false; eflagsVirtual8086Mode = false; eflagsResume = false; } else if (targetSegment.getDPL() == currentPrivilegeLevel) { //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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -