Commit 37a1e9d1 authored by Julian Kranz's avatar Julian Kranz

X86 Specification

- Segmentation
parent d1b5879e
# vim:filetype=sml:ts=3:sw=3:expandtab # vim:filetype=sml:ts=3:sw=3:expandtab
export = translate #translateBlock export = translate translateBlock
val t-mode64? = do val t-mode64? = do
mode64 <- query $mode64; mode64 <- query $mode64;
...@@ -2445,3 +2445,26 @@ val translate-bottom-up insn = ...@@ -2445,3 +2445,26 @@ val translate-bottom-up insn =
stack <- query $stack; stack <- query $stack;
return stack return stack
end end
val transInstr = do
ic <- query $ins_count;
update@{tmp=0,ins_count=ic+1};
insn <- decode;
semantics insn
end
val transBlock = do
update@{stack=SEM_NIL,foundJump='0'};
transInstr;
jmp <- query $foundJump;
ic <- query $ins_count;
if jmp or ic>10 then query $stack else transBlock
end
val translateBlock = do
update @{ins_count=0,mode64='1'};
# the type checker is seriously broken when it comes to infinite recursion,
# I cannot as of yet reproduce this bug
update @{ptrsz=0, reg/opcode='000', rm='000', mod='00', vexm='00001', vexv='0000', vexl='0', vexw='0'};
transBlock
end
...@@ -53,7 +53,6 @@ type seg_override = ...@@ -53,7 +53,6 @@ type seg_override =
SEG_DEFAULT SEG_DEFAULT
| SEG_OVERRIDE of register | SEG_OVERRIDE of register
val set-CS = do val set-CS = do
m <- query $mode64; m <- query $mode64;
if m then if m then
...@@ -566,7 +565,7 @@ type opnd = ...@@ -566,7 +565,7 @@ type opnd =
| IMM32 of 32 | IMM32 of 32
| IMM64 of 64 | IMM64 of 64
| REG of register | REG of register
| MEM of {sz:int,psz:int,segment:seg_override,opnd:opnd} | MEM of {sz:int,psz:int,segment:register,opnd:opnd}
| SUM of {a:opnd,b:opnd} | SUM of {a:opnd,b:opnd}
| SCALE of {imm:2,opnd:opnd} | SCALE of {imm:2,opnd:opnd}
...@@ -1871,13 +1870,46 @@ val /7-reg ['11 111 rm:3'] = update @{mod='11', rm=rm} ...@@ -1871,13 +1870,46 @@ val /7-reg ['11 111 rm:3'] = update @{mod='11', rm=rm}
## Decoding the SIB byte ## Decoding the SIB byte
# TODO: this is only for 32bit addressing # TODO: this is only for 32bit addressing
val segmentation-set-for-base base =
let
val override-ss = do
segment <- query $segment;
case segment of
SEG_DEFAULT: update@{segment=SEG_OVERRIDE SS}
| _: return void
end
end
in
do
mode64 <- mode64?;
if not(mode64) then
case base of
REG ESP: override-ss
| REG EBP: override-ss
| _: return void
end
else
return void
end
end
val sib-without-index reg = do val sib-without-index reg = do
mod <- query $mod; mod <- query $mod;
rexb <- query $rexb; rexb <- query $rexb;
case mod of case mod of
'00': imm32 '00': imm32
| '01': return (reg rexb '101') # rBP | '01':
| '10': return (reg rexb '101') # rBP do
rBP <- return (reg rexb '101'); # rBP
segmentation-set-for-base rBP;
return rBP
end
| '10':
do
rBP <- return (reg rexb '101'); # rBP
segmentation-set-for-base rBP;
return rBP
end
end end
end end
...@@ -1892,7 +1924,11 @@ val sib-without-base reg scale index = do ...@@ -1892,7 +1924,11 @@ val sib-without-base reg scale index = do
i <- imm32; i <- imm32;
return (SUM{a=scaled, b=i}) return (SUM{a=scaled, b=i})
end end
| _ : return (SUM{a=scaled, b=reg rexb '101'}) # rBP | _:
do
base <- return (reg rexb '101'); # rBP
return (SUM{a=scaled, b=base})
end
end end
end end
...@@ -1902,14 +1938,26 @@ val sib-with-index-and-base psz reg s i b = do ...@@ -1902,14 +1938,26 @@ val sib-with-index-and-base psz reg s i b = do
rexb <- query $rexb; rexb <- query $rexb;
case i of case i of
'100': '100':
case b of do
'101': sib-without-index reg case b of
| _: return (reg rexb b) '101': sib-without-index reg
end | _:
do
reg-b <- return (reg rexb b);
segmentation-set-for-base reg-b;
return reg-b
end
end
end
| _: | _:
case b of case b of
'101': sib-without-base reg s i '101': sib-without-base reg s i
| _: return (SUM{b=SCALE{imm=s, opnd=reg rexx i}, a=reg rexb b}) | _:
do
base <- return (reg rexb b);
segmentation-set-for-base base;
return (SUM{b=SCALE{imm=s, opnd=reg rexx i}, a=base})
end
end end
end end
end end
...@@ -1932,7 +1980,15 @@ end ...@@ -1932,7 +1980,15 @@ end
val mem op = do val mem op = do
sz <- query $ptrty; sz <- query $ptrty;
psz <- query $ptrsz; psz <- query $ptrsz;
seg <- query $segment; seg <-
do
seg <- query $segment;
case seg of
SEG_DEFAULT: return DS
| SEG_OVERRIDE r: return r
end
end
;
return (MEM {sz=sz,psz=psz,segment=seg,opnd=op}) return (MEM {sz=sz,psz=psz,segment=seg,opnd=op})
end end
...@@ -1970,17 +2026,26 @@ val r/m-without-sib = do ...@@ -1970,17 +2026,26 @@ val r/m-without-sib = do
then mem (SUM{a=REG RIP,b=i}) then mem (SUM{a=REG RIP,b=i})
else mem i else mem i
end end
| _ : mem (addr-reg rexb rm) | _ :
do
base <- return (addr-reg rexb rm);
segmentation-set-for-base base;
mem base
end
end end
| '01': | '01':
do do
i <- imm8; i <- imm8;
mem (SUM{a=addr-reg rexb rm, b=i}) base <- return (addr-reg rexb rm);
segmentation-set-for-base base;
mem (SUM{a=base, b=i})
end end
| '10': | '10':
do do
i <- imm32; i <- imm32;
mem (SUM{a=addr-reg rexb rm, b=i}) base <- return (addr-reg rexb rm);
segmentation-set-for-base base;
mem (SUM{a=base, b=i})
end end
end end
end end
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment