什么是Linux实用程序来破坏C ++符号名称?
我有c++filt
命令来去掉一个符号,什么是做相反的工具,并打破了一个符号名称?
如果我想调用dlsym()
一个错误的C ++函数名称,这将是有用的。 我宁愿不要在代码中硬编码名称,因为随着时间的推移,由于新的编译器版本或新的编译器品牌被使用,或者由于编译多个平台,目前可能会改变。
是否有一个程序化的方式来获得代表一个C ++函数在运行时的string,以便代码是独立于编译器? 一种可能的方法是在编译时调用一个实用程序,为正在使用的编译器执行名称修改,并将适当的错位C ++符号名称插入到dlsym()
使用的string中。
这里是最接近我在这个网站上find的解决scheme ,它是通过使用一个固定的C风格的名字来间接地在你想要dlsym()
的库中定义的C ++符号来完成的,但是如果你没有控制权图书馆提供了什么,这不是一个选项。
您可以通过查看您正在查看的.so的符号表来获取所需内容:其他人已经回答了此问题返回共享库符号表 。
但是,如果有太多的符号…可能无法正常工作。
所以这是一个疯狂的想法。 买者自负!
潜在的解决scheme是:
-
使用一个名字创build一个文件,名字是:你想要的名字:void myfunction(){}
-
编译该文件(使用-fPIC和-shared,这是一个dynamic库)
-
在该特定文件上调用dlopen / dlsym
-
遍历符号(应该只有一个想要加上其他常规垃圾,你可以过滤)。 遍历符号是笨拙的,但你可以这样做: 返回一个共享库符号表
-
dlclose()释放它(丢失你的符号存根)
-
用dlopen打开你想要的文件
基本上,你会从你的代码调用编译器,它会创build一个.so你可以看看,得到唯一的价值,然后卸载.so所以你可以加载你想要的。
这很疯狂。
这就是g ++的名字。 你可以在你的程序上实现这些强制规则。
另一个(疯狂的)解决scheme是列出要使用的库中的所有符号(理解格式并不难),将它们全部解压缩,然后在列表中search函数的名称。 这种方法的优点是,demangling更容易,因为有一个函数调用来执行它: abi::__cxa_demangle
,从cxxabi.h头。
名称修改是特定于实现的。
名称修改没有标准,所以最好的办法是find一个编译器来为你做。
名称捣毁
这里有一个表格,可以帮助你,如果你想手动这样做
比首先发布更容易的方法。 写一个如下的C ++程序:
#include <stdlib.h> extern int doit(const char *toto, bool is); int main(int argc, char *argv[]) { exit(doit (argv[0], true)); }
用它来构build
# g++ -S test.cpp
从汇编源程序中提取符号名称
# cat test.s | grep call | grep doit | awk '{print $2}'
你得到:
rcoscali@srjlx0001:/tmp/TestC++$ cat test.s | grep call | grep doit | awk '{print $2}' _Z4doitPKcb rcoscali@srjlx0001:/tmp/TestC++$
_Z4doitPKcb
symbol mangled是_Z4doitPKcb
使用你打算使用的编译器,因为每个编译器都有它自己的名字修改规则(正如之前说过的,从一个编译器到另一个编译器这些规则可能会改变)。
玩的开心 !