プログラムがメモリにロードされ、実行される方法を理解するための実践演習
質問
実行可能ファイルをメモリにロードする、共有ライブラリの動的ロードなど、main()が呼び出される前に起こったことに興味があります。これらのことを実践的な演習で理解する方法について提案はありますか?
私が知っているツールと現在使用しているツールには、次のものが含まれます。
- strace
- 逆アセンブル
- readelf
- / proc / pid / map
注:すばらしい本リンカーとローダーは知っていますが、エクササイズについては、本を読むよりも教えてくれるかもしれません。
解決
- ld.so manページドキュメント動的リンクプロセスを微調整するか、追加の詳細を提供するために設定できるいくつかの環境変数。
e.g。
LD_DEBUG=all cat </dev/null
- Linuxカーネル、ダイナミックリンカー、Cライブラリ、スタートアップコード(crt0.oなど)の各部分のソースコードを簡単に取得できます。コードを調べて実験的な変更を加えることから始めることができます。
他のヒント
バイナリのパック方法とそのさまざまなセクションを確認する場合は、 objdump 。
実行可能ファイルを選択して実行:
objdump -S <executable> > myfile.S
もう1つの良いエクササイズは次のとおりです。
- 外部ライブラリを使用するプログラムを作成します
- 静的リンクを使用してプログラムをコンパイルします
- プログラムを実行します
- ライブラリファイルの名前を変更し、プログラムが実行されるかどうかを確認します
- 共有ライブラリを使用してプログラムをコンパイルする
- ライブラリの名前を変更し、プログラムが実行されるかどうかを確認します
これは、カーテンの下で何が起こっているのか、どのように起こっているのかについてのあなたの質問のいくつかに答えます。
2つの興味深い関連リンク(少なくともLinuxの場合)と、言及されている本(リンカーとローダー)よりも少し短いリンクが見つかりました
大学でOSクラスを受講したとき、 Nachos を使用しました。これはオペレーティングシステムそれ自体ではなく、一種のオペレーティングシステム「シミュレーション」です。ユーザー空間で実行されます。それはC ++で書かれており、Nachosがロードして実行できる実行可能ファイルをクロスコンパイルできます。コードをいじって、システムコールインターフェースを試して、一般的な実験をすることができます。
私たちはSolarisラボでそれを実行しましたが、個人用マシンのLinuxでそれを立ち上げて実行するのに苦労しましたが、コードを掘り下げてみるのは楽しいおもちゃかもしれません。
私は、あなたが探しているものにはおそらく多くのことを知っていますが、独自のアセンブラとリンカを書くことは非常に教育的です。私は大学にいたときにそれをし、それを愛していました。私がやりたいと思っていた基本的なことを実現するために、それを思い出すと、おそらく120時間の作業を要しました。このプロジェクトは他の何よりも、プログラミングのキャリアが自分のためであることを確信させたと思います。