Solaris 64 ビット 開発ガイド

第 3 章 32 ビットと 64 ビットインタフェースの比較

第 2 章「64 ビットの使用方法」で説明したように、ほとんどの 32 ビットアプリケーションは、変更しなくても Solaris 64 ビットオペレーティング環境で動作します。アプリケーションによっては、64 ビットアプリケーションとして再コンパイルのみが必要となるものや、変換する必要があるものもあります。この章では、アプリケーションを再コンパイルしたり、64 ビットに変換する必要がある開発者向けに、第 2 章「64 ビットの使用方法」で述べた項目に基づいて説明します。

アプリケーションプログラミングインタフェース

64 ビットオペレーティング環境でサポートされている 32 ビットアプリケーションプログラミングインタフェース (API) は、32 ビットオペレーティング環境でサポートされている API と同じです。したがって、32 ビットアプリケーションを 32 ビットおよび 64 ビットの環境間で変更する必要はありません。ただし、64 ビットアプリケーションとして再コンパイルする場合には修正作業が必要になります。64 ビットアプリケーション用にコードを修正するためのガイドラインについては、第 4 章「アプリケーションの変換」を参照してください。

64 ビット API とは、基本的に UNIX 98 ファミリーの API です。その仕様は、派生型を使って書かれています。64 ビットバージョンを作成するには、その派生型のいくつかを 64 ビットに拡張します。これらの API を使って正しく書かれたアプリケーションは、32 ビットと 64 ビット間でソースを移植できます。

アプリケーションバイナリインタフェース

SPARCTM V8 ABI は、既存のプロセッサ固有のアプリケーションバイナリインタフェース (ABI) で、32 ビット SPARC バージョンの Solaris 実装はこのインタフェースに基づいています。SPARC V9 ABI は、SPARC V8 ABI を拡張して 64 ビット動作をサポートし、拡張アーキテクチャの新しい機能を定義しています。詳細は、「アプリケーションに関する新しい情報」 を参照してください。

互換性

以降の節では、32 ビットおよび 64 ビットアプリケーション間のさまざまなレベルの互換性について説明します。

アプリケーションバイナリ

既存の 32 ビットアプリケーションは、32 ビットまたは 64 ビットのどちらのオペレーティング環境でも実行できます。唯一の例外は、libkvm/dev/mem/dev/kmem、または /proc を使用するアプリケーションです。詳細は、第 2 章「64 ビットの使用方法」を参照してください。

アプリケーションソースコード

32 ビットアプリケーションに対しては、ソースレベルの互換性が維持されています。64 ビットアプリケーションについては、アプリケーションプログラミングインタフェースに使用される派生型に変更が加えられています。正しい派生型およびインタフェースを使用しているアプリケーションは、32 ビットに対してソースレベルで互換性があり、より容易に 64 ビットに移行することができます。

デバイスドライバ

32 ビットデバイスドライバは、64 ビットオペレーティングシステムでは使用できないため、32 ビットデバイスドライバは、64 ビットオブジェクトとして再コンパイルしなければなりません。さらに、64 ビットドライバは、32 ビットと 64 ビットの両方のアプリケーションをサポートしなければなりません。64 ビットオペレーティング環境に提供されているドライバはすべて、32 ビットと 64 ビットの両方のアプリケーションをサポートしています。ただし、基本ドライバモデル、および DDI (Device Driver Interface) でサポートされているインタフェースに変更はありません。必要な作業は、LP64 データ型モデルの環境で適切となるようにコードを修正することです。詳細は、『Writing Device Drivers』を参照してください。

どちらの Solaris オペレーティング環境が実行されているか

Solaris オペレーティング環境は、2 つのアプリケーションバイナリインタフェース (ABI) を同時にサポートしています。言い換えれば、2 つの独立した、完全に機能するシステムコールパスが、64 ビットカーネルに接続されており、2 組のライブラリがアプリケーションをサポートします。図 2-1 を参照してください。

64 ビットオペレーティングシステムは、64 ビット CPU ハードウェア上でのみ動作しますが、32 ビットオペレーティングシステムは、32 ビットと 64 ビットのどちらの CPU ハードウェア上でも動作します。Solaris の 32 ビットと 64 ビットのオペレーティング環境は同じように見えるので、特定のハードウェアプラットフォーム上でどちらのバージョンが動作しているかをすぐには判断できません。

