我正在开发可以作为插件加载到另一个程序中的共享库(.so)。该程序包含一组其他库。其中一个库,名为libA.so,导出自己的implements :: operator new()和:: operator delete()。但我不想使用new和delete的这个实现,并使用自己的实现(静态链接到我的库)。一切正常,但libA.so有函数,返回指向已分配内存的指针,我应该通过从libA.so调用operator delete来释放它。所以,我需要来自libA.so的_ZdlPv符号的地址。
我使用函数dlsym获取_ZdlPv的地址:dlsym(RTLD_DEFAULT,“_ ZdlPv”)。我自己的operator delete(_ZdlPv符号)实现在动态符号表中,在我的共享库中不存在,所以我希望得到libA.so中定义的operator delete()的地址。
但是我从dlsym函数得到了完全错误的结果 - 它返回驻留在其他库libB.so中的地址。并且libB.so不包含_ZdlPv符号的定义,但它需要此符号(在该库中未定义)。并且dlsym()返回的地址指向libB.so的.MIPS.stubs部分。看起来这就像PLT(但在MIPS架构上 - 是的,我正在为MIPS开发)。当我用dlsym返回的地址调用函数时 - 线程终止。难以调试......
这是错的吗?为什么dlsym()不适合我?据我所知,$ gp寄存器保存指向“全局链接表”的指针。每个共享库都有自己的链接表?并且从stubs部分调用函数,gp应该有正确的值 - 对吗?当我从其他库(libB.so)的存根部分调用代码时 - 我用不正确的$ gp值调用它,因为这个线程崩溃了?但是为什么dlsym()返回指向其他(libB.so)库的stubs部分中的代码的指针?这是因为我的库的存根部分不包含_ZdlPv符号,因为它不存在于我的库的动态符号表中?
如果我的假设是正确的,我不明白,如何在MIPS平台上使用dlsym()从其他库调用arbitraty函数?