@printf "should be: 0x%08x\n" 0x1337
./$< tests/Instance1 | grep mainresult
@printf "should be: 0x%08x 0x%08x\n" 0x55 0x11
+ ./$< tests/Instance2 | grep mainresult
+ @printf "should be: 0x%08x\n" 0x198
%.class: %.java
$(JAVAC) $<
module Mate.ClassPool (
getClassInfo,
getClassFile,
- getFieldAddr
+ getFieldOffset,
+ getStaticFieldAddr
) where
+import Data.Int
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.ByteString.Lazy as B
ci <- getClassInfo path
return $ fromIntegral $ (clStaticMap ci) M.! field
-getFieldOffset :: B.ByteString -> B.ByteString -> IO (CUInt)
+getFieldOffset :: B.ByteString -> B.ByteString -> IO (Int32)
getFieldOffset path field = do
ci <- getClassInfo path
- return $ fromIntegral $ (clFieldMap ci) M.! field
+ return $ (clFieldMap ci) M.! field
-foreign export ccall getFieldAddr :: CUInt -> Ptr () -> IO CUInt
-getFieldAddr :: CUInt -> Ptr () -> IO CUInt
-getFieldAddr from ptr_trapmap = do
+foreign export ccall getStaticFieldAddr :: CUInt -> Ptr () -> IO CUInt
+getStaticFieldAddr :: CUInt -> Ptr () -> IO CUInt
+getStaticFieldAddr from ptr_trapmap = do
trapmap <- ptr2tmap ptr_trapmap
let w32_from = fromIntegral from
let sfi = trapmap M.! w32_from
-- new fields "overwrite" old ones, if they have the same name
let staticmap = (M.fromList sm) `M.union` sc_sm
- let im = zipbase 0 ifields
let sc_im = getsupermap clFieldMap
+ -- TODO(bernhard): not efficient :-(
+ let max_off = if (M.size sc_im) > 0 then maximum $ M.elems sc_im else 0
+ let im = zipbase (max_off + 4) ifields
-- new fields "overwrite" old ones, if they have the same name
let fieldmap = (M.fromList im) `M.union` sc_im
where
(CMethod rc nt) = (constsPool cls) M.! idx
-buildFieldID :: Class Resolved -> Word16 -> StaticFieldInfo
-buildFieldID cls idx = StaticFieldInfo rc (ntName fnt)
+buildStaticFieldID :: Class Resolved -> Word16 -> StaticFieldInfo
+buildStaticFieldID cls idx = StaticFieldInfo rc (ntName fnt)
+ where (CField rc fnt) = (constsPool cls) M.! idx
+
+buildFieldOffset :: Class Resolved -> Word16 -> (B.ByteString, B.ByteString)
+buildFieldOffset cls idx = (thisClass cls, ntName fnt)
where (CField rc fnt) = (constsPool cls) M.! idx
methodGetArgsCount :: Class Resolved -> Word16 -> Word32
pop eax
trapaddr <- getCurrentOffset
mov (Addr 0x00000000) eax -- it's a trap
- return $ Just $ (trapaddr, SFI $ buildFieldID cls cpidx)
+ return $ Just $ (trapaddr, SFI $ buildStaticFieldID cls cpidx)
emit' (GETSTATIC cpidx) = do
trapaddr <- getCurrentOffset
mov eax (Addr 0x00000000) -- it's a trap
push eax
- return $ Just $ (trapaddr, SFI $ buildFieldID cls cpidx)
+ return $ Just $ (trapaddr, SFI $ buildStaticFieldID cls cpidx)
emit' insn = emit insn >> return Nothing
emit :: J.Instruction -> CodeGen e s ()
emit (GETFIELD x) = do
pop eax -- this pointer
- push (Disp (fromIntegral x * 4), eax) -- get field
+ let (cname, fname) = buildFieldOffset cls x
+ let offset = unsafePerformIO $ getFieldOffset cname fname
+ push (Disp (fromIntegral $ offset * 4), eax) -- get field
emit (PUTFIELD x) = do
pop ebx -- value to write
pop eax -- this pointer
- mov (Disp (fromIntegral x * 4), eax) ebx -- set field
+ let (cname, fname) = buildFieldOffset cls x
+ let offset = unsafePerformIO $ getFieldOffset cname fname
+ mov (Disp (fromIntegral $ offset * 4), eax) ebx -- set field
emit IADD = do pop ebx; pop eax; add eax ebx; push eax
emit ISUB = do pop ebx; pop eax; sub eax ebx; push eax
#include <asm/ucontext.h>
unsigned int getMethodEntry(unsigned int, void *, void *);
-unsigned int getFieldAddr(unsigned int, void*);
+unsigned int getStaticFieldAddr(unsigned int, void*);
#define NEW_MAP(prefix) \
void* prefix ## _map = NULL; \
printf("staticfieldtrap: something is wrong here. abort\n");
exit(0);
}
- unsigned int patchme = getFieldAddr(from, trap_map);
+ unsigned int patchme = getStaticFieldAddr(from, trap_map);
printf(" to_patch: 0x%08x\n", (unsigned int) to_patch);
printf("*to_patch: 0x%08x\n", *to_patch);
}
public static int id(int a) {
+ // System.out.printf("0x%08x\n", a);
return a;
}
}
--- /dev/null
+package tests;
+
+public class Instance2 extends Instance1 {
+ public int y;
+
+ public Instance2() {
+ x = 0x66;
+ y = 0x77;
+ }
+
+ public static void main(String []args) {
+ int sum = 0;
+ Instance1 a = new Instance1();
+ Instance2 b = new Instance2();
+ sum += a.x; // 0x55
+ sum += b.x; // 0x66
+ sum += b.y; // 0x77
+ a.x = 0x11; sum += a.x; // 0x11
+ b.x = 0x22; sum += b.x; // 0x22
+ b.y = 0x33; sum += b.y; // 0x33
+ Instance1.id(sum); // 0x198
+ }
+}