Skip to content

Commit

Permalink
Reverse syscall override return register ordering (#284)
Browse files Browse the repository at this point in the history
When a user overrides a system call on an architecture that supports returning two values from a system call and they provide a context containing the result of the system call in the form

```
empty :> v0 :> v1
```

macaw will perform the register assignment

```
r0 := v1
r1 := v0
```

This change reverses this behavior so that the assignment becomes

```
r0 := v0
r1 := v1
```

This brings the expected ordering of the result context in agreement
with the left-to-right ordering of the argument context:

```
empty :> arg1 :> arg2 :> ...
```
  • Loading branch information
bboston7 authored May 4, 2022
1 parent bbc0b6a commit a5796fc
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
14 changes: 10 additions & 4 deletions macaw-aarch32/src/Data/Macaw/ARM/Arch.hs
Original file line number Diff line number Diff line change
Expand Up @@ -644,8 +644,11 @@ a32InstructionMatcher (ARMDis.Instruction opc operands) =
<*> G.getRegVal (ARMReg.ARMGlobalBV (ASL.knownGlobalRef @"_R6"))
<*> G.getRegVal (ARMReg.ARMGlobalBV (ASL.knownGlobalRef @"_R7"))
res <- G.addExpr =<< evalArchFn sc
G.setRegVal r0 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index0))
G.setRegVal r1 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index1))
-- res is a tuple of form (R1, R0). This is reversed from the
-- user provided return Assignment of empty :> R0 :> R1 because
-- the conversion from Assignment to Tuple reversed the order.
G.setRegVal r1 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index0))
G.setRegVal r0 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index1))

-- Increment the PC; we don't get the normal PC increment from the
-- ASL semantics, since we are intercepting them to just add this statement
Expand Down Expand Up @@ -698,8 +701,11 @@ t32InstructionMatcher (ThumbDis.Instruction opc operands) =
<*> G.getRegVal (ARMReg.ARMGlobalBV (ASL.knownGlobalRef @"_R6"))
<*> G.getRegVal (ARMReg.ARMGlobalBV (ASL.knownGlobalRef @"_R7"))
res <- G.addExpr =<< evalArchFn sc
G.setRegVal r0 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index0))
G.setRegVal r1 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index1))
-- res is a tuple of form (R1, R0). This is reversed from the
-- user provided return Assignment of empty :> R0 :> R1 because
-- the conversion from Assignment to Tuple reversed the order.
G.setRegVal r1 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index0))
G.setRegVal r0 =<< G.addExpr (G.AppExpr (MC.TupleField PC.knownRepr res PL.index1))

-- Increment the PC; we don't get the normal PC increment from the
-- ASL semantics, since we are intercepting them to just add this statement
Expand Down
7 changes: 5 additions & 2 deletions macaw-riscv/src/Data/Macaw/RISCV/Disassemble.hs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,11 @@ disStmt opcode stmt = do
<*> getReg GPR_A6
<*> getReg GPR_A7
res <- evalArchFn ec
setReg GPR_A0 =<< evalApp (MC.TupleField knownRepr res L.index0)
setReg GPR_A1 =<< evalApp (MC.TupleField knownRepr res L.index1)
-- res is a tuple of form (A1, A0). This is reversed from the user
-- provided return Assignment of empty :> A0 :> A1 because the conversion
-- from Assignment to Tuple reversed the order.
setReg GPR_A1 =<< evalApp (MC.TupleField knownRepr res L.index0)
setReg GPR_A0 =<< evalApp (MC.TupleField knownRepr res L.index1)
_ -> return ()
F.traverse_ disAssignStmt (collapseStmt stmt)

Expand Down
7 changes: 5 additions & 2 deletions x86/src/Data/Macaw/X86/Generator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,11 @@ addArchSyscall :: X86Generator st_s ids ()
addArchSyscall = do
sc <- X86Syscall (knownNat @64) <$> getRegValue RAX <*> getRegValue RDI <*> getRegValue RSI <*> getRegValue RDX <*> getRegValue R10 <*> getRegValue R8 <*> getRegValue R9
res <- evalArchFn sc
setReg RAX =<< eval (app (TupleField knownRepr res PL.index0))
setReg RDX =<< eval (app (TupleField knownRepr res PL.index1))
-- res is a tuple of form (RDX, RAX). This is reversed from the user
-- provided return Assignment of empty :> RAX :> RDX because the conversion
-- from Assignment to Tuple reversed the order.
setReg RDX =<< eval (app (TupleField knownRepr res PL.index0))
setReg RAX =<< eval (app (TupleField knownRepr res PL.index1))
addTermStmt FetchAndExecute

-- | execute a primitive instruction.
Expand Down

0 comments on commit a5796fc

Please sign in to comment.