本文に進む 日本−日本語
日本HPホーム 製品とサービス お客様サポート/ ダウンロード ソリューション ご購入の方法
≫ お問い合わせ
詳細検索オプション
日本HPホーム
HP-UX リファレンス: セクション 4 : ファイルフォーマット > a

a.out(4)

HP-UX 11i Version 2: September 2004
≫ 

テクニカル ドキュメント

PDF版
フィードバック
ここから本文が始まります

 ≫ 目次

 ≫ 索引

名称

a.out ― アセンブラ出力とリンクエディタ出力

構文

#include <elf.h> (ELF ファイル用)

#include <a.out.h> (SOM ファイル用)

説明

ELF の a.out

a.out というファイル名は、リンクエディタ ld(1) からのデフォルトの出力ファイル名です。 リンク中にエラーがなければ、リンクエディタは a.out 実行可能ファイルを作成します。 アセンブラ as(1) の出力ファイルも、そのデフォルトの名前は異なりますが、 a.out ファイルのフォーマットに従います。

ELF ファイルを扱うプログラムは、 elf(3E) で記述するライブラリを使用する可能性があります。 このファイルフォーマットの概要は、次のとおりです。 詳細は下で述べる「参照」をご覧ください。


               リンクビュー                      実行ビュー
           _______________________         _______________________
                   ELF ヘッダー                     ELF ヘッダー
           |_____________________|         |______________________|
           |プログラムヘッダー   |         |プログラムヘッダー    |
           |     テーブル        |         |       テーブル       |
           |       任意          |         |                      |
           |_____________________|         | _____________________|
           |      セクション 1   |         |                      |
           |_____________________|         |                      |
           |        . . .        |         |    セグメント 1      |
           |                     |         |                      |
           |_____________________|         | _____________________|
           |      セクション n   |         |                      |
           |_____________________|         |                      |
           |        . . .        |         |    セグメント 2      |
           |                     |         |                      |
           |_____________________|         | _____________________|
           |        . . .        |         |         . . .        |
           |_____________________|         | _____________________|
           |セクションヘッダー   |         |セクションヘッダー    |
           |   テーブル          |         |      テーブル        |
           |                     |         |        任意          |
           |_____________________|         |______________________|

ELF ヘッダーは先頭にあり、その中にはファイルの構成を記述する「ロードマップ」があります。セクションには、命令、データ、シンボルテーブル、再配置情報など、リンクビューへの大半のオブジェクトファイル情報が入っています。 セグメントには、プログラム実行ビューへのオブジェクトファイル情報が入っています。 上で示したように、セグメントは 1 つまたは複数のセクションを含む可能性があります。

プログラムヘッダーテーブルが存在する場合、それは、プロセスイメージの作成方法をシステムに指示します。 プロセスイメージの作成 (プログラムの実行) に使用されるファイルにはプログラムヘッダーテーブルがなければなりません。 再配置可能なファイルには、プログラムヘッダーテーブルは必要ありません。 セクションヘッダーテーブルには、ファイルのセクションを説明する情報が含まれています。 テーブル内のそれぞれのセクションにはエントリーが 1 つずつあり、それぞれのエントリーがセクション名、セクションサイズなどの情報を与えます。 リンク中に使用されるファイルには、セクションヘッダーテーブルがなければなりません。 他のオブジェクトファイルには、セクションヘッダーテーブルはあってもなくてもかまいません。

この図では、ELF ヘッダーの直後にプログラムヘッダーテーブルを、またセクションの後にセクションヘッダーテーブルを示していますが、実際のファイルでは異なる可能性があります。 さらに、セクションおよびセグメントの順序に指定はありません。 ELF ヘッダーだけがファイル内の固定位置にあります。

a.out ファイルが実行のためにメモリ内にロードされると、テキストセグメント、データセグメント (初期化済みデータの次に初期化されていないデータの順、後者は実際にはすべてゼロで初期化済み)、およびスタックという 3 つの論理セグメントが設定されます。 テキストセグメントは、プログラムからは書き込み不可です。 つまり、別々のプロセスが同じ a.out ファイルを実行している場合、これらのプロセスは 1 つのテキストセグメントを共有します。

データセグメントは、最後のテキストアドレスの後にある最大のページ境界から始まります (システムで複数のページサイズがサポートされている場合「最大のページ」とはサポートされている最大のサイズです)。 プロセスイメージが作成される際に、テキストの最後およびデータの先頭が入っているファイルの部分が 2 度現れる可能性があります。 データの先頭にある重複したテキスト部分が実行されることはありません。 このように重複している場合、オペレーティングシステムは、データセクションの先頭をページ境界に配置し直さないで、ファイルの部分を実際のページサイズの倍数で取り込むことがあります。したがって、最後のテキストの後にある最大のページ境界に、最後のテキストアドレスを最大のページサイズで割った余りを加算した値が、最初のデータアドレスとなります。 最後のテキストアドレスが最大のページサイズの倍数である場合は、重複は起こりません。 スタックは、必要に応じて、自動的に拡張されます。 データセグメントは、 brk(2) システムコールで要求された通りに拡張されます。

SOM の a.out (PA-RISC のみ)

ファイル名 a.out は、アセンブラ (as(1)を参照)、コンパイラ、およびリンカ (ld(1)を参照) の出力ファイルのデフォルトファイル名です。アセンブラとコンパイラは、リンカにすぐ入力できる再配置可能オブジェクトファイルを作成します。リンカは、実行可能オブジェクトファイルと共有ライブラリファイルを作成します。

オブジェクトファイルは、ファイルヘッダー、補助ヘッダー、スペースディクシ ョナリ、サブスペースディクショナリ、シンボルテーブル、再配置情報、コンパイ ラレコード、空白文字列テーブル、シンボル文字列テーブル、および初期化済みコー ドとデータについてのデータで構成されます。これらのセクションのすべてがあらゆる オブジェクトファイルで必要なわけではありません。ファイルの先頭はファイル ヘッダーでなければなりませんが、残りのセクションは特定の順序である必要はありま せん。ファイルヘッダーには、ファイルの他の各セクションを指し示すポインターが 入っています。

