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

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

このコミットは、Go言語のARMアーキテクチャ向けツールチェイン(5*ツールチェイン、具体的にはアセンブラの5a、Cコンパイラの5c、リンカの5l)に関する大幅な変更を含んでいます。主な変更は、これらのツールをGoのビルドシステムに統合し、既存のx86向けツールチェイン(6c/6a/6l)の構造に合わせるための調整、そしてコードベース全体でlong型をint32型に統一する作業です。

変更されたファイルは多岐にわたり、主にsrc/cmd/5a/src/cmd/5c/src/cmd/5l/ディレクトリ内のソースコードとMakefileが含まれます。具体的には、Makefileの新規作成や修正、ヘッダーファイルのインクルードパスの変更、そして多数のC言語ソースファイルにおける型定義の変更(longからint32への置換)が行われています。

コミット

commit 99cc2fee815e6377d5de1244fda8b220df43ad5a
Author: Kai Backman <kaib@golang.org>
Date:   Wed Mar 25 16:31:38 2009 -0700

    This is really two changes in one but given interdependencies
    and expected review latency I needed to combine the CLs.
    
    1. Made the 5* toolpath build using the go build
       system. Hooked the subdirectories to clean.bash but added a
       separate make5.bash for now. Minor massage to make the code
       more similar to the current structure of 6c/6a/6l.
    
    2. Change all references from long to int32 in line with
       similar change for the other toolchains.
    
    The end result is that 5c, 5a and 5l can now be compiled and
    the executables start up properly. Haven't thrown any input at
    them yet.
    
    R=rsc
    APPROVED=rsc
    DELTA=1052  (392 added, 328 deleted, 332 changed)
    OCL=26757
    CL=26761

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

https://github.com/golang/go/commit/99cc2fee815e6377d5de1244fda8b220df43ad5a

元コミット内容

This is really two changes in one but given interdependencies
and expected review latency I needed to combine the CLs.

1. Made the 5* toolpath build using the go build
   system. Hooked the subdirectories to clean.bash but added a
   separate make5.bash for now. Minor massage to make the code
   more similar to the current structure of 6c/6a/6l.

2. Change all references from long to int32 in line with
   similar change for the other toolchains.

The end result is that 5c, 5a and 5l can now be compiled and
the executables start up properly. Haven't thrown any input at
them yet.

R=rsc
APPROVED=rsc
DELTA=1052  (392 added, 328 deleted, 332 changed)
OCL=26757
CL=26761

変更の背景

このコミットは、Go言語が初期段階にあった2009年に行われたもので、Goのクロスコンパイル能力とマルチアーキテクチャサポートの基盤を築く上で非常に重要な意味を持っています。

当時のGo言語のツールチェインは、C言語で書かれた部分が多く、各アーキテクチャ(x86、ARMなど)向けに個別のコンパイラ、アセンブラ、リンカが存在していました。このコミットの背景には、以下の主要な動機があります。

  1. ビルドシステムの一元化と効率化: Go言語のプロジェクトが成長するにつれて、異なるアーキテクチャ向けのツールチェインのビルドプロセスを統一し、Go自身のビルドシステム(Go build system)で管理することが求められました。これにより、ビルドの複雑性を軽減し、メンテナンス性を向上させることが目的でした。特に、x86アーキテクチャ向けの6c/6a/6lツールチェインが既にGoのビルドシステムに統合されていたため、ARM向けの5*ツールチェインも同様の構造に合わせる必要がありました。
  2. 型の一貫性とポータビリティの向上: C言語におけるlong型は、そのサイズがプラットフォームによって32ビットまたは64ビットと異なる場合があります。Go言語は、明確なビット幅を持つ整数型(例: int32, int64)を採用しており、これにより異なるプラットフォーム間での挙動の不一致を防ぎ、コードのポータビリティを確保しています。このコミットは、C言語で書かれたツールチェインのコードベースにおいて、将来的なGo言語の型システムとの整合性を高め、潜在的なバグや移植性の問題を回避するために、long型を明示的なint32型に統一する作業を進めたものです。これは、Go言語の設計哲学である「シンプルさ」と「明確さ」にも合致する変更と言えます。
  3. ARMサポートの確立: ARMアーキテクチャは、モバイルデバイスや組み込みシステムで広く利用されており、Go言語がこれらのプラットフォームで動作するためには、堅牢なARM向けツールチェインが不可欠でした。このコミットは、ARM向けツールチェインがGoのビルドシステムで適切にコンパイルされ、実行可能になるための初期ステップであり、GoのARMサポートを本格的に開始するための重要なマイルストーンでした。

