Я пишу небольшой загрузчик программ для моего языка, потому что я разочаровался в понимании формата ELF (и, делая это, я, в конечном счете, могу понять его лучше). Я mmap файлы в памяти, и смокинг радуется что угодно ..
Я не хочу препятствовать совместному использованию программы, внося в нее какие-либо изменения. Поэтому в итоге я делаю то же самое, что и 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 в регистрах.