アセンブラまたはコンパイラが作成する再配置可能ファイルには、少なくとも、ファイ ルヘッダー、スペースディクショナリ、サブスペースディクショナリ、シンボ ルテーブル、再配置情報、空白文字列テーブル、シンボル文字列テーブル、および コードとデータのセクションがなければなりません。補助ヘッダーとコンパイラレ コードが入っていてもかまいません。再配置可能ファイルには、一般に、未解決のシン ボルが入っています。リンカは再配置可能ファイルを結合し、ライブラリを検索して 実行可能ファイルを作成します。リンカを使用して、再配置可能ファイルを結合し、後 のリンカ実行の入力に適切な新しい再配置可能ファイルを作成することもできます。

リンカの作成する実行可能ファイルは通常、ファイルヘッダー、HP-UX 補助ヘッ ダー、スペースディクショナリ、サブスペースディクショナリ、シンボルテーブ ル、コンパイラレコード、空白文字列テーブル、シンボル文字列テーブル、および初 期化済みコードとデータについてのセクションで構成されます。また、リンカは、補助 ヘッダーとコンパイラレコードを、入力ファイルから出力ファイルにコピーします。 ファイルが削除されている (strip(1)を参照) 場合、ファイルにはシンボルテーブル、シンボル文字列テーブル、またはコンパイ ラレコードがありません。実行可能ファイルには、未解決のシンボルが入っていては なりません。

リンカの作成する共有ライブラリファイルには、実行可能ファイルと同じファイルが 入っているだけでなく、ファイルのコードセクションに情報が追加されています。こ の追加情報には、ヘッダー、エクスポートテーブル、インポートテーブル、および 動的ローダーの使用する動的再配置レコードが含まれます。

プログラムは、次の 2 つのロード可能スペースで構成されています。 $TEXT$ という名称の読み取り専用共有コードスペースと、 $PRIVATE$ という名称の書き込み可能プライベートデータスペースです。 プログラムには他に、 $THREAD_SPECIFIC$ という名称のロード可能プライベートデータスペースを入れることもできます。 プログラムには、開発ツールに必要なデータが入った他のロード不可能なスペースが入っていることもあり ます。たとえば、シンボリックデバッグ情報は、 $DEBUG$ または $PINFO$ というスペースに入っています。リンカは、ロード可能なスペースもロード不可能なス ペースも、まったく同じように取り扱うので、シンボル解決と再配置は、シンボリッ クデバッグ情報として完全な一般性を保持します。

スペースのアドレス指定範囲は 4,294,967,296 (2^32) バイトです。ロード可能な各ス ペースは、1/4 ずつ 4 つの 1,073,741,824 (2^30) バイトに分割されていま す。HP-UX オペレーティングシステムは、コードをすべて最初の 1/4 $TEXT$ スペースに入れ、データをすべて 2 番目の 1/4 $PRIVATE$ スペースに入れ、共有ライブラリコードをすべて 3 番目の 1/4 共有メモリスペース に入れます。

各スペースはさらにサブスペースと呼ばれる論理単位に分割されます。リンカは、再配 置可能オブジェクトファイルを結合するとき、入力ファイルの全サブスペースを名称 ごとにグループ分けしてから、スペース内のグループを各サブスペースに対応する ソートキーで配列します。サブスペースはアーキテクチャとしては重要ではありませ ん。多数の入力ファイルから独立に、スペースの個々の部分を結合するためのメカニズ ムに過ぎません。プログラムの代表的なサブスペースを次表に示します。

$SHLIB_INFO$動的ロードに必要な情報
$MILLICODE$ミリコードルーチン用コード
$LIT$共有可能リテラル
$CODE$コード
$UNWIND$スタックアンワインド情報
$GLOBAL$Pascal の外側ブロック宣言
$DATA$初期化済み静的データ
$COMMON$FORTRAN コモン
$BSS$初期化されていないデータ
$TBSS$スレッドのローカル記憶領域

サブスペースは初期化しても初期化しなくてもかまいません (通常は、 $BSS$$TBSS$ だけは初期化されません)。初期化済みサブスペースに関するサブスペースディクショ ナリエントリーには初期化データを指し示すファイルポインターが入れられるのに 対し、初期化済みでないサブスペースに関するエントリーには、ロード時に領域全体を 初期化するために使用される 32 ビットのパターンだけが入れられます。

再配置可能ファイルでは、初期化済みコードとデータに、ファイル内の他のどこかの位 置の参照、および他のファイルで定義されている未解決シンボルの参照が入っているこ とがよくあります。これらの参照は、リンク時に再配置情報を使用して埋め込まれま す。再配置情報 (「解決情報」) 内の各エントリーは、サブスペースに関して初期化済み データ内の位置を指定し、1 つまたは 2 つのシンボルに相対的にその位置に配置しなけ ればならない実際の値を定義する式を指定します。

リンカは、実行可能ファイルを作成するとき、サブスペースディクショナリ を HP-UX 補助ヘッダー内に要約します。HP-UX プログラムが別個に保持できのるは、 コード用セクション、初期化済みデータ用セクション、および初期化されていないデー タ用セクションの 3 つだけです。通常、この補助ヘッダーはファイルヘッダーの直後 に配置されます。

a.out ファイルが実行のためにメモリにロードされるとき、次の 3 つのメモリ領域がセットアップされます。 a.out コードは、新しい共有可能スペースの最初の 1/4 にロードされます。データ (初期化済 みのデータの後に初期化されていないデータが続く) は、新しいプライベートスペー スの 2 番目の 1/4 にロードされます。スタックは、データスペースの 2 番目の 1/4 の中央付近の固定アドレスで開始するように作成されます。

a.out ファイルが共有ライブラリを使用する場合は、動的ローダー /usr/lib/dld.sl が、メモリにロードされ、プログラムの要求する共有ライブラリをすべてメモリ にマップするために呼び出されます。共有ライブラリテキストは、共有メモリ スペースの 3 番目の 1/4 にロードされ、共有ライブラリデータはデータスペース の 2 番目の 1/4 に割り当てられます。

