[インデックス 18082] ファイルの概要
このコミットは、Go言語のリンカ (cmd/ld
) における変更を扱っています。具体的には、OpenBSD 5.3/5.4 およびそれ以降のバージョンで、GoプログラムがネイティブのCコード(hostobj
)とリンクする際に発生する問題を解決するためのものです。OpenBSDの新しいバージョンでは、Position-Independent Executable (PIE) がデフォルトで有効になっているため、Goリンカが生成するオブジェクトファイルとの互換性の問題が生じていました。
コミット
commit 0eaabf6452149ecbcc1caf40e22ae16cf73c768e
Author: Joel Sing <jsing@google.com>
Date: Fri Dec 20 03:58:27 2013 +1100
cmd/ld: make hostobj work on newer openbsd
Make hostobj work on OpenBSD 5.3/5.4/-current - these have PIE
enabled by default and linking fails since the Go linker generates
objects that are neither PIC nor PIE.
Fixes #5067
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7572049
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0eaabf6452149ecbcc1caf40e22ae16cf73c768e
元コミット内容
cmd/ld: make hostobj work on newer openbsd
Make hostobj work on OpenBSD 5.3/5.4/-current - these have PIE
enabled by default and linking fails since the Go linker generates
objects that are neither PIC nor PIE.
Fixes #5067
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7572049
変更の背景
この変更の背景には、OpenBSDオペレーティングシステムのセキュリティ強化があります。OpenBSDは、その堅牢なセキュリティで知られており、Position-Independent Executable (PIE) の採用はその一環です。PIEは、実行ファイルがメモリ上のランダムなアドレスにロードされることを可能にし、Address Space Layout Randomization (ASLR) と組み合わせて、バッファオーバーフローなどの攻撃を困難にします。
しかし、Go言語のリンカ (cmd/ld
) は、当時(2013年頃)はPIEまたはPosition-Independent Code (PIC) に対応したオブジェクトファイルを生成していませんでした。そのため、OpenBSD 5.3/5.4以降でデフォルトでPIEが有効になっている環境では、GoプログラムがC言語で書かれたライブラリ(hostobj
、つまりホストシステムが提供するオブジェクトファイル)とリンクしようとすると、リンカエラーが発生していました。このコミットは、この互換性の問題を解決し、GoプログラムがOpenBSDの新しいバージョンで正しく動作するようにすることを目的としています。
前提知識の解説
リンカ (Linker)
リンカは、コンパイラによって生成された複数のオブジェクトファイル(コンパイルされたソースコード)と、必要なライブラリを結合して、実行可能なプログラムまたはライブラリを作成するツールです。リンカの主な役割は、異なるオブジェクトファイル間で参照されるシンボル(関数や変数など)を解決し、それらをメモリ上の適切なアドレスに配置することです。
Position-Independent Code (PIC)
PICは、メモリ上の任意のアドレスにロードされても正しく実行されるように設計された機械語コードです。これは主に共有ライブラリ(ダイナミックリンクライブラリ)で使用されます。PICでは、絶対アドレスではなく、プログラムカウンタ相対アドレス指定やグローバルオフセットテーブル (GOT) を使用してデータや関数にアクセスします。これにより、ライブラリが複数のプロセスで共有される際に、各プロセスが異なるメモリ位置にロードされても問題なく動作します。
Position-Independent Executable (PIE)
PIEは、PICの原則を適用した実行可能ファイルです。PIEとしてコンパイルされた実行ファイルは、メモリ上のランダムなアドレスにロードされることが可能になります。これは、Address Space Layout Randomization (ASLR) と組み合わせて使用され、セキュリティを向上させます。攻撃者が特定の関数のアドレスを予測して悪用するのを困難にするため、バッファオーバーフローなどの脆弱性に対する防御策となります。
hostobj
Go言語の文脈におけるhostobj
は、Goのツールチェインではなく、ホストシステム(オペレーティングシステム)のCコンパイラやリンカによって生成されたオブジェクトファイルを指します。GoプログラムがC言語で書かれたライブラリ(例えば、cgo
を使ってCコードを呼び出す場合)とリンクする必要がある場合、これらのhostobj
がGoのリンカによって取り込まれます。
HEADTYPE
Goのリンカ (cmd/ld
) において、HEADTYPE
はターゲットとなる実行ファイルのヘッダタイプ、つまりターゲットOSの種類を示す内部変数です。例えば、Hdarwin
はmacOS、Hopenbsd
はOpenBSDを指します。この変数は、リンカが特定のOSに特化した処理を行う際に使用されます。
技術的詳細
このコミットの技術的な核心は、OpenBSDのリンカに対して、Goリンカが生成するオブジェクトファイルがPIEではないことを明示的に伝える点にあります。OpenBSD 5.3/5.4以降では、デフォルトでPIEが有効になっているため、リンカはすべてのオブジェクトファイルがPIE互換であることを期待します。しかし、当時のGoリンカはPIE互換のオブジェクトを生成していなかったため、この期待が満たされず、リンクエラーが発生していました。
解決策として、GoリンカはOpenBSDをターゲットとする場合に、外部リンカ(通常はgcc
など)に-Wl,-nopie
というフラグを渡すように変更されました。
-Wl,
:これは、gcc
などのコンパイラドライバに対して、続く引数をリンカに直接渡すように指示するフラグです。-nopie
:これは、OpenBSDのリンカ(ld
)に対するフラグで、生成される実行ファイルがPIEではないことを明示的に指定します。これにより、リンカはPIE互換性のチェックを緩和し、Goリンカが生成した非PIEオブジェクトファイルとのリンクを許可します。
この変更により、GoリンカはOpenBSDの新しいバージョンでhostobj
と正しくリンクできるようになり、GoプログラムがOpenBSD環境で問題なくビルドおよび実行されるようになりました。
コアとなるコードの変更箇所
変更はsrc/cmd/ld/lib.c
ファイルにあります。
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -574,6 +574,8 @@ hostlink(void)
}
if(HEADTYPE == Hdarwin)
argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000";
+ if(HEADTYPE == Hopenbsd)
+ argv[argc++] = "-Wl,-nopie";
if(iself && AssumeGoldLinker)
argv[argc++] = "-Wl,--rosegment";
コアとなるコードの解説
hostlink
関数は、GoプログラムがC言語のオブジェクトファイル(hostobj
)とリンクする際に、外部リンカを呼び出すための引数を構築する役割を担っています。
変更前のコードでは、HEADTYPE == Hdarwin
(macOSをターゲットとする場合)にのみ、特定のリンカフラグ(-Wl,-no_pie,-pagezero_size,4000000
)が追加されていました。これは、macOSのリンカに対する特定の要件に対応するためのものです。
このコミットでは、以下の行が追加されました。
if(HEADTYPE == Hopenbsd)
argv[argc++] = "-Wl,-nopie";
このコードは、GoリンカがOpenBSDをターゲットとしてビルドを行う場合にのみ実行されます。HEADTYPE
がHopenbsd
であると判断された場合、argv
配列(外部リンカに渡される引数のリスト)に"-Wl,-nopie"
が追加されます。
argv[argc++]
:これは、argv
配列の現在の末尾に新しい引数を追加し、argc
(引数の数)をインクリメントするC言語の一般的なイディオムです。
このシンプルな追加により、OpenBSDのリンカは、Goリンカが生成するオブジェクトファイルがPIEではないことを認識し、リンクプロセスを正常に完了できるようになります。
関連リンク
- Go Issue #5067: cmd/ld: make hostobj work on newer openbsd
- Go CL 7572049: cmd/ld: make hostobj work on newer openbsd
参考にした情報源リンク
- Position-independent code - Wikipedia: https://en.wikipedia.org/wiki/Position-independent_code
- Position-independent executable - Wikipedia: https://en.wikipedia.org/wiki/Position-independent_executable
- Address space layout randomization - Wikipedia: https://en.wikipedia.org/wiki/Address_space_layout_randomization
- OpenBSD: https://www.openbsd.org/
- GCC Command Options - Linker Options: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
- ld(1) - OpenBSD man page: (通常、オンラインで
ld(1) openbsd
で検索すると見つかります。例: https://man.openbsd.org/ld.1) - Go言語のリンカに関するドキュメント(Goのソースコードや公式ドキュメントを参照)# [インデックス 18082] ファイルの概要
このコミットは、Go言語のリンカ (cmd/ld
) における変更を扱っています。具体的には、OpenBSD 5.3/5.4 およびそれ以降のバージョンで、GoプログラムがネイティブのCコード(hostobj
)とリンクする際に発生する問題を解決するためのものです。OpenBSDの新しいバージョンでは、Position-Independent Executable (PIE) がデフォルトで有効になっているため、Goリンカが生成するオブジェクトファイルとの互換性の問題が生じていました。
コミット
commit 0eaabf6452149ecbcc1caf40e22ae16cf73c768e
Author: Joel Sing <jsing@google.com>
Date: Fri Dec 20 03:58:27 2013 +1100
cmd/ld: make hostobj work on newer openbsd
Make hostobj work on OpenBSD 5.3/5.4/-current - these have PIE
enabled by default and linking fails since the Go linker generates
objects that are neither PIC nor PIE.
Fixes #5067
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7572049
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/0eaabf6452149ecbcc1caf40e22ae16cf73c768e
元コミット内容
cmd/ld: make hostobj work on newer openbsd
Make hostobj work on OpenBSD 5.3/5.4/-current - these have PIE
enabled by default and linking fails since the Go linker generates
objects that are neither PIC nor PIE.
Fixes #5067
R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7572049
変更の背景
この変更の背景には、OpenBSDオペレーティングシステムのセキュリティ強化があります。OpenBSDは、その堅牢なセキュリティで知られており、Position-Independent Executable (PIE) の採用はその一環です。PIEは、実行ファイルがメモリ上のランダムなアドレスにロードされることを可能にし、Address Space Layout Randomization (ASLR) と組み合わせて、バッファオーバーフローなどの攻撃を困難にします。
しかし、Go言語のリンカ (cmd/ld
) は、当時(2013年頃)はPIEまたはPosition-Independent Code (PIC) に対応したオブジェクトファイルを生成していませんでした。そのため、OpenBSD 5.3/5.4以降でデフォルトでPIEが有効になっている環境では、GoプログラムがC言語で書かれたライブラリ(hostobj
、つまりホストシステムが提供するオブジェクトファイル)とリンクしようとすると、リンカエラーが発生していました。このコミットは、この互換性の問題を解決し、GoプログラムがOpenBSDの新しいバージョンで正しく動作するようにすることを目的としています。
前提知識の解説
リンカ (Linker)
リンカは、コンパイラによって生成された複数のオブジェクトファイル(コンパイルされたソースコード)と、必要なライブラリを結合して、実行可能なプログラムまたはライブラリを作成するツールです。リンカの主な役割は、異なるオブジェクトファイル間で参照されるシンボル(関数や変数など)を解決し、それらをメモリ上の適切なアドレスに配置することです。
Position-Independent Code (PIC)
PICは、メモリ上の任意のアドレスにロードされても正しく実行されるように設計された機械語コードです。これは主に共有ライブラリ(ダイナミックリンクライブラリ)で使用されます。PICでは、絶対アドレスではなく、プログラムカウンタ相対アドレス指定やグローバルオフセットテーブル (GOT) を使用してデータや関数にアクセスします。これにより、ライブラリが複数のプロセスで共有される際に、各プロセスが異なるメモリ位置にロードされても問題なく動作します。
Position-Independent Executable (PIE)
PIEは、PICの原則を適用した実行可能ファイルです。PIEとしてコンパイルされた実行ファイルは、メモリ上のランダムなアドレスにロードされることが可能になります。これは、Address Space Layout Randomization (ASLR) と組み合わせて使用され、セキュリティを向上させます。攻撃者が特定の関数のアドレスを予測して悪用するのを困難にするため、バッファオーバーフローなどの脆弱性に対する防御策となります。
hostobj
Go言語の文脈におけるhostobj
は、Goのツールチェインではなく、ホストシステム(オペレーティングシステム)のCコンパイラやリンカによって生成されたオブジェクトファイルを指します。GoプログラムがC言語で書かれたライブラリ(例えば、cgo
を使ってCコードを呼び出す場合)とリンクする必要がある場合、これらのhostobj
がGoのリンカによって取り込まれます。
HEADTYPE
Goのリンカ (cmd/ld
) において、HEADTYPE
はターゲットとなる実行ファイルのヘッダタイプ、つまりターゲットOSの種類を示す内部変数です。例えば、Hdarwin
はmacOS、Hopenbsd
はOpenBSDを指します。この変数は、リンカが特定のOSに特化した処理を行う際に使用されます。
技術的詳細
このコミットの技術的な核心は、OpenBSDのリンカに対して、Goリンカが生成するオブジェクトファイルがPIEではないことを明示的に伝える点にあります。OpenBSD 5.3/5.4以降では、デフォルトでPIEが有効になっているため、リンカはすべてのオブジェクトファイルがPIE互換であることを期待します。しかし、当時のGoリンカはPIE互換のオブジェクトを生成していなかったため、この期待が満たされず、リンクエラーが発生していました。
解決策として、GoリンカはOpenBSDをターゲットとする場合に、外部リンカ(通常はgcc
など)に-Wl,-nopie
というフラグを渡すように変更されました。
-Wl,
:これは、gcc
などのコンパイラドライバに対して、続く引数をリンカに直接渡すように指示するフラグです。-nopie
:これは、OpenBSDのリンカ(ld
)に対するフラグで、生成される実行ファイルがPIEではないことを明示的に指定します。これにより、リンカはPIE互換性のチェックを緩和し、Goリンカが生成した非PIEオブジェクトファイルとのリンクを許可します。
この変更により、GoリンカはOpenBSDの新しいバージョンでhostobj
と正しくリンクできるようになり、GoプログラムがOpenBSD環境で問題なくビルドおよび実行されるようになりました。
コアとなるコードの変更箇所
変更はsrc/cmd/ld/lib.c
ファイルにあります。
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -574,6 +574,8 @@ hostlink(void)
}
if(HEADTYPE == Hdarwin)
argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000";
+ if(HEADTYPE == Hopenbsd)
+ argv[argc++] = "-Wl,-nopie";
if(iself && AssumeGoldLinker)
argv[argc++] = "-Wl,--rosegment";
コアとなるコードの解説
hostlink
関数は、GoプログラムがC言語のオブジェクトファイル(hostobj
)とリンクする際に、外部リンカを呼び出すための引数を構築する役割を担っています。
変更前のコードでは、HEADTYPE == Hdarwin
(macOSをターゲットとする場合)にのみ、特定のリンカフラグ(-Wl,-no_pie,-pagezero_size,4000000
)が追加されていました。これは、macOSのリンカに対する特定の要件に対応するためのものです。
このコミットでは、以下の行が追加されました。
if(HEADTYPE == Hopenbsd)
argv[argc++] = "-Wl,-nopie";
このコードは、GoリンカがOpenBSDをターゲットとしてビルドを行う場合にのみ実行されます。HEADTYPE
がHopenbsd
であると判断された場合、argv
配列(外部リンカに渡される引数のリスト)に"-Wl,-nopie"
が追加されます。
argv[argc++]
:これは、argv
配列の現在の末尾に新しい引数を追加し、argc
(引数の数)をインクリメントするC言語の一般的なイディオムです。
このシンプルな追加により、OpenBSDのリンカは、Goリンカが生成するオブジェクトファイルがPIEではないことを認識し、リンクプロセスを正常に完了できるようになります。
関連リンク
- Go Issue #5067: cmd/ld: make hostobj work on newer openbsd
- Go CL 7572049: cmd/ld: make hostobj work on newer openbsd
参考にした情報源リンク
- Position-independent code - Wikipedia: https://en.wikipedia.org/wiki/Position-independent_code
- Position-independent executable - Wikipedia: https://en.wikipedia.org/wiki/Position-independent_executable
- Address space layout randomization - Wikipedia: https://en.wikipedia.org/wiki/Address_space_layout_randomization
- OpenBSD: https://www.openbsd.org/
- GCC Command Options - Linker Options: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
- ld(1) - OpenBSD man page: (通常、オンラインで
ld(1) openbsd
で検索すると見つかります。例: https://man.openbsd.org/ld.1) - Go言語のリンカに関するドキュメント(Goのソースコードや公式ドキュメントを参照)