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

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

このコミットは、Go言語のリンカ (cmd/ld) の data.c ファイルに対する変更です。data.c は、リンカが実行可能ファイルを生成する際に、データセクションのシンボルやリロケーション情報を処理し、デバッグ出力(特に -a フラグによるアセンブリ出力)を整形する役割を担っています。

コミット

  • コミットハッシュ: 4c40e5ae51a3a8ba76ffae04b394523e154fe1b7
  • Author: Russ Cox rsc@golang.org
  • Date: Sun Mar 10 16:32:00 2013 -0400

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

https://github.com/golang/go/commit/4c40e5ae51a3a8ba76ffae04b394523e154fe1b7

元コミット内容

    cmd/ld: wrap long data lines in -a output
    
    Also move symbol names onto lines by themselves: some are very long.
    Show relocations.
    
    R=ken2
    CC=golang-dev
    https://golang.org/cl/7689043

変更の背景

このコミットの主な目的は、Go言語のリンカ (cmd/ld) が -a フラグ(アセンブリ出力)を指定して実行された際の出力の可読性を向上させることです。

以前のリンカの -a 出力では、以下のような問題がありました。

  1. 長いデータ行の可読性: データセクションの内容が1行に長く表示されることがあり、特にバイナリデータが多い場合に視認性が悪かった。
  2. シンボル名の表示: シンボル名がデータ行と同じ行に表示されていたため、シンボル名が長い場合にデータ表示領域を圧迫し、全体的なレイアウトが崩れる原因となっていた。
  3. リロケーション情報の欠如: デバッグ出力において、リロケーション(再配置)に関する詳細情報が表示されていなかったため、リンカの動作や生成されるバイナリの構造を理解する上で不十分な点があった。

これらの問題を解決し、リンカのデバッグ出力がより有用で理解しやすいものになるように、本コミットで改善が図られました。

前提知識の解説

Go言語のリンカ (cmd/ld)

cmd/ld は、Go言語のコンパイラツールチェーンの一部であり、Goのソースコードから生成されたオブジェクトファイル(.o ファイル)を結合して、実行可能なバイナリファイルや共有ライブラリを生成する役割を担っています。リンカは、シンボル解決(関数や変数の参照を実際のアドレスに解決する)や、リロケーション(コード内のアドレス参照を最終的な実行時アドレスに調整する)といった重要な処理を行います。

-a フラグ (アセンブリ出力)

Goのリンカ (cmd/ld) に -a フラグを付けて実行すると、リンカが生成するバイナリの各セクション(テキスト、データなど)の内容をアセンブリ形式でダンプします。これは、デバッグやバイナリの内部構造を詳細に分析する際に非常に有用な機能です。

シンボル (Symbol)

プログラミングにおいて、シンボルとは、変数、関数、ラベルなどのプログラム要素の名前を指します。リンカは、これらのシンボルを解決し、それぞれがメモリ上のどこに配置されるかを決定します。リンカの出力では、シンボル名とそのアドレス、サイズなどが表示されます。

リロケーション (Relocation)

リロケーション(再配置)は、リンカの主要な機能の一つです。コンパイラが生成するオブジェクトファイル内のコードやデータは、通常、0番地からの相対アドレスで記述されています。しかし、複数のオブジェクトファイルを結合して一つの実行可能ファイルを生成する際、これらの相対アドレスは、最終的なメモリ配置に合わせて絶対アドレスに修正される必要があります。このアドレスの修正プロセスがリロケーションです。

リロケーションエントリは、どの位置のどの種類の参照を、どのシンボルに基づいて、どのように修正するかをリンカに指示します。

  • Reloc 構造体: リロケーション情報を保持する構造体。off (オフセット), siz (サイズ), type (タイプ), sym (参照するシンボル), add (加算値) などのフィールドを持ちます。
  • D_ADDR (Address Relocation): 特定のアドレスへの参照を修正するリロケーションタイプ。例えば、グローバル変数のアドレスを参照する場合などに使用されます。
  • D_PCREL (PC-relative Relocation): プログラムカウンタ (PC) からの相対アドレスへの参照を修正するリロケーションタイプ。ジャンプ命令や関数呼び出しなどでよく使用されます。

Bprintbso

Goのリンカのコードベースでは、Bprint はバッファリングされた出力を行うための関数であり、bso はその出力先となるバッファまたはストリームを表す変数です。これは、標準出力やファイルへの書き込みを効率的に行うために使用されます。

