Qt 5 の未来は明るいブログ

libQt5Core.so が実行可能にならないバグを修正しました

Published: 2015-07-15 / Last modified: 2015-07-16

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 を実行できますね!