互联网科技嵌入式编程

动态库问题

2020-05-01  本文已影响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,点击注册

上一篇 下一篇

猜你喜欢

热点阅读