技術的詳細

このコミットは、src/cmd/ld/data.c ファイル内の datblk 関数を変更しています。datblk 関数は、データセクションのブロックを処理し、その内容をデバッグ出力として整形する役割を担っています。

主な変更点は以下の3つです。

  1. 長いデータ行の折り返し:

    • 以前は、データが1行に連続して出力されていましたが、変更後は16バイトごとに改行されるようになりました。これにより、長いデータブロックも視覚的に区切られ、読みやすさが向上しています。
    • 具体的には、while(p < ep) ループ内で if(p > sym->p && (int)(p-sym->p)%16 == 0) という条件が追加され、16バイトごとに新しい行とアドレス (%.8ux|) が出力されるようになっています。
  2. シンボル名の独立した行への移動:

    • 以前は、シンボル名がデータ行の先頭に表示されていましたが、変更後はシンボル名が独立した行に表示されるようになりました。これにより、シンボル名が長くてもデータ表示領域を圧迫せず、レイアウトの崩れを防ぎます。
    • Bprint(&bso, "%s\\n\\t%.8ux|", sym->name, (uint)addr); のように、シンボル名の後に改行が挿入され、次の行にインデントされたアドレスとデータが続く形式に変更されています。
  3. リロケーション情報の表示:

    • isobj フラグが真の場合(オブジェクトファイルの場合)、各シンボルに関連付けられたリロケーション情報が詳細に表示されるようになりました。
    • シンボル内のリロケーション (sym->r) をループで処理し、リロケーションのオフセット、サイズ、タイプ (D_ADDR, D_PCREL など)、参照するシンボル名、および加算値 (r->add) が出力されます。
    • これにより、リンカがどのようにアドレスを再配置しているかをデバッグ出力から直接確認できるようになり、バイナリの解析やデバッグが容易になります。

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

--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -553,8 +553,10 @@ void
 datblk(int32 addr, int32 size)
 {
 	Sym *sym;
-\tint32 eaddr;\n+\tint32 i, eaddr;
 	uchar *p, *ep;
+\tchar *typ, *rsname;
+\tReloc *r;
 
 	if(debug['a'])
 		Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\\n", addr, addr+size, cpos());
@@ -574,23 +576,46 @@ datblk(int32 addr, int32 size)
 		if(sym->value >= eaddr)
 			break;
 		if(addr < sym->value) {
-\t\t\tBprint(&bso, "%-20s %.8ux| 00 ...\\n", "(pre-pad)", addr);
+\t\t\tBprint(&bso, "\\t%.8ux| 00 ...\\n", addr);
 			addr = sym->value;
 		}
-\t\tBprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr);
+\t\tBprint(&bso, "%s\\n\\t%.8ux|", sym->name, (uint)addr);
 		p = sym->p;
 		ep = p + sym->np;
-\t\twhile(p < ep)
+\t\twhile(p < ep) {
+\t\t\tif(p > sym->p && (int)(p-sym->p)%16 == 0)
+\t\t\t\tBprint(&bso, "\\n\\t%.8ux|", (uint)(addr+(p-sym->p)));
 			Bprint(&bso, " %.2ux", *p++);
+\t\t}
 		addr += sym->np;
 		for(; addr < sym->value+sym->size; addr++)
 			Bprint(&bso, " %.2ux", 0);
 		Bprint(&bso, "\\n");
+\t\t
+\t\tif(isobj) {
+\t\t\tfor(i=0; i<sym->nr; i++) {
+\t\t\t\tr = &sym->r[i];
+\t\t\t\trsname = "";
+\t\t\t\tif(r->sym)
+\t\t\t\t\trsname = r->sym->name;
+\t\t\t\ttyp = "?";
+\t\t\t\tswitch(r->type) {
+\t\t\t\tcase D_ADDR:
+\t\t\t\t\ttyp = "addr";
+\t\t\t\t\tbreak;
+\t\t\t\tcase D_PCREL:
+\t\t\t\t\ttyp = "pcrel";
+\t\t\t\t\tbreak;
+\t\t\t\t}
+\t\t\t\tBprint(&bso, "\\treloc %.8ux/%d %s %s+%#llx [%#llx]\\n",
+\t\t\t\t\t(uint)(sym->value+r->off), r->siz, typ, rsname, r->add, r->sym->value+r->add);\n+\t\t\t}\n+\t\t}\t\t\t\t
 	}
 
 	if(addr < eaddr)
-\t\tBprint(&bso, "%-20s %.8ux| 00 ...\\n", "(post-pad)", (uint)addr);
-\tBprint(&bso, "%-20s %.8ux|\\n", "", (uint)eaddr);
+\t\tBprint(&bso, "\\t%.8ux| 00 ...\\n", (uint)addr);
+\tBprint(&bso, "\\t%.8ux|\\n", (uint)eaddr);
 }
 
 void

コアとなるコードの解説

  1. 変数の追加:

    • int32 i, eaddr; -> i はリロケーションループのカウンタとして追加。
    • char *typ, *rsname; -> リロケーションタイプと参照シンボル名のための文字列ポインタ。
    • Reloc *r; -> リロケーション構造体へのポインタ。 これらの変数は、リロケーション情報を取得し、整形して出力するために必要です。
  2. シンボル名の出力変更:

    • - Bprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr);
    • + Bprint(&bso, "%s\\n\\t%.8ux|", sym->name, (uint)addr); シンボル名 (sym->name) の後に \\n (改行) が追加され、その後にタブ (\\t) とアドレス (%.8ux|) が続くように変更されました。これにより、シンボル名が独立した行に表示され、その下の行にデータがインデントされて表示されるようになります。
  3. データ行の折り返し:

    • while(p < ep) ループ内に以下のコードが追加されました。
      if(p > sym->p && (int)(p-sym->p)%16 == 0)
          Bprint(&bso, "\\n\\t%.8ux|", (uint)(addr+(p-sym->p)));
      
    • これは、現在のポインタ p がシンボルの開始位置 sym->p より後ろにあり、かつ、シンボル開始位置からのオフセットが16の倍数である場合に、改行と新しいアドレス (%.8ux|) を出力します。これにより、データが16バイトごとに折り返され、可読性が向上します。
  4. リロケーション情報の表示:

    • if(isobj) ブロックが追加されました。isobj は、現在の処理がオブジェクトファイルに対して行われているかどうかを示すフラグと考えられます。
    • このブロック内で、for(i=0; i<sym->nr; i++) ループが追加され、シンボル sym に関連付けられた全てのリロケーション (sym->r) を反復処理します。
    • 各リロケーション r について、そのタイプ (r->type) に応じて typ (例: "addr", "pcrel") を設定します。
    • rsname は、リロケーションが参照するシンボル名 (r->sym->name) を保持します。
    • 最後に、Bprint を使用して、リロケーションのオフセット、サイズ、タイプ、参照シンボル名、および加算値を含む詳細なリロケーション情報が出力されます。
      Bprint(&bso, "\\treloc %.8ux/%d %s %s+%#llx [%#llx]\\n",
          (uint)(sym->value+r->off), r->siz, typ, rsname, r->add, r->sym->value+r->add);
      
      この行は、リロケーションのオフセット (sym->value+r->off)、サイズ (r->siz)、タイプ (typ)、参照シンボル名 (rsname)、加算値 (r->add)、そして最終的なリロケーション先のアドレス (r->sym->value+r->add) を表示します。
  5. パディング行の出力変更:

    • - Bprint(&bso, "%-20s %.8ux| 00 ...\\n", "(pre-pad)", addr);
    • + Bprint(&bso, "\\t%.8ux| 00 ...\\n", addr);
    • - Bprint(&bso, "%-20s %.8ux|\\n", "", (uint)eaddr);
    • + Bprint(&bso, "\\t%.8ux|\\n", (uint)eaddr); パディング行の出力も、シンボル名が削除され、インデントされたアドレスから始まる形式に変更されています。これにより、出力の一貫性が保たれます。

