[インデックス 17923] ファイルの概要
このコミットは、Goコンパイラのcmd/5g
(ARM), cmd/6g
(AMD64), cmd/8g
(386) において、リンカの共通ライブラリであるliblink
を使用するように変更するものです。これは、Go 1.3におけるリンカの再設計(golang.org/s/go13linker
)に向けた準備作業の一環です。
コミット
commit f606c1be805e939e1aebcb9d3e15adf4eb5f7016
Author: Russ Cox <rsc@golang.org>
Date: Sun Dec 8 22:51:55 2013 -0500
cmd/5g, cmd/6g, cmd/8g: use liblink
Preparation for golang.org/s/go13linker work.
This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.
R=iant
CC=golang-dev
https://golang.org/cl/34590045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016
元コミット内容
cmd/5g, cmd/6g, cmd/8g: use liblink
Preparation for golang.org/s/go13linker work.
This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.
変更の背景
このコミットの主な背景は、Go 1.3リリースに向けて計画されていたリンカの大規模な再設計です。Goの初期バージョンでは、各アーキテクチャ(ARM, AMD64, 386など)のコンパイラ(5g
, 6g
, 8g
)がそれぞれ独自のオブジェクトファイル生成ロジックと、それに密接に関連するリンカとの連携部分を持っていました。これにより、新しいアーキテクチャのサポートやリンカの機能改善を行う際に、各コンパイラの実装を個別に変更する必要があり、開発のオーバーヘッドが大きくなっていました。
golang.org/s/go13linker
で言及されているように、Go 1.3ではリンカのコードベースを共通化し、よりモジュール化された設計に移行する目標がありました。この目標を達成するためには、コンパイラ側がリンカとやり取りする方法も標準化する必要がありました。
このコミットは、その標準化の一歩として、各コンパイラが共通のリンカライブラリであるliblink
を利用するように変更することで、将来のリンカの変更がコンパイラに与える影響を最小限に抑え、コードの重複を排除することを目的としています。コミットメッセージにある「This CL does not build by itself. It depends on 35740044 and 35790044 and will be submitted at the same time.」という記述は、この変更がリンカ側の変更と密接に連携しており、単独では機能しないことを示しています。
前提知識の解説
Goコンパイラの構造 (Go 1.x以前)
Goのコンパイラは、gc
(Go Compiler) と呼ばれるフロントエンドと、各アーキテクチャ固有のバックエンド(例: 5g
for ARM, 6g
for AMD64, 8g
for 386)に分かれていました。
gc
: Go言語のソースコードを解析し、抽象構文木 (AST) を生成し、型チェック、最適化、中間コード(PcodeまたはSSAの前段階)への変換を行います。5g
,6g
,8g
など:gc
から出力された中間コードを受け取り、各アーキテクチャの機械語に変換し、オブジェクトファイルを生成します。このオブジェクトファイルは、最終的にリンカによって実行可能ファイルに結合されます。
リンカの役割
リンカは、コンパイラが生成した複数のオブジェクトファイルやライブラリを結合し、実行可能なプログラムを生成するツールです。シンボル解決(関数や変数のアドレスを決定する)や、再配置(コード内のアドレス参照を実際のメモリ位置に調整する)などの重要なタスクを実行します。
liblink
liblink
は、Goのリンカが内部的に使用する共通のライブラリです。Go 1.3以前は、各コンパイラがオブジェクトファイルを生成する際に、リンカと密接に連携する独自のコードを持っていました。liblink
を導入することで、これらの共通のリンカ関連の処理を一つのライブラリに集約し、コンパイラとリンカ間のインターフェースを標準化することが可能になります。これにより、リンカの内部実装が変更されても、コンパイラ側の変更を最小限に抑えることができます。
golang.org/s/go13linker
これは、Go 1.3におけるリンカの再設計に関する設計ドキュメントまたは提案を指します。Goのリンカは元々Plan 9のツールチェインから派生しており、その設計はシンプルでしたが、大規模なプロジェクトやクロスコンパイルの複雑さが増すにつれて、いくつかの課題を抱えていました。go13linker
の取り組みは、これらの課題を解決し、リンカのパフォーマンス、機能、保守性を向上させることを目的としていました。このコミットは、その大規模な変更の前提となる、コンパイラ側の準備作業です。
技術的詳細
このコミットは、主に以下の技術的な変更を含んでいます。
-
Addr
およびProg
構造体の削除:src/cmd/5g/gg.h
,src/cmd/6g/gg.h
,src/cmd/8g/gg.h
から、Addr
(アドレス表現) およびProg
(命令表現) 構造体の定義が削除されています。これらの構造体は、各コンパイラが独自に持っていたオブジェクトコード生成のための内部表現でした。liblink
の導入により、これらの共通のデータ構造はliblink
内で定義され、コンパイラはliblink
が提供するインターフェースを通じてオブジェクトコードを生成するようになります。これにより、各コンパイラがこれらの構造体を個別に管理する必要がなくなります。
-
zname
,zfile
,zhist
,zaddr
,zsymreset
,zsym
,zsymaddr
,dumpfuncs
関数の削除:src/cmd/*/gobj.c
から、オブジェクトファイルの書き出しやシンボル管理に関連する多数の関数が削除されています。これらの関数は、各コンパイラがオブジェクトファイルを生成する際の低レベルな処理を担っていました。- これらの機能は
liblink
に集約され、コンパイラはliblink
が提供する高レベルなAPIを呼び出すことで、同様の処理を実行するようになります。これにより、各コンパイラの実装が大幅に簡素化されます。
-
linksym
関数の導入と利用:- 多くの箇所で、シンボル(
Sym*
)を直接使用していた部分がlinksym(sym)
という形式に変更されています。linksym
は、liblink
が提供する関数で、コンパイラ内部のシンボルをリンカが認識できる形式に変換する役割を担います。これは、コンパイラとリンカ間のシンボル管理の橋渡しをする重要な変更です。 - 例えば、
p->to.sym = n->left->sym;
がp->to.sym = linksym(n->left->sym);
に変更されています。
- 多くの箇所で、シンボル(
-
LinkArch
構造体の利用:src/cmd/*/galign.c
において、LinkArch* thelinkarch = &linkarm;
のような行が追加されています。これは、各アーキテクチャ固有のリンカ設定をliblink
に渡すための構造体です。これにより、liblink
は各アーキテクチャの特性(アライメント、レジスタなど)を考慮したオブジェクトコードを生成できるようになります。
-
newplist
関数の変更:src/cmd/*/gsubr.c
のnewplist
関数(プログラムリストの管理に関連)が、linknewplist(ctxt)
を呼び出すように変更されています。これは、プログラムリストの管理もliblink
に委譲されることを示しています。
これらの変更は、各コンパイラがオブジェクトファイルを生成する際の低レベルな詳細をliblink
に抽象化し、コンパイラコードの複雑性を軽減するとともに、リンカの共通化を促進するためのものです。
コアとなるコードの変更箇所
このコミットは、Goコンパイラの複数のアーキテクチャ固有のバックエンド(cmd/5g
, cmd/6g
, cmd/8g
)と、共通のフロントエンド(cmd/gc
)にわたる広範な変更を含んでいます。
特に影響が大きいのは以下のファイル群です。
src/cmd/*/gg.h
: 各アーキテクチャのヘッダーファイル。Addr
とProg
構造体の定義が削除されています。src/cmd/5g/gg.h
src/cmd/6g/gg.h
src/cmd/8g/gg.h
src/cmd/*/gobj.c
: 各アーキテクチャのオブジェクトファイル生成ロジック。zname
,zfile
,zhist
,zaddr
,zsymreset
,zsym
,zsymaddr
,dumpfuncs
など、オブジェクトファイルの書き出しとシンボル管理に関連する多数の関数が削除されています。src/cmd/5g/gobj.c
src/cmd/6g/gobj.c
src/cmd/8g/gobj.c
src/cmd/*/ggen.c
,src/cmd/*/gsubr.c
,src/cmd/*/list.c
,src/cmd/*/peep.c
,src/cmd/*/reg.c
: これらのファイルでは、Addr
構造体やSym
構造体の直接的な操作が、linksym
関数を介した操作や、nil
チェックへの変更など、liblink
のインターフェースに合わせた変更が行われています。src/cmd/*/galign.c
:LinkArch* thelinkarch
変数の追加。src/cmd/5g/galign.c
src/cmd/6g/galign.c
src/cmd/8g/galign.c
src/cmd/gc/obj.c
:gc
フロントエンドにおけるオブジェクト関連の処理も変更されています。
変更の性質上、削除行が挿入行を大幅に上回っており、これは多くのコードが各コンパイラからliblink
へと移動したことを示しています。
コアとなるコードの解説
このコミットの核心は、Goコンパイラのバックエンドが、オブジェクトファイルの生成とシンボル管理の責任を、共通のliblink
ライブラリに委譲する点にあります。
具体的な変更のパターンは以下の通りです。
-
データ構造の抽象化:
- 以前は各コンパイラが独自に定義していた
Addr
やProg
といった低レベルなデータ構造が、ヘッダーファイルから削除されました。これは、これらの構造体がliblink
内部で管理されるようになり、コンパイラはそれらを直接操作する必要がなくなったことを意味します。 - 例:
src/cmd/5g/gg.h
からAddr
とProg
の定義が削除。
- 以前は各コンパイラが独自に定義していた
-
オブジェクトファイル書き出しロジックの共通化:
zname
,zfile
,zhist
,zaddr
,dumpfuncs
といった、オブジェクトファイルへのバイト列書き込みやシンボル情報のシリアライズを担当していた関数群が、gobj.c
ファイルから削除されました。- これらの機能は
liblink
に移行し、コンパイラはliblink
が提供するより抽象化されたAPI(例:linknewplist
,linksym
)を呼び出すことで、同様の処理を実行します。これにより、各アーキテクチャのgobj.c
ファイルは大幅に簡素化されます。 - 例:
src/cmd/5g/gobj.c
からzname
関数が削除。
-
シンボル解決の委譲:
- コンパイラ内部で管理されていたシンボル(
Sym*
)が、リンカが理解できる形式に変換されるようになりました。これは、linksym
関数を介して行われます。 - 例:
p->to.sym = n->left->sym;
がp->to.sym = linksym(n->left->sym);
に変更。これは、n->left->sym
というコンパイラ内部のシンボル表現を、リンカが処理できるシンボル表現に変換してp->to.sym
に設定していることを示します。
- コンパイラ内部で管理されていたシンボル(
-
アーキテクチャ固有情報のリンカへの引き渡し:
- 各アーキテクチャの
galign.c
ファイルにLinkArch* thelinkarch
変数が追加され、アーキテクチャ固有のリンカ設定(例:linkarm
,linkamd64
,link386
)がliblink
に渡されるようになりました。これにより、liblink
は各アーキテクチャの特性に応じたコード生成や最適化を行うことができます。 - 例:
src/cmd/5g/galign.c
にLinkArch* thelinkarch = &linkarm;
が追加。
- 各アーキテクチャの
これらの変更は、Goコンパイラのバックエンドとリンカの間の結合度を緩め、リンカの再設計を容易にするための重要なステップです。これにより、将来的にリンカの内部実装が大きく変更されても、コンパイラ側のコードを大幅に修正する必要がなくなります。
関連リンク
- Go 1.3 Release Notes (リンカの変更に関する言及がある可能性): https://go.dev/doc/go1.3
- Goのツールチェインに関するドキュメント (一般的な情報): https://go.dev/doc/
参考にした情報源リンク
- コミットハッシュ:
f606c1be805e939e1aebcb9d3e15adf4eb5f7016
- GitHubコミットページ: https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016
- Go issue tracker (関連するissueやCLがある可能性): https://go.dev/issue
- Goのメーリングリストアーカイブ (golang-devなど、議論の履歴がある可能性): https://groups.google.com/g/golang-dev
golang.org/s/go13linker
(このコミットの背景にある設計ドキュメント): このリンクはGoの内部ドキュメントへのショートリンクであり、直接アクセスはできませんが、Goのソースコードリポジトリや関連する設計ドキュメントでその内容が公開されている可能性があります。liblink
に関するGoのソースコード:src/cmd/link
ディレクトリ以下にliblink
の実装が含まれています。```markdown
[インデックス 17923] ファイルの概要
このコミットは、Goコンパイラのcmd/5g
(ARM), cmd/6g
(AMD64), cmd/8g
(386) において、リンカの共通ライブラリであるliblink
を使用するように変更するものです。これは、Go 1.3におけるリンカの再設計(golang.org/s/go13linker
)に向けた準備作業の一環です。
コミット
commit f606c1be805e939e1aebcb9d3e15adf4eb5f7016
Author: Russ Cox <rsc@golang.org>
Date: Sun Dec 8 22:51:55 2013 -0500
cmd/5g, cmd/6g, cmd/8g: use liblink
Preparation for golang.org/s/go13linker work.
This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.
R=iant
CC=golang-dev
https://golang.org/cl/34590045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016
元コミット内容
cmd/5g, cmd/6g, cmd/8g: use liblink
Preparation for golang.org/s/go13linker work.
This CL does not build by itself. It depends on 35740044
and 35790044 and will be submitted at the same time.
変更の背景
このコミットの主な背景は、Go 1.3リリースに向けて計画されていたリンカの大規模な再設計です。Goの初期バージョンでは、各アーキテクチャ(ARM, AMD64, 386など)のコンパイラ(5g
, 6g
, 8g
)がそれぞれ独自のオブジェクトファイル生成ロジックと、それに密接に関連するリンカとの連携部分を持っていました。これにより、新しいアーキテクチャのサポートやリンカの機能改善を行う際に、各コンパイラの実装を個別に変更する必要があり、開発のオーバーヘッドが大きくなっていました。
golang.org/s/go13linker
で言及されているように、Go 1.3ではリンカのコードベースを共通化し、よりモジュール化された設計に移行する目標がありました。この目標を達成するためには、コンパイラ側がリンカとやり取りする方法も標準化する必要がありました。
このコミットは、その標準化の一歩として、各コンパイラが共通のリンカライブラリであるliblink
を利用するように変更することで、将来のリンカの変更がコンパイラに与える影響を最小限に抑え、コードの重複を排除することを目的としています。コミットメッセージにある「This CL does not build by itself. It depends on 35740044 and 35790044 and will be submitted at the same time.」という記述は、この変更がリンカ側の変更と密接に連携しており、単独では機能しないことを示しています。
前提知識の解説
Goコンパイラの構造 (Go 1.x以前)
Goのコンパイラは、gc
(Go Compiler) と呼ばれるフロントエンドと、各アーキテクチャ固有のバックエンド(例: 5g
for ARM, 6g
for AMD64, 8g
for 386)に分かれていました。
gc
: Go言語のソースコードを解析し、抽象構文木 (AST) を生成し、型チェック、最適化、中間コード(PcodeまたはSSAの前段階)への変換を行います。5g
,6g
,8g
など:gc
から出力された中間コードを受け取り、各アーキテクチャの機械語に変換し、オブジェクトファイルを生成します。このオブジェクトファイルは、最終的にリンカによって実行可能ファイルに結合されます。
リンカの役割
リンカは、コンパイラが生成した複数のオブジェクトファイルやライブラリを結合し、実行可能なプログラムを生成するツールです。シンボル解決(関数や変数のアドレスを決定する)や、再配置(コード内のアドレス参照を実際のメモリ位置に調整する)などの重要なタスクを実行します。
liblink
liblink
は、Goのリンカが内部的に使用する共通のライブラリです。Go 1.3以前は、各コンパイラがオブジェクトファイルを生成する際に、リンカと密接に連携する独自のコードを持っていました。liblink
を導入することで、これらの共通のリンカ関連の処理を一つのライブラリに集約し、コンパイラとリンカ間のインターフェースを標準化することが可能になります。これにより、リンカの内部実装が変更されても、コンパイラ側の変更を最小限に抑えることができます。
golang.org/s/go13linker
これは、Go 1.3におけるリンカの再設計に関する設計ドキュメントまたは提案を指します。Goのリンカは元々Plan 9のツールチェインから派生しており、その設計はシンプルでしたが、大規模なプロジェクトやクロスコンパイルの複雑さが増すにつれて、いくつかの課題を抱えていました。go13linker
の取り組みは、これらの課題を解決し、リンカのパフォーマンス、機能、保守性を向上させることを目的としていました。このコミットは、その大規模な変更の前提となる、コンパイラ側の準備作業です。
技術的詳細
このコミットは、主に以下の技術的な変更を含んでいます。
-
Addr
およびProg
構造体の削除:src/cmd/5g/gg.h
,src/cmd/6g/gg.h
,src/cmd/8g/gg.h
から、Addr
(アドレス表現) およびProg
(命令表現) 構造体の定義が削除されています。これらの構造体は、各コンパイラが独自に持っていたオブジェクトコード生成のための内部表現でした。liblink
の導入により、これらの共通のデータ構造はliblink
内で定義され、コンパイラはliblink
が提供するインターフェースを通じてオブジェクトコードを生成するようになります。これにより、各コンパイラがこれらの構造体を個別に管理する必要がなくなります。
-
zname
,zfile
,zhist
,zaddr
,zsymreset
,zsym
,zsymaddr
,dumpfuncs
関数の削除:src/cmd/*/gobj.c
から、オブジェクトファイルの書き出しやシンボル管理に関連する多数の関数が削除されています。これらの関数は、各コンパイラがオブジェクトファイルを生成する際の低レベルな処理を担っていました。- これらの機能は
liblink
に集約され、コンパイラはliblink
が提供する高レベルなAPIを呼び出すことで、同様の処理を実行するようになります。これにより、各コンパイラの実装が大幅に簡素化されます。
-
linksym
関数の導入と利用:- 多くの箇所で、シンボル(
Sym*
)を直接使用していた部分がlinksym(sym)
という形式に変更されています。linksym
は、liblink
が提供する関数で、コンパイラ内部のシンボルをリンカが認識できる形式に変換する役割を担います。これは、コンパイラとリンカ間のシンボル管理の橋渡しをする重要な変更です。 - 例えば、
p->to.sym = n->left->sym;
がp->to.sym = linksym(n->left->sym);
に変更されています。
- 多くの箇所で、シンボル(
-
LinkArch
構造体の利用:src/cmd/*/galign.c
において、LinkArch* thelinkarch = &linkarm;
のような行が追加されています。これは、各アーキテクチャ固有のリンカ設定をliblink
に渡すための構造体です。これにより、liblink
は各アーキテクチャの特性(アライメント、レジスタなど)を考慮したオブジェクトコードを生成できるようになります。
-
newplist
関数の変更:src/cmd/*/gsubr.c
のnewplist
関数(プログラムリストの管理に関連)が、linknewplist(ctxt)
を呼び出すように変更されています。これは、プログラムリストの管理もliblink
に委譲されることを示しています。
これらの変更は、各コンパイラがオブジェクトファイルを生成する際の低レベルな詳細をliblink
に抽象化し、コンパイラコードの複雑性を軽減するとともに、リンカの共通化を促進するためのものです。
コアとなるコードの変更箇所
このコミットは、Goコンパイラの複数のアーキテクチャ固有のバックエンド(cmd/5g
, cmd/6g
, cmd/8g
)と、共通のフロントエンド(cmd/gc
)にわたる広範な変更を含んでいます。
特に影響が大きいのは以下のファイル群です。
src/cmd/*/gg.h
: 各アーキテクチャのヘッダーファイル。Addr
とProg
構造体の定義が削除されています。src/cmd/5g/gg.h
src/cmd/6g/gg.h
src/cmd/8g/gg.h
src/cmd/*/gobj.c
: 各アーキテクチャのオブジェクトファイル生成ロジック。zname
,zfile
,zhist
,zaddr
,zsymreset
,zsym
,zsymaddr
,dumpfuncs
など、オブジェクトファイルの書き出しとシンボル管理に関連する多数の関数が削除されています。src/cmd/5g/gobj.c
src/cmd/6g/gobj.c
src/cmd/8g/gobj.c
src/cmd/*/ggen.c
,src/cmd/*/gsubr.c
,src/cmd/*/list.c
,src/cmd/*/peep.c
,src/cmd/*/reg.c
: これらのファイルでは、Addr
構造体やSym
構造体の直接的な操作が、linksym
関数を介した操作や、nil
チェックへの変更など、liblink
のインターフェースに合わせた変更が行われています。src/cmd/*/galign.c
:LinkArch* thelinkarch
変数の追加。src/cmd/5g/galign.c
src/cmd/6g/galign.c
src/cmd/8g/galign.c
src/cmd/gc/obj.c
:gc
フロントエンドにおけるオブジェクト関連の処理も変更されています。
変更の性質上、削除行が挿入行を大幅に上回っており、これは多くのコードが各コンパイラからliblink
へと移動したことを示しています。
コアとなるコードの解説
このコミットの核心は、Goコンパイラのバックエンドが、オブジェクトファイルの生成とシンボル管理の責任を、共通のliblink
ライブラリに委譲する点にあります。
具体的な変更のパターンは以下の通りです。
-
データ構造の抽象化:
- 以前は各コンパイラが独自に定義していた
Addr
やProg
といった低レベルなデータ構造が、ヘッダーファイルから削除されました。これは、これらの構造体がliblink
内部で管理されるようになり、コンパイラはそれらを直接操作する必要がなくなったことを意味します。 - 例:
src/cmd/5g/gg.h
からAddr
とProg
の定義が削除。
- 以前は各コンパイラが独自に定義していた
-
オブジェクトファイル書き出しロジックの共通化:
zname
,zfile
,zhist
,zaddr
,dumpfuncs
といった、オブジェクトファイルへのバイト列書き込みやシンボル情報のシリアライズを担当していた関数群が、gobj.c
ファイルから削除されました。- これらの機能は
liblink
に移行し、コンパイラはliblink
が提供するより抽象化されたAPI(例:linknewplist
,linksym
)を呼び出すことで、同様の処理を実行します。これにより、各アーキテクチャのgobj.c
ファイルは大幅に簡素化されます。 - 例:
src/cmd/5g/gobj.c
からzname
関数が削除。
-
シンボル解決の委譲:
- コンパイラ内部で管理されていたシンボル(
Sym*
)が、リンカが理解できる形式に変換されるようになりました。これは、linksym
関数を介して行われます。 - 例:
p->to.sym = n->left->sym;
がp->to.sym = linksym(n->left->sym);
に変更。これは、n->left->sym
というコンパイラ内部のシンボル表現を、リンカが処理できるシンボル表現に変換してp->to.sym
に設定していることを示します。
- コンパイラ内部で管理されていたシンボル(
-
アーキテクチャ固有情報のリンカへの引き渡し:
- 各アーキテクチャの
galign.c
ファイルにLinkArch* thelinkarch
変数が追加され、アーキテクチャ固有のリンカ設定(例:linkarm
,linkamd64
,link386
)がliblink
に渡されるようになりました。これにより、liblink
は各アーキテクチャの特性に応じたコード生成や最適化を行うことができます。 - 例:
src/cmd/5g/galign.c
にLinkArch* thelinkarch = &linkarm;
が追加。
- 各アーキテクチャの
これらの変更は、Goコンパイラのバックエンドとリンカの間の結合度を緩め、リンカの再設計を容易にするための重要なステップです。これにより、将来的にリンカの内部実装が大きく変更されても、コンパイラ側のコードを大幅に修正する必要がなくなります。
関連リンク
- Go 1.3 Release Notes (リンカの変更に関する言及がある可能性): https://go.dev/doc/go1.3
- Goのツールチェインに関するドキュメント (一般的な情報): https://go.dev/doc/
参考にした情報源リンク
- コミットハッシュ:
f606c1be805e939e1aebcb9d3e15adf4eb5f7016
- GitHubコミットページ: https://github.com/golang/go/commit/f606c1be805e939e1aebcb9d3e15adf4eb5f7016
- Go issue tracker (関連するissueやCLがある可能性): https://go.dev/issue
- Goのメーリングリストアーカイブ (golang-devなど、議論の履歴がある可能性): https://groups.google.com/g/golang-dev
golang.org/s/go13linker
(このコミットの背景にある設計ドキュメント): このリンクはGoの内部ドキュメントへのショートリンクであり、直接アクセスはできませんが、Goのソースコードリポジトリや関連する設計ドキュメントでその内容が公開されている可能性があります。liblink
に関するGoのソースコード:src/cmd/link
ディレクトリ以下にliblink
の実装が含まれています。