您好,我有一个链接器脚本,在其中我找到了此代码“ __exidx_start = .;
”,它将标签值设置为位置计数器“ .
”的值。此标签不在同一链接描述文件中的任何地方使用。
在第一行下面有一个类似的标签定义了几行,它的定义方式相同“ __exidx_end = .;
”。
这两个标签是.text
和.rodata
部分的边界,但我不知道如果链接描述文件中没有使用它们,为什么会有人定义这两个标签?
您好,我有一个链接器脚本,在其中我找到了此代码“ __exidx_start = .;
”,它将标签值设置为位置计数器“ .
”的值。此标签不在同一链接描述文件中的任何地方使用。
在第一行下面有一个类似的标签定义了几行,它的定义方式相同“ __exidx_end = .;
”。
这两个标签是.text
和.rodata
部分的边界,但我不知道如果链接描述文件中没有使用它们,为什么会有人定义这两个标签?
这些符号由 GCC 中的调用链展开机制在内部使用,该机制在异常处理阶段进行控制。例如,在 unwind-arm-common.inc:104中有一个示例,其中异常处理表的边界作为指向这些符号的指针获得。
至于.ARM.exidx*
符号所包含的条目,它们形成一个异常处理索引表,它是C++的ARM 异常处理 ABI(在第 4.4.1 节中)的一部分。
@pixelou 回答问题:
这些部分与调试无关,但构成异常展开机制的基础。剥离这些*.exidx*
部分会导致无法清理混乱,迫使程序abort
(完全失败)而不是准确处理堆栈上的无效状态。如果没有这些展开信息,程序的行为就像使用-fno-exceptions
option构建的一样。
它们不在链接描述文件中使用,但它们被声明为外部变量并在 gcc 库中使用。把它们拿出来,这就是发生的事情:
.../gcc/config/arm/unwind-arm.c:614:未定义对 `__exidx_start' 的引用 .../gcc/config/arm/unwind-arm.c:614: 未定义对 `__exidx_end' 的引用