Upgrade to Pro — share decks privately, control downloads, hide ads and more …

リンカを作ってみた

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for hotaru hotaru
April 17, 2026
130

 リンカを作ってみた

Avatar for hotaru

hotaru

April 17, 2026

Transcript

  1. ほたるいか 詳細なプロフィール 東京科学大学 学士3年 サイボウズ・ラボユース ‘25 SecHack365 '25 坂井ゼミ セキュリティキャンプ

    2024 全国大会 ハイパーバイザゼミ 2 ハイパーバイザやCコンパイラを作成しています
  2. オブジェクトファイルの中身 8 オブジェクトファイルとは、linkableな方のelf fileである。 elf は executable and linkable formatの略であり、実行可能fileとリンク可能fileの

    2つの形態がある。 executable elf そのままローダに通して、‘./a.out’等で実行可能なelf linkable elf (オブジェクトファイル) Cコードやアセンブリと1対1で対応する型式 Cコードやアセンブリでexternとして外部定義するシンボル(関数/変数)は アドレスを決められずに残ったまま
  3. 外部シンボルの解決方法 10 ※静的リンクの場合 object file object/archive file を読む object fileのセクションのうち

    必要なものをまとめる シンボルをまとめて 未解決シンボルを解決 .textセクション等に relocationを適用 executable elfを 出力する executable elf
  4. object/archive fileを読む 11 標準ライブラリへの対応には、object fileだけでなく、archive fileも読めなければなら ない。 archive fileはUnixのar型式で、object fileをまとめたもの。

    このarchive file内部にobject fileが複数並んでいるので、それを必要に応じて入れる。 archive fileにはどのobject fileになんのシンボルが定義されているか/未定義のまま残さ れているかが書かれている。 このmain.cをコンパイルしたmain.oには printfが未定義 ↓ 標準ライブラリのarchive fileからprintf が定義されているobject fileを探して一緒にリンク
  5. object fileのセクションのうち 必要なものをまとめる 12 object fileには色々なセクションがある .textセクション: プログラムが入る .dataセクション: グローバル変数が入る

    .rodataセクション: read onlyなグローバル変数が入る .bssセクション: 0埋めのグローバル変数が入る .noteセクション: gccのメモ書き等で使われたりする .debugセクション: DWARFが入ってたりする ※より正確にはSHF_ALLOCであるもののみ持って、SHT_NOBITSなら.bss、SHF_EXECINSTRなら.text、 SHF_WRITEなら.data、それ以外を.rodataに入れている 今回は最低限の.text .data .rodata .bss以外すべて捨てる! デバッグ用等で実際にはメモリに乗らないものも多いので、 、 、
  6. .textセクション等にrelocationを適用 14 .textセクションでは機械語が実際に書かれている その際に、関数呼び出し等があるが、object fileの時点で未解決なシンボルに相当する 機械語部分は0埋め(RELA)または情報が置かれている(REL) ここに実際のシンボルのアドレスを入れる シンボルが関数の場合 関数アドレスを入れる シンボルが変数の場合

    変数のアドレスを入れる 絶対アドレスによる呼び出し、PC相対呼び出し等によって入れるべき値が違うため、 object fileのrelocation情報の書かれたセクションからどういう計算をすればいいかを知る .e.g.: R_X86_64_PC32であれば相対32bitなので、 symbol_addr + addend /* offsetのようなもの */ - place_addr で計算される ※今回はRELA対応のみ
  7. executable elfを出力する 15 最後、executableなelfとして出力する elfには最初に実行されるべきentry pointを必要とするが、これは_startシンボルのアドレス とする また、.text .data .rodata

    .bssはそれぞれpage size alignされている必要がある これをしてなかったせいで、.dataと.rodataが一緒のページに配置されてセグフォした
  8. TODO 16 Thread Local Storageへの対応 グローバル変数はプロセスごとにわかれているのみであり、同じプロセス のスレッドは変数を共有してしまう ライブラリではerrno等、スレッドごとに記憶領域を別にしたいものは Thread Local

    Storage(TLS)に入れられている。 CではTLSは通常の変数へのアクセスのように扱われるが、linuxではTLSへ のアクセスはFS セグメントからの相対アドレスで扱われる このため、executable elfでも.dataセクション等とは別の扱いが必要であ り、.tdataセクション等にまとめる必要がある。