Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15662] ファイルの概要

このコミットは、Go言語のリンカ (cmd/ld) におけるMach-O (macOSの実行可能ファイル形式) のセクション生成方法を改善し、内部的なセクション表現との整合性を高めることを目的としています。これにより、Mach-Oバイナリの構造がELF (Linux/Unixの実行可能ファイル形式) の生成方法により近づき、デバッグ情報やランタイムメタデータ(シンボルテーブルやPC-Lineテーブルなど)の格納とアクセスがより標準的かつ効率的になります。特に、非推奨となっていたデバッグセグメントの使用を廃止し、これらを通常のセクションとして扱うように変更されています。

コミット

commit b83d4af330858e819787efbbf6c5267f44d5b654
Author: Russ Cox <rsc@golang.org>
Date:   Sun Mar 10 14:17:04 2013 -0400

    cmd/ld: make mach-o sections match internal sections
    
    This brings Mach-O generation more in line with ELF generation.
    
    Having separate sections for the symtab and pclntab mean that we
    can find them that way, instead of using the deprecated debug segments.
    (And the host linker will keep separate sections for us, but probably
    not the debug segments.)
    
    R=ken2
    CC=golang-dev
    https://golang.org/cl/7688043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/b83d4af330858e819787efbbf6c5267f44d5b654

元コミット内容

cmd/ld: make mach-o sections match internal sections

このコミットは、Mach-Oの生成をELFの生成により近づけます。 symtab (シンボルテーブル) と pclntab (PC-Lineテーブル) を個別のセクションとして持つことで、非推奨のデバッグセグメントを使用する代わりに、そのように見つけることができます。(そして、ホストリンカは個別のセクションを保持しますが、おそらくデバッグセグメントは保持しません。)

変更の背景

Go言語のリンカ (cmd/ld) は、Goプログラムを様々なプラットフォーム向けの実行可能ファイルに変換する役割を担っています。macOS向けの実行可能ファイル形式であるMach-Oは、Linux/Unix向けのELFとは異なる構造を持っています。

このコミット以前は、GoリンカがMach-Oファイルを生成する際に、シンボルテーブル (symtab) やPC-Lineテーブル (pclntab) といった重要なメタデータを、Mach-Oの「デバッグセグメント」と呼ばれる特定の領域に格納していました。しかし、この「デバッグセグメント」はMach-Oの仕様において非推奨(deprecated)とされており、将来的な互換性や、macOSのシステムリンカやデバッガとの連携において問題が生じる可能性がありました。

また、GoリンカはELF形式の生成においては、これらの情報を標準的なセクションとして扱っていました。そのため、Mach-Oの生成においても同様のアプローチを採用することで、リンカの内部ロジックを統一し、コードの複雑性を減らし、保守性を向上させることが期待されました。

この変更の主な背景は以下の点に集約されます。

  1. Mach-Oの非推奨機能からの脱却: 非推奨のデバッグセグメントの使用を避け、より標準的で将来性のあるMach-Oの構造に準拠すること。
  2. ホストリンカとの互換性向上: macOSのシステムリンカやデバッガが、Goが生成するMach-Oバイナリ内のシンボル情報やデバッグ情報をより適切に解釈できるようにすること。標準的なセクションとして情報を提供することで、外部ツールとの連携がスムーズになります。
  3. リンカ内部ロジックの統一: ELF生成とMach-O生成の間で、シンボルテーブルやPC-Lineテーブルの扱いに関するロジックを共通化し、リンカ全体の設計を簡素化すること。

これらの背景から、GoリンカはMach-Oのセクション生成を再設計し、symtabpclntabを通常のセクションとして、適切なセグメント内に配置するように変更されました。

前提知識の解説

このコミットを理解するためには、以下の技術的な概念について理解しておく必要があります。

1. リンカ (Linker)

リンカは、コンパイラによって生成された複数のオブジェクトファイル(機械語コードとデータを含む)やライブラリを結合し、単一の実行可能ファイルやライブラリを生成するプログラムです。リンカの主な役割は以下の通りです。

  • シンボル解決: オブジェクトファイル間で未解決のシンボル(関数名や変数名など)を解決し、それらがメモリ上のどこに配置されるかを決定します。
  • 再配置: オブジェクトファイル内の相対アドレスを、最終的な実行可能ファイル内の絶対アドレスに変換します。
  • セクションの結合: 異なるオブジェクトファイルに存在する同じ種類のセクション(例: コードセクション、データセクション)を結合し、最終的な実行可能ファイルの構造を構築します。

Go言語においては、cmd/ldがGoプログラムのリンカとして機能します。

2. 実行可能ファイル形式 (Executable File Formats)

実行可能ファイルは、プログラムのコードとデータを特定の構造で格納したファイルです。オペレーティングシステムは、この構造を解析してプログラムをメモリにロードし、実行します。主要な実行可能ファイル形式には以下のようなものがあります。

  • ELF (Executable and Linkable Format): Linux、Unix、Androidなどの多くのUnix系システムで広く使用されている標準的な実行可能ファイル形式です。プログラムのコード、データ、シンボル情報、デバッグ情報などがセクションと呼ばれる論理的なブロックに分割されて格納されます。
  • Mach-O (Mach Object): macOS、iOS、watchOS、tvOSなどのApple製オペレーティングシステムで使用されている実行可能ファイル形式です。ELFと同様に、コードやデータをセクションに分割しますが、セクションはさらにセグメントと呼ばれる大きな論理的なグループにまとめられます。Mach-Oは、動的リンキングやメモリ保護などの機能に特化した設計がされています。

3. セクション (Sections) と セグメント (Segments)

実行可能ファイルは、その内容を論理的なブロックに分割して格納します。

  • セクション (Section): 実行可能ファイル内の最も基本的な論理単位です。例えば、.textセクションは実行可能なコードを、.dataセクションは初期化されたデータを、.bssセクションは初期化されていないデータを格納します。デバッグ情報(DWARFなど)も、通常は専用のセクション(例: .debug_info, .debug_line)に格納されます。
  • セグメント (Segment): Mach-Oファイルに特有の概念で、関連する複数のセクションをまとめたものです。セグメントは、メモリ管理ユニット(MMU)によってメモリにロードされる際の単位となります。例えば、__TEXTセグメントは実行可能なコードや読み取り専用データを格納し、__DATAセグメントは読み書き可能なデータを格納します。各セグメントには、そのセグメントがメモリにロードされる際の仮想アドレスやサイズ、ファイル内のオフセットなどが定義されます。

4. シンボルテーブル (Symbol Table: symtab)

シンボルテーブルは、プログラム内のシンボル(関数名、変数名、ラベルなど)とそのアドレスや型などの情報を格納するデータ構造です。リンカはシンボルテーブルを使用して、異なるオブジェクトファイル間でシンボルを解決し、プログラム全体を結合します。デバッガもシンボルテーブルを利用して、ソースコードの変数名や関数名を使ってプログラムの状態を検査します。

5. PC-Lineテーブル (PC-Line Table: pclntab)

PC-Lineテーブルは、Go言語に特有のランタイムメタデータです。プログラムカウンタ(PC)の値と、対応するソースコードのファイル名、行番号、関数名などの情報をマッピングします。これにより、Goランタイムはスタックトレースの生成、プロファイリング、デバッグなどの際に、実行中のコードがソースコードのどの位置に対応するかを特定できます。

6. DWARF (Debugging With Attributed Record Formats)

DWARFは、ソースレベルデバッグを可能にするための標準的なデバッグ情報形式です。コンパイラやリンカによって生成され、実行可能ファイル内の専用セクション(例: .debug_info, .debug_line, .debug_abbrevなど)に格納されます。デバッガはこれらのDWARF情報を解析して、ソースコードの変数、型、関数、行番号などの情報を取得し、ユーザーがソースコードレベルでプログラムをデバッグできるようにします。

7. 非推奨のデバッグセグメント (Deprecated Debug Segments)

Mach-Oには、過去にデバッグ情報を格納するために使用された特定のセグメントやロードコマンドが存在しました。しかし、これらの方法は時代遅れとなり、より柔軟で標準的なDWARF形式のデバッグ情報が推奨されるようになりました。このコミットで言及されている「deprecated debug segments」は、おそらくMach-OのLC_SYMTABロードコマンドやLC_SYMSEGロードコマンドに関連する古いメカニズムを指していると考えられます。これらのロードコマンドは、シンボルテーブルやデバッグセグメントの情報を直接指定するものでしたが、DWARFのようなよりリッチなデバッグ情報形式の登場により、その役割は限定的になりました。

このコミットは、これらの非推奨のメカニズムから脱却し、symtabpclntabといったGo固有のメタデータも、DWARFデバッグ情報と同様に、標準的なセクションとしてMach-Oファイル内に配置するように変更しています。

技術的詳細

このコミットの技術的な詳細は、Goリンカ (cmd/ld) がMach-Oファイルを生成する際の内部構造と、libmach(実行可能ファイルを読み取るためのライブラリ)がその構造を解析する方法に大きな変更を加えている点にあります。

1. Mach-Oセクション生成の汎用化

以前のGoリンカは、Mach-Oファイルを生成する際に、__text__data__bssといった主要なセクションを個別に、かつ比較的ハードコードされた方法で作成していました。また、symtabpclntabといったGo固有のメタデータは、MachoDebug構造体や関連する非推奨のデバッグセグメントメカニズムを通じて扱われていました。

このコミットでは、Mach-Oセクションの生成ロジックが大幅に汎用化されました。

  • machoshbits関数の導入: 新たに導入されたmachoshbits関数は、リンカの内部的なSectionオブジェクトを受け取り、それに対応するMach-OのMachoSectオブジェクトを生成する役割を担います。この関数は、セクションの名前、所属するセグメント名(例: __TEXT__DATA)、アドレス、サイズ、ファイルオフセット、そしてセクションの属性(実行可能かどうか、ゼロフィルかどうかなど)を設定します。
  • asmbmacho関数のリファクタリング: asmbmacho関数は、Mach-Oファイルの全体的な構造を組み立てる主要な関数です。この関数内で、以前は個別にセクションを作成していた部分が、segtext.sect(テキストセグメント内のセクションリスト)とsegdata.sect(データセグメント内のセクションリスト)をイテレートし、それぞれの内部セクションに対してmachoshbitsを呼び出すように変更されました。これにより、リンカの内部表現とMach-Oの出力構造がより密接に連携するようになりました。
  • symtabpclntabのセクション化: symtabpclntabは、もはや特別なデバッグセグメントとして扱われるのではなく、__gosymtab__gopclntabという名前の通常のセクションとして、それぞれ__TEXTセグメント内に配置されるようになりました。これにより、これらの情報も他のコードやデータと同様に、標準的なMach-Oのセクションメカニズムを通じて管理されます。

2. 非推奨のMachoDebug構造体と関連ロジックの削除

コミットメッセージで言及されている「deprecated debug segments」に対応するため、src/cmd/ld/macho.cおよびsrc/cmd/ld/macho.hからMachoDebug構造体、newMachoDebug関数、およびそれらを使用していた関連ロジック(xdebug配列、ndebugカウンタ、machowrite関数内のMachoDebug関連の書き込みループなど)が完全に削除されました。

これにより、GoリンカはMach-Oの古いデバッグ情報メカニズムへの依存を断ち切り、より現代的なDWARFベースのアプローチに一本化されました。DWARFデバッグ情報は、引き続きdwarf.c内のdwarfaddmachoheaders関数によって生成され、__DWARFセグメント内の適切なセクションに格納されます。

3. libmachにおけるMach-O解析の更新

src/libmach/executable.cは、GoのツールチェインがMach-Oファイルを読み取り、その構造を解析するために使用するライブラリです。リンカがMach-Oの生成方法を変更したため、libmachもその新しい構造を正しく解釈できるように更新されました。

  • セクションの動的な探索: 以前は、__text__data__bssといった特定のセクション名を直接参照してサイズなどを取得していましたが、変更後は、__TEXTセグメントや__DATAセグメント内のすべてのセクションをイテレートし、__gosymtab__gopclntabといった新しいセクション名を探すようになりました。これにより、より柔軟なセクション配置に対応できます。
  • セグメント情報からのサイズ取得: textsizedatasizebsssizeの計算方法も変更され、特定のセクションのサイズに依存するのではなく、セグメント全体の仮想サイズやファイルサイズから導出されるようになりました。これは、セクションがセグメント内にどのように配置されても、正確なサイズ情報を取得できるようにするためです。
  • MACH_SYMSEGロードコマンドの扱い: MACH_SYMSEGロードコマンドは、非推奨のデバッグセグメントに関連するものでした。このコミットでは、libmachがこのロードコマンドを処理する際に、symtabpclntabの情報を、ロードコマンド自体からではなく、既に解析されたセクション情報(symoff, symsize, pclnoff, pclnsize)から取得するように変更されました。これは、リンカがこれらの情報を通常のセクションとして出力するようになったことと整合しています。

4. lib.hにおけるシンボルタイプとセクション順序の調整

src/cmd/ld/lib.hでは、リンカが内部的に使用するシンボルタイプ(STYPE)の列挙型が調整されました。SMACHOPLTSMACHOSMACHOGOTといったMach-O固有のシンボルタイプが追加または再配置され、リンカがMach-Oの特定の構造(例: PLT、GOT、間接シンボルテーブル)をより正確に表現できるようになりました。これは、Mach-Oのセクション構造をより詳細に制御するための準備です。

これらの変更により、GoリンカはMach-Oバイナリの生成において、より標準的で堅牢なアプローチを採用し、将来的な互換性とデバッグツールのサポートを向上させています。

コアとなるコードの変更箇所

このコミットにおけるコアとなるコードの変更箇所は、主に以下のファイルに集中しています。

  1. src/cmd/ld/macho.c: Mach-Oファイルの生成ロジックの大部分がここにあります。

    • MachoDebug構造体と関連する関数の削除。
    • newMachoSect関数のシグネチャ変更(segname引数の追加)。
    • machoshbits関数の新規追加。この関数が、リンカの内部セクションをMach-Oセクションにマッピングする中心的な役割を担います。
    • asmbmacho関数の大幅なリファクタリング。特に、__TEXTセグメントと__DATAセグメントの生成部分で、個別のセクション作成ロジックがmachoshbits関数を呼び出す汎用的なループに置き換えられました。
    • symtabpclntabを非推奨のデバッグセグメントとして扱うロジックの削除と、dwarfaddmachoheadersの直接呼び出しへの変更。
  2. src/cmd/ld/macho.h: macho.cで使用される構造体と関数の宣言が含まれます。

    • MachoDebug構造体の削除。
    • MachoSect構造体にsegnameフィールドの追加。
    • newMachoSect関数のシグネチャ変更。
  3. src/cmd/ld/dwarf.c: DWARFデバッグ情報の生成に関連します。

    • newMachoSectの呼び出し箇所で、__DWARFセグメント名を明示的に渡すように変更。これにより、DWARF関連のセクションが適切なセグメントに配置されるようになります。
  4. src/libmach/executable.c: Mach-Oファイルを読み取るためのライブラリです。

    • machdotout関数内で、__TEXTセグメントと__DATAセグメント内のセクションをイテレートし、__gosymtab__gopclntabセクションを探すロジックが追加されました。
    • textsize, datasize, bsssizeの計算ロジックが、セグメントのサイズに基づいてより汎用的に変更されました。
    • MACH_SYMSEGロードコマンドの処理において、symoff, symsize, pclnoff, pclnsizeをセグメント内のセクションから取得するように変更されました。
  5. src/cmd/ld/lib.h: リンカの内部的なシンボルタイプ定義が含まれます。

    • Mach-O固有のシンボルタイプ(SMACHOPLT, SMACHO, SMACHOGOT)の順序と定義が調整されました。

これらの変更は相互に関連しており、GoリンカがMach-Oファイルを生成する際の内部モデルと、その出力形式を根本的に変更しています。

コアとなるコードの解説

ここでは、特に重要な変更点であるsrc/cmd/ld/macho.cmachoshbits関数とasmbmacho関数の変更、およびsrc/libmach/executable.cのMach-O解析ロジックについて詳しく解説します。

src/cmd/ld/macho.c

machoshbits関数の新規追加

