バイナリパッチを当てて

しかし、世の中には暇人というかスゴイ人が居るもんだ。バージョン8.39.4のドライバにバイナリパッチを当てて動かした人がいる。「Patch for fglrx & fc7 64-bit」に詳しく出ている。
私も昔はバイナリパッチで動かないソフトを無理やり動くようにしたことはあるが、かなりの時間と根気を必要とするんだな。それに、このページを見て感心したのでは何とsedを使ってパッチを当てているところだ。昔はadbとかを使っていたが。勉強になった。

さて、Linux(ん)でバイナリパッチを当てたところ見事に動いた。暫く、Linux(あ)ではなくLinux(ん)で運用することにした。(「あ」と「ん」はHDDのパーティションの愛称。)

パッチの方法は上のPhoronix Forumのmmastrac氏が詳しく書いているが、念のためコピーしておく。

# cd /usr/lib64/xorg/modules/drivers/
# mv fglrx_drv.so fglrx_drv.so.orig
# cat fglrx_drv.so.orig | sed "s/\xe8\xb1\x30\xfe\xff/\x90\x90\x90\x90\x90/g" > fglrx_drv.so
# diff fglrx_drv.so fglrx_drv.so.orig (must report that binary files differ)
# aticonfig --initial

call命令を1つnop命令に変えている。
ちょっと調べたら今のLinuxにはojbdumpという逆アセンブル機能をもつコマンドがあった。早々、試してみる。

# objdump -d fglrx_drv.so.00 > /tmp/00
# objdump -d fglrx_drv.so.01 > /tmp/01
# diff /tmp/00 /tmp/01
		:
37900c37900,37904
<    aba3a:     e8 b1 30 fe ff          callq  8eaf0 
    • -
> aba3a: 90 nop > aba3b: 90 nop > aba3c: 90 nop > aba3d: 90 nop > aba3e: 90 nop

どうもmmastrac氏は「atiddxSave64BitBAR」という関数の呼び出しを制限したようである。では、mmastrac氏はどうやってatiddxSave64BitBARの呼び出しを制限すれば動くと断定できたのだろうか?

オリジナル(バイナリパッチを当てていない)ドライバ fglrx_drv.so でXを起動しようとすると途中でXサーバが中断してしまい、/var/log/Xorg.0.logの最後に次のようなログが残る。

Backtrace:
0: /usr/bin/Xorg(xf86SigHandler+0x6d) [0x48b99d]
1: /lib64/libc.so.6 [0x3d87a30630]
2: /usr/lib64/xorg/modules/drivers//fglrx_drv.so(atiddxSave64BitBAR+0x2d) [0x2aaaabedbb4d]
3: /usr/lib64/xorg/modules/drivers//fglrx_drv.so(atiddxProbeMain+0x37f) [0x2aaaabee6a3f]
4: /usr/bin/Xorg(InitOutput+0x6e7) [0x463707]
5: /usr/bin/Xorg(main+0x275) [0x434625]
6: /lib64/libc.so.6(__libc_start_main+0xf4) [0x3d87a1dab4]
7: /usr/bin/Xorg(FontFileCompleteXLFD+0x229) [0x433ad9]

Fatal server error:
Caught signal 11.  Server aborting

fglrx_drv.soのatiddxProbeMain関数の0x37fバイト目からatiddxSave64BitBAR関数が呼び出され、atiddxSave64BitBAR関数の0x2dバイト目の命令を実行してシグナル11、つまりセグメント違反を起こして、/lib64/lic.so.6のシグナルハンドラが呼び出されている、という感じかな。

mmastrac氏がatiddxSave64BitBAR関数呼び出しを丸ごと削ったのは正しいのかどうか分からない。(atiddxSave64BitBAR関数で本来行われるべき機能を実行していない訳だから。)しかし、結果all rightで、今のところは動いているので由とするしかない。

(しかし、ここまで不具合の原因が特定できていのだから、早期に正常に動くドライバがリリースされるのを期待したい。)