Таможенное распределение и Boehm GC

В моем проекте компилятора "снова снова выключен" я реализовал замыкания как выделенную память с исполняемым префиксом. Итак, замыкание распределяется так:

c = make_closure(code_ptr, env_size, env_data);

c указатель на блок выделенной памяти, который выглядит так:

movl $closure_call, %eax
call *%eax
.align 4
; size of environment
; environment data
; pointer to closure code

closure_call - это вспомогательная функция, которая просматривает адрес, последний помещенный в стек, и использует его для поиска данных замыкания и указателя кода. Boehm GC используется для общего управления памятью, и когда на закрытие больше нет ссылок, он может быть освобожден GC.

В любом случае эта выделенная память должна быть помечена как исполняемая; фактически целые страницы, которые он охватывает, помечаются. Когда замыкания создаются и освобождаются, все больше и больше памяти в процессе будет исполняемым.

По соображениям защитного программирования я бы предпочел минимизировать количество исполняемой кучи. Мой план состоит в том, чтобы попытаться сохранить все замыкания вместе на одной и той же странице (страницах) и распределять и освобождать исполняемые страницы по мере необходимости; т.е. реализовать пользовательский распределитель для замыканий. (Это проще, если все замыкания имеют одинаковый размер; поэтому первым шагом является перемещение данных среды в отдельное неисполняемое распределение, которым можно нормально управлять. Это также имеет смысл в защитном программировании.)

Но остающаяся проблема - GC. Бем уже делает это! Я хочу как-то сообщить Бему о моих пользовательских распределениях и попросить Бема сообщить мне, когда они могут быть GC'd, но оставить за мной право освободить их.

Поэтому мой вопрос заключается в том, есть ли в Boehm хуки, обеспечивающие пользовательское распределение, подобное этому?

1 ответ

Вы можете делать с финализатором все, что хотите, - Boehm GC по-прежнему освобождает его, но у вас будет возможность заранее зафиксировать закрытие с помощью точек останова (0xCC на x86) и пометить его страницу как неисполняемую, если это возможно.

Тем не менее, финализаторы имеют производительность производительности, поэтому не следует использовать слегка. Boehm GC основан на алгоритме очистки разметки, который сначала идентифицирует все фрагменты, которые не должны быть освобождены (mark.c), а затем освобождает все остальное сразу (reclaim.c). В вашем случае имеет смысл изменить процесс восстановления, чтобы также заполнить все свободное пространство в вашем исполняемом регионе операциями точек останова и пометить страницы как неисполняемые, поскольку они становятся полностью пустыми. Это позволяет избежать финализаторов за счет разветвления библиотеки (я не смог найти какой-либо механизм расширения для этого).

И наконец, обратите внимание, что предотвращение выполнения является мерой глубокой защиты и не должно быть вашей единственной защитой. Возвратно-ориентированное программирование может использоваться для выполнения произвольного кода с использованием неизменяемых исполняемых областей.

Другие вопросы по тегам