Я пишу небольшой загрузчик программ для своего языка, потому что я разочаровался в понимании формата ELF (и, делая это, я, возможно, в конечном итоге пойму его лучше). Я mmap файлы на память и tux радуется чему угодно..
Я не хочу мешать совместному использованию программы, внося в нее какие-либо изменения. Поэтому я делаю то же, что и C и elf: глобальную таблицу смещений.
Проблема в том, как я могу пройти GOT для моей программы?
Первое, что приходит на ум, это указать его в аргументе регистра или стека. В регистре было бы здорово, но x86 отстает по количеству регистров. Это может означать, что я потеряю ebx, ebp или что-то в этом роде. В разумной архитектуре это был бы справедливый компромисс. В x86 он чувствует себя немного неудачно.
Разборка разделяемой библиотеки показывает мне, что gcc делает это как относительную IP-адресацию. Если бы я сделал это, это было бы:
call 0
here:
pop eax
; do something with [eax + (got - here) + index*4]
Хотя отчасти это кажется сложным. Мне не нравится это делать.
Есть еще идеи, кто-нибудь?
Редактировать: При работе с несколькими библиотеками я понял следующее: у меня будет несколько GOT для каждого приложения, и использование определенных GOT зависит от того, в каком фрагменте кода я нахожусь. Поэтому хранение GOT в отдельный регистр потребует некоторых дополнительных уловок, о которых я не знаю. Я хотел бы знать, как они решают эту проблему при сохранении GOT в реестрах.