Замена указателя на JVM в стеке переполнения

Поэтому я решил, что «самый простой» способ ответить мой другой вопрос стоит «просто» взглянуть на реализацию небезопасного в C / C ++.

(

В двух словах, у меня есть Object base и long offset в Java, что я перехожу к C / C ++ с помощью собственного интерфейса Java (JNI), откуда я хочу выполнить эквивалент C / C ++

unsafe.setInt(base,offset,1)

)

Такая реализация предоставляется, например, OpenJDK: unsafe.cpp

Меня больше не волнует, что там, я просто хочу получить прямой доступ к ценностям.

Итак, глядя на реализацию, я вижу

#define SET_FIELD(obj, offset, type_name, x) \
oop p = JNIHandles::resolve(obj); \
*(type_name*)index_oop_from_field_offset_long(p, offset) = x

Что, я надеюсь, делает то, что я ожидаю.

Итак, глядя на inline oop JNIHandles::resolve(jobject handle) в jniHandles.hpp, первая строка переводится как

oop p = (handle == NULL ? (oop)NULL : *(oop*)handle);

Вторая строка — приведение адреса к правильному типу указателя и запись значения, поэтому index_oop_from_field_offset_long(p,offset) должно быть то, что производит адрес. Этот переводится как

if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
return (address)p + (jint) byte_offset;
else
return (address)p +        byte_offset;

где byte_offset == offset,

Объединяя их, я считаю, что это способ получить правильный адрес (который мне придется приводить к нужному типу при чтении / записи):

inline void* get_addr(jobject base, jlong offset){
oop p = (base == NULL ? (oop)NULL : *(oop*)base);
if (sizeof(char*) == sizeof(jint))
return (address)p + (jint) offset;
else
return (address)p +        offset;

}

Отлично, теперь все, что мне нужно знать, это как выбрать oop а также address S.T. адрес правильно создан.

Мне не обязательно заботиться о том, что они есть, мне просто нужно сделать

using oop = SOMETHING_MATCHING_OOP_IN_SIZE;
using address = SOMETHING_ELSE_THAT_MATCHES_ADDRESS;

Но что? Я пролистал файлы, пока не устал от того, что пропустил то, что ищу, и скачал исходные файлы горячей точки (ссылки внизу навигации слева).

grep -r "typedef .* oop" .

выполнено изнутри src папка показывает

./share/vm/memory/classify.hpp:typedef enum oop_type {
./share/vm/oops/oopsHierarchy.hpp:typedef juint narrowOop; // Offset instead of address for an oop within a java object
./share/vm/oops/oopsHierarchy.hpp:typedef class klassOopDesc* wideKlassOop; // to keep SA happy and unhandled oop
./share/vm/oops/oopsHierarchy.hpp:typedef class oopDesc*    oop;

так grep -r ".*class oopDesc.*" .

дает мне

./share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp:class oopDesc;
./share/vm/interpreter/bytecodeInterpreter.hpp:    class oopDesc*   r;
./share/vm/memory/universe.hpp:  friend class oopDesc;
./share/vm/oops/oop.hpp:class oopDesc {
./share/vm/oops/oopsHierarchy.hpp:typedef class oopDesc*    oop;

открытие oop.hpp, мы нашли определение класса из 353 строк, которое я пока не знаю, как перевести на полезную фигуру, тем более, что, по крайней мере, одно из полей может быть или не быть там, в зависимости от #ifndef

Должен быть более простой способ сделать это. Но я не сразу вижу, как. Какие-либо предложения?

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]