ここで説明するファイルフォーマットは、HP のプレシジョンアーキテクチャ向けに 設計されたあらゆるオペレーティングシステムに共通なフォーマットです。したがって、HP-UX には、使用されないフィールドおよび構造体、または将来使用するために予約済みの フィールドおよび構造体もあります。

ファイルヘッダー

ファイルヘッダーのフォーマットは、 <filehdr.h> 内の次の構造体宣言で記述されます。

struct header { 
    short int    system_id;               /* system id */ 
    short int    a_magic;                 /* magic number */ 
    unsigned int version_id;              /* a.out format version */ 
    struct       sys_clock file_time;     /* timestamp */ 
    unsigned int entry_space; /* index of space containing entry point */ 
    unsigned int entry_subspace;          /* subspace index of entry */ 
    unsigned int entry_offset;            /* offset of entry point */ 
    unsigned int aux_header_location;     /* file ptr to aux hdrs */ 
    unsigned int aux_header_size;         /* sizeof aux hdrs */ 
    unsigned int som_length;              /* length of object module */ 
    unsigned int presumed_dp;   /* DP value assumed during compilation */ 
    unsigned int space_location;          /* file ptr to space dict */ 
    unsigned int space_total;             /* # of spaces */ 
    unsigned int subspace_location;       /* file ptr to subsp dict */ 
    unsigned int subspace_total;          /* # of subspaces */ 
    unsigned int loader_fixup_location;   /* space reference array */ 
    unsigned int loader_fixup_total;      /* # of space reference recs */ 
    unsigned int space_strings_location;  /* file ptr to sp. strings */ 
    unsigned int space_strings_size;      /* sizeof sp. strings */ 
    unsigned int init_array_location;     /* location of init pointers */ 
    unsigned int init_array_total;        /* # of init pointers */ 
    unsigned int compiler_location;       /* file ptr to comp recs */ 
    unsigned int compiler_total;          /* # of compiler recs */ 
    unsigned int symbol_location;         /* file ptr to sym table */ 
    unsigned int symbol_total;            /* # of symbols */ 
    unsigned int fixup_request_location;  /* file ptr to fixups */ 
    unsigned int fixup_request_total;     /* # of fixups */ 
    unsigned int symbol_strings_location; /* file ptr to sym strings */ 
    unsigned int symbol_strings_size;     /* sizeof sym strings */ 
    unsigned int unloadable_sp_location;  /* file ptr to debug info */ 
    unsigned int unloadable_sp_size;      /* size of debug info */ 
    unsigned int checksum;                /* header checksum */ 
}; 

タイムスタンプは、次に示すように 2 ワードの構造体です。タイムスタンプが使用されない場合は、両方のフィールドがゼロになります。

struct sys_clock { 
    unsigned int secs; 
    unsigned int nanosecs; 
}; 

補助ヘッダー

補助ヘッダーは、ファイル内の 1 つの連続領域に入れられ、ファイルヘッダー内のポインターによって配置されます。補助ヘッダーは次の 2 つの目的のために使用されます。ユーザーのバージョンと著作権文字列をオブジェクトファイルに結び付けるためと、実行可能プログラムをロードするのに必要な情報を入れるためです。実行可能プログラム内では、HP-UX 補助ヘッダーは他の補助ヘッダーの前になければなりません。次の宣言は、 <aouthdr.h> にあります。

struct aux_id { 
    unsigned int mandatory : 1; /* linker must understand aux hdr info */ 
    unsigned int copy : 1;      /* copy aux hdr without modification */ 
    unsigned int append : 1;    /* merge multiple entries of same type */ 
    unsigned int ignore : 1;    /* ignore aux hdr if type unknown */ 
    unsigned int reserved : 12; /* reserved */ 
    unsigned int type : 16;     /* aux hdr type */ 
    unsigned int length;        /* sizeof rest of aux hdr */ 
}; 
 
/* Values for the aux_id.type field */ 
#define HPUX_AUX_ID            4 
#define VERSION_AUX_ID         6 
#define COPYRIGHT_AUX_ID       9 
#define SHLIB_VERSION_AUX_ID  10 
 
struct som_exec_auxhdr {         /* HP-UX auxiliary header */ 
    struct   aux_id som_auxhdr;  /* aux header id */ 
    long     exec_tsize;         /* text size */ 
    long     exec_tmem;          /* start address of text */ 
    long     exec_tfile;         /* file ptr to text */ 
    long     exec_dsize;         /* data size */ 
    long     exec_dmem;          /* start address of data */ 
    long     exec_dfile;         /* file ptr to data */ 
    long     exec_bsize;         /* bss size */ 
    long     exec_entry;         /* address of entry point */ 
    long     exec_flags;         /* loader flags */ 
    long     exec_bfill;         /* bss initialization value */ 
}; 
 
/* Values for exec_flags */ 
#define TRAP_NIL_PTRS    01 
 
struct user_string_aux_hdr {       /* Version string auxiliary header */ 
    struct aux_id header_id;       /* aux header id */ 
    unsigned int  string_length;   /* strlen(user_string) */ 
    char          user_string[1];  /* user-defined string */ 
}; 
 
struct copyright_aux_hdr {       /* Copyright string auxiliary header */ 
    struct aux_id  header_id;      /* aux header id */ 
    unsigned int   string_length;  /* strlen(user_string) */ 
    char           copyright[1];   /* user-defined string */ 
}; 
 
struct shlib_version_aux_hdr { 
    struct aux_id  header_id;      /* aux header id */ 
    short          version;        /* version number */ 
}; 

スペースディクショナリ

スペースディクショナリは、 <spacehdr.h> に定義されているように、一連のスペースレコードで構成されています。

