从linux获取导出函数的名称和地址
我可以使用PIMAGE_DOS_HEADER API(
example)从Windows中的可执行文件中获取导出的函数名称和指针列表.
什么是Linux的等效API? 对于上下文我正在创建单元测试可执行文件,我正在导出以名称“test_”开头的函数,我希望可执行文件只是在运行时旋转并执行所有测试函数. 示例伪代码: int main(int argc,char** argv) { auto run = new_trun(); auto module = dlopen(NULL); auto exports = get_exports(module); // <- how do I do this on unix? for( auto i = 0; i < exports->length; i++) { auto export = exports[i]; if(strncmp("test_",export->name,strlen("test_")) == 0) { tcase_add(run,export->func); } } return trun_run(run); } 编辑: 在使用这个问题的最佳答案后,我能够找到我的样子: 另外,我必须使用Nominal Animal的答案中的gnu_hashtab_symbol_count函数来处理DT_GNU_HASH而不是DT_HASH. 我的最终测试主要功能如下所示: int main(int argc,char** argv) { vector<string> symbols; dl_iterate_phdr(retrieve_symbolnames,&symbols); TRun run; auto handle = dlopen(NULL,RTLD_LOCAL | RTLD_LAZY); for(auto i = symbols.begin(); i != symbols.end(); i++) { auto name = *i; auto func = (testfunc)dlsym(handle,name.c_str()); TCase tcase; tcase.name = string(name); tcase.func = func; run.test_cases.push_back(tcase); } return trun_run(&run); } 然后我在程序集中定义测试,如: // test.h #define START_TEST(name) extern "C" EXPORT TResult test_##name () { #define END_TEST return tresult_success(); } // foo.cc START_TEST(foo_bar) { assert_pending(); } END_TEST 这会产生如下所示的输出: test_foo_bar: pending 1 pending 0 succeeded 1 total 解决方法
要从Linux下的共享库(.so)获取导出符号的列表,有两种方法:简单方法和稍微更难方法.
最简单的方法是使用已经可用的控制台工具:objdump(包含在GNU binutils中): $objdump -T /usr/lib/libid3tag.so.0 00009c15 g DF .text 0000012e Base id3_tag_findframe 00003fac g DF .text 00000053 Base id3_ucs4_utf16duplicate 00008288 g DF .text 000001f2 Base id3_frame_new 00007b73 g DF .text 000003c5 Base id3_compat_fixup ... 稍微更难的方法是使用libelf并编写一个C/C++程序来自己列出符号.看看elfutils包,它也是从libelf源构建的.有一个名为eu-readelf的程序(relflf的elfutils版本,不要与binutils readelf混淆). eu-readelf -s $LIB使用libelf列出导出的符号,因此您应该能够将其用作起点. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |