社長:やはり、MacOSXでもやりたいですね。
開発:焦点は、LD_PRELOAD と同じ機能が MacOSXにあるかなのですが、どうやら DYLD_INSERT_LIBRARIES というのがそれのようです。あと、LD_LIBRARY_PATH でなくて DYLD_LIBRARY_PATH だということは覚えています。
開発:では、さっそくやってみましょう…
基盤:できた!
開発:イキナリできてしまった・・・
社長:まじですか?しかもGoで。
開発:いや正直、そもそも実現性の目星がつくまでに数時間はかかると思っていたのですが、、5分でできてしまいました。あと、DYLD_INSERT_LIBRARIESはこういうふうに書くと、DYLD_LIBRARY_PATHも要らないようです。
社長:めでたいので飲みに行きたい…
* * *
社長:というべきところですが、少し昨日の飲み疲れが残っていまして。このまま続けましょう。何か他のアプリというかコマンドで。
開発:まず ls あたりかと思うんですが、MacOSXにはstraceというのが無いんですね。そういえば確かtruss系だったようにも思うんですが… というか一昨日、XCodeのコマンドのbinがどこかにあるのを知って試しもしたのですが、メモルのを忘れました… 全端末と全ブラウザの表示テキストを全文検索できると良いのですが… あきらめて検索します。
基盤:あれ?このページじゃないですか?Vivaldiのguestユーザで開いてます。
基盤:/Library/Developer/CommandLineTools/usr/bin ですね。
開発:思い出しました。その dyldinfo というのが必要だったんです。ldd みたいなやつ。
基盤:でも他はほとんど /usr/bin にもありますね。ただ、サイズが異様に違うんですが。
開発:まあ、ライブラリを静的にリンクしているか動的にリンクしてるかでしょうね。dyldinfo…
基盤:なるほど… というか、/usr/bin/ld のほうってなんにも入ってないですね。起動用のスクリプトですか?みたいな。
開発:一昨日はタイムスリップの実現性について絶望のフチをさまよいながらやたらと色々やってたんで、何やってたんだかですが、そういえば dtruss だか dtrace だか使えという結論だったように思います。dtrace … 複雑過ぎる… dtruss … sudo が必要なのか。sudo dtruss godate。おお、出た。
基盤:しかし、gettimeofdayの呼び出しは記録されていないですね。
開発:どうもよくわからないですね。うちの欲しいのは、特定の動的ライブラリの特定のシンボルの参照をトレースするということで… てかそれは実行しなくても静的にわかるか。結局ld.so相当のものが MacOSX にあるのかという話しになる。ああ思い出した、それが dyld じゃないかというところで、path になかったから SEE ALSO の dyldinfo に行ったという経緯です。あと、otool といのが objdump の後継でみたいな話しとか…
社長:objdump って昔使ってましたね。今もあるんですか?
開発:objdump… ありますね。ですが、Mach-O x86-64 がどうも、Invalid/Unsupported object file format. とか。
社長:一休みしましょう。
基盤:一休するって、子供とてまりをついたりするやつですかね。
開発:そういえば空気を吹いてでボールを浮かす健康器具、だいぶ前に届いたんですがまだ開けてませんでした。どこにいっちゃいましたかね。
社長:子供の頃よく遊びましたよね。あれって思うに、タバコ代わりにならないですかね?
* * *
開発:それで前読んで何がいいたいのかわからなかった man dyld をもう一度読んだんですが、要するに環境変数 DYLD_PRINT_LIBRARIES と DYLD_PRINT_BINDINGS を定義してやれば、動的リンクをトレースできる、ということでした。
基盤:標準エラー出力に出すって書いてないんですが、書いた人のムラ気ですかね。
開発:で、これを定義して実行してやると、ばっちりどのライブラリがロードされてどうバインドされたかが見えるのでした。
開発:そして残念なこと。/bin/date とか /bin/ls は、dyld で制御されている実行形式ではないようなのです。かといって中身がぜんぶ静的に詰まっているわけでもなく、nm でみると参照は全部 U。dyld_stub_binder というのを呼んで、自分で動的リンクをしているようなのです。
開発:Apple は dyld_stub_binder のソースを公開しています。30step 程度の小さなアセンブラのコードで、86版とARM版が入っています。
社長:うーん、ARM の LDR とか BL 命令がナツカシス。
基盤:というか、DYLDの ARM 版て… MacのプログラムがARMで動くってことですか。
開発:そういえば… だとすると衝撃的ですね。
* * *
開発:xclock dylib をタイムスリップさせようとしてちょっと行き詰まったので、気分を変えて Liunux の cal でやってみました。
社長:ブラボー!
基盤:まあ cal 1 1970 と大差ないでけどね。
開発:ところがどっこい。それだと「今日」を示すハイライトが出ないわけですよ。
開発:まあ、cal 1 1 1970 では出るわけですけど。
社長:まあこれはあくまで動的リンクの使用例のデモ用ですからね。
社長:ていうか今私は、Google IME で分節を広げたり縮めたりするのが Control-O、Control-I だというのに気づいてびっくりしています。これって onew と同じなんです。素晴らしい。
開発:それで、instantTimeSlipperのコマンド型式なんですが。コマンド名は its、時刻設定する引数の型式は date に上位互換、が良いかなと思います。
開発:実装上は、差し替えたgettimeofdayやclock_gettimeで、現時刻からその分のオフセットを足した値を返すのが良いと思います。
開発:課題は、自分で差し替えてしまったオリジナル関数をどう参照するかという点です。
社長:DeleGate でVCのランタイムを差し替えた時には、open を差し替えて _open を呼ぶ、みたいにしてましたね。ソケットのハンドルが、普通のファイルのハンドルと別世界なので、普通のハンドルと同じように見せてストリームI/Oをできるようにするためでした。
開発:それで、標準ライブラリをnmして気づいたのですが、libc もそうなっているようなんです。それで今、クロスリファレンスをみるコマンドってなんだっけと思い出そうとしているのですが…
社長:昔は性能を測定するのに使ってた prof コマンドの機能としてあったような… というかあれはソースからクロスリファレンスを作るやつでしたね。
開発:この、知りたいのはこの __ をシンボル名に前置した版はなんなのかという事ですが…
基盤:洗濯おわりました。結論として、この血痕を落とすのは絶望的です。ズボンには膝に穴もあいちゃったし、捨てるのが吉かと。
社長:しかたがないですね。というか同じズボンの一代目も、階段からころげおちた時に膝に穴があいて終わりました。あのときの膝の出血はひどくて、かさぶたがとれるまでに1ヶ月以上かかりました。
基盤:けっかん商品?
開発:それで、underscore symbol とかで検索すると、シンボル名の前につける _ には色んな意味がある。我々の育った頃にはCかアセンブラか、的な。その後は、非常に様々な定義というか仕様があるようです。
What are the rules about using an underscore in a C++ identifier? [Stackoverflow, 2008]
開発:非常に簡単なサマリーとしては、_ はプライベート、__ はコンパイラが使用する、というものです。
開発:あまりここに深入りしても仕方がないので、我々としては、Linux版ではユーザは標準関数名 func() で呼ぶ、我々は func をラップして、 __func() を呼ぶ、とりあえずこれで行けると想定して進めたいと思います。
社長:そうしましょう。
* * *
開発:Linuxについてはおおむねこれで行けることがわかりました。MacOSXですが、/bin/date などは dyld では制御できない。一方、そのアセンブリファイル(dyld_stub_binder.s)を見てみると、要するにこれを呼んでるだけなんです。
// call dyld::fastBindLazySymbol(loadercache, lazyinfo)
bl __Z21_dyld_fast_stub_entryPvl
開発:で、この関数の仕様がわからないのですが、動的リンクをやってるんだと思います。なので、この関数に、こちらで用意した動的ライブラリを見てもらうにはどうしたらよいか、ということになります。
開発:それと、このあたりを調べていたら、lldb というのが、MacOSXにおける dbx 相当品であることがわかりました。ただ残念ながらセキュリティ上の制約から、/bin/date とかをトレースすることはできないようです。
開発:それと、Appleが公開しているソースプログラムの中に dyld.cpp があること。これも何かに使えそうです。
開発:というようなことで、かなり状況は見えてきた気はします。まあ、gettimeofday は単に糸口だったので、そこそこのところで切り上げて、本質に切り込んで行きたいと思います。
社長:そうですね。ただ、せっかくなのでタイムスリッパはなんかの形で公開しましょう。今日はこのへんで。
-- 2020-0712 SatoxITS