struct space_dictionary_record { 
    union name_pt name;               /* index to space name */ 
    unsigned int is_loadable: 1;      /* space is loadable */ 
    unsigned int is_defined: 1;       /* space is defined within file */ 
    unsigned int is_private: 1;       /* space is not sharable */ 
    unsigned int has_intermediate_code: 1;  /* contains intermediate 
                                               code */ 
    unsigned int is_tspecific: 1;     /* space is $thread_specific$ */ 
    unsigned int reserved: 11;        /* reserved */ 
    unsigned int sort_key: 8;         /* sort key for space */ 
    unsigned int reserved2: 8;        /* reserved */ 
    int          space_number;        /* space index */ 
    int          subspace_index;      /* index to first subspace */ 
    unsigned int subspace_quantity;   /* # of subspaces in space */ 
    int          loader_fix_index;    /* index into loader fixup array */ 
    unsigned int loader_fix_quantity;   /* # of loader fixups in space */ 
    int          init_pointer_index;  /* index into init pointer array */ 
    unsigned int init_pointer_quantity;   /* # of init ptrs */ 
}; 

スペース名称用の文字列は、ファイルヘッダーのポインターが位置付けるスペース文字列テーブルに入れられます。 スペース文字列テーブルの各エントリーの先頭には文字列の長さを定義する 4 バイトの整数が付けられ、各エントリーの末尾は、ワード境界まで文字列をパディングする 1〜5 個のヌル文字で終了されます。 このテーブルのインデックスは、テーブルの先頭に相対的で、文字列の最初のバイト (その前にある長さを示すワードではありません) をポイントします。 次に定義する共用体は、そのような文字列ポインターすべてに使用されます。 文字列テーブルをメモリに読み込み、スペースレコードのメモリ内コピーを再配置するプログラムについて、文字ポインターが定義されています。

union name_pt { 
    char         *n_name; 
    unsigned int n_strx; 
}; 

サブスペースディクショナリ

サブスペースディクショナリは、 <scnhdr.h> に定義されている一連のサブスペースレコードで構成されます。サブスペース名称の文字列はスペース文字列テーブルに入っています。

struct subspace_dictionary_record { 
    int           space_index;          /* index into space dictionary */ 
    unsigned int  access_control_bits: 7;   /* access and priv levels 
                                               of subsp */ 
    unsigned int  memory_resident: 1;   /* lock in memory during exec */ 
    unsigned int  dup_common: 1;    /* duplicate data symbols allowed */ 
    unsigned int  is_common: 1;         /* initialized common block */ 
    unsigned int  is_loadable: 1;       /* subspace is loadable */ 
    unsigned int  quadrant: 2;          /* quadrant in space subsp 
                                           should reside in */ 
    unsigned int  initially_frozen: 1;  /* lock in memory 
                                           when OS booted */ 
    unsigned int  is_first: 1;          /* must be first subspace */ 
    unsigned int  code_only: 1;         /* subspace contains only code */ 
    unsigned int  sort_key: 8;          /* subspace sort key */ 
    unsigned int  replicate_init: 1;    /* init values to be replicated 
                                           to fill subsp len */ 
    unsigned int  continuation: 1;      /* subspace is a continuation */ 
    unsigned int  is_tspecific: 1;      /* subspace contains TLS */ 
    unsigned int  reserved: 5;          /* reserved */ 
    int           file_loc_init_value;  /* file location or init value */ 
    unsigned int  initialization_length;  /* length of initialization */ 
    unsigned int  subspace_start;       /* starting offset */ 
    unsigned int  subspace_length;      /* total subspace length */ 
    unsigned int  reserved2: 16;        /* reserved */ 
    unsigned int  alignment: 16;        /* alignment required */ 
    union name_pt name;                 /* index of subspace name */ 
    int           fixup_request_index;  /* index to first fixup */ 
    unsigned int  fixup_request_quantity;   /* # of fixup requests */ 
}; 

シンボルテーブル

シンボルテーブルは、 <syms.h> から取られた、次に示す一連のエントリーで構成されています。シンボルと修飾子の名称の文字列は、シンボル文字列テーブルにあります。このテーブルの構造はスペース文字列テーブルと同じです。

struct symbol_dictionary_record { 
    unsigned int   hidden: 1;         /* symbol not visible to loader */ 
    unsigned int   secondary_def: 1;  /* secondary def symbol */ 
    unsigned int   symbol_type: 6;    /* symbol type */ 
    unsigned int   symbol_scope: 4;   /* symbol value */ 
    unsigned int   check_level: 3;    /* type checking level */ 
    unsigned int   must_qualify: 1;   /* qualifier required */ 
    unsigned int   initially_frozen: 1;   /* lock in memory 
                                             when OS booted */ 
    unsigned int   memory_resident: 1;  /* lock in memory during exec */ 
    unsigned int   is_common: 1;      /* common block */ 
    unsigned int   dup_common: 1;   /* duplicate data symbols allowed */ 
    unsigned int   xleast: 2;         /* MPE-only */  
    unsigned int   arg_reloc: 10;     /* parameter relocation bits */ 
    union name_pt  name;              /* index to symbol name */ 
    union name_pt  qualifier_name;    /* index to qual name */ 
    unsigned int   symbol_info;       /* subspace index */ 
    unsigned int   symbol_value;      /* symbol value */ 
}; 
 
/* Values for symbol_type */ 
#define ST_NULL      0     /* unused symbol entry */ 
#define ST_ABSOLUTE  1     /* non-relocatable symbol */ 
#define ST_DATA      2     /* initialized data symbol */ 
#define ST_CODE      3     /* generic code symbol */ 
#define ST_PRI_PROG  4     /* program entry point */ 
#define ST_SEC_PROG  5     /* secondary prog entry point*/ 
#define ST_ENTRY     6     /* procedure entry point */ 
#define ST_STORAGE   7     /* storage request */ 
#define ST_STUB      8     /* MPE-only */ 
#define ST_MODULE    9     /* Pascal module name */ 
#define ST_SYM_EXT   10    /* symbol extension record */ 
#define ST_ARG_EXT   11    /* argument extension record */ 
#define ST_MILLICODE 12    /* millicode entry point */ 
#define ST_PLABEL    13    /* MPE-only */ 
#define ST_OCT_DIS   14    /* Used by OCT only--ptr to translated code */ 
#define ST_MILLI_EXT 15    /* address of external millicode */ 
#define ST_TSTORAGE  16    /* TLS common symbol */ 
 