これらの変更は、Go言語が多様なハードウェア環境で利用されるための基盤を固め、その後の発展に大きく貢献しました。

前提知識の解説

このコミットを理解するためには、以下の前提知識が役立ちます。

  1. Go言語のツールチェイン:

    • コンパイラ (c): Goのソースコードをアセンブリコードに変換します。例えば、x86向けは6c、ARM向けは5cです。
    • アセンブラ (a): アセンブリコードをオブジェクトファイルに変換します。x86向けは6a、ARM向けは5aです。
    • リンカ (l): オブジェクトファイルを結合し、実行可能ファイルを生成します。x86向けは6l、ARM向けは5lです。
    • Go言語の初期のツールチェインは、Plan 9 from Bell Labsのツールチェインをベースにしており、C言語で実装されていました。Go 1.5以降、これらのツールはGo言語自身で再実装され、セルフホスティングが可能になりました。このコミットは、Go 1.5より前のC言語ベースのツールチェインに対する変更です。
    • 5 ツールチェイン*: ARMアーキテクチャ向けのツールチェインを指します。具体的には5a (アセンブラ), 5c (Cコンパイラ), 5l (リンカ) です。数字の5は、ARMv5アーキテクチャを指すことが多いですが、広義にはARM全般を指すこともあります。
    • 6c/6a/6l ツールチェイン: x86アーキテクチャ向けのツールチェインを指します。
  2. C言語のデータ型 longint32:

    • long: C言語の整数型の一つで、そのサイズは処理系(コンパイラやOS、アーキテクチャ)によって異なります。一般的には32ビットまたは64ビットです。この可変性が、異なるプラットフォーム間でのコードの移植性を損なう原因となることがあります。
    • int32: これは通常、stdint.hヘッダーで定義される固定幅整数型の一つです。int32_tとして定義され、常に32ビットの符号付き整数であることを保証します。これにより、プラットフォームに依存しない一貫した挙動が期待できます。
    • このコミットでは、C言語で書かれたツールチェインのコードベースにおいて、long型が持つプラットフォーム依存性を排除し、明示的に32ビット整数を意味するint32型に統一することで、コードの堅牢性とポータビリティを高めることを目指しています。
  3. GoのビルドシステムとMakefile:

    • Go言語は、独自のビルドシステムを持っており、go buildコマンドでプロジェクトをビルドできます。しかし、初期のGoツールチェインのビルドには、伝統的なUnixのmakeユーティリティとMakefileが使用されていました。
    • このコミットでは、ARM向けツールチェインのビルドを、Goのビルドシステムに統合するために、Makefileの構造を既存のx86向けツールチェインのそれに合わせる変更が行われています。これは、ビルドプロセスの標準化と自動化を促進するためのステップです。

技術的詳細

このコミットは、大きく分けて二つの技術的な変更を含んでいます。

1. 5* ツールチェインのGoビルドシステムへの統合

この変更の目的は、ARMアーキテクチャ向けのコンパイラ(5c)、アセンブラ(5a)、リンカ(5l)のビルドプロセスを、Go言語の標準的なビルドシステムに組み込むことです。これにより、Goプロジェクト全体のビルドの一貫性が保たれ、クロスコンパイル環境の構築が容易になります。

  • Makefileの新規作成と修正:
    • src/cmd/5a/Makefilesrc/cmd/5c/Makefilesrc/cmd/5l/Makefileが新規作成または大幅に修正されています。これらのMakefileは、../../Make.confをインクルードし、Goのビルドシステムが使用する共通のビルド設定を利用するように変更されています。
    • これにより、各ツールチェインのコンパイル、リンク、クリーンアップ、インストールといったプロセスが標準化されます。
    • 例えば、$(LD) -o $(TARG) -L$(GOROOT)/lib $(OFILES) -lbio -l9 のような行は、Goのリンカ($(LD))を使用して、生成されたオブジェクトファイル($(OFILES))をリンクし、最終的な実行可能ファイル($(TARG))を作成することを示しています。-L$(GOROOT)/libはGoの標準ライブラリのパスを指定し、-lbio -l9はPlan 9由来のI/Oライブラリとシステムコールライブラリをリンクすることを示唆しています。
  • コード構造の調整:
    • コミットメッセージにある「Minor massage to make the code more similar to the current structure of 6c/6a/6l」は、ARM向けツールチェインのソースコードが、既存のx86向けツールチェイン(6c/6a/6l)のディレクトリ構造やコーディングスタイルに合わせるように調整されたことを意味します。これには、ヘッダーファイルのインクルードパスの変更(例: ../5c/5.out.hから../5l/5.out.hへの変更)や、共通のユーティリティ関数の利用などが含まれます。
    • src/cmd/clean.bashsrc/cmd/make5.bashの追加も、ビルドプロセスの自動化と標準化の一環です。clean.bashは生成されたファイルをクリーンアップするためのスクリプトであり、make5.bashはARM向けツールチェインをビルドするための補助スクリプトとして一時的に追加されたものです。

2. long型からint32型への変更

この変更は、C言語で書かれたツールチェインのコードベースにおけるデータ型の統一とポータビリティの向上を目的としています。

  • 型定義の変更:
    • src/cmd/5a/a.hsrc/cmd/5c/gc.hsrc/cmd/5c/cgen.csrc/cmd/5c/mul.csrc/cmd/5c/reg.csrc/cmd/5c/swt.csrc/cmd/5c/txt.csrc/cmd/5l/l.hsrc/cmd/5l/asm.csrc/cmd/5l/list.csrc/cmd/5l/noop.csrc/cmd/5l/obj.csrc/cmd/5l/pass.cなど、多数のファイルでlong型がint32型に置き換えられています。
    • これは、C言語のlong型がプラットフォームによって32ビットまたは64ビットのいずれかになりうるという曖昧さを排除し、明示的に32ビット整数を使用することを保証するためです。
    • 例えば、ポインタのオフセット、行番号、サイズ、レジスタの値など、多くの場所でlongが使用されていましたが、これらがint32に変更されています。これにより、32ビットアーキテクチャであるARM環境でのメモリレイアウトや計算の正確性が保証されます。
  • 5.out.hの移動と参照の変更:
    • src/cmd/5c/5.out.hsrc/cmd/5l/5.out.hにリネームされ、移動しています。これは、このヘッダーファイルがリンカ(5l)により密接に関連しているため、より適切な場所に配置されたことを意味します。
    • これに伴い、他のファイルからのインクルードパスも更新されています。例えば、src/cmd/5a/a.hsrc/cmd/5c/gc.hでは、#include "../5c/5.out.h"#include "../5l/5.out.h"に変更されています。
  • compat.hの導入:
    • src/cmd/5a/a.h#include "compat.h"が追加されています。これは、異なるプラットフォーム間での互換性レイヤーを提供するためのヘッダーファイルである可能性が高いです。C言語の標準ライブラリ関数やシステムコールがプラットフォームによって異なる場合、このファイルで抽象化を行うことで、コードの移植性を高めることができます。

これらの変更は、Go言語のツールチェインが、異なるアーキテクチャやオペレーティングシステム上で一貫して動作するための基盤を強化するものであり、Goのクロスコンパイル能力の重要な側面を形成しています。

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

このコミットにおけるコアとなるコードの変更箇所は、主に以下の2点に集約されます。

  1. Makefileの新規作成と変更:

    • src/cmd/5a/Makefilesrc/cmd/5c/Makefilesrc/cmd/5l/Makefileの新規作成または大幅な変更。
    • 例: src/cmd/5a/Makefileの新規作成部分
    --- /dev/null
    +++ b/src/cmd/5a/Makefile
    @@ -0,0 +1,42 @@
    +# Copyright 2009 The Go Authors. All rights reserved.
    +# Use of this source code is governed by a BSD-style
    +# license that can be found in the LICENSE file.
    +
    +include ../../Make.conf
    +
    +TARG=\
    +	5a\
    +
    +HFILES=\
    +	a.h\
    +	y.tab.h\
    +	../5l/5.out.h\
    +	compat.h\
    +
    +OFILES=\
    +	y.tab.$O\
    +	lex.$O\
    +	compat.$O\
    +#	../5l/enam.$O\
    +
    +YFILES=\
    +	a.y\
    +
    +$(TARG): $(OFILES)
    +	$(LD) -o $(TARG) -L$(GOROOT)/lib $(OFILES) -lbio -l9
    +
    +$(OFILES): $(HFILES)
    +
    +lex.$O:	../cc/macbody ../cc/lexbody
    +
    +y.tab.h: $(YFILES)
    +	bison -y $(YFLAGS) $(YFILES)
    +
    +y.tab.c: y.tab.h
    +	test -f y.tab.c && touch y.tab.c
    +
    +clean:
    +	rm -f $(OFILES) $(TARG) *.5 enam.c 5.out a.out y.tab.h y.tab.c
    +
    +install: $(TARG)
    +	cp $(TARG) $(BIN)/$(TARG)
    
  2. longからint32への型変更:

    • 多数のC言語ソースファイルにおける変数、構造体メンバー、関数引数、戻り値の型定義の変更。
    • 例1: src/cmd/5a/a.hにおける構造体メンバーの型変更
    --- a/src/cmd/5a/a.h
    +++ b/src/cmd/5a/a.h
    @@ -59,7 +60,7 @@ struct	Sym
     {
     	Sym*	link;
     	char*	macro;
    -	long	value;
    +	int32	value;
     	ushort	type;
     	char	*name;
     	char	sym;
    @@ -91,7 +92,7 @@ EXTERN	struct
     struct	Gen
     {
     	Sym*	sym;
    -	long	offset;
    +	int32	offset;
     	short	type;
     	short	reg;
     	short	name;
    @@ -103,8 +104,8 @@ struct	Hist
     {
     	Hist*	link;
     	char*	name;
    -	long	line;
    -	long	offset;
    +	int32	line;
    +	int32	offset;
     };
     #define	H	((Hist*)0)
    
    • 例2: src/cmd/5c/gc.hにおけるEXTERN変数の型変更
    --- a/src/cmd/5c/gc.h
    +++ b/src/cmd/5c/gc.h
    @@ -163,16 +163,16 @@ struct	Rgn
     	short	regno;
     };
     
    -EXTERN	long	breakpc;
    +EXTERN	int32	breakpc;
     EXTERN	Case*	cases;
     EXTERN	Node	constnode;
     EXTERN	Node	fconstnode;
    -EXTERN	long	continpc;
    -EXTERN	long	curarg;
    -EXTERN	long	cursafe;
    +EXTERN	int32	continpc;
    +EXTERN	int32	curarg;
    +EXTERN	int32	cursafe;
     EXTERN	Prog*	firstp;
     EXTERN	Prog*	lastp;
    -EXTERN	long	maxargsafe;
    +EXTERN	int32	maxargsafe;
     EXTERN	int	mnstring;
     EXTERN	Multab	multab[20];
     EXTERN	int	retok;
    
    • 例3: src/cmd/5c/5.out.hからsrc/cmd/5l/5.out.hへのファイル移動と内容変更
    --- a/src/cmd/5c/5.out.h
    +++ b/src/cmd/5l/5.out.h
    @@ -220,8 +220,8 @@ enum	as
     typedef	struct	ieee	Ieee;
     struct	ieee
     {
    -	long	l;	/* contains ls-man	0xffffffff */
    -	long	h;	/* contains sign	0x80000000
    +	int32	l;	/* contains ls-man	0xffffffff */
    +	int32	h;	/* contains sign	0x80000000
     			    exp		0x7ff00000
     			    ms-man	0x000fffff */
     };
    

コアとなるコードの解説

1. Makefileの新規作成と変更

src/cmd/5a/Makefileの例に見られるように、このコミットではARM向けツールチェインの各コンポーネント(5a, 5c, 5l)に対して、専用のMakefileが導入されています。

  • include ../../Make.conf: これは、Goのビルドシステム全体で共有される共通のビルド設定ファイルMake.confをインクルードしています。これにより、コンパイラ($(CC))、リンカ($(LD))、アセンブラ($(AS))などのツールパスや、共通のコンパイル・リンクフラグが定義され、各ツールチェインのビルドプロセスが標準化されます。
  • TARG=\\ 5a\\: TARG変数は、ビルドされるターゲット(この場合はアセンブラの実行可能ファイル名5a)を定義します。
  • HFILESOFILES: それぞれヘッダーファイルとオブジェクトファイルをリストアップしています。HFILESには、a.h(アセンブラ固有のヘッダー)、y.tab.h(Yacc/Bisonで生成されるパーサーのヘッダー)、../5l/5.out.h(リンカ関連の共通ヘッダー)、compat.h(互換性レイヤーのヘッダー)が含まれています。OFILESには、コンパイル後に生成されるオブジェクトファイルがリストされています。
  • $(TARG): $(OFILES): これは、ターゲット$(TARG)$(OFILES)に依存することを示し、オブジェクトファイルがすべて揃った後にリンク処理が行われることを定義しています。
  • $(LD) -o $(TARG) -L$(GOROOT)/lib $(OFILES) -lbio -l9: リンクコマンドです。$(LD)はリンカ、-o $(TARG)は出力ファイル名、-L$(GOROOT)/libはGoの標準ライブラリの検索パス、$(OFILES)はリンクするオブジェクトファイル、-lbio -l9はPlan 9由来のI/Oライブラリとシステムコールライブラリをリンクすることを指定しています。
  • clean:install:: ビルド成果物を削除するクリーンアップターゲットと、ビルドされた実行可能ファイルを指定されたバイナリディレクトリ($(BIN))にコピーするインストールターゲットを定義しています。

これらのMakefileの導入により、ARM向けツールチェインのビルドがGoの全体的なビルドプロセスに組み込まれ、管理が容易になりました。

2. longからint32への型変更

この変更は、C言語のコードベースにおけるデータ型のプラットフォーム依存性を排除し、明示的な32ビット整数を使用することを保証するためのものです。

  • 構造体メンバーの変更:
    • src/cmd/5a/a.hstruct Symstruct Genstruct Histの例では、valueoffsetlineといったメンバーの型がlongからint32に変更されています。これらの値は、シンボルの値、メモリ上のオフセット、ソースコードの行番号など、32ビットで十分な範囲を表現するものです。longのサイズが64ビットのシステムでコンパイルされた場合、不必要にメモリを消費したり、予期せぬ挙動を引き起こす可能性がありましたが、int32にすることでこの問題が解消されます。
  • EXTERN変数の変更:
    • src/cmd/5c/gc.hの例では、breakpccontinpccurargcursafemaxargsafeなどのグローバル変数(EXTERNで宣言)の型がlongからint32に変更されています。これらは、プログラムカウンタ、引数のサイズ、スタックフレームのサイズなど、コンパイラの内部処理で使用される値であり、32ビットで十分な精度を持つものです。
  • 5.out.hの移動と内容変更:
    • src/cmd/5c/5.out.hsrc/cmd/5l/5.out.hに移動し、ファイル名が変更されただけでなく、その内容も更新されています。特に、struct ieee内の浮動小数点数の下位(l)と上位(h)のマンティッサを格納するメンバーの型がlongからint32に変更されています。これは、浮動小数点数の内部表現が32ビットのセグメントに分割されていることを示しており、ここでも明示的な32ビット型を使用することで、データ構造の正確性とポータビリティを確保しています。

これらの型変更は、Go言語のツールチェインが、異なるアーキテクチャ(特に32ビットのARM)上で一貫したメモリレイアウトと数値計算を行うための基盤を固めるものです。C言語のlong型が持つ曖昧さを排除し、明示的な固定幅整数型を使用することで、クロスコンパイル時の潜在的な問題を回避し、コードの堅牢性を高めています。

関連リンク

参考にした情報源リンク