背景 オリジナルの IBM OS/360 オブジェクト ファイル フォーマットは 、1964 年に新しいIBM System/360 メインフレーム コンピュータ 向けに開発されました。このフォーマットは、Univac 90/60、90/70、90/80 やFujitsu B2800 など、 プラグ互換 および類似のメインフレームのメーカーでも使用されました。このフォーマットは、シンボル レコードとモジュールに関する拡張情報を追加し、8 文字を超える名前のプロシージャと関数をサポートするように拡張されました。これは役立ちましたが、今日のより複雑なプログラミング言語や、オブジェクト、プロパティ、メソッド、Unicode サポート、仮想 メソッドなどのより高度な機能に必要な拡張情報を提供するには至りませんでした。
GOFF オブジェクト ファイル フォーマットは、これらの問題を克服する手段として、IBM によって 1995 年頃に開発されました。[ 2 ] このフォーマットが最初に言及されたのは、新しい高水準アセンブラの紹介情報でした。[ 3 ] GOFF は、関連データ (ADATA) フォーマットでデバッグ情報を埋め込むことをサポートしていますが、TEST オプションで生成される古い SYM レコードはサポートしていません。OS/360 オブジェクト ファイル フォーマットは、単に GOFF フォーマットに置き換えられただけで、廃止されたわけではなく、古いフォーマットの制限に耐えられる言語であれば、アセンブラや言語コンパイラで今でも使用されていることに注意してください。
慣例 この記事では、「モジュール」という用語は、参照先のスコープ 外にあるコードまたはデータの識別子を提供するために使用される名前または同等の記号を指します。 [ a ] モジュールは、サブルーチン、関数、Fortran 共通データまたはブロックデータ、オブジェクトまたはクラス、オブジェクトまたはクラスのメソッドまたはプロパティ、あるいはその特定のスコープ外にある外部名を参照するその他の名前付きルーチンまたは識別子を指す場合があります。この記事で「モジュール」という用語を使用しているのは、主題をより理解しやすくするためであり、IBMが「モジュール」という用語を使用する意味とは異なります。
アセンブリ言語を 機械語 に変換するプログラムを指す「アセンブラ」、アセンブリ言語を使用するプロセスを指す「アセンブルする」 、高水準言語に対して同様の処理を行う「 コンパイラ 」を使用するプロセスを指す「コンパイルする 」という用語があります。この記事では、「コンパイル」と「コンパイラ」は「アセンブル」と「アセンブラ」と互換性があります。
この記事で使用される数値は、16進数 (基数16)として指定されていない限り、すべて10進数(基数10)で表されます。数値を16進数で表す必要がある場合は、メインフレームのアセンブラ標準形式に従い、数値の前に大文字のXを付け、数値内の16進数文字をすべて大文字で表し、数値をシングルクォーテーションで囲みます。例えば、数値15deadbeef 16 はX'15DEADBEEF'と表されます。
この記事で使用される「バイト」は8ビットであり、特に指定がない限り、「バイト」と「文字」は同じものです。EBCDICの文字も8ビットです。ユーザープログラムでマルチバイト文字セット( Unicode など)を使用する場合は、2バイト(またはそれ以上)を使用します。
要件と制限 このフォーマットはOS/360オブジェクトファイルフォーマットに似ていますが、アプリケーションの構築に使用するための追加情報が追加されています。[ 4 ]
GOFFファイルは、固定長レコードまたは可変長レコードのいずれかです。 GOFFレコードは、基となるファイルシステム の単一レコード内に完全に収まる必要があります。GOFFファイルはストリーム タイプのファイルではありません。固定長レコードは80バイトでなければなりません。可変長レコードの最小サイズは56バイトです。固定長レコードの場合、レコードの末尾に未使用のバイトが発生します。これらのバイトはバイナリゼロに設定する必要があります。 GOFFレコードを読み書きするプログラムは、レコードの内部フォーマットについて仮定を立てるべきではありません。オペレーティングシステムは、プログラムがオペレーティングシステムの内部ファイル管理を意識することなく、固定長または可変長のレコードを提供できるものと想定されています。レコードの長さは、レコード自体の一部ではありません。 バイナリ値はビッグエンディアン 形式で格納されます。たとえば、値1は8ビット値の場合はX'01'、16ビット値の場合はX'0001'、32ビット値の場合はX'000000001'、64ビット値の場合はX'0000000000000001'となります。ビットは左から右に数えられ、ビット0はバイトまたはワードの一番左のビットです。 Unix システムにデプロイされるGOFFファイルには、固定長レコードが必要です。記録は、後続の記録に継続することができる。記録が継続される場合、継続される記録と継続記録の間には、中間記録が存在してはならない。 GOFFオブジェクトファイルは、HDRレコードで始まり、ENDレコードで終わります。ENDレコードには、ファイル内のGOFFレコードの数(物理レコードの数ではありません)を含める必要があります。 言語コンパイラやアセンブラは、1回のコンパイル/アセンブリで複数のGOFFファイルを生成できますが、個々のGOFFファイルは互いに分離されている必要があります。つまり、HDRレコード、中間のESD、TXTなどから構成され、ENDレコードで終わるモジュールまたはコンパイル単位の後に、HDRで始まりENDで終わる別のコンパイル単位が続く、といった具合に、必要に応じて繰り返して構成できます。 モジュール名とクラス名は大文字と 小文字を区別します。C言語で使用される「exit」という名前のモジュールは、Fortran 言語で使用される「EXIT」と同じである必要はありません。OS/360オブジェクトファイルフォーマットに適用されるいくつかの規則は、GOFFオブジェクトファイルフォーマットにも引き継がれています。これには以下が含まれます。 特に指定がない限り、すべての文字はEBCDIC 文字セットに属します。ただし、以下に示す外部名については例外とします。 ESD項目(メインプログラム、サブルーチン、関数、FORTRAN共通、オブジェクトのメソッドおよびプロパティ)は1から番号付けを開始し、新しい項目には番号のシーケンスに「ギャップ」を設けずに、次の番号を順番に付ける必要があります。 ESD項目は、他のレコード(TXTレコードやRLDレコードなど)がそれを参照する前に定義されていなければなりません。 各ESDレコードには、正確に1つのESD項目が含まれます。(これは、各ESDレコードに最大3つのESD項目を含めることができた旧形式とは異なります。) RLDレコード(移転辞書[ 5 ] )には1つ以上の項目が含まれる場合があり、RLDレコードは後続のレコードに続く場合があります。 将来の互換性を確保するため、「予約済み」と表示されているフィールドはバイナリのゼロに設定する必要があります。 外部名に使用される文字セットは GOFF 標準では定義されていませんが、使用されている文字セットを示すファイルが用意されています。(これは、2 バイト文字セットのUnicode ベースのモジュール名をサポートするためです。)ただし、一部の IBM 製品では、外部名やその他の識別子に使用できる文字が制限された範囲に限定されており、通常は (EBCDIC) の 16 進数値 X'41' から X'FE' まで、さらにシフトイン文字とシフトアウト文字である X'0F' と X'0E' がそれぞれ使用できます。 新しいフォーマットではクラス名がサポートされており、クラス名には予約済み と ユーザー指定 (非予約) の2種類があります。すべてのクラス名の最大長は16文字です。 予約済みクラス名は、1文字、アンダースコア、および1~14文字で構成されます。B_ で始まる予約済みクラス名はバインダー用に予約されています。C_ で始まり、ロード可能 としてマークされている予約済みクラス名は 、 IBM Language Environment (LE) で使用するために作成されたプログラム用に予約されています。C_ で始まり、ロード可能としてマークされていないクラス名、およびX_、Y_ 、Z_で始まるクラス名は 、 予約されていないクラス として一般に使用できます。 ユーザーが指定するクラス名は小文字でも構いません。 クラス名は外部シンボルではありません 。 IBMのマニュアルにはこのフォーマットで使用されるコードページ については記載されていませんが、この記事では037であると仮定します。ただし、これはこのフォーマットによって格納されるマシン命令やデータには影響しないはずです。 コンパイルの目的で必要であれば、バインダーが使用する以下のクラスを参照することができます。 以下のクラス名はバインダーによって予約されており、ユーザーアプリケーションからはアクセスできません。 360オブジェクトファイル形式レコードのSYMオブジェクトファイルシンボルテーブル情報は、GOFFオブジェクトファイルでは利用できません。代わりにADATAレコード(TXTのサブレコード)を使用する必要があります。
サイズ制限 z/OS XL C/C++ ユーザーガイドによると、「GOFF オブジェクトの最大サイズは 1 ギガバイトです。」[ 6 ]
レコードの種類 旧OS/360フォーマットと同様に、オブジェクトファイルレコードは6種類のレコードタイプに分類され、追加、削除、変更されたレコードが含まれます。
HDR記録(これは新しい機能です)は最初に実行される必要があり、オブジェクトファイルのヘッダーを定義します。 ESDレコードは、メインプログラム、サブルーチン、関数、ダミーセクション、Fortran共通、メソッドとプロパティ、および他のモジュールから呼び出し可能なモジュールまたはルーチンを定義します。これらは、このコンパイラ実行時にコンパイルされたプログラムまたはプログラムセグメント、およびプログラムで使用される外部ルーチン(C 言語のexit() 、FortranのCALL EXIT、 Pascal のnew()およびdispose()など)を定義するために使用されます。ESDレコードは、ESDシンボルへの参照の前に記述する必要があります。 TXTレコードは拡張され、モジュールが保持する機械語命令やデータに加えて、識別データ(IDR)レコード(20種類以上)、関連データ(ADATA)レコード、およびモジュールに関連する追加情報も含まれるようになりました。 RLDレコードはアドレスの再配置に使用されます。たとえば、モジュール内の500バイトにあるアドレスを参照するプログラムは、内部的にはそのアドレスを500として格納しますが、モジュールがメモリにロードされると、必ず別の場所に配置されます。そのため、RLDレコードはリンケージエディタまたはローダにどのアドレスを変更すべきかを指示します。また、モジュールが外部シンボルを参照する場合、通常はシンボルの値をゼロに設定し、そのシンボルのRLDエントリを含めることで、ローダまたはリンケージエディタがアドレスを正しい値に変更できるようにします。 LENレコードは新しいもので、特定の長さ情報を提供する。 ENDレコードはモジュールの終了を示し、必要に応じてプログラムの実行開始位置を指定します。これはファイル内の最後のレコードでなければなりません。
GOFF レコードは固定長または可変長にすることができます。可変長レコードを使用する場合の最小長は 56 文字ですが、ほとんどのレコードはこれより長くなります。モジュール名とクラス名を除き、すべての文字はEBCDIC 文字セットに含まれます。Unix ベースのシステムでは、固定長 (80 バイト) レコードを使用する必要があります。固定長ファイル内のレコードが固定長より短い場合は、ゼロで埋める必要があります。GOFF レコードを古い OS/360 オブジェクト形式 (レコードの最初のバイトが X'02' の場合) やファイル内に存在する可能性のあるコマンドと区別するために、各 GOFF レコードの最初のバイトは常にバイナリ値 X'03' ですが、コマンドは少なくともスペース (X'40') の文字値で開始する必要があります。GOFF レコードの次の 2 バイトは、レコードの種類、継続、およびファイル形式のバージョンを示します。これらの最初の 3 バイトはPTV フィールドとして知られています。
PTV PTVフィールドは、すべてのGOFFレコードの最初の3バイトを表します。
HDR HDRレコードは必須であり、最初のレコードでなければなりません。
ESD ESDレコードは、オブジェクト、Fortran共通エントリポイント、または代替エントリポイント内のモジュール、メインプログラム、サブルーチン、プロシージャ、関数、プロパティ、またはメソッドの公開名を示します。公開名に対応するESDレコードは、他のレコードがその名前を参照する前に、ファイル内に存在している必要があります。
継続 名前が継続レコードを必要とする固定長レコードの場合、以下が使用されます。
ADATAレコード ADATA(「関連データ」)レコードは、モジュールに関する追加のシンボル情報を提供するために使用されます。これらは、360オブジェクトファイル形式の古いSYMレコードに取って代わりました。ADATAレコードを作成するには、
レコードが属するクラス名に対して、タイプEDのESDレコードを作成します。 行動属性レコード のすべてのフィールドを0に設定するが、 クラスローディング(バイト5のビット0~1)はX'10'です バインディングアルゴリズムは0です テキストレコードスタイル(バイト2のビット0~3)はX'0010'です。 必要に応じて、読み取り専用 (バイト3のビット4)と実行不可 (バイト3のビット5~7)の値を設定します。各ADATA項目ごとにTXTレコードを作成します。 要素ESDIDは 、その特定のADATAエントリに対応するADATA EDレコードの値です。オフセット はゼロですデータ長 はADATAレコードの長さですデータ フィールドには、実際のADATAレコード自体が含まれます。 ADATAレコードは、宣言された順序でクラスの末尾に追加されます。
ADATAレコードに割り当てられたクラス名は、IBMプログラムによってバイナリ値をテキストに変換し、それを名前C_ADATAに追加することによって変換されます。したがって、番号X'0033'の項目は、テキスト文字列 C_ADATA0033 になります。
TXT TXTレコードは、モジュール内の特定のアドレス位置に配置するマシンコード命令とデータを指定します。このレコードに「長さ」を指定する必要がある場合は、その長さの値にこのレコードへの継続部分も含める必要があることに注意してください。
注意 22~23バイト目のデータ長が符号なし値であることは誤りである可能性があります。LLVMコンパイラスイートのGOFFジェネレータ部分のコメントによると 、
「仕様書に何と書いてあろうと、RLD または TXT レコードとその継続に含めることができる最大バイト数は、符号付き 16 ビット整数です。したがって、カードに添付できるバイト数は、任意に制限されて 32K-1 バイトになります。」[ 7 ]
圧縮表 TXTレコードの20~21バイト目がゼロ以外の場合、圧縮テーブルが使用されます。R値は文字列を繰り返す回数を決定するために使用され、L値は「R」回繰り返されるテキストの長さを示します。これは、テーブルや配列を空白またはゼロで初期化する場合、あるいは繰り返しデータを繰り返し回数と値で表現することが有用なその他の目的に使用できます。
IDRデータ表 TXTレコードの24バイト目から始まるIDRテーブルには、このオブジェクトファイルを作成したコンパイラまたはアセンブラ(およびそのバージョン番号)が識別されます。
GOFFファイルに格納されるほとんどの数値とは異なり、「version」、「release」、「trans_date」の値はバイナリではなくテキスト文字としての数値であることに注意してください。
通常、コンパイラやアセンブラはこのフォーマットレコードを生成せず、通常はバインダーによって作成されます。
この項目に含まれるテキストはすべて文字データであり、バイナリ情報は使用されていません。
RLD RLDレコードを使用すると、モジュールは、自身内の特定の場所への参照や外部モジュールへの参照など、再配置が必要なアドレスを参照している場所を示すことができます。
移転データ [A] R_Pointer ( Flags フィールドのバイト 0 のビット 0が 1 の場合) が省略された場合、このフィールドは 4 バイト下、バイト 8-11 で開始します。 [B] R_PointerまたはP_Pointer ( Flags フィールドのバイト 0 のビット 1が 1 の場合) が省略された場合、このフィールドは 4 バイト下、バイト 12-15 で開始します。両方の フィールドが省略された場合、このフィールドは 8 バイト下、バイト 8-11 で開始します。 [C] R_Pointer、P_Pointer、またはOffset ( Flags フィールドのバイト 0 のビット 2が 1 の場合) が省略された場合、このフィールドは 4 バイト下で開始します。いずれか 2 つが省略された場合、このフィールドは 8 バイト下で開始します。すべて が省略された場合、このフィールドは 12 バイト下で開始します。
明確にするために説明すると、Cプログラム内の「Basura」という名前のモジュールが「exit」関数を呼び出して自身を終了させる場合、R_Pointerのアドレスはルーチン「exit」のESDIDとなり、P_Pointerのアドレスは「Basura」のESDIDとなります。アドレスが同じモジュール内にある場合(内部サブルーチンや、同じモジュール内のデータへの参照など)、R_PointerとP_Pointerは同じ値になります。
レン LENレコードは、ESDレコードが作成された時点でモジュールの長さが不明だった場合に、モジュールの長さを宣言するために使用されます。たとえば、ワンパスコンパイラの場合などです。
要素 遅延長要素エントリは、継続または分割できません。
終わり END はモジュールの最後のレコードでなければなりません。「エントリ ポイント」は、モジュールの先頭以外のアドレスをその実行開始点として使用する場合に使用します。これは、プログラムにモジュールの開始前に実行不可能なデータが存在する場合に使用されます(古いバージョンのアセンブラでは、命令が指定された後、プログラムに格納されたデータの組み立てが非常に遅かったため、古いアセンブリ プログラマではよく見られるケースです)。
継続 固定長ENDレコードで指定されたエントリポイント名が54バイトより長い場合、または(このレコード自体も継続される場合)さらに77バイトより長い場合は、次の継続レコードが使用されます。
注記 ↑ この用法は IBM の用法とは異なり、IBM ではオブジェクト モジュール (コンパイル ユニット) に複数のサブルーチンなどが含まれる場合があり、ロード モジュールには複数のオブジェクト モジュールからのサブルーチンなどが含まれる場合があります。
参考文献 ↑ John R. Ehrman (2001 年 3 月 1 日). 「リンケージ エディタの仕組み: オブジェクト / ロード モジュール、リンク エディタ、ローダー、およびそれらがユーザーのために (そしてユーザーに対して) 何をするのかについてのチュートリアル」(PDF) 。FTPサーバー ( FTP ) 。IBM シリコン バレー (サンタ テレサ) 研究所、サン ノゼ。2019年 9 月 8 日 取得 。 (文書を表示するには、ヘルプ:FTPを参照してください) ↑ 「付録 C. 一般化オブジェクト ファイル フォーマット (GOFF)」 (PDF) 。MVS プログラム管理: 高度な機能 (PDF) 。z/OS (第 8 版)。ニューヨーク州ポキプシー: IBM。2007 年 9 月。pp. 205–240。SA22-7644-07。2021 年 10 月 19 日に オリジナル (PDF) からアーカイブ。2013 年 8 月 9 日 に取得 。 ↑ IBM High Level Assembler for MVS & VM & VSE Release 2 Presentation Guide (PDF) 。1995 年 12 月。SG24-3910-01。2016 年 1 月 23 日に オリジナル (PDF)からアーカイブ済み。2015 年 11 月 13 日 に取得 。 ↑ z/OS、z/VM、z/VSE 用高水準アセンブラ プログラマーズ ガイド (PDF) (第 6 版)。カリフォルニア州サンノゼ: IBM。2008 年 7 月。付録 C。SC26-4941-05。2019 年 9 月 8 日 取得 。 ↑ 「RLD」 。www.ibm.com。IBM 。2013年8月16日。 2020年7 月 10日 取得 。 ↑ "Lp64 | Ilp32" . IBM . ↑ "llvm/BinaryFormat/GOFF.h - GOFF 定義" . LLVM.ORG . 2024 年 8 月 16 日 取得 .