В общем смысле mprotect
является предпочтительным выбором (в системах, соответствующих POSIX) под sys/mman.h
(отметьте http://linux.die.net/man/2/mprotect).. Просто получите адрес и количество системных страниц исполняемой секции вашего процесса и вызовите mprotect
для запроса разрешений; запись в него; затем снова вызовите mprotect
, чтобы освободить разрешение на запись.
Однако, если это предназначено для низкоуровневых подпрограмм, где скорость имеет абсолютное значение (или mprotect
недоступна), тогда вы захотите скомпилировать библиотеку с ее секцией .text
, доступной для записи как вызывающую mprotect
Скорее всего, возникает сбрасывание Translation Lookaside Buffer (TLB), которое (особенно в многопроцессорной среде) может и станет причиной узкого места. Если конкретная система использует аппаратную защиту с помощью подкачки (что сейчас есть почти у всех), то единственный способ изменить защиту - выполнить сброс TLB, который должен выполняться на каждой странице, на которую ссылаются, на таблицу ссылочных страниц (группу страниц), на которую ссылаются каталог страниц (группа таблиц страниц) и каждый процессор. Чтобы завершить это, это должно быть выполнено в кольце 0, который требует системного вызова, который просто помещает вишню сверху для накладных расходов.
В последнем случае самым простым решением было бы нормально скомпилировать библиотеку, а затем objcopy
с помощью --writable-text
(как упомянуто ggiroux).
Другое решение - определить файл карты компоновщика linker.ld
самостоятельно. Тогда вы можете явно указать разрешения для любого раздела. Это не слишком сложно; если зависит от системы. См. Документацию по http://www.math.utah.edu/docs/info/ld_3.html.. Вы также можете просмотреть предоставленный системой файл linker.ld
и изменить его оттуда. Передача -Wl,--verbose
в gcc заставит компоновщик выложить все соответствующие файлы (включая его по умолчанию linker.ld), в котором вы можете затем изменить разрешения раздела .text и перекомпилировать библиотеку (навсегда), используя новый linker.ld
файл.
Подводя итог, я рекомендую сделать так, как указано в последнем абзаце, и скомпилировать вашу библиотеку с немного измененным сценарием компоновщика.