Opensuse

建構 snipersim 時出錯:“在製作共享對象時無法使用針對 `.rodata.str1.1’ 的重定位 R_X86_64_32S;使用 -fPIC 重新編譯”

  • November 13, 2015

我知道 snipersim 不是一個非常典型的“項目”,但這更像是一個 linux/連結問題,所以我認為它就在這裡。我也聯繫了開發人員,但尚未收到答复。

首先,為了快速解釋我正在嘗試做的事情:

對於我的碩士論文,我使用的是建築模擬器 snipersim ( http://www.snipersim.org )。我將它下載到我的本地機器(執行 Linux Mint 17.2),建構它,然後開始使用它。一切正常。

鑑於我需要進行數百次模擬,每次都需要數小時,因此我獲得了使用 HTCondor 在 x86_64 OpenSUSE 13.1 機器上訪問大學計算集群的權限。顯然,我沒有對集群的 root 訪問權限。

由於它們具有不同的分佈,我不能簡單地複制二進製文件(我後來嘗試了,但程式碼行為不規律),所以我想重新編譯 snipersim。

我的編譯過程

在集群的訪問機器中(您可以使用 condor_submit 送出並行作業),我複製了我的 snipersim 分支。

SQLite3

我檢查了是否安裝了必要的庫,發現缺少 libsqlite3。為了解決這個問題,我從 SQLite.org 網站下載了 sqlite-autoconf-3090200.tar.gz,將其配置為安裝到 ~/sqlite (./configure -prefix=~/sqlite),然後make && make install.

然後我將其配置SQLITE_PATH為指向~/sqlite,以及兩者LIBRARY_PATHLD_LIBRARY_PATH指向~/sqlite/lib

到現在為止還挺好。

(供將來參考,是的,SQLite3 是用 -fPIC 編譯的)

狙擊手

把所有的庫都排除在外,我開始編譯 sniper。切換到主目錄,輸入make. 一切似乎都很好,就像在我的家用機器上一樣。它遍歷所有依賴項、源文件等,然後到達最後一步,即主執行檔的連結sniper。在這裡,它突然出錯,並停止:

[LD    ] lib/sniper
/usr/lib/gcc/x86_64-pc-linux-gnu/4.8.4/../../../../x86_64-pc-linux-gnu/bin/ld: ~/sniper/standalone/../standalone/standalone.o: relocation R_X86_6ldrelocationssnipecompilation4_32S against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
~/sniper/standalone/../standalone/standalone.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:34: recipe for target '~/sniper/standalone/../lib/sniper' failed
make: *** [~/sniper/standalone/../lib/sniper] Error 1

這個錯誤資訊讓我難住了。一切都是用 -fPIC 編譯的,所以這個錯誤一定與一些從外部拉入的庫有關。

此處為連結執行的命令(對於那些從未使用過狙擊手的人)(它實際上使用完整路徑,而不是“~”,但我用“~”替換了那些路徑,因為它們包含大量個人辨識資訊):

g++ -L~/sniper/standalone/../lib -L~/sniper/standalone/../sift -L~/sniper/standalone/../pin_kit/extras/xed-intel64/lib -L~/sqlite/lib -L~/sniper/standalone/../pin_kit/extras/xed2-intel64/lib -o ~/sniper/standalone/../lib/sniper ~/sniper/standalone/../standalone/exceptions.o ~/sniper/standalone/../standalone/standalone.o -lcarbon_sim -lpthread -lsift -lxed -L~/sniper/standalone/../python_kit/intel64/lib -lpython2.7 -lrt -lz -lsqlite3 -lxed -O2 -g -std=c++0x

特別是,參考之前在此過程-lcarbon_sim -sift中編譯的自定義庫,並參考英特爾 PIN 庫(用於處理器檢測)。make``-lxed

我的想法/我嘗試過的

這是一個令人驚訝的錯誤消息。出於某種原因,當所有編譯步驟都具有 -fPIC (我三重檢查)時,它說明standalone.o 是位置相關的並且不能編譯成共享對象。同樣,我想到的唯一一件事是,其中一個庫是在沒有 -fPIC 的情況下編譯的,這不太可能,我一定忽略了一些東西。有什麼方法可以讓 ld 列印它提取的所有庫的列表嗎?例如,如果我能找出問題所在,我也許可以引入一個手動編譯的庫。

此外,我在我的家用機器上檢查了重定位,並且完全相同的重定位 ld 抱怨 ( R_X86_64_32S against .rodata.str1.1) 存在於standalone.o 文件中,但在那裡一切正常。

我認為這可能是由於我自定義安裝了 SQLite3(我通過家庭機器上的包管理器安裝了它),因此我嘗試通過與集群完全相同的過程在家庭機器上安​​裝副本。一切仍然有效,我通過 ldd 確認它實際上鍊接到我的副本(而不是系統版本)。

我還比較了兩台機器之間的 gcc、g++ 和 ld 版本,它們匹配。

此外,我注意到一件奇怪的事情:該文件~/sniper/lib/pin_sim.so(從一些引入英特爾 PIN 庫的狙擊程式碼編譯而來)是一個 64 位動態連結的 ELF 執行檔(如預期的那樣),但在我的家用機器上執行時ldd pin_sim.so只需列印not a dynamic executable它列印所有使用的共享庫。我嘗試從我的電腦複製pin_sim.so到集群,並且 ldd 也無法讀取它。readelf -d pin_sim.so仍然適用於兩台機器。

這很奇怪。當 readelf/objdump 沒有時,我能找到的對 ldd 失敗的唯一參考是在 64 位系統下的 32 位執行檔上呼叫它時。在這種情況下,執行檔和系統都是 64 位的,所以不是這樣。


我完全不知道該怎麼做。我今天花了大約 5 個小時在網上搜尋類似問題的解決方案並嘗試了所有方法,但無濟於事。希望這裡有人有一些想法?


編輯1:兩台機器之間連結器參數的比較

正如 siblynx 所建議的那樣,我使用-v參數在兩台機器上執行 g++ 來嘗試找出呼叫連結器(collect2)時的差異。我稍微清理了它們(僅相關文件名,而不是整個路徑),並刪除了庫目錄(-L):

常用參數:

--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o lib/sniper
crti.o crtn.o
standalone/exceptions.o standalone/standalone.o
-lcarbon_sim -lpthread -lsift -lxed -lpython2.7 -lrt -lz -lsqlite3 -lxed -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc 

我的家用機器獨有的參數(Linux Mint 17.2,狙擊手工作的地方):

--sysroot=/ --build-id -z relro
crt1.o crtbegin.o crtend.o

集群機器獨有的參數(不起作用):

-pie -z now
Scrt1.o crtbeginS.o crtendS.o

在連結方面我不是很了解,但我確實注意到我的家庭設置包括crt1.o crtbegin.o crtend.o,而集群包括Scrt1.o crtbeginS.o crtendS.o(注意額外的“S”)。這些文件究竟做了什麼,文件名中的S是什麼意思?(我假設是“共享”或“靜態”之一?)

原因

‘-pie’ 參數似乎破壞了 Sniper 的編譯。我嘗試將它添加到我的家用機器上,但它失敗並出現完全相同的錯誤。將其從集群行中刪除,連結器成功。

正如使用者 siblynx 所提到的,OpenSUSE(至少是集群中的那個)強制執行檔在連結時使用 PIE,而 Linux Mint 則沒有。


解決方案

只需添加-fno-pie到文件中的 $(TARGET) 連結器呼叫standalone/Makefile即可覆蓋 COLLECT_GCC_OPTIONS-pie並且一切似乎都正常工作。

ldd pin_sim.so仍然不起作用,但這完全是一個不同的問題。實際上,我可能會為此發布一個單獨的問題。

引用自:https://unix.stackexchange.com/questions/242755