[インデックス 15995] ファイルの概要
このコミットは、src/cmd/ld/lib.c
ファイルに対して変更を加えています。具体的には、リンカが-rdynamic
フラグを渡す条件を修正しています。
コミット
commit 47ec6e23d23aa95797aed517388845e7c0e14a45
Author: Ian Lance Taylor <iant@golang.org>
Date: Thu Mar 28 15:04:25 2013 -0700
cmd/ld: only pass -rdynamic to host linker on ELF target
Fixes #5150.
R=golang-dev, franciscossouza
CC=golang-dev
https://golang.org/cl/8120043
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/47ec6e23d23aa95797aed517388845e7c0e14a45
元コミット内容
cmd/ld: only pass -rdynamic to host linker on ELF target
このコミットは、cmd/ld
(Go言語のリンカコマンド)において、ホストリンカに-rdynamic
フラグを渡すのはELFターゲットの場合のみに限定するという内容です。これにより、Issue #5150 が修正されます。
変更の背景
以前のリンカの挙動では、-rdynamic
フラグがターゲットOSに関わらず常にホストリンカに渡されていました。しかし、コミットメッセージのコメント「NOTE: May not work on OS X or Windows. We'll see.」が示唆するように、このフラグはすべてのプラットフォームで適切に機能するわけではありませんでした。特に、ELF形式を使用しないOS(例: macOSやWindows)では、このフラグは無意味であるか、あるいは問題を引き起こす可能性がありました。
Issue #5150 は、この-rdynamic
フラグの不適切な使用によって引き起こされる具体的な問題(おそらくビルドエラーや予期せぬ挙動)を報告していたと考えられます。このコミットは、その問題を解決するために、-rdynamic
フラグをELF形式の実行ファイルを生成するターゲット(主にLinuxなどのUnix系システム)に限定して渡すように変更することで、リンカの挙動をより堅牢でプラットフォームに依存しないものにすることを目的としています。
前提知識の解説
リンカ (Linker)
リンカは、コンパイラによって生成されたオブジェクトファイル(機械語コードとデータを含むファイル)やライブラリを結合し、実行可能なプログラムや共有ライブラリを生成するプログラムです。リンカの主な役割は以下の通りです。
- シンボル解決: オブジェクトファイル間で参照されている関数や変数のアドレスを解決します。
- 再配置: コード内のアドレス参照を、最終的なメモリレイアウトに合わせて調整します。
- ライブラリの結合: 静的ライブラリや動的ライブラリから必要なコードを取り込みます。
-rdynamic
フラグ
-rdynamic
は、主にGCC(GNU Compiler Collection)とそのリンカ(ld
)で使用されるリンカオプションです。このフラグは、実行可能ファイル内のすべてのシンボル(関数名や変数名など)を動的シンボルテーブルに追加するようリンカに指示します。
- 動的シンボルテーブル: 実行時に動的にリンクされるライブラリや、
dlopen()
のような関数を使ってロードされるモジュールが、メインの実行可能ファイル内のシンボルを参照できるようにするために使用されます。 - 用途:
- バックトレース: クラッシュレポートなどで関数名を表示するために、実行時にシンボル情報を必要とする場合。
- プラグインアーキテクチャ: 実行時にロードされるプラグインが、メインアプリケーションの関数や変数にアクセスする必要がある場合。
- デバッグ: デバッグツールが実行中のプログラムのシンボル情報を利用する場合。
- 影響: すべてのシンボルを動的シンボルテーブルに含めるため、実行可能ファイルのサイズが増加する可能性があります。また、このフラグは主にELF形式のシステム(Linuxなど)で意味を持ち、他のOS(macOSやWindows)では挙動が異なるか、サポートされていない場合があります。
ELF (Executable and Linkable Format)
ELFは、Unix系オペレーティングシステム(Linux、BSDなど)で広く使用されている、実行可能ファイル、オブジェクトファイル、共有ライブラリの標準ファイル形式です。ELF形式は、プログラムの構造、セクション(コード、データなど)、シンボルテーブル、デバッグ情報などを定義します。WindowsではPE (Portable Executable) 形式、macOSではMach-O形式がそれぞれ使用されています。
技術的詳細
このコミットの技術的な核心は、Go言語のリンカがホストリンカを呼び出す際に、-rdynamic
フラグを渡すかどうかを、ターゲットシステムがELF形式であるかどうかに基づいて条件分岐させる点にあります。
変更前のコードでは、hostlink
関数内で、以下の行によって無条件に-rdynamic
フラグがargv
(リンカに渡す引数リスト)に追加されていました。
// Force global symbols to be exported for dlopen, etc.
// NOTE: May not work on OS X or Windows. We'll see.
argv[argc++] = "-rdynamic";
このコメントは、開発者がこのフラグのプラットフォーム依存性を認識していたことを示唆しています。しかし、Goのクロスコンパイル能力を考えると、WindowsやmacOSのような非ELFターゲット向けにビルドする際にもこのフラグが渡されてしまい、問題を引き起こす可能性がありました。
このコミットでは、iself
というグローバル変数(または同様のフラグ)を導入し、リンカが現在処理しているターゲットがELF形式である場合にのみ-rdynamic
フラグを渡すように修正しています。これにより、リンカはターゲットOSの実行ファイル形式に合わせた適切な挙動をするようになります。
具体的には、src/cmd/ld/lib.c
に../ld/elf.h
がインクルードされ、iself
変数が利用可能になったことで、ELFターゲットの判定が可能になりました。
コアとなるコードの変更箇所
src/cmd/ld/lib.c
ファイルの以下の部分が変更されました。
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -31,6 +31,7 @@
#include "l.h"
#include "lib.h"
+#include "../ld/elf.h"
#include "../../pkg/runtime/stack.h"
#include <ar.h>
@@ -640,8 +641,8 @@ hostlink(void)\n \t\targv[argc++] = smprint(\"-Wl,-rpath,%s\", rpath);\n \n \t// Force global symbols to be exported for dlopen, etc.\n-\t// NOTE: May not work on OS X or Windows. We\'ll see.\n-\targv[argc++] = \"-rdynamic\";\n+\tif(iself)\n+\t\targv[argc++] = \"-rdynamic\";\n \n \t// already wrote main object file\n \t// copy host objects to temporary directory\n```
## コアとなるコードの解説
1. **`#include "../ld/elf.h"` の追加**:
この行は、ELF関連の定義、特に`iself`変数が宣言されているヘッダファイル`elf.h`をインクルードしています。これにより、`lib.c`内で`iself`変数の値にアクセスできるようになります。`iself`は、現在のビルドターゲットがELF形式である場合に真となるフラグであると推測されます。
2. **`-rdynamic` フラグの条件付き追加**:
変更前のコードでは、以下の行で無条件に`-rdynamic`フラグが追加されていました。
```c
argv[argc++] = "-rdynamic";
```
これが、以下の条件分岐に置き換えられました。
```c
if(iself)
argv[argc++] = "-rdynamic";
```
この変更により、`iself`が真(つまり、ターゲットがELF形式)の場合にのみ、`-rdynamic`フラグがホストリンカに渡されるようになります。これにより、非ELFシステム(macOSやWindowsなど)向けにビルドする際に、不要または問題を引き起こす可能性のある`-rdynamic`フラグが渡されることがなくなります。
この修正は、Goのリンカがよりスマートに、そしてターゲットプラットフォームの特性を考慮して動作するように改善されたことを意味します。
## 関連リンク
* Go CL 8120043: [https://golang.org/cl/8120043](https://golang.org/cl/8120043)
* Go Issue 5150: (直接のリンクはコミットメッセージに記載されていませんが、`Fixes #5150`からGoのIssueトラッカーで検索可能です)
## 参考にした情報源リンク
* `-rdynamic` flag:
* [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFojUI3yuvYRKK3M7u8DXKL4QNF8uOt1KbM5GnduZwL4xsiav_mbshrFYBvG9js1slkeLwLolbUNvO_KaPuc9FsEGsSrLYaArRNLW4_dwG_](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFojUI3yuvYRKK3M7u8DXKL4QNF8uOt1KbM5GnduZwL4xsiav_mbshrFYBvG9js1slkeLwLolbUNvO_KaPuc9FsEGsSrLYaArRNLW4_dwG_)
* [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFR9brM3K8hENazcfqK3cN4_GKncTFJS8HyfKS_bSzuX7GZz9ISyUAwWHgaBgeC0E6-Vqel_yynYo32P4WDk8O8DsMiXBBObBwtUu3hL6OJPIZ48ThE2iJk1xIVFvyfFpPu45knc3TV3O99Lp3bVWHL](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFR9brM3K8hENazcfqK3cN4_GKncTFJS8HyfKS_bSzuX7GZz9ISyUAwWHgaBgeC0E6-Vqel_yynYo32P4WDk8O8DsMiXBBObBwtUu3hL6OJPIZ48ThE2iJk1xIVFvyfFpPu45knc3TV3O99Lp3bVWHL)
* [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEkC4PpdWwLFJ-Q55bgvrVTwR44kHLGC-RzVemb0Aq6HilUnZGdmZuM7Sjs6lANiXRcZjQ-rhMy15Faf0Ga2qeuZp22xCFGTIsHdeksr6Vwsusfb62FuAzGiEzx-XSn7M_q3E3WEZ3CNfCJK1EIohNCQamnIdFInll7](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEkC4PpdWwLFJ-Q55bgvrVTwR44kHLGC-RzVemb0Aq6HilUnZGdmZuM7Sjs6lANiXRcZjQ-rhMy15Faf0Ga2qeuZp22xCFGTIsHdeksr6Vwsusfb62FuAzGiEzx-XSn7M_q3E3WEZ3CNfCJK1EIohNCQamnIdFInll7)
* [https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFS7Vi7z9VA98swkXVGWumDTfXHPEbMI6C_TjRvQO6J641TmJgp9Z_pCynSra9YS6pGAvilL3lStEzGXioiYDm1-2d4F-nTKsuNH3CRffLIvs5O6MifBMdi8_gM_v6diMks9lL_9O0eL8EOxXP10jBto6vCTefkuks=](https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFS7Vi7z9VA98swkXVGWumDTfXHPEbMI6C_TjRvQO6J641TmJgp9Z_pCynSra9YS6pGAvilL3lStEzGXioiYDm1-2d4F-nTKsuNH3CRffLIvs5O6MifBMdi8_gM_v6diMks9lL_9O0eL8EOxXP10jBto6vCTefkuks=)