src: move files into a Mate package
[mate.git] / Mate.hs
diff --git a/Mate.hs b/Mate.hs
index 60eef34ea8114df6aedfc453f2bd14ea3fb08f30..a8e18e4ff80ae155da1b462f73863b091683b019 100644 (file)
--- a/Mate.hs
+++ b/Mate.hs
@@ -27,10 +27,17 @@ import Foreign.C.Types
 import Harpy
 import Harpy.X86Disassembler
 
+import Mate.Utilities
 
 foreign import ccall "dynamic"
    code_void :: FunPtr (CInt -> IO CInt) -> (CInt -> IO CInt)
 
+foreign import ccall "getaddr"
+  getaddr :: CUInt
+
+foreign import ccall "callertrap"
+  callertrap :: IO ()
+
 
 $(callDecl "callAsWord32" [t|Word32|])
 
@@ -59,21 +66,41 @@ main = do
 
 runstuff :: Ptr Int32 -> B.ByteString -> IO ()
 runstuff env bytecode = do
-          let emittedcode = compile $ codeInstructions $ decodeMethod bytecode
-          (_, Right (entryPtr, disasm)) <- runCodeGen emittedcode env ()
+          let emittedcode = (compile (fromIntegral getaddr)) $ codeInstructions $ decodeMethod bytecode
+          (_, Right ((entryPtr, endOffset), disasm)) <- runCodeGen emittedcode env ()
           printf "entry point: 0x%08x\n" ((fromIntegral $ ptrToIntPtr entryPtr) :: Int)
 
+          
           let entryFuncPtr = ((castPtrToFunPtr entryPtr) :: FunPtr (CInt -> IO CInt))
+          printf "got ptr\n"
           result <- code_void entryFuncPtr (fromIntegral 0x1337)
+          printf "called code_void\n"
           let iresult::Int; iresult = fromIntegral result
-          printf "result: 0x%08x\n" iresult
+          printf "result: 0x%08x\n" iresult -- expecting (2 * 0x1337) + 0x42 = 0x26b0
 
           result2 <- code_void entryFuncPtr (fromIntegral (-0x20))
           let iresult2::Int; iresult2 = fromIntegral result2
-          printf "result: 0x%08x\n" iresult2
+          printf "result: 0x%08x\n" iresult2 -- expecting 0x2
+
+
+          -- s/mov ebx 0x6666/mov eax 0x6666/
+          let patchit = plusPtr entryPtr 0xb
+          poke patchit (0xb8 :: Word8)
+
+          result3 <- code_void entryFuncPtr (fromIntegral 0)
+          let iresult3::Int; iresult3 = fromIntegral result3
+          printf "result: 0x%08x\n" iresult3 -- expecting 0x6666
 
           printf "disasm:\n"
           mapM_ (putStrLn . showAtt) disasm
+
+          printf "patched disasm:\n"
+          Right newdisasm <- disassembleBlock entryPtr endOffset
+          mapM_ (putStrLn . showAtt) $ newdisasm
+
+          let addr :: Int; addr = (fromIntegral getaddr :: Int)
+          printf "getaddr: 0x%08x\n" addr
+
           return ()
 
 
@@ -86,29 +113,31 @@ exitCode = do mov esp ebp
               pop ebp
               ret
 
-compile :: [J.Instruction] -> CodeGen (Ptr Int32) s (Ptr Word8, [Instruction])
-compile insn = do
+compile :: Word32 -> [J.Instruction] -> CodeGen (Ptr Int32) s ((Ptr Word8, Int), [Instruction])
+compile trapaddr insn = do
+  ep <- getEntryPoint
+  let w32_ep = (fromIntegral $ ptrToIntPtr ep) :: Word32
   entryCode
   mapM compile_ins insn
+  push eax
+  calladdr <- getCodeOffset
+  -- '5' is the size of the `call' instruction ( + immediate)
+  let w32_calladdr = 5 + w32_ep + (fromIntegral calladdr) :: Word32
+  call (trapaddr - w32_calladdr)
+  pop eax
   exitCode
   d <- disassemble
-  c <- getEntryPoint
-  return (c,d)
+  end <- getCodeOffset
+  return ((ep,end),d)
 
 compile_ins :: J.Instruction -> CodeGen (Ptr Int32) s ()
 compile_ins (BIPUSH w8) = do mov eax ((fromIntegral w8) :: Word32)
 compile_ins (PUTSTATIC w16) = do add eax (Disp 8, ebp) -- add first argument to %eax
 compile_ins (GETSTATIC w16) = do nop
-compile_ins ICONST_2 = do nop
+compile_ins ICONST_2 = do mov ebx (0x6666 :: Word32) -- patch me!
 compile_ins IMUL = do nop
+  -- mov eax (0 :: Word32)
+  -- jmp eax
 compile_ins RETURN = do nop
 compile_ins _ = do nop
 
--- TODO: actually this function already exists in hs-java-0.3!
-lookupMethod :: B.ByteString -> Class Resolved -> Maybe (Method Resolved)
-lookupMethod name cls = look (classMethods cls)
-  where
-    look [] = Nothing
-    look (f:fs)
-      | methodName f == name = Just f
-      | otherwise  = look fs