Coins Java - Experiment05

インスタンスの構造を調べる

[Coins Java - Experiment]

目的

作業

アドレスを探す

CNIを呼び出すクラスを作る

$ emacs Start.java
--- Start.java
public class Start {
    public static void main(String[] args) {
        nativeMethod();
    }
    public static native void nativeMethod();
}
---
$ gcj -C Start.java

フィールドなどを定義したクラスを作る

$ emacs FieldTest.java
--- FieldTest.java
public class FieldTest {
    public int ifield0;
    public int ifield1;
    public static int sfield;
    public void imethod(){}
    public static void smethod(){}
}
---
$ gcj -C FieldTest.java

ヘッダを生成

$ gcjh Start
$ gcjh FieldTest

CNIで実装(クラスのサイズを取得)

$ emacs natStart.cc
--- natStart.cc
#include <stdio.h>

#include "Start.h"
#include "FieldTest.h"

extern "C" void dumpInstance(size_t size, long *inst);

void Start::nativeMethod (){
  FieldTest *ftest = new FieldTest();
  ftest->ifield0 = 0x01234567;
  ftest->ifield1 = 0x89abcdef;

  dumpInstance(sizeof(FieldTest), (long *)ftest);

  printf("ifield0 at %08x\n", &(ftest->ifield0));
  printf("ifield1 at %08x\n", &(ftest->ifield1));
}

void dumpInstance(size_t size, long *inst) {
  int i;
  printf("Instance Size = %08x\n", size);
  for (i = 0; i < size/sizeof(long); ++i) {
    printf("%08x(+%04x) : %08x\n", &inst[i], i * sizeof(long), inst[i]);
  }
}
---
$ gcc -c natStart.cc

結果

以下のような結果になった。

$ ./a.out
Instance Size = 0000000c
08f14e80(+0000) : 080490a8
08f14e84(+0004) : 01234567
08f14e88(+0008) : 89abcdef
ifield0 at 08f14e84
ifield1 at 08f14e88

ここで、オフセット+0000の内容 0x080490a8 を探してみると

$ nm -C | grep vtable
         U vtable for java::lang::Class
080491a0 D vtable for Start
080490a0 D vtable for FieldTest

と、vtableの先頭アドレスを+8したものになっていた。

以下のようになっている。

考察

以下のような仕様になっていると考えられる

Copyright (C) 2002-2006 s.arakawa