/* Values for symbol_scope */ 
#define SS_UNSAT     0     /* unsatisfied reference */ 
#define SS_EXTERNAL  1     /* import request to external symbol */ 
#define SS_LOCAL     2     /* local symbol */ 
#define SS_UNIVERSAL 3     /* global symbol */ 

シンボル値の意味は、シンボルのタイプで定まります。コードシンボル (総称コード、プログラムエントリー点、手続き、およびミリコードエントリー点) の場合、シンボル値の下位 2 ビットが実行特権レベルをエンコードします。これは HP-UX では使用されませんが、一般には 3 に設定されます。これらのビットをマスクしたシンボル値が、シンボルのアドレスです (必ず 4 の倍数です)。データシンボルの場合、シンボル値はシンボルの単なるアドレスです。 スレッドの (共通ではない) ローカル記憶領域シンボルの場合、シンボル値は、ライブラリまたは実行可能ファイルにおけるスレッドローカル記憶領域のオフセットです。また再配置可能ファイルでは、シンボル値はシンボルの大きさです。 記憶領域要求またはスレッドの共通ローカル記憶領域の場合、シンボル値は要求されたバイト数です。リンカは、 $BSS$ または $TBSS$ サブスペース内の各シンボルについて、最大の要求を満たすスペースを割り当てます。ただし、そのシンボルについてローカルシンボルまたは普遍的シンボルが見つかった場合は別です (この場合、記憶領域要求は満足されない参照のように処理されます)。

再配置可能ファイルをパラメータの型チェックを指定してコンパイルすると、拡張レ コードが、手続きエントリー点とグローバル変数を定義するシンボルの後に続きます。 最初の拡張レコードである 「シンボル拡張レコード」 が、戻り値またはグローバル変数の型を定義し、(定義値または関数の場合) パラメー ターの数と最初の 3 つのパラメータの型を定義します。多数のパラメータの型記述 子が必要は場合は、その後に 1 つまたは複数の「引き数拡張レコード」 が続き、それぞれにさらに 4 つの記述子が入れられます。チェックレベルが 0 の場合 は型チェックは行われません。拡張レコードは後続しません。チェックレベル 1 以上 の場合、戻り値またはグローバル変数の型のチェックが指定されます。チェックレベ ルが 2 以上の場合、パラメータ数のチェックが指定されます。チェックレベルが 3 の場合、個々の各パラメータの型のチェックが指定されます。リンカは、シンボル参 照を解決するとき、満たされないシンボルと、ローカルシンボルまたは普遍的シンボ ルの間で、要求されたレベルの型チェックを行います。

union arg_descriptor { 
    struct { 
    unsigned int    reserved: 3;    /* reserved */ 
    unsigned int    packing: 1;     /* packing algorithm used */ 
    unsigned int    alignment: 4;   /* byte alignment */ 
    unsigned int    mode: 4;        /* type of descriptor and its use */ 
    unsigned int    structure: 4;   /* structure of symbol */ 
    unsigned int    hash: 1;        /* set if arg_type is hashed */ 
    int             arg_type: 15;   /* data type */ 
    }  arg_desc; 
    unsigned int    word; 
}; 
 
struct symbol_extension_record { 
    unsigned int    type: 8;                /* always ST_SYM_EXT */ 
    unsigned int    max_num_args: 8;        /* max # of parameters */ 
    unsigned int    min_num_args: 8;        /* min # of parameters */ 
    unsigned int    num_args: 8;            /* actual # of parameters */ 
    union arg_descriptor symbol_desc;       /* symbol type desc. */ 
    union arg_descriptor argument_desc[3];  /* first 3 parameters */ 
}; 
 
struct argument_desc_array { 
    unsigned int    type: 8;                /* always ST_ARG_EXT */ 
    unsigned int    reserved: 24;           /* reserved */ 
    union arg_descriptor argument_desc[4];  /* next 4 parameters */ 
}; 

arg_descriptoralignment フィールドは、データの最小整列を示します。ここで、 n の値は 2^n バイトの整列を表わします。 arg_descriptor 内の mode\cstructure\c 、および arg_type の各フィールドの値 (データ型がハッシュされないとき) を次表に示します。

モード 構造 arg_type
0任意任意任意
1値パラメータスカラーvoid
2参照パラメータ配列符号付きバイト
3値の結果構造体符号なしバイト
4名称ポインター符号付きショート
5変数ロングポインター符号なしショート
6関数戻り値C 文字列符号付きロング
7手続きPascal 文字列符号なしロング
8ロング参照パラメータ手続き符号付きダブルワード
9 関数符号なしダブルワード
10 ラベルショート実数
11  実数
12  ロング実数
13  ショート複素数
14  複素数
15  ロング複素数
16  パック 10 進数
17  構造体/配列

手続きエントリー点の場合、パラメータ再配置ビットが、仮パラメータと戻り値の位置を定義します。通常、パラメータリストの最初の 4 ワードは、スタックではなく汎用レジスタ (r26-r23) で渡され、戻り値は r29 で返されます。これに対し、この範囲の浮動小数点パラメータは、浮動小数点レジスタ (fr4-fr7) で渡され、浮動小数点値は fr4 で返されます。パラメータ再配置ビットは、パラメータリストの最初の 4 ワードと戻り値を記述する 5 組のビットで構成されます。最上位の 1 組のビットが最初のパラメータワードを記述し、最下位の 1 組のビットは戻り値を表します。これらのビットの意味を次表に示します。

ビット意味
00パラメータも戻り値もなし
01パラメータまたは戻り値は汎用レジスタ
10パラメータまたは戻り値は浮動小数点レジスタ
11倍精度値

倍精度浮動小数点パラメータの場合、奇数のパラメータワードは 11 とマークされ、奇数のパラメータワードは 10 とマークされるはずです。倍精度浮動小数点戻り値は単に 11 とマークされます。

手続きの呼び出しごとに、類似のビットの集合がタグ付けされる (以下の「再配置情報」を参照) ので、リンカは、各呼び出しを、予想される手続きエントリー点と照合できます。呼び出しとエントリー点が一致しない場合、リンカは、パラメータと戻り値を適宜再配置するポインターの控えを作成します。

再配置情報