isainfo コマンドを使用すると、これを簡単に確認することができます。この新しいコマンドは、システムでサポートされているアプリケーション環境に関する情報を出力します。

次に示すのは、64 ビットオペレーティングシステムが実行されている UltraSPARCTM システムで実行した isainfo コマンドの出力例です。


% isainfo -v
64-bit sparcv9 applications
32-bit sparc applications  

同じコマンドを古い SPARC システム、または 32 ビットオペレーティングシステムが実行されている UltraSPARC システム上で実行した場合は、次のように出力されます。


% isainfo -v
32-bit sparc applications

同じコマンドを IA システム上で実行すると次のようになります。


% isainfo -v
32-bit i386 applications

isainfo(1) コマンドのオプションの 1 つに -n オプションがあります。このオプションは、動作中のプラットフォームにネイティブな命令セットの名前を出力します。


% isainfo -n
sparcv9

-b オプションを使用すると、対応するネイティブのアプリケーション環境のアドレス空間のビット幅を、次のように出力できます。


% echo "Welcome to "`isainfo -b`"-bit Solaris"
Welcome to 64-bit Solaris

uname(1) で OS のバージョンを調べるか、または /usr/bin/isainfo が存在するかどうかを調べて、64 ビット機能があるかどうかを判定することによって、以前のバージョンの Solaris オペレーティング環境で実行しなければならないアプリケーションであるかどうかを判断することができます。

関連コマンドの isalist(1) は、シェルスクリプトに使用するのに適しており、プラットフォームでサポートされている命令セットをすべて出力するのに使うことができます。isalist で出力される命令セットアーキテクチャのなかには、かなりプラットフォームに固有なものもありますが、isainfo(1) ではシステム上で最も移植性のあるアプリケーション環境の属性だけを出力します。これら 2 つのコマンドとも、sysinfo(2) システムコールの SI_ISALIST サブオプションを使って構築されています。詳細は isalist(5) のマニュアルページを参照してください。

次の例は、64 ビットオペレーティングシステムが動作している UltraSPARC システム上で isalist コマンドを実行したときの出力です。


% isalist
sparcv9+vis sparcv9 sparcv8plus+vis sparcv8plus sparcv8 
sparcv8-fsmuld sparcv7 sparc 

注 -

上記の isalist コマンドの出力例中にある sparcv9+vis および sparcv8+vis は、システムが UltraSPARC-1 拡張命令セットをサポートしていることを示しています。この拡張命令セットはすべての SPARC V9 システムでサポートされているわけではないので、移植できるアプリケーションはこの拡張命令セットに依存しないようにしてください。また、UltraSPARC に固有の機能に合わせてコーディングしないようにしてください。


サポートされている命令セットのリストは、性能および機能のレベル順に並べられています。このコマンドの使用法についての詳細は、isalist(1) のマニュアルページを参照してください。また、optisa(1) のマニュアルページも参照してください。

プログラミング例

次に示すプログラミング例 foo.c では、LP64 と ILP32 のデータ型モデルの効果を直接的に示しています。同じプログラムを 32 ビットまたは 64 ビットプログラムとしてコンパイルすることができます。


#include <stdio.h>
int
main(int argc, char *argv[])
{
		(void) printf("char is ¥t¥t%lu bytes¥n", sizeof (char));
		(void) printf("short is ¥t%lu bytes¥n", sizeof (short));
		(void) printf("int is ¥t¥t%lu bytes¥n", sizeof (int));
		(void) printf("long is ¥t¥t%lu bytes¥n", sizeof (long));
		(void) printf("long long is ¥t¥t%lu bytes¥n", sizeof (long long));
		(void) printf("pointer is ¥t%lu bytes¥n", sizeof (void *));
		return (0);
} 

32 ビットコンパイルの結果は、次のようになります。


% cc -O -o foo32 foo.c
% foo32 
char is          1 bytes
short is         2 bytes
int is           4 bytes
long is          4 bytes
long long is     8 bytes
pointer is       4 bytes   

64 ビットコンパイルの結果は、次のようになります。


% cc -xarch=v9 -O -o foo64 foo.c 
% foo64
char is          1 bytes
short is         2 bytes
int is           4 bytes
long is          8 bytes
long long is     8 bytes 
pointer is       8 bytes

注 -

デフォルトのコンパイル環境は、移植性を最大限にするように設計されているため、32 ビットのアプリケーションを作成します。