Android N限制共享库为PIC

来源:互联网 发布:深圳楼市成交数据 编辑:程序博客网 时间:2024/06/07 05:34

    最近有位同事遇到个问题,他们的模块提供给产品的共享库是带有.text.rel段的,而android N的linker限制共享库不能有TEXTREL,导致加载失败。

    首先,该模块有大量的汇编代码,即使有编译开关-fPIC,生成的so仍然带有TEXTREL。

    其次,linker对so的这个限制只针对API level大于22,本来只需要修改AndroidManifest.xml中的target sdk version就可以解决,但是产品端比较强势,改不了。

    没有办法了,只能针对.text.rel中所有重定位符号,一个个修正,好在不多。

    但是遇到了个问题,有一个重定位符号,是一个段名,源码大概如此:

.section .rodata.align 4pmovmskb_byte:.byte 1,2,4,8,16,32,64,128.byte 1,2,4,8,16,32,64,128....text...movrel      r1, pmovmskb_byte...movrel是自定义宏,定义为:.macro  movrel rd, val        ldr             \rd, =\val.endm

最终利用了开源代码,将movrel修改为相对pc寻址来解决了。


至于原因,在arm官网貌似找到了答案:

https://community.arm.com/tools/f/discussions/532/problem-in-generating-position-independent-code-with-out-textrel


1. 当告诉armasm汇编器,增加pic开关‘--apcs /fpic',合理的情况下,RO sections会标记为PIC,这和C/C++编译器不同,增加'--apcs /fpic'会告诉编译器,必须把RO sections目标代码标记为PIC。汇编器不能增加相对PC来寻址的relocation,但编译器可以。

所以,如果是C/C++与arm指令混合编码,arm指令是否为PIC不受c/c++编译开关-fPIC的影响。

2. 汇编代码中使用了DCD or LDR rx,=等指令,会造成绝对寻址,汇编代码无法再被优化,只能在运行时重定位,所以增加了TEXTREL

原创粉丝点击