简体   繁体   English

带有弱符号的奇怪链接行为(ARM-EABI展开例程__cxa_begin_cleanup)

[英]Strange linking behaviour with weak symbols (ARM-EABI unwinding routines __cxa_begin_cleanup)

I've got a problem with our ARM-EABI toolchain and/or libstdc++. 我的ARM-EABI工具链和/或libstdc ++有问题。

When I compile and link a simple C++ library consisting of the files test.cpp, TestClass.cpp, TestClass.h some unwinding support routines like __cxa_begin_cleanup are weak-referenced from the library, objdump -T showing them as 当我编译并链接由文件test.cpp,TestClass.cpp,TestClass.h组成的简单C ++库时,库中弱引用了诸如__cxa_begin_cleanup类的一些放松支持例程, objdump -T将它们显示为

00000000  w   D  *UND*  00000000 __cxa_begin_cleanup
00000000  w   D  *UND*  00000000 __cxa_call_unexpected

__cxa_begin_cleanup is implemented in libsupc++, which our library is linked with, but the function is not linked into the library. __cxa_begin_cleanup是在libsupc ++中实现的,该库与我们的库链接在一起,但该函数未链接到该库中。 Why? 为什么?

If the code from the library is changed and a std::string is used (prepared in comments in test.cpp), the function __cxa_begin_cleanup will be linked to the resulting binary and objdump -T won't show them anymore. 如果更改了库中的代码,并使用了std::string (在test.cpp的注释中准备),则函数__cxa_begin_cleanup将链接到生成的二进制文件,而objdump -T将不再显示它们。

There is a similar issue here , but the mentioned linker options --start-group and --end-group didn't help. 有一个类似的问题在这里 ,但提到的连接选项--start-group--end-group没有帮助。

Can anyone help? 有人可以帮忙吗?

The ARM-EABI toolchain consists of: GCC 6.3.0 Binutils 2.27 Newlib 2.4.0 ARM-EABI工具链包括:GCC 6.3.0 Binutils 2.27 Newlib 2.4.0

Commandline: 命令行:

arm-eabi-gcc.exe test.cpp TestClass.cpp -fPIC -O0 -lstdc++ -lsupc++ -o a.out

Source: 资源:

test.cpp 测试文件

#include <string>
#include "testclass.h"

int bur_heap_size = 0;

//std::string str1;

int fun ()
{
   TestClass obj1;
//   str1 = "blabla";
   return 0;
}

TestClass.cpp TestClass.cpp

#include "testclass.h"

TestClass::TestClass(){    public_member = 1;}
TestClass::~TestClass(){}
int TestClass::PublicMethodGetPublicMember(){    return public_member;}

TestClass.h 测试类

#ifndef TESTCLASS_H_
#define TESTCLASS_H_

class TestClass
{
    public:
    TestClass();
    ~TestClass();
    int PublicMethodGetPublicMember();
    public:
    int public_member;
};

#endif

See ELF Standard p. 参见ELF标准 p。 1-18: 1-18:

When the link editor searches archive libraries, it extracts archive members that contain definitions of undefined global symbols. 链接编辑器搜索存档库时,它将提取包含未定义全局符号定义的存档成员。 The member's definition may be either a global or a weak symbol. 成员的定义可以是全局符号或弱符号。 The link editor does not extract archive members to resolve undefined weak symbols. 链接编辑器不会提取存档成员来解析未定义的弱符号。 Unresolved weak symbols have a zero value. 未解析的弱符号的值为零。

This means for the example above, no object will be extracted from the library, because of the weak-declaration. 这意味着对于上面的示例,由于弱声明,因此不会从库中提取任何对象。 But the usage of std::string leads to the extraction of the object, which also satisfies the used weak-Symbols. 但是std :: string的使用导致对象的提取,这也满足使用的弱符号。

To "solve" this, it is possible to use the linker option -u symbol : 要“解决”此问题,可以使用链接器选项-u symbol

Force symbol to be entered in the output file as an undefined symbol. 强制将符号作为未定义符号输入到输出文件中。 Doing this may, for example, trigger linking of additional modules from standard libraries. 这样做可能会例如触发来自标准库的其他模块的链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM