2010-04-15 30 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

对我来说,看起来这段代码是创建节,没有得到它们。它从何而来? – 2010-04-15 07:03:25

+0

如果这是部分创建,那么这个新部分中的构造函数是如何放置的?我最初认为这是从编译器放置的传统名称的一部分中提取构造函数。 这是用C++编写的Linux内核驱动程序的一部分。 – Basilevs 2010-04-15 07:13:45

回答

5

这实际上并不是由CPU执行的代码,而是它被添加到目标文件的元数据中。它告诉链接器在存储构造函数的最终可执行文件的同一节(=部分)中创建一些全局变量(上例中为__ctors_begin__)(该节称为.ctors)。为了使它工作,你只需要确保带有“begin”变量的文件首先被链接,带有“end”变量的文件最后被链接(但是也可以用__SECTION_FLAGS来控制它)。这给你你正在寻找的记忆范围。至于“安全”:那么,C++运行时并不神奇。不知何故,它必须知道如何在启动时运行所有构造函数和析构函数,并且不会一直改变。所以对于编译器的主要版本号来说,这应该是非常安全的。此外,你会很快知道它什么时候破的:-)