当编译器找到静态初始化程序时,它会将其放在特殊部分中。该部分的名称类似于“.CRT $ XCU”。链接器将按节名的字母顺序定位所有节。
当我想实现初始化函数时。为此,我介绍了两个部分:
typedef void(*PVF)();
#pragma data_seg(".CRT$XAA")
PVF _init_begin[] = { 0 };
#pragma data_seg(".CRT$XZZ")
PVF _init_end[] = { 0 };
当链接器正确地对该部分进行排序时,会在_init_begin
和_init_end
之间指向初始化器。
问题是这些部分是使用属性0xC0300040
创建的,即可以进行写/读/执行访问。但是编译器使用属性0x40300040
发出“.CRT $ XCU”部分。这会导致链接器将这些部分放在一起。
我已经尝试使用此pragma定义该部分:
#pragma section(".CRT$XAA",execute,read)
但是这不会在.obj文件中创建任何“.CRT $ XAA”部分。
如何创建包含所需属性的部分?
答案 0 :(得分:0)
typedef int (__cdecl* _PIFV)(void);
#pragma section(".ABC$XAA", long, read)
#pragma section(".ABC$XZZ", long, read)
__declspec(allocate(".ABC$XAA")) _PIFV init_begin = { 0 };
__declspec(allocate(".ABC$XZZ")) _PIFV init_end = { 0 };
不应将初始化程序标记为可执行文件。您只存储指向函数的指针,而不是实际函数。函数指针不需要是可执行的。
请注意,实际的CRT初始化程序部分(int .CRT
)未记录实施细节,可能随时更改。