static void
machoshbits(MachoSeg *mseg, Section *sect, char *segname)
{
	MachoSect *msect;
	char buf[40];
	char *p;
	
	snprint(buf, sizeof buf, "__%s", sect->name+1);
	for(p=buf; *p; p++)
		if(*p == '.')
			*p = '_';

	msect = newMachoSect(mseg, estrdup(buf), segname);
	
	while(1<<msect->align < sect->align)
		msect->align++;
	msect->addr = sect->vaddr;
	msect->size = sect->len;
	msect->off = sect->seg->fileoff + sect->vaddr - sect->seg->vaddr;
	
	if(sect->vaddr < sect->seg->vaddr + sect->seg->filelen) {
		// data in file
		if(sect->len > sect->seg->vaddr + sect->seg->filelen - sect->vaddr)
			diag("macho cannot represent section %s crossing data and bss", sect->name);
	} else {
		// zero fill
		msect->flag |= 1;
	}

	if(sect->rwx & 1)
		msect->flag |= 0x400; /* has instructions */
	
	if(strcmp(sect->name, ".plt") == 0) {
		msect->name = "__symbol_stub1";
		msect->flag = 0x80000408; /* only instructions, code, symbol stubs */
		msect->res1 = 0;
		msect->res2 = 6;
	}

	if(strcmp(sect->name, ".got") == 0) {
		msect->name = "__nl_symbol_ptr";
		msect->flag = 6;	/* section with nonlazy symbol pointers */
		msect->res1 = lookup(".linkedit.plt", 0)->size / 4;	/* offset into indirect symbol table */
	}
}
  • 目的: リンカの内部表現であるSectionオブジェクトを、Mach-OのMachoSectオブジェクトに変換し、適切な属性を設定します。
  • セクション名の変換: 内部セクション名(例: .text)をMach-Oの慣例に従ったセクション名(例: __text)に変換します。先頭の.__に、途中の._に置き換えています。
  • newMachoSectの呼び出し: MachoSeg(所属するセグメント)、変換されたセクション名、そしてsegname(セグメント名、例: __TEXT)を引数としてnewMachoSectを呼び出し、新しいMach-Oセクションを作成します。
  • アドレス、サイズ、オフセットの設定: 内部セクションの仮想アドレス (vaddr)、長さ (len)、およびファイル内のオフセットをMach-Oセクションにコピーします。
  • フラグの設定:
    • msect->flag |= 1;: セクションがゼロフィル(BSSのような)である場合に設定されます。
    • msect->flag |= 0x400;: セクションが実行可能なコード(命令)を含む場合に設定されます。
  • 特殊なセクションの処理: .plt(Procedure Linkage Table)と.got(Global Offset Table)のような特殊なセクションに対しては、Mach-Oの特定のセクション名(__symbol_stub1__nl_symbol_ptr)とフラグを設定します。これらは動的リンキングにおいて重要な役割を果たします。

asmbmacho関数のリファクタリング

void
asmbmacho(void)
{
	// ... (前略)

	/* text */
	v = rnd(HEADR+segtext.len, INITRND);
	ms = newMachoSeg("__TEXT", 20); // セクション数を2から20に拡張
	ms->vaddr = va;
	ms->vsize = v;
	ms->fileoffset = 0;
	ms->filesize = v;
	ms->prot1 = 7; // 読み取り、書き込み、実行可能
	ms->prot2 = 5; // 読み取り、実行可能

	for(sect=segtext.sect; sect!=nil; sect=sect->next)
		machoshbits(ms, sect, "__TEXT"); // 各テキストセクションに対してmachoshbitsを呼び出し

	/* data */
	w = segdata.len;
	ms = newMachoSeg("__DATA", 20); // セクション数を3から20に拡張
	ms->vaddr = va+v;
	ms->vsize = w;
	ms->fileoffset = v;
	ms->filesize = segdata.filelen;
	ms->prot1 = 3; // 読み取り、書き込み
	ms->prot2 = 3; // 読み取り、書き込み
		
	for(sect=segdata.sect; sect!=nil; sect=sect->next)
		machoshbits(ms, sect, "__DATA"); // 各データセクションに対してmachoshbitsを呼び出し

	// ... (中略)

	if(!debug['s']) // -s フラグが指定されていない場合(シンボル情報を削除しない場合)
		dwarfaddmachoheaders(); // DWARFヘッダを追加
}
  • 汎用的なセクション生成ループ: 以前は__text__data__bss__nl_symbol_ptrなどを個別に作成していましたが、この変更により、segtext.sectsegdata.sectというリンカ内部のセクションリストをループし、それぞれのセクションに対してmachoshbits関数を呼び出すようになりました。これにより、リンカの内部セクション定義に基づいてMach-Oセクションが動的に生成されるため、より柔軟で拡張性の高い構造になりました。
  • セグメントのプロパティ設定: __TEXTセグメントと__DATAセグメントの仮想アドレス、サイズ、ファイルオフセット、保護フラグ(prot1prot2)が設定されます。
  • MachoDebug関連ロジックの削除: symtabpclntabMachoDebugとして扱う古いロジックが削除され、代わりにdwarfaddmachoheaders()が直接呼び出されます。これは、symtabpclntabが通常のセクションとして扱われるようになったため、DWARFデバッグ情報と同様に処理されることを意味します。

src/libmach/executable.c

machdotout関数のMach-O解析ロジックの変更

