带有弱符号的奇怪链接行为(ARM-EABI 展开例程 __cxa_begin_cleanup)
Strange linking behaviour with weak symbols (ARM-EABI unwinding routines __cxa_begin_cleanup)
我的 ARM-EABI 工具链有问题 and/or libstdc++。
当我编译 link 一个由文件组成的简单 C++ 库时
test.cpp、TestClass.cpp、TestClass.h
一些像 __cxa_begin_cleanup
这样的展开支持例程是从库中弱引用的,
objdump -T
显示为
00000000 w D *UND* 00000000 __cxa_begin_cleanup
00000000 w D *UND* 00000000 __cxa_call_unexpected
__cxa_begin_cleanup
是在 libsupc++ 中实现的,我们的库是 linked 的,但是函数没有 linked 到库中。
为什么?
如果更改库中的代码并使用 std::string
(在 test.cpp 中的注释中准备),函数 __cxa_begin_cleanup
将被 link 编辑为生成的二进制文件和 objdump -T
将不再显示它们。
有一个类似的问题 here,但提到的 link 其他选项 --start-group
和 --end-group
没有帮助。
有人能帮忙吗?
ARM-EABI 工具链包括:
海湾合作委员会 6.3.0
二进制实用程序 2.27
新库 2.4.0
命令行:
arm-eabi-gcc.exe test.cpp TestClass.cpp -fPIC -O0 -lstdc++ -lsupc++ -o a.out
来源:
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
#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
参见第 ELF Standard 页。 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.
这意味着对于上面的示例,由于弱声明,不会从库中提取任何对象。但是使用std::string导致提取对象,也满足used weak-Symbols.
为了"solve"这个,可以使用链接器选项-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.
我的 ARM-EABI 工具链有问题 and/or libstdc++。
当我编译 link 一个由文件组成的简单 C++ 库时
test.cpp、TestClass.cpp、TestClass.h
一些像 __cxa_begin_cleanup
这样的展开支持例程是从库中弱引用的,
objdump -T
显示为
00000000 w D *UND* 00000000 __cxa_begin_cleanup
00000000 w D *UND* 00000000 __cxa_call_unexpected
__cxa_begin_cleanup
是在 libsupc++ 中实现的,我们的库是 linked 的,但是函数没有 linked 到库中。
为什么?
如果更改库中的代码并使用 std::string
(在 test.cpp 中的注释中准备),函数 __cxa_begin_cleanup
将被 link 编辑为生成的二进制文件和 objdump -T
将不再显示它们。
有一个类似的问题 here,但提到的 link 其他选项 --start-group
和 --end-group
没有帮助。
有人能帮忙吗?
ARM-EABI 工具链包括: 海湾合作委员会 6.3.0 二进制实用程序 2.27 新库 2.4.0
命令行:
arm-eabi-gcc.exe test.cpp TestClass.cpp -fPIC -O0 -lstdc++ -lsupc++ -o a.out
来源:
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
#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
参见第 ELF Standard 页。 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.
这意味着对于上面的示例,由于弱声明,不会从库中提取任何对象。但是使用std::string导致提取对象,也满足used weak-Symbols.
为了"solve"这个,可以使用链接器选项-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.