これらの変更により、リンカの -a 出力は、データの内容、シンボルの配置、そして特にリロケーションの動作について、より詳細で理解しやすい情報を提供するようになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (Go linker, cmd/ld)
  • リンカとローダに関する一般的な情報源 (シンボル、リロケーションの概念)
  • Go言語のソースコード (src/cmd/ld/data.c および関連ファイル)
  • Go言語のIssueトラッカーやメーリングリスト (過去の議論や背景情報)
  • Go言語のコンパイラとリンカの内部構造に関する技術記事や書籍```markdown

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

このコミットは、Go言語のリンカ (cmd/ld) の data.c ファイルに対する変更です。data.c は、リンカが実行可能ファイルを生成する際に、データセクションのシンボルやリロケーション情報を処理し、デバッグ出力(特に -a フラグによるアセンブリ出力)を整形する役割を担っています。

コミット

  • コミットハッシュ: 4c40e5ae51a3a8ba76ffae04b394523e154fe1b7
  • Author: Russ Cox rsc@golang.org
  • Date: Sun Mar 10 16:32:00 2013 -0400

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

https://github.com/golang/go/commit/4c40e5ae51a3a8ba76ffae04b394523e154fe1b7

元コミット内容

    cmd/ld: wrap long data lines in -a output
    
    Also move symbol names onto lines by themselves: some are very long.
    Show relocations.
    
    R=ken2
    CC=golang-dev
    https://golang.org/cl/7689043

変更の背景

このコミットの主な目的は、Go言語のリンカ (cmd/ld) が -a フラグ(アセンブリ出力)を指定して実行された際の出力の可読性を向上させることです。

以前のリンカの -a 出力では、以下のような問題がありました。

  1. 長いデータ行の可読性: データセクションの内容が1行に長く表示されることがあり、特にバイナリデータが多い場合に視認性が悪かった。
  2. シンボル名の表示: シンボル名がデータ行と同じ行に表示されていたため、シンボル名が長い場合にデータ表示領域を圧迫し、全体的なレイアウトが崩れる原因となっていた。
  3. リロケーション情報の欠如: デバッグ出力において、リロケーション(再配置)に関する詳細情報が表示されていなかったため、リンカの動作や生成されるバイナリの構造を理解する上で不十分な点があった。

これらの問題を解決し、リンカのデバッグ出力がより有用で理解しやすいものになるように、本コミットで改善が図られました。

前提知識の解説

Go言語のリンカ (cmd/ld)

cmd/ld は、Go言語のコンパイラツールチェーンの一部であり、Goのソースコードから生成されたオブジェクトファイル(.o ファイル)を結合して、実行可能なバイナリファイルや共有ライブラリを生成する役割を担っています。リンカは、シンボル解決(関数や変数の参照を実際のアドレスに解決する)や、リロケーション(コード内のアドレス参照を最終的な実行時アドレスに調整する)といった重要な処理を行います。

-a フラグ (アセンブリ出力)

Goのリンカ (cmd/ld) に -a フラグを付けて実行すると、リンカが生成するバイナリの各セクション(テキスト、データなど)の内容をアセンブリ形式でダンプします。これは、デバッグやバイナリの内部構造を詳細に分析する際に非常に有用な機能です。

シンボル (Symbol)

プログラミングにおいて、シンボルとは、変数、関数、ラベルなどのプログラム要素の名前を指します。リンカは、これらのシンボルを解決し、それぞれがメモリ上のどこに配置されるかを決定します。リンカの出力では、シンボル名とそのアドレス、サイズなどが表示されます。

リロケーション (Relocation)

リロケーション(再配置)は、リンカの主要な機能の一つです。コンパイラが生成するオブジェクトファイル内のコードやデータは、通常、0番地からの相対アドレスで記述されています。しかし、複数のオブジェクトファイルを結合して一つの実行可能ファイルを生成する際、これらの相対アドレスは、最終的なメモリ配置に合わせて絶対アドレスに修正される必要があります。このアドレスの修正プロセスがリロケーションです。

リロケーションエントリは、どの位置のどの種類の参照を、どのシンボルに基づいて、どのように修正するかをリンカに指示します。

  • Reloc 構造体: リロケーション情報を保持する構造体。off (オフセット), siz (サイズ), type (タイプ), sym (参照するシンボル), add (加算値) などのフィールドを持ちます。
  • D_ADDR (Address Relocation): 特定のアドレスへの参照を修正するリロケーションタイプ。例えば、グローバル変数のアドレスを参照する場合などに使用されます。
  • D_PCREL (PC-relative Relocation): プログラムカウンタ (PC) からの相対アドレスへの参照を修正するリロケーションタイプ。ジャンプ命令や関数呼び出しなどでよく使用されます。

Bprintbso

Goのリンカのコードベースでは、Bprint はバッファリングされた出力を行うための関数であり、bso はその出力先となるバッファまたはストリームを表す変数です。これは、標準出力やファイルへの書き込みを効率的に行うために使用されます。

技術的詳細

このコミットは、src/cmd/ld/data.c ファイル内の datblk 関数を変更しています。datblk 関数は、データセクションのブロックを処理し、その内容をデバッグ出力として整形する役割を担っています。

主な変更点は以下の3つです。

  1. 長いデータ行の折り返し:

    • 以前は、データが1行に連続して出力されていましたが、変更後は16バイトごとに改行されるようになりました。これにより、長いデータブロックも視覚的に区切られ、読みやすさが向上しています。
    • 具体的には、while(p < ep) ループ内で if(p > sym->p && (int)(p-sym->p)%16 == 0) という条件が追加され、16バイトごとに新しい行とアドレス (%.8ux|) が出力されるようになっています。
  2. シンボル名の独立した行への移動:

    • 以前は、シンボル名がデータ行の先頭に表示されていましたが、変更後はシンボル名が独立した行に表示されるようになりました。これにより、シンボル名が長くてもデータ表示領域を圧迫せず、レイアウトの崩れを防ぎます。
    • Bprint(&bso, "%s\\n\\t%.8ux|", sym->name, (uint)addr); のように、シンボル名の後に改行が挿入され、次の行にインデントされたアドレスとデータが続く形式に変更されています。
  3. リロケーション情報の表示:

    • isobj フラグが真の場合(オブジェクトファイルの場合)、各シンボルに関連付けられたリロケーション情報が詳細に表示されるようになりました。
    • シンボル内のリロケーション (sym->r) をループで処理し、リロケーションのオフセット、サイズ、タイプ (D_ADDR, D_PCREL など)、参照するシンボル名、および加算値 (r->add) が出力されます。
    • これにより、リンカがどのようにアドレスを再配置しているかをデバッグ出力から直接確認できるようになり、バイナリの解析やデバッグが容易になります。

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

--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -553,8 +553,10 @@ void
 datblk(int32 addr, int32 size)
 {
 	Sym *sym;
-\tint32 eaddr;\n+\tint32 i, eaddr;
 	uchar *p, *ep;
+\tchar *typ, *rsname;
+\tReloc *r;
 
 	if(debug['a'])
 		Bprint(&bso, "datblk [%#x,%#x) at offset %#llx\\n", addr, addr+size, cpos());
@@ -574,23 +576,46 @@ datblk(int32 addr, int32 size)
 		if(sym->value >= eaddr)
 			break;
 		if(addr < sym->value) {
-\t\t\tBprint(&bso, "%-20s %.8ux| 00 ...\\n", "(pre-pad)", addr);
+\t\t\tBprint(&bso, "\\t%.8ux| 00 ...\\n", addr);
 			addr = sym->value;
 		}
-\t\tBprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr);
+\t\tBprint(&bso, "%s\\n\\t%.8ux|", sym->name, (uint)addr);
 		p = sym->p;
 		ep = p + sym->np;
-\t\twhile(p < ep)
+\t\twhile(p < ep) {
+\t\t\tif(p > sym->p && (int)(p-sym->p)%16 == 0)
+\t\t\t\tBprint(&bso, "\\n\\t%.8ux|", (uint)(addr+(p-sym->p)));
 			Bprint(&bso, " %.2ux", *p++);
+\t\t}
 		addr += sym->np;
 		for(; addr < sym->value+sym->size; addr++)
 			Bprint(&bso, " %.2ux", 0);
 		Bprint(&bso, "\\n");
+\t\t
+\t\tif(isobj) {
+\t\t\tfor(i=0; i<sym->nr; i++) {
+\t\t\t\tr = &sym->r[i];
+\t\t\t\trsname = "";
+\t\t\t\tif(r->sym)
+\t\t\t\t\trsname = r->sym->name;
+\t\t\t\ttyp = "?";
+\t\t\t\tswitch(r->type) {
+\t\t\t\tcase D_ADDR:
+\t\t\t\t\ttyp = "addr";
+\t\t\t\t\tbreak;
+\t\t\t\tcase D_PCREL:
+\t\t\t\t\ttyp = "pcrel";
+\t\t\t\t\tbreak;
+\t\t\t\t}
+\t\t\t\tBprint(&bso, "\\treloc %.8ux/%d %s %s+%#llx [%#llx]\\n",
+\t\t\t\t\t(uint)(sym->value+r->off), r->siz, typ, rsname, r->add, r->sym->value+r->add);\n+\t\t\t}\n+\t\t}\t\t\t\t
 	}
 
 	if(addr < eaddr)
-\t\tBprint(&bso, "%-20s %.8ux| 00 ...\\n", "(post-pad)", (uint)addr);
-\tBprint(&bso, "%-20s %.8ux|\\n", "", (uint)eaddr);
+\t\tBprint(&bso, "\\t%.8ux| 00 ...\\n", (uint)addr);
+\tBprint(&bso, "\\t%.8ux|\\n", (uint)eaddr);
 }
 
 void

コアとなるコードの解説

  1. 変数の追加:

    • int32 i, eaddr; -> i はリロケーションループのカウンタとして追加。
    • char *typ, *rsname; -> リロケーションタイプと参照シンボル名のための文字列ポインタ。
    • Reloc *r; -> リロケーション構造体へのポインタ。 これらの変数は、リロケーション情報を取得し、整形して出力するために必要です。
  2. シンボル名の出力変更:

    • - Bprint(&bso, "%-20s %.8ux|", sym->name, (uint)addr);
    • + Bprint(&bso, "%s\\n\\t%.8ux|", sym->name, (uint)addr); シンボル名 (sym->name) の後に \\n (改行) が追加され、その後にタブ (\\t) とアドレス (%.8ux|) が続くように変更されました。これにより、シンボル名が独立した行に表示され、その下の行にデータがインデントされて表示されるようになります。
  3. データ行の折り返し:

    • while(p < ep) ループ内に以下のコードが追加されました。
      if(p > sym->p && (int)(p-sym->p)%16 == 0)
          Bprint(&bso, "\\n\\t%.8ux|", (uint)(addr+(p-sym->p)));
      
    • これは、現在のポインタ p がシンボルの開始位置 sym->p より後ろにあり、かつ、シンボル開始位置からのオフセットが16の倍数である場合に、改行と新しいアドレス (%.8ux|) を出力します。これにより、データが16バイトごとに折り返され、可読性が向上します。
  4. リロケーション情報の表示:

    • if(isobj) ブロックが追加されました。isobj は、現在の処理がオブジェクトファイルに対して行われているかどうかを示すフラグと考えられます。
    • このブロック内で、for(i=0; i<sym->nr; i++) ループが追加され、シンボル sym に関連付けられた全てのリロケーション (sym->r) を反復処理します。
    • 各リロケーション r について、そのタイプ (r->type) に応じて typ (例: "addr", "pcrel") を設定します。
    • rsname は、リロケーションが参照するシンボル名 (r->sym->name) を保持します。
    • 最後に、Bprint を使用して、リロケーションのオフセット、サイズ、タイプ、参照シンボル名、および加算値を含む詳細なリロケーション情報が出力されます。
      Bprint(&bso, "\\treloc %.8ux/%d %s %s+%#llx [%#llx]\\n",
          (uint)(sym->value+r->off), r->siz, typ, rsname, r->add, r->sym->value+r->add);
      
      この行は、リロケーションのオフセット (sym->value+r->off)、サイズ (r->siz)、タイプ (typ)、参照シンボル名 (rsname)、加算値 (r->add)、そして最終的なリロケーション先のアドレス (r->sym->value+r->add) を表示します。
  5. パディング行の出力変更:

    • - Bprint(&bso, "%-20s %.8ux| 00 ...\\n", "(pre-pad)", addr);
    • + Bprint(&bso, "\\t%.8ux| 00 ...\\n", addr);
    • - Bprint(&bso, "%-20s %.8ux|\\n", "", (uint)eaddr);
    • + Bprint(&bso, "\\t%.8ux|\\n", (uint)eaddr); パディング行の出力も、シンボル名が削除され、インデントされたアドレスから始まる形式に変更されています。これにより、出力の一貫性が保たれます。

これらの変更により、リンカの -a 出力は、データの内容、シンボルの配置、そして特にリロケーションの動作について、より詳細で理解しやすい情報を提供するようになりました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (Go linker, cmd/ld)
  • リンカとローダに関する一般的な情報源 (シンボル、リロケーションの概念)
  • Go言語のソースコード (src/cmd/ld/data.c および関連ファイル)
  • Go言語のIssueトラッカーやメーリングリスト (過去の議論や背景情報)
  • Go言語のコンパイラとリンカの内部構造に関する技術記事や書籍