web-dev-qa-db-ja.com

snipersimの構築中にエラーが発生しました:「共有オブジェクトの作成時に、 `.rodata.str1.1 'に対する再配置R_X86_64_32Sは使用できません。-fPICで再コンパイルしてください"

Snipersimはあまり典型的な「プロジェクト」ではないことは知っていますが、これは他の何よりもLinux /リンクの問題であるため、ここにあると思います。開発者にも連絡を取りましたが、まだ回答がありません。

まず、私がやろうとしていることを簡単に説明するために:

私の修士論文では、建築シミュレーターsnipersim( http://www.snipersim.org )を使用しています。ローカルマシン(Linux Mint 17.2を実行)にダウンロードしてビルドし、作業を開始しました。すべてが完全に正常に動作します。

数百のシミュレーションを行う必要があり、それぞれに数時間かかるため、x86_64 OpenSUSE13.1マシンでHTCondorを使用して大学のコンピューティングクラスターにアクセスできました。明らかに、私はクラスターへのルートアクセス権を持っていません。

ディストリビューションが異なるため、バイナリを単純にコピーすることはできません(後で試してみましたが、コードの動作が不安定です)。そのため、snipersimを再コンパイルしたいと思いました。

私のコンパイルプロセス

クラスターのアクセスマシン(condor_submitを使用して並列ジョブを送信できる場所)で、snipersimフォークのクローンを作成しました。

SQLite3

必要なライブラリがインストールされているかどうかを確認したところ、libsqlite3が欠落していることに気付きました。これを修正するために、SQLite.org Webサイトからsqlite-autoconf-3090200.tar.gzをダウンロードし、〜/ sqlite(./ configure -prefix =〜/ sqlite)にインストールするように構成し、make && make installを実行しました。

次に、SQLITE_PATH~/sqliteを指すように構成し、LIBRARY_PATHLD_LIBRARY_PATHの両方を~/sqlite/libを指すように構成しました。

ここまでは順調ですね。

(将来の参考のために、はい、SQLite3は-fPICでコンパイルされました)

スナイパー

すべてのライブラリが邪魔にならないので、私は狙撃兵のコンパイルに着手しました。メインディレクトリに移動し、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は、以前にmakeプロセス中にコンパイルされたカスタムライブラリを参照し、-lxedは、Intel PINライブラリ(プロセッサインストルメンテーションに使用)を参照します。

私の考え/私が試したこと

これは驚くべきエラーメッセージです。何らかの理由で、allのコンパイルステップに-fPIC(トリプルチェック)がある場合、standalone.oは位置に依存し、共有オブジェクトにコンパイルできないと述べています。 。繰り返しになりますが、頭に浮かぶ唯一のことは、プルされているライブラリの1つが-fPICなしでコンパイルされているということです。 ldに、プルするすべてのライブラリのリストを出力させる方法はありますか?問題がどこにあるのかを理解できれば、たとえば、手動でコンパイルされたライブラリを取り込むことができるかもしれません。

さらに、自宅のマシンで再配置を確認しました。まったく同じ再配置ldがstandalone.oファイルに(R_X86_64_32S against .rodata.str1.1)について不平を言っていますが、すべて正常に動作します。

SQLite3のカスタムインストール(ホームマシンのパッケージマネージャーを介してインストールした)が原因である可能性があると考えたため、クラスターとまったく同じプロセスでホームマシンにコピーをインストールしてみました。すべてがまだ機能しており、lddを介して、(システムバージョンではなく)実際に自分のコピーに対してリンクしていることを確認しました。

また、2台のマシン間でgcc、g ++、およびldのバージョンを比較しましたが、それらは一致しています。

さらに、私が気付いた奇妙なことが1つあります。ファイル~/sniper/lib/pin_sim.so(Intel 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時間かけて、同様の問題の解決策をWebで探し、それらすべてを試しましたが、役に立ちませんでした。うまくいけば、ここの誰かがいくつかのアイデアを持っていますか?


編集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 [〜#〜]はどういう意味ですか? (「共有」または「静的」のいずれかだと思いますか?)

3
rpinheiro

原因

'-pie'パラメーターはSniperのコンパイルを中断するようです。自宅のマシンに追加しようとしましたが、まったく同じエラーで失敗します。クラスタラインとリンカからそれを削除すると成功します。

ユーザーsiblynxが述べたように、OpenSUSE(少なくともクラスター内の1つ)は、リンク時にPIEを使用するように実行可能ファイルを強制しますが、LinuxMintはそうではありません。


解決

ファイル-fno-pieの$(TARGET)リンカー呼び出しにstandalone/Makefileを追加するだけで、COLLECT_GCC_OPTIONS -pieがオーバーライドされ、すべてが正しく機能しているように見えます。

ldd pin_sim.soはまだ機能しませんが、それはまったく別の問題です。実際、これについては別の質問を投稿するかもしれません。

1
rpinheiro