4

我想研究如何在没有 libstdc++ 但支持 rtti 的情况下链接 C++ 程序。我尝试按照下面描述的方式编译它。我可以在示例中定义任何必要但不存在的符号,例如函数 strcmp,但是是否可以在没有显式 mangle/demangle 魔术的情况下定义 typeinfo 符号?如果可能的话怎么做?

cd /tmp && cat << 'eof' >rtti.cpp && g++ -nodefaultlibs -lc rtti.cpp

extern "C" int strcmp(const char *s1, const char *s2) { return 0; };
#include "typeinfo"

int main(){
    return typeid(int) == typeid(char);
}

链接器 说:

/tmp/cc6rBAef.o:在函数“main”中:

rtti.cpp:(.text+0x18): undefined reference to `typeinfo for char'
rtti.cpp:(.text+0x1d): undefined reference to `typeinfo for int'
collect2: error: ld returned 1 exit status

那么,如何使用 g++ 或 clang++ 在源文件中定义 'typeinfo of char'(_ZTIc@@CXXABI_1.3) ?

PS。不要问我为什么需要它。只是好奇。

4

2 回答 2

4

由于 RTTI 所需的符号似乎在libstdc++库中,没有它你就不能完全做到。请注意,我通过运行找到了这个

readelf -Ws `g++ -print-file-name=libstdc++.so` | awk '{print $8}' | c++filt | grep 'typeinfo for'

但是,您可以做的是静态链接libstdc++

g++ -static-libstdc++ rtti.cpp

通过这种方式,您将不会有任何动态依赖关系,libstdc++并且只有您实际需要的符号被拉入您的可执行文件。(好吧,目标文件中包含所需符号的所有符号,fundamental_type_info.o在你的例子中,我想。)

于 2013-06-18T12:23:28.577 回答
2

感谢gcc 社区的提示。

答案是:

“gcc 使用一些魔法将 __fundamental_type_info 的析构函数替换为一组 typeinfo 符号”

替换代码放在文件:gcc-4.7.2/gcc/cp/rtti.c, void emit_support_tinfos(void);

rtti.cc:

#include <typeinfo>
namespace __cxxabiv1 {
class __fundamental_type_info:public std::type_info{
public:
     explicit __fundamental_type_info(const char* __n) : std::type_info(_n) { } 
     virtual ~__fundamental_type_info(){}; 
};
}
int main(){
    return typeid(int) == typeid(char);
}

所有基本类型信息都在编译期间插入到目标文件中。

$g++ -c ./rtti.cc;readelf -sW ./rtti.o |c++filt|grep typeinfo|wc -l

$153

所以这个问题得到了回答。

于 2013-06-19T15:07:16.283 回答