Notes

Do not read codes but patch binary.

musl code reading ( 0. 概略編 )

xv6のuserland側を拡張しようと、最近musl(https://www.musl-libc.org/)のsourceを読んでいて、なかなか美しいので、備忘録的に何回かに分けてlogを残しておく。

先ず、musl自体なんだけど、軽量glibcの一種で,特徴として

1.単一のshared libraryになる.

->glibcやbionicだとlibc.soの他に,ld.so,libm.so...に分割され、必要に応じてdlopen()されるが、muslの場合,libc.soに纏めてくれる。   なお、静的linkも可能な様で、その場合は、単一にするメリットもないので、数個生成される.

2.docker向けcontainerのalpine linuxで採用.

->alpine imageのcontainer上でbuildして簡単にhack

3.source code量が少ない.

->buildが速い.

つまりsource code readingには良い教材という意味.

自分は以下の様なcycleでやってる。

  1. sourceのclone

  2. docker run --privileged -v /source_full_path:/root -it alpine /bin/sh  (host側にsourceを残し,container上にbind mount)

  3. apk add gcc make (必要library install)

  4. cd ./root && make (muslをbuild)

  5. /root/lib/libc.so 実行file名(e.g. a.out) (buildしたmuslのlibc.soでprogramをexec)

  6. (libraryまたはprogramをhost側で任意に変更し,4 or 5に戻る)

5の共有libraryを直接実行することにより,defaultのmuslではなく,buildしたmuslで引数で与えたprogramの実行が可能.また、組み込みcommand(e.g. /bin/ls)もmuslを利用しているので、実行fileはそれらでもよし. 共有libraryの直接実行は,通常実行と一部sequenceが異なるが,便利なdebug optionもある(glibcのものよりは少なめ).詳しくは、 /root/lib/libc.so --helpを参照して下さい.

基本,読者が一緒にdebugしてくれながら読むことを想定して書きます.

とはいっても、あまり真面目に連載するつもりはないのだけれど..

libcは、細かいネタの集合と見えがち(sys/..を除いたheaderだけでも117個)なので,入り口の使い方から入るのではなく、 src以下のdir(https://github.com/bminor/musl/tree/master/src)42個(でもまだ多いのだけれど..),或いはsystem callを見出しにして、なんとなくまとめていくつもり.

とりあえずsrc/から書くべしテーマを推察してみる. majorどころだと,

  • ldso/(start up routine , dynamic linkのお話)
  • malloc/(別mallocとの比較/performance分析)
  • thread/(tlsとかthread_attrとかfutexとか)
  • signal/(あまり知られてない諸々細かいこと)
  • ipc/(kernel実装と絡めたお話)

その他だと、今の自分の知識だと、こんなの知ってる!?的な投稿になってしまいがちなのだが、できるだけ統合的に書くつもり. なお、投稿はあくまで自分の備忘録(勉強log)なので、読者の理解に最適化されているかはあまり考えてません.