libQt5Core.so が実行可能にならないバグを修正しました
libQt5Core.so の実行結果のバグを修正しました で紹介したとおり、libQt5Core.so は実行可能なのですが、自分でビルドした libQt5Core.so を実行すると以下のエラーになったので色々調べて修正しました。
問題点
$ ./lib/libQt5Core.so ./lib/libQt5Core.so: cannot execute binary file: Exec format error
色々調べる
前回見た、qt_core_boilerplate ですが、ELF_INTERPRETER というマクロが定義されていた場合のみ有効になっています。
そして、このマクロは global.pri の中で以下のとおり指定されます。
if(linux*|hurd*):!cross_compile:!static:!*-armcc* {
QMAKE_LFLAGS += -Wl,-e,qt_core_boilerplate
prog=$$quote(if (/program interpreter: (.*)]/) { print $1; })
DEFINES += ELF_INTERPRETER=\\\"$$system(readelf -l /bin/ls | perl -n -e \'$$prog\')\\\"
}
/bin/ls を readelf でオブジェクトの情報を表示させて、「program interpreter:」の項目を取り出して使っているようですね。
実際同じことを自分の環境でやると以下のようになりました。
$ readelf -l /bin/ls
Elf ファイルタイプは EXEC (実行可能ファイル) です
エントリポイント 0x404cf8
10 個のプログラムヘッダ、始点オフセット 64
プログラムヘッダ:
タイプ オフセット 仮想Addr 物理Addr
ファイルサイズ メモリサイズ フラグ 整列
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x0000000000000230 0x0000000000000230 R E 8
INTERP 0x0000000000000270 0x0000000000400270 0x0000000000400270
0x000000000000001c 0x000000000000001c R 1
[要求されるプログラムインタプリタ: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000001abc8 0x000000000001abc8 R E 200000
LOAD 0x000000000001add8 0x000000000061add8 0x000000000061add8
0x0000000000000840 0x0000000000001570 RW 200000
DYNAMIC 0x000000000001adf0 0x000000000061adf0 0x000000000061adf0
0x0000000000000200 0x0000000000000200 RW 8
NOTE 0x000000000000028c 0x000000000040028c 0x000000000040028c
0x0000000000000020 0x0000000000000020 R 4
GNU_EH_FRAME 0x0000000000017580 0x0000000000417580 0x0000000000417580
0x000000000000072c 0x000000000000072c R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 8
GNU_RELRO 0x000000000001add8 0x000000000061add8 0x000000000061add8
0x0000000000000228 0x0000000000000228 R 1
PAX_FLAGS 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 8
セグメントマッピングへのセクション:
セグメントセクション...
00
01 .interp
02 .interp .note.ABI-tag .hash .gnu.hash .dynsym .gnu.liblist .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .dynstr .gnu.conflict
03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .dynbss .bss
04 .dynamic
05 .note.ABI-tag
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dynamic .got
09
というわけで、「program interpreter:」は「要求されるプログラムインタプリタ:」と訳されてしまっているため、ELF_INTERPRETER は空になってしまいます。
修正する
なんかのコマンドが翻訳されてしまっているせいで予期したとおりの動作をしないことは たまにありますが、自分たちで積極的に直していきましょう。
というわけで、同じように readelf の出力を英語にするようなパッチ fix running libQtCore.so failure を書きました。
不安定な CI のせいでそこそこ採用されるまでに苦労しましたが、無事取り込まれました。
これで安心して libQt5Core.so を実行できますね!