初期化されたサブスペースはそれぞれ、そのサブスペース内のデータに適用される解決 情報の範囲を定義します。解決情報要求は、再配置が必要な各ワード、または満たされ ていない参照の入っている各ワードと対応させられます。シリーズ 800 システム上 で HP-UX リリース 3.0 以前に作成された再配置可能オブジェクトファイルでは、各 解決情報要求は、リンク時に記入されるコードまたはデータを記述する 5 ワードの構造 体です。リリース 3.0 以降で作成されたオブジェクトファイルには、サブスペース の各バイトを記述する可変長の解決情報要求が入っています。ファイルヘッダー内の version_id フィールドは、これら 2 つの形式を区別します。古いオブジェクトファイルには定数 VERSION_ID があり、新しいオブジェクトファイルには定数 NEW_VERSION_ID があります。

古いオブジェクトファイルでは、解決情報はゼロ個、1 個、または 2 個のシンボル と 1 個の定数を含む式を計算し、その結果からビットの 1 フィールドを抽出し、それら のビットを (プレシジョンアーキテクチャ命令セットに対応する) いくつかの異なる 形式でため込めます。サブスペースディクショナリエントリーの fixup_request_index フィールドは、ファイルヘッダーで定義される解決情報要求領域をインデックスで指 し示し、 fixup_request_quantity フィールドは、そのサブスペースに使用される解決情報要求の数を指します。解決情報 要求の構造体は、 <reloc.h> に入っています。

struct fixup_request_record { 
    unsigned int  need_data_ref: 1;    /* reserved */ 
    unsigned int  arg_reloc: 10;       /* parameter relocation bits */ 
    unsigned int  expression_type: 5;  /* how to compute value */ 
    unsigned int  exec_level: 2;       /* reserved */ 
    unsigned int  fixup_format: 6;     /* how to deposit bits */ 
    unsigned int  fixup_field: 8;      /* field to extract */ 
    unsigned int  subspace_offset;     /* subspace offset of word */ 
    unsigned int  symbol_index_one;    /* index of first symbol */ 
    unsigned int  symbol_index_two;    /* index of second symbol */ 
    int           fixup_constant;      /* constant */ 
}; 
 
/* Values for expression_type */ 
#define e_one     0   /* symbol1 + constant */ 
#define e_two     1   /* symbol1 - symbol2 + constant */ 
#define e_pcrel   2   /* symbol1 - pc + constant */ 
#define e_con     3   /* constant */ 
#define e_plabel  7   /* symbol1 + constant */ 
#define e_abs     18  /* absolute, 1st sym index is address */ 
 
/* Values for fixup_field (assembler mnemonics shown) */ 
#define e_fsel    0   /* F': no change */ 
#define e_lssel   1   /* LS': inverse of RS' */ 
#define e_rssel   2   /* RS': rightmost 11 bits, signed */ 
#define e_lsel    3   /* L': leftmost 21 bits */ 
#define e_rsel    4   /* R': rightmost 11 bits */ 
#define e_ldsel   5   /* LD': inverse of RD' */ 
#define e_rdsel   6   /* RD': rightmost 11 bits, filled left with ones */ 
#define e_lrsel   7   /* LR': L' with "rounded" constant */ 
#define e_rrsel   8   /* RR': R' with "rounded" constant */ 
#define e_nsel    9   /* N1': set all bits to zero: for id of 3-inst 
                              code gen sequence */ 
 
/* Values for fixup_format (typical instructions shown) */ 
#define i_exp14   0   /* 14-bit immediate (LDW, STW) */ 
#define i_exp21   1   /* 21-bit immediate (LDIL, ADDIL) */ 
#define i_exp11   2   /* 11-bit immediate (ADDI, SUBI) */ 
#define i_rel17   3   /* 17-bit pc-relative (BL) */ 
#define i_rel12   4   /* 12 bit pc-relative (COMBT, COMBF, etc.) */ 
#define i_data    5   /* whole word */ 
#define i_none    6 
#define i_abs17   7   /* 17-bit absolute (BE, BLE) */ 
#define i_milli   8   /* 17-bit millicode call (BLE) */ 
#define i_break   9   /* reserved (no effect on HP-UX) */ 

新しいオブジェクトファイルでは、再配置エントリーはバイトストリームで構成さ れます。サブスペースディクショナリエントリー内の fixup_request_index フィールドはファイルヘッダーで定義された解決情報ディクショナリへのバイトオ フセットであり、 fixup_request_quantity フィールドはそのサブスペースに関する解決情報要求ストリームの長さをバイト単位で 定義します。各解決情報要求の最初のバイト (命令コード) で、要求が識別され、要求 の長さが決定されます。

一般に、解決情報ストリームは、 a.out ファイル内のデータをリンカがどのように配置するかを制御する一連のリンカ命令です 。入力サブスペースから出力サブスペースに変更なしに 1 バイトまたは複数バイトをリ ンカにコピーさせる解決情報要求もありますし、複数ワードを再配置したり、外部参照 を解決するようリンカに指示する解決情報要求もあります。出力サブスペースにゼロを 挿入したり、または入力サブスペースからデータをコピーせずに領域を初期化しないま まにするようリンカに指示する解決情報要求もありますし、新しいデータを出力ファイ ルに入れずにコード内のポイントを記述するようリンカに指示する解決情報要求もあり ます。

インクルードファイル <reloc.h> は、主な各命令コードについて定数を定義します。数多くの解決情報要求が、ある範囲 の命令コードを使用します。範囲の先頭の定数だけが定義されます。各解決情報要求の 意味を以下に説明します。各解決情報の命令コードの範囲とパラメータについては、 その下の表で説明します。

R_NO_RELOCATION 

再配置なしに L バイトだけコピー

R_ZEROES 

L 個のゼロバイトを出力シーケンスに挿入

R_UNINIT 

出力サブスペース内の L バイトをスキップ

R_RELOCATION 

再配置を行いながら 1 データワードをコピー。ワードには、自身のサブスペースに相対的な 32 ビットのポインターが含まれると仮定する

R_DATA_ONE_SYMBOL
  

シンボルインデックスが S の外部シンボルに相対的に、再配置を行いながら 1 ワードをコピー

