#include "debug.h"
module Mate.ClassPool (
getClassInfo,
+ classLoaded,
getClassFile,
getMethodTable,
getObjectSize,
Nothing -> loadAndInitClass path
Just ci -> return ci
+classLoaded :: B.ByteString -> IO Bool
+classLoaded path = do
+ class_map <- getClassMap
+ return $ M.member path class_map
+
getClassFile :: B.ByteString -> IO (Class Direct)
getClassFile path = do
ci <- getClassInfo path
VirtualMethod Bool MethodInfo | -- for virtual calls
InterfaceMethod Bool MethodInfo | -- for interface calls
InstanceOf B.ByteString | -- class name
+ NewObject B.ByteString | -- class name
StaticField StaticFieldInfo deriving Show
data StaticFieldInfo = StaticFieldInfo {
push eax
forceRegDump
return $ Just (trapaddr, InstanceOf $ buildClassID cls cpidx)
+ emit' (NEW objidx) = do
+ let objname = buildClassID cls objidx
+ trapaddr <- getCurrentOffset
+ -- place something like `push $objsize' instead
+ emit32 (0x9090ffff :: Word32) >> emit8 (0x90 :: Word8)
+ callMalloc
+ -- 0x13371337 is just a placeholder; will be replaced with mtable ptr
+ mov (Disp 0, eax) (0x13371337 :: Word32)
+ return $ Just (trapaddr, NewObject objname)
+
emit' insn = emit insn >> return Nothing
emit :: J.Instruction -> CodeGen e s ()
pop ebx -- length
mov (Disp 0, eax) ebx -- store length at offset 0
push eax -- push ref again
- emit (NEW objidx) = do
- let objname = buildClassID cls objidx
- amount <- liftIO $ getObjectSize objname
- push (amount :: Word32)
- callMalloc
- -- TODO(bernhard): save reference somewhere for GC
- -- set method table pointer
- mtable <- liftIO $ getMethodTable objname
- mov (Disp 0, eax) mtable
+
emit (CHECKCAST _) = nop -- TODO(bernhard): ...
emit ATHROW = -- TODO(bernhard): ...
emit32 (0xffffffff :: Word32)
| VirtualMethodCall Bool
| InterfaceMethodCall Bool
| InstanceOfMiss B.ByteString
+ | NewObjectTrap B.ByteString
| NoKnownTrap String
getTrapType :: TrapMap -> CPtrdiff -> CPtrdiff -> TrapType
(Just (StaticMethod _)) -> StaticMethodCall
(Just (StaticField _)) -> StaticFieldAccess
(Just (InstanceOf cn)) -> InstanceOfMiss cn
+ (Just (NewObject cn)) -> NewObjectTrap cn
(Just _) -> NoKnownTrap "getTrapMap: doesn't happen"
-- maybe we've a hit on the second `from' value
Nothing -> case M.lookup (fromIntegral from2) tmap of
StaticMethodCall -> staticCallHandler eip
StaticFieldAccess -> staticFieldHandler eip
(InstanceOfMiss cn) -> instanceOfMissHandler eip cn
+ (NewObjectTrap cn) -> newObjectHandler eip cn
VirtualMethodCall imm8 -> invokeHandler eax eax esp imm8
InterfaceMethodCall imm8 -> invokeHandler eax ebx esp imm8
NoKnownTrap err ->
return eip
else error "instanceOfMissHandler: something is wrong here. abort.\n"
+newObjectHandler :: CPtrdiff -> B.ByteString -> IO CPtrdiff
+newObjectHandler eip classname = do
+ let push_insn_ptr = intPtrToPtr (fromIntegral eip) :: Ptr CUChar
+ let push_imm_ptr = intPtrToPtr (fromIntegral (eip + 1)) :: Ptr CPtrdiff
+ let mov_imm_ptr = intPtrToPtr (fromIntegral (eip + 16)) :: Ptr CPtrdiff
+ checkMe <- peek mov_imm_ptr
+ if checkMe == 0x13371337
+ then do
+ objsize <- getObjectSize classname
+ mtable <- getMethodTable classname
+ poke push_insn_ptr 0x68 -- push_imm insn
+ poke push_imm_ptr (fromIntegral objsize)
+ poke mov_imm_ptr (fromIntegral mtable)
+ return eip
+ else error "newObjectHandler: something is wrong here. abort.\n"
+
invokeHandler :: CPtrdiff -> CPtrdiff -> CPtrdiff -> Bool -> IO CPtrdiff
invokeHandler method_table table2patch esp imm8 = do
-- table2patch: note, that can be a method-table or a interface-table
--- /dev/null
+package tests;
+
+public class Instance5 {
+ public static void main(String []args) {
+ int i_am_null = 0;
+ if (i_am_null > 0) {
+ new Instance5_notload();
+ System.out.printf("loaded notload stuff o_O\n");
+ } else {
+ System.out.printf("Nothing to do here\n");
+ }
+ }
+}
+
+class Instance5_notload {
+ static {
+ System.out.printf("sup, I'm Instance5_notload\n");
+ }
+}