gpt4 book ai didi

c++ - 全局构造函数调用不在 .init_array 部分

转载 作者:可可西里 更新时间:2023-11-01 16:25:30 46 4
gpt4 key购买 nike

我正在尝试在嵌入式目标 (ARM Cortex-M3) 上添加全局构造函数支持。假设我有以下代码:

class foobar
{
int i;

public:
foobar()
{
i = 100;
}

void inc()
{
i++;
}
};

foobar foo;

int main()
{
foo.inc();
for (;;);
}

我是这样编译的:

arm-none-eabi-g++ -O0 -gdwarf-2 -mcpu=cortex-m3 -mthumb -c foo.cpp -o foo.o

当我使用 objdump 查看 .init_array 部分时,它显示 .init_section 的大小为零。

我确实得到了一个名为 _Z41__static_initialization_and_destruction_0ii 的符号。当我反汇编目标文件时,我看到全局构造是在 static_initialization_and_destruction 符号中完成的。

为什么在 .init_section 中这个符号没有添加指针?

最佳答案

我知道这个问题被问到已经快两年了,但我只需要自己弄清楚 GCC 裸机 C++ 初始化的机制,所以我想在这里分享细节。事实证明,网络上有很多过时或令人困惑的信息。例如,经常提到的 collect2 包装器似乎没有用于 ARM ELF 目标,因为它的任意部分支持支持下面描述的方法。

首先,当我使用 Sourcery CodeBench Lite 2012.09-63 通过给定的命令行编译上面的代码时,我确实看到了正确的 .init_array 部分大小为 4:

$ arm-none-eabi-objdump -h foo.o

foo.o: file format elf32-littlearm

Sections:
Idx Name Size VMA LMA File off Algn
...
13 .init_array 00000004 00000000 00000000 0000010c 2**2
CONTENTS, ALLOC, LOAD, RELOC, DATA
...

当我查看部分内容时,它只包含 0:

$ arm-none-eabi-objdump -j .init_array -s foo.o
Contents of section .init_array:
0000 00000000 ....

但是,还有一个重定位部分将其正确设置为 _GLOBAL__sub_I_foo:

$ arm-none-eabi-objdump -x foo.o
...
RELOCATION RECORDS FOR [.init_array]:
OFFSET TYPE VALUE
00000000 R_ARM_TARGET1 _GLOBAL__sub_I_foo

通常,.init_array 指向您所有的_GLOBAL__sub_I_XXX 初始化器 stub ,每个 stub 调用它自己的_Z41__static_initialization_and_destruction_0ii 拷贝(是的,它是多重定义的),它使用适当的参数调用构造函数。

因为我在构建中使用了 -nostdlib,所以我无法使用 CodeSourcery 的 __libc_init_array 为我执行 .init_array,所以我需要自己调用静态初始化程序:

extern "C"
{
extern void (**__init_array_start)();
extern void (**__init_array_end)();

inline void static_init()
{
for (void (**p)() = __init_array_start; p < __init_array_end; ++p)
(*p)();
}
}

__init_array_start__init_array_end 由链接描述文件定义:

. = ALIGN(4);
.init_array :
{
__init_array_start = .;
KEEP (*(.init_array*))
__init_array_end = .;
}

这种方法似乎适用于 CodeSourcery 交叉编译器和原生 ARM GCC,例如在 Ubuntu 12.10 for ARM 中。支持这两种编译器是使用 -nostdlib 而不是依赖 CodeSourcery CS3 裸机支持的原因之一。

关于c++ - 全局构造函数调用不在 .init_array 部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6343348/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com