Я пишу JIT-компилятор для x86-64, и у меня есть вопрос относительно наилучшей практики для включения констант в машинный код, который я генерирую.
Мой подход пока прост:
VirtualAlloc
или же mmap
VirtualProtect
или же mprotect
(и удалите привилегию записи для безопасности).Когда я генерирую код, я должен включать константы (числовые, строковые), и я не уверен, как лучше всего это сделать. Я имею в виду несколько подходов:
Каков предпочтительный способ пойти по этому поводу?
Многое зависит от того, как вы генерируете свой двоичный код. Если вы используете JIT-ассемблер, который обрабатывает метки и определяет смещения, все довольно просто. Вы можете прикрепить константы в блоке после конца кода, используя относящиеся к ПК ссылки на эти метки, и в итоге получите один блок байтов с кодом и константами (простое управление). Если вы пытаетесь сгенерировать двоичный код на лету, у вас уже есть проблема выяснения, как обрабатывать прямые относительные ссылки на ПК (например, для прямых ветвей). Если вы используете обратное исправление, вам нужно расширить его для поддержки ссылок на ваш блок констант.
Вы можете избежать вычислений относительного смещения для ПК, поместив константы в отдельный блок и передав адрес этого блока в качестве параметра в свой код. Это в значительной степени «Выделите отдельный регион для констант», который вы предлагаете. Вам не нужно знать адрес блока, если вы передаете его в качестве аргумента.