2010-04-15 3 views
1

Может ли кто-нибудь объяснить мне, как работает следующий код?Получение информации о разделе памяти

# if defined(__ELF__) 
# define __SECTION_FLAGS ", \"aw\" , @progbits" 
    /* writable flag needed for ld ".[cd]tors" sections bug workaround) */ 
# elif defined(__COFF__) 
# define __SECTION_FLAGS ", \"dr\"" 
    /* untested, may be writable flag needed */ 
# endif 

asm 
(
    ".section .ctors" __SECTION_FLAGS "\n" 
    ".globl __ctors_begin__\n" 
    "__ctors_begin__:\n" 
    ".previous\n" 
); 
asm /* ld ".[cd]tors" sections bug workaround */ 
(
    ".section .ctors0" __SECTION_FLAGS "\n" 
    ".globl __ctors0_begin__\n" 
    "__ctors0_begin__:\n" 
    ".previous\n" 
); 

Точно так же мы получаем __ctors_end__, __ctors0_end__ и деструкторы место также получают таким образом. После некоторых обходных ошибок ld выполняются все функции, указанные указателями от __ctors_begin__ до __ctors_end__. Я не знаю ассемблера, и этот код для меня невозможно интерпретировать.

ОТВЕТ: Я знаю, что вызов C++-конструкторов/деструкторов из C не является задачей, которую следует считать безопасным или легким.

+0

Мне кажется, этот код создает разделы, а не получает их. От куда это? –

+0

Если это создание раздела, то как конструкторы помещаются в этот новый раздел? Сначала я думал, что это извлечение конструкторов из раздела обычного имени, где они помещаются компилятором. Это часть драйвера ядра Linux, написанная на C++. – Basilevs

ответ

5

Это не код, выполняемый процессором, но он добавлен в метаданные объектных файлов. Он сообщает компоновщику, чтобы создать некоторые глобальные переменные (__ctors_begin__ в примере выше) в том же разделе (= часть) конечного исполняемого файла, где хранятся конструкторы (этот раздел называется .ctors). Чтобы заставить его работать, вам нужно только убедиться, что файл с переменной «begin» связан сначала, а файл с переменной «end» связан последним (но, возможно, вы также можете управлять этим с помощью __SECTION_FLAGS). Это дает вам диапазон памяти, который вы ищете.

Что касается «безопасного»: ну, время выполнения C++ не является магии. Как-то он должен знать, как запускать все конструкторы и деструкторы при запуске, и это не меняется все время. Поэтому для основного номера версии вашего компилятора это должно быть довольно безопасно. Кроме того, вы узнаете довольно скоро, когда он сломается :-)

Смежные вопросы