R_DATA_PLABEL 

シンボル S を参照しながら、1 データワードを 32 ビットの手続きラベルとしてコピー。ワードのオリジナルの内容は 0 (静的リンクなし) または 2 (静的リンク必要) でなければならない

R_SPACE_REF 

1 データワードをスペース参照としてコピー。この解決情報は現時点ではサポートされていない

R_REPEATED_INIT 

出力サブスペース内の M バイトを埋めるデータを複写しながら、入力サブスペースから L バイトをコピー

R_PCREL_CALL 

再配置を行いながら 1 命令ワードをコピー。ワードは、プログラムカウンターに相対的な手続き呼び出し命令と仮定される (たとえば、 BL) 。ターゲットの手続きは、シンボル S で識別され、パラメータ再配置ビットは R である

R_ABS_CALL 

再配置を行いながら 1 命令ワードをコピー。ワードは絶対的な手続き呼び出し命令と仮定される (たとえば、 BLE) 。ターゲットの手続きは、シンボル S で識別され、パラメータ再配置ビットは R である

R_DP_RELATIVE 

再配置を行いながら 1 命令ワードをコピー。ワードは、データポインターに相対的なロード命令または保存命令と仮定される (たとえば、 ADDIL\cLDW\cSTW) 。ターゲットシンボルはシンボル S で識別される。リンカは、シンボル S の値とシンボル $global$ の値の間の相違を形成する。通常、 $global$ の値は必ずレジスタ 27 に入れられる。命令の変位フィールドには小さな定数を入れることができる

R_DLT_REL 

再配置を行いながら 1 命令ワードをコピー。ワードは、レジスタ 18 に相対的なロード命令または保存命令と仮定される (たとえば、 LDW\cLDO\cSTW) 。ターゲットシンボルはシンボル S で識別される。リンカは、シンボル S についてレジスタ 18 (位置独立コード内のリンクテーブルポインター用に予約済み) に相対的なリンクテーブルオフセットを計算する

R_CODE_ONE_SYMBOL
  

再配置を行いながら 1 命令ワードをコピー。ワードは、シンボル S を参照する命令と仮定される (たとえば、 LDIL\cLDW\cBE) 。命令の変位フィールドには小さな定数を入れることができる

R_MILLI_REL 

再配置を行いながら 1 命令ワードをコピー。ワードは、ショートミリコード呼び出し命令と仮定される (たとえば、 BLE) 。リンカは、ターゲットシンボル S の値とモジュール内のシンボル 1 の値の間の相違を形成する。通常、シンボル 1 の値は、BLE 命令で使用される基底レジスタに既にロード済みでなければならない。命令の変位フィールドには小さな定数を入れることができる

R_CODE_PLABEL 

再配置を行いながら 1 命令ワードをコピー。ワードは、シンボル S を参照している手続きラベル (たとえば、 LDIL\cLDO) を形成するコードシーケンスの一部と仮定される。 LDO 命令の変位フィールドには値 0 (静的リンクでない) または 2 (静的リンクが必要) が入らなければならない

R_BREAKPOINT 

条件に応じて 1 命令ワードをコピー。HP-UX では、リンカは必ずワードを NOP 命令と置き換える

R_ENTRY 

手続きエントリー点を定義。スタックアンワインドビット U、およびフレームサイズ F が、スタックアンワインド記述子に記録される

R_ALT_ENTRY 

代わりの手続きエントリー点を定義

R_EXIT 

手続き終了点を定義

R_BEGIN_TRY 

試行/回復領域の先頭を定義

R_END_TRY 

試行/回復領域の末尾を定義。オフセット R は、領域の末尾から、回復ブロックの先頭までの距離をバイト単位で定義する

R_BEGIN_BRTAB 

分岐テーブルの先頭を定義

R_END_BRTAB 

分岐テーブルの末尾を定義

R_AUX_UNWIND 

補助アンワインドテーブルを定義。 CN は、コンパイル単位文字列テーブルの先頭のラベルとなるシンボルインデックスである。 SN は、有効範囲名称文字列のオフセットで、 CN に相対的である。 SK は有効範囲の種類を指定する整数である

R_STATEMENT 

文番号 N の先頭を定義

R_SEC_STATEMENT 

2 次的文番号 N の先頭を定義

R_DATA_EXPR 

式スタックから 1 ワード取り出し、入力サブスペースの 1 データワードにその取り出した値を加え、出力サブスペースにコピー

R_CODE_EXPR 

式スタックから 1 ワード取り出し、入力サブスペースの 1 命令ワードの命令変位フィールドにその取り出した値を加えながら、出力サブスペースにコピー

R_FSEL 