uvlong textsize, datasize, bsssize;
uchar *cmdbuf;
uchar *cmdp;
int i, j, hdrsize;
uint32 textva, textoff, datava, dataoff, symoff, symsize, pclnoff, pclnsize;

// ... (中略)

for(i=0; i<mp->ncmds; i++) {
	c = (MachCmd*)cmdp;
	switch(leswal(c->cmd)) {
	case MACH_SEGMENT:
		seg32 = (MachSeg32*)c;
		if (strcmp(seg32->segname, "__TEXT") == 0) {
			textva = seg32->vmaddr;
			textoff = seg32->fileoff;
			textsize = seg32->vmsize; // セグメントの仮想サイズを使用
			sect32 = (MachSect32*)(cmdp + sizeof(MachSeg32));
			for(j = 0; j < seg32->nsects; j++, sect32++) {
				if (strcmp(sect32->sectname, "__gosymtab") == 0) {
					symoff = swal(sect32->offset);
					symsize = swal(sect32->size);
				}
				if (strcmp(sect32->sectname, "__gopclntab") == 0) {
					pclnoff = swal(sect32->offset);
					pclnsize = swal(sect32->size);
				}
			}
		}
		if (strcmp(seg32->segname, "__DATA") == 0) {
			datava = seg32->vmaddr;
			dataoff = seg32->fileoff;
			datasize = seg32->filesize; // セグメントのファイルサイズを使用
			bsssize = seg32->vmsize - seg32->filesize; // BSSサイズは仮想サイズとファイルサイズの差
		}
		break;
	case MACH_SYMSEG: // 非推奨のMACH_SYMSEGロードコマンドの処理
		if (symtab == 0) {
			symtab = (MachSymSeg*)c;
			symoff = swal(symtab->fileoff);
			symsize = swal(symtab->filesize);
		} else if (pclntab == 0) {
			pclntab = (MachSymSeg*)c;
			pclnoff = swal(pclntab->fileoff);
			pclnsize = swal(pclntab->filesize);
		}
		break;
	}
	cmdp += c->size;
}

// ... (後略)

if(symoff > 0)
	setsym(fp, symoff, symsize, 0, 0, pclnoff, pclnsize);
  • セクションの動的探索: 以前は特定のセクション名(__text, __data, __bss)を直接参照していましたが、変更後は__TEXTセグメントと__DATAセグメント内のすべてのセクションをループし、__gosymtab__gopclntabという新しいセクション名を探すようになりました。これにより、リンカが生成する新しいセクション構造に柔軟に対応できます。
  • サイズ計算の変更: textsize__TEXTセグメントの仮想サイズ (vmsize) から、datasize__DATAセグメントのファイルサイズ (filesize) から取得されるようになりました。bsssize__DATAセグメントの仮想サイズとファイルサイズの差として計算されます。これは、Mach-Oのセグメントが複数のセクションを含むことができ、BSSセクションがファイル内に存在しない(ゼロフィルされる)という特性を反映しています。
  • MACH_SYMSEGの処理: MACH_SYMSEGロードコマンドは非推奨ですが、既存のバイナリとの互換性のために引き続き処理されます。しかし、このコミットでは、symoff, symsize, pclnoff, pclnsizeの取得元が、このロードコマンド自体からではなく、セグメント内の__gosymtab__gopclntabセクションから取得された値が優先されるように変更されています。これにより、新しいリンカが生成するバイナリでは、セクションベースの情報が使用されることが保証されます。

これらの変更により、GoリンカはMach-Oの生成においてより標準的で堅牢なアプローチを採用し、libmachもその新しい構造を正しく解釈できるようになりました。

関連リンク

  • Go言語のリンカ (cmd/ld): Go言語のビルドプロセスにおける重要なコンポーネントであり、Goプログラムを最終的な実行可能ファイルに変換します。
  • Mach-Oファイル形式: macOSやiOSなどのAppleプラットフォームで使用される実行可能ファイル形式の仕様。
  • ELFファイル形式: LinuxやUnixなどのシステムで広く使用される実行可能ファイル形式の仕様。
  • DWARFデバッグ情報形式: ソースレベルデバッグを可能にするための標準的なデバッグ情報形式。
  • GoのPC-Lineテーブル (pclntab): Goランタイムがスタックトレースやプロファイリングに使用する、プログラムカウンタとソースコード位置のマッピング情報。

参考にした情報源リンク

これらの情報源を組み合わせて、コミットの背景、技術的詳細、および関連する概念を深く掘り下げました。