add rsp, rsp, t2
wripi t1, 0
};
+
+def macroop RET_FAR {
+ .adjust_env oszIn64Override
+
+ # Get the return RIP
+ ld t1, ss, [1, t0, rsp]
+
+ # Get the return CS
+ ld t2, ss, [1, t0, rsp], dsz
+
+ # Get the rpl
+ andi t3, t2, 0x3
+
+ # Get the cpl
+
+ # Here we'd check if we're changing priviledge levels. We'll just hope
+ # that doesn't happen yet.
+
+ # Do stuff if they're equal
+ chks t4, t2, flags=(EZF,)
+ fault "new GeneralProtection(0)", flags=(CEZF,)
+ ld t3, flatseg, [1, t0, t4], addressSize=8, dataSize=8
+ wrdl cs, t3, t2
+ # There should be validity checks on the RIP checks here, but I'll do
+ # that later.
+ wrip t0, t1
+ bri t0, label("end")
+
+ # Do other stuff if they're not.
+end:
+ fault "NoFault"
+};
'''
code = '''
SegDescriptor desc = SrcReg1;
SegAttr attr = 0;
- Addr base = 0, limit = 0;
attr.dpl = desc.dpl;
attr.defaultSize = desc.d;
- if (!desc.p)
- panic("Segment not present.\\n");
- if (!desc.s)
+ if (!desc.s) {
+ SegBaseDest = SegBaseDest;
+ SegLimitDest = SegLimitDest;
+ SegAttrDest = SegAttrDest;
panic("System segment encountered.\\n");
- if (desc.type.codeOrData) {
- panic("Code segment encountered with c = %d, r = %d, a = %d.\\n",
- desc.type.c, desc.type.r, desc.type.a);
} else {
- attr.expandDown = desc.type.e;
- attr.readable = 1;
- attr.writable = desc.type.w;
- base = desc.baseLow | (desc.baseHigh << 24);
- limit = desc.limitLow | (desc.limitHigh << 16);
+ if (!desc.p)
+ panic("Segment not present.\\n");
+ if (desc.type.codeOrData) {
+ attr.readable = desc.type.r;
+ attr.longMode = desc.l;
+ } else {
+ attr.expandDown = desc.type.e;
+ attr.readable = 1;
+ attr.writable = desc.type.w;
+ }
+ Addr base = desc.baseLow | (desc.baseHigh << 24);
+ Addr limit = desc.limitLow | (desc.limitHigh << 16);
if (desc.g)
limit = (limit << 12) | mask(12);
+ SegBaseDest = base;
+ SegLimitDest = limit;
+ SegAttrDest = attr;
}
- SegBaseDest = base;
- SegLimitDest = limit;
- SegAttrDest = attr;
'''
}};