命令に該当するデフォルトの代わりに、次の解決情報要求に F\(fm フィールドを使用

R_LSEL 

命令に該当するデフォルトの代わりに、次の解決情報要求に L クラスフィールド選択子を使用。現在の丸めモードにしたがって、L\(fm、LS\(fm、LD\(fm、または LR\(fm が使用できる

R_RSEL 

命令に該当するデフォルトの代わりに、次の解決情報要求に R クラスフィールド選択子を使用。現在の丸めモードにしたがって、R\(fm、RS\(fm、RD\(fm、または RR\(fm が使用できる

R_N_MODE 

切り捨てモード (L\(fm/R\(fm) を選択。これは各サブスペースの始めでのデフォルトモードである。この設定は、明示的に変更されるまで、またはサブスペースの終わりまで有効である

R_S_MODE 

最も近いページに四捨五入モード (LS\(fm/RS\(fm) を選択。この設定は、明示的に変更されるまで、またはサブスペースの終わりまで有効である

R_D_MODE 

切り上げモードを (LD\(fm/RD\(fm) を選択。この設定は、明示的に変更されるまで、またはサブスペースの終わりまで有効である

R_R_MODE 

調整済み定数で切り捨てモード (LR\(fm/RR\(fm) を選択。この設定は、明示的に変更されるまで、またはサブスペースの終わりまで有効である

R_DATA_OVERRIDE 

入力サブスペースのデータワードまたは命令からの定数の代わりに、次の解決情報要求に定数 V を使用

R_TRANSLATED 

「変換済み」モードをトグル。この解決情報要求は、再配置可能リンクの間に、もともと古い形式の再配置可能なオブジェクトファイルから読み取られたサブスペースを示すためにだけ、リンカが生成する

R_COMP1 

操作をスタック。この解決情報要求の 2 バイト目には、二次命令コードが入れられる。以下の説明で、A はスタックの一番上、B はスタックの次の項目を指す。スタック上の項目はすべて符号付き 32 ビット整数とみなされる。

R_PUSH_PCON1 

(正の) 定数 V をプッシュ

R_PUSH_DOT 

現在の仮想アドレスをプッシュ

R_MAX 

A と B を取り出してから、max(A, B) をプッシュ

R_MIN 

A と B を取り出してから、min(A, B) をプッシュ

R_ADD 

A と B を取り出してから、A + B をプッシュ

R_SUB 

A と B を取り出してから、B \(mi A をプッシュ

R_MULT 

A と B を取り出してから、A * B をプッシュ

R_DIV 

A と B を取り出してから、B / A をプッシュ

R_MOD 

A と B を取り出してから、B % A をプッシュ

R_AND 

A と B を取り出してから、A & B をプッシュ

R_OR 

A と B を取り出してから、A | B をプッシュ

R_XOR 

A と B を取り出してから、A XOR B をプッシュ

R_NOT 

A をその補数で置き換え

R_LSHIFT 

C = 0 の場合、A と B を取り出してから、B << A をプッシュ。そうでない場合は、A を << C で置き換え

R_ARITH_RSHIFT 

C = 0 の場合、A と B を取り出してから、B >> A をプッシュ。そうでない場合は、A を A >> C で置き換え。シフトでは符号拡張を行う

R_LOGIC_RSHIFT 

C = 0 の場合、A と B を取り出してから、B >> A をプッシュ。そうでない場合は、A を A >> C で置き換え。シフトではゼロを埋める

R_PUSH_NCON1 

(負の) 定数 V をプッシュ

R_COMP2 

その他のスタック操作

R_PUSH_PCON2 

(正の) 定数 V をプッシュ

R_PUSH_SYM 

シンボル S の値をプッシュ

R_PUSH_PLABEL 

シンボル S の手続きラベル値をプッシュ。静的リンクビットは L

R_PUSH_NCON2 

(負の) 定数 V をプッシュ

R_COMP3 

その他のスタック操作

R_PUSH_PROC 

手続きエントリー点 S の値をプッシュ。パラメータ再配置ビットは R

R_PUSH_CONST 

定数 V をプッシュ

R_PREV_FIXUP 

リンカは、最後の 4 つの重複しない複数バイトの解決情報要求の待ち行列を保持する。これは、待ち行列にあるものと同一の解決情報要求の短縮形である。待ち行列インデックス X は、4 つのうちの 1 つを参照する。X = 0 は、最も新しいものを指す。この解決情報要求の副次効果として、参照された解決情報は待ち行列の前面に移動される

R_N0SEL 

次の解決情報が、コンパイラが生成した、データにアクセスするための 3 命令シーケンスの最初のものに適用され、共有ライブラリデータのインポートを使用可能にすることを示す

R_N1SEL 

次の解決情報用に、(N\(fm) フィールド選択子を使用。これは、命令の変位にゼロのビットが使用されることを示す。この解決情報は、(共有ライブラリデータをインポートするため) データにアクセスする 3 命令シーケンスを識別するのに使用される

R_LINETAB 

行テーブルの先頭を定義。CU は、行テーブルの先頭のラベルであるシンボルのインデックスである。SM は、CU シンボルに相対的なオフセットである。ES は、現在の行テーブルについて、バージョン情報を示す

R_LINETAB_ESC 

行テーブルに記入するエスケープエントリーを定義。ES は、テーブルに記入されるエスケープエントリーを示す。M は、raw の 8 ビットテーブルデータとして解釈される R_STATEMENT 解釈情報の数を示す

R_LTP_OVERRIDE 

次の解決情報を上書きする。この解決情報は、共有ライブラリを生成するときに、再配置なしに 1 データワードをコピーする R_DATA_ONE_SYMBOL 解決情報であると予想される。リンクテーブルポインターに相対的なシンボルの絶対バイトオフセットがコピーされる。リンカが完全な実行可能ファイルを生成している場合は、絶対仮想アドレスがコピーされる

R_COMMENT 

コンパイラからリンカへコメント情報を渡すために使用する解決情報

R_TP_OVERRIDE 

命令の解決時にスレッドローカル記憶領域のオフセットを使用するため、R_DP_RELATIVE、R_DLT_REL、R_DATA_ONE_SYMBOL 解決情報のうちの次の 1 つを上書きする。 この解決情報は、スレッドローカル記憶領域シンボルの不一致の際にも使用される。

R_RESERVED 

この範囲内の解決情報は、コンパイラとリンカが内部的に使用するために予約済みである

次表に、各範囲の命令コードについてのニーモニック解決情報要求タイプと長さ、およびパラメータ情報を示します。パラメータの欄で、シンボル D は、命令コードと、そのテーブルエントリーが記述する範囲の先頭との間の差を指します。シンボル B1、B2、B3、および B4 はそれぞれ、解決情報要求の、次の 1、2、3、または 4 バイトの値を指します。

 命令  
ニーモニックコード長さパラメータ
R_NO_RELOCATION 0-231L = (D+1) * 4
24-272L = (D<<8 + B1 + 1) * 4
28-303L = (D<<16 + B2 + 1) * 4
314L = B3 + 1
R_ZEROES322L = (B1 + 1) * 4
334L = B3 + 1
R_UNINIT342L = (B1 + 1) * 4
354L = B3 + 1
R_RELOCATION361なし
R_DATA_ONE_SYMBOL372S = B1
384S = B3
R_DATA_PLABEL392S = B1
404S = B3
R_SPACE_REF411なし
R_REPEATED_INIT422L = 4; M = (B1 + 1) * 4
433L = (B1 + 1) * 4; M = (B1 + 1) * L
445L = (B1 + 1) * 4; M = (B3 + 1) * 4