Android N限制共享庫爲PIC

    最近有位同事遇到個問題,他們的模塊提供給產品的共享庫是帶有.text.rel段的,而android N的linker限制共享庫不能有TEXTREL,導致加載失敗。

    首先,該模塊有大量的彙編代碼,即使有編譯開關-fPIC,生成的so仍然帶有TEXTREL。

    其次,linker對so的這個限制只針對API level大於22,本來只需要修改AndroidManifest.xml中的target sdk version就可以解決,但是產品端比較強勢,改不了。

    沒有辦法了,只能針對.text.rel中所有重定位符號,一個個修正,好在不多。

    但是遇到了個問題,有一個重定位符號,是一個段名,源碼大概如此:

.section .rodata
.align 4
pmovmskb_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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章