1

我的 ARM-EABI 工具链和/或 libstdc++ 有问题。

当我编译和链接一个由文件 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在 libsupc++ 中实现,与我们的库链接,但函数未链接到库中。为什么?

如果更改了库中的代码并std::string使用了 a(在 test.cpp 的注释中准备),则该函数__cxa_begin_cleanup将链接到生成的二进制文件并且objdump -T不再显示它们。

这里有一个类似的问题,但是提到的链接器选项--start-group--end-group没有帮助。

任何人都可以帮忙吗?

ARM-EABI 工具链包括: GCC 6.3.0 Binutils 2.27 Newlib 2.4.0

命令行:

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

资源:

测试.cpp

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

int bur_heap_size = 0;

//std::string str1;

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

测试类.cpp

#include "testclass.h"

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

测试类.h

#ifndef TESTCLASS_H_
#define TESTCLASS_H_

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

#endif
4

1 回答 1

1

ELF 标准p. 1-18:

当链接编辑器搜索归档库时,它会提取包含未定义全局符号定义的归档成员。成员的定义可以是全局符号或弱符号。链接编辑器不会提取存档成员来解析未定义的弱符号。未解析的弱符号具有零值。

这意味着对于上面的示例,由于弱声明,不会从库中提取任何对象。但是 std::string 的使用导致了对象的提取,这也满足了使用的弱符号。

要“解决”这个问题,可以使用链接器选项-u symbol

强制符号作为未定义符号输入到输出文件中。例如,这样做可能会触发标准库中附加模块的链接。

于 2017-09-13T10:16:50.090 回答