win64. как вызвать виртуальный метод? (Решено)

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

win64. как вызвать виртуальный метод? (Решено)

Сообщение zub » 21.11.2011 08:48:55

Знаю адрес VMT и смещение в нем нужного метода object`а. Нужно его вызвать, под вин32, лин32, лин64 работала следующая конструкция:
Код: Выделить всё
SimpleProcOfObj=procedure of object;
tm:tmethod;
....
tm.Data:=obj{указатель на нужный object};
tm.Code:=ppointer(GDBPlatformint(PVMT{указатель на VMT})+GDBPlatformint(MetodAddr{смещение метода в VMT}))^;
SimpleProcOfObj(tm);

Метод без параметров. Нужно для реализации паскалеподобного скрипта, поэтому напрямую вызывать не катит

update:

возможно дело в неправильном вызове конструктора, он тоже вызывается из скрипта:
под вин64 насколько понял надо так:
Код: Выделить всё
mov rcx,[obj]{указатель на выделенную под object память}]
mov rdx,[p]{указатель на VMT}]
call tm.Code{в tm.Code лежит адрес конструктора} 

под лин64 работало так:
Код: Выделить всё
mov rdi,[obj]
mov rsi,[p]
call tm.Code
Последний раз редактировалось zub 21.11.2011 21:12:14, всего редактировалось 3 раз(а).
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: win64. как вызвать виртуальный метод?

Сообщение Sergei I. Gorelkin » 21.11.2011 10:21:20

Если считать ассемблерный код для Linux правильным, то в виндовом коде rcx и rdx перепутаны местами.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: win64. как вызвать виртуальный метод?

Сообщение zub » 21.11.2011 10:32:31

вроде заработало если адрес метода считать со смещением 12
Код: Выделить всё
tm.Code:=ppointer(GDBPlatformint(self.PVMT)+GDBPlatformint(pmd^.MetodAddr)+12)^;

что это за смещение? и почему не кратно 8?

Если считать ассемблерный код для Linux правильным, то в виндовом коде rcx и rdx перепутаны местами.

в линуксе всё работало нормально. вроде не перепутал, ориентируюсь на тестовый код генерируемый FPC приведеный на скрине (a.init - конструктор, a.a - виртуальный метод)
строка callq *0x18(%rax) как будет выглядеть в интеловском синтаксисе?

надо было тему назвать "как вызвать виртуальный метод через задний проход?" :lol:
У вас нет необходимых прав для просмотра вложений в этом сообщении.
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: win64. как вызвать виртуальный метод?

Сообщение Sergei I. Gorelkin » 21.11.2011 10:58:10

zub писал(а):что это за смещение? и почему не кратно 8?

Вообще в теории TObject.ClassType указывает на структуру TVmt (из rtl/inc/objpash.inc), после которой находятся указатели на виртуальные методы. А уж как вы у себя вычисляете MethodAddr, это не ко мне вопрос :)

upd: А, тут вообще речь не о классах, а об object'ах...

zub писал(а):в линуксе всё работало нормально. вроде не перепутал, ориентируюсь на тестовый код генерируемый FPC приведеный на скрине

Да, в Linux первый параметр таки в rdi. Это я ступил, каюсь.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1406
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: win64. как вызвать виртуальный метод?

Сообщение zub » 21.11.2011 11:14:24

указатель на VMT получаю
Код: Выделить всё
pvmt:=TypeOf(ТипОбъекта)

Номер виртуального метода в VMT получаю парсеньем исходников

Добавлено спустя 10 часов 10 минут 11 секунд:
Re: win64. как вызвать виртуальный метод? (Решено)
Дошло откуда взялось это 12
Вообще в теории TObject.ClassType указывает на структуру TVmt

у обжектов есть свой аналог TVmt, состоящий из 3х указателей (почемуто не нашел где он описан). на 32 разрядах методы начинались с смещения 12, на 64 соответственно с 24. вот это тридцатидвух разрядное смещение было учтено в дебрях исходников, а на 64 работало только еще добавив 12. Зато осталось загадкой как это работало на лин64))

Где описано TVmt для обжектов?
Можно ли какнибудь изловчиться вызвать конструктор без асм вставок?
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru