动态库问题

作者: 罗蓁蓁 | 来源:发表于2020-05-01 12:34 被阅读0次

    问题现象

    源码一样,使用diab工具链编译生成的dl库,可以加载动态库。但是使用gnu工具链编译生成的dl库,可以加载动态库。

    问题修改

    修改dl库里的load.c中的_rtld_load_got_pointer接口和_rtld_load_object接口。

    rtld_load_got_pointer

    修改如下:

    [图片上传失败...(image-b06640-1588307653871)]

    改为:

    [图片上传失败...(image-8fb25b-1588307653872)]

    rtld_load_object

    修改如下:

    [图片上传失败...(image-79ce12-1588307653872)]

    改为:

    [图片上传失败...(image-f040bc-1588307653872)]

    问题分析

    写了一个最简单的c文件:

    [图片上传失败...(image-1948fb-1588307653872)]

    分别使用vx工具链下的gnu和diab,以及linaro下的gnu工具链,以及裝发下自己编译生成的工具链编译生成.o过程文件,并使用objdump反汇编查看。只有vx工具链下的gnu会生成memset接口,如下:

    [图片上传失败...(image-fc5218-1588307653872)]

    而memcpy接口存在于c库,而没有存在于dl中。因此在生成rtp.vxe的时候,会因为找不到该接口,而认为该类似接口存在于动态库中,因为会跳转到PLT表查找该接口执行。而dl库此时还处于加载动态库到内存,并生成GLOBAL_OFFSET_TABLEPROCEDURE_LINKAGE_TABLE的过程中,因此会报错。

    [图片上传失败...(image-f85146-1588307653872)]

    解决方法

    方法1

    把需要gnu自动生成类似memcpy这种赋初值的地方,先不赋初值,而是在之后使用strcpy赋初值,因为,该接口在dl库中会在预处理时被替换为_rtld_strcpy,而gnu自动生成类似memcpy这种赋初值的地方,却不会被替换。

    [图片上传失败...(image-802d83-1588307653872)]

    而这些接口在dl库中是有实现的。

    目前可以确认使用vx的GCC工具链对函数的局部变量(字符串,结构体)赋初值时,会使用memset来处理,而使用其它GNU工具链则是使用普通汇编指令完成变量在栈空间的初始化,不会出现调用C库接口的情况。

    方法2

    在生成dl库以后,使用objcopy对生成的dl进行替换memset为_rtld_memset.

    这种方法更好,命名如下:

    dcore-objcopy-arm --redefine-sym memcpy=_rtld_memcpy --redefine-sym memset=_rtld_memset libdl.a
    

    出差必备

    买火车票、高铁票、机票,订酒店都打9折的出行工具TRIP,点击注册

    相关文章

      网友评论

        本文标题:动态库问题

        本文链接:https://www.haomeiwen.com/subject/tnafghtx.html