場合によります。IA-32(Intel 32ビット)用にコンパイルされたものは、Intel上のLinuxが32ビットアプリケーション(適切なソフトウェアがインストールされている)との後方互換性を保持するため、amd64で実行できます。ここにあなたのだcode
(2002年頃、gccのバージョン2.96)のRedHat 7.3 32ビットシステム上でコンパイルして、バイナリにコピーし、(2017年頃)CentOSに7.4 64ビットシステム上で実行するには:
-bash-4.2$ file code
code: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped
-bash-4.2$ ./code
-bash: ./code: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory
-bash-4.2$ sudo yum -y install glibc.i686
...
-bash-4.2$ ./code ; echo $?
99
Ancient RedHat 7.3からCentos 7.4(本質的にRedHat Enterprise Linux 7.4)は同じ「ディストリビューション」ファミリーにとどまっているため、2002年からのランダムな「ゼロからのLinux」インストールから2018年に他のランダムなLinuxディストリビューションに移行するよりも移植性が高い可能性が高い。
amd64用にコンパイルされたものは、Linuxの32ビットのみのリリースでは実行されません(古いハードウェアは新しいハードウェアを認識しません)。これは、ライブラリやシステムコールでさえも後方への移植性がないため、古代の古いもので実行することを目的とした現代のシステムでコンパイルされた新しいソフトウェアにも当てはまります。そのため、コンパイルトリックや古いコンパイラーの入手などが必要になる場合があります古いシステムでコンパイルします。(これは古代の古いものの仮想マシンを保持する正当な理由です。)
アーキテクチャは重要です。amd64(またはIA-32)はARMまたはMIPSとは大きく異なるため、これらの1つのバイナリが別のバイナリで実行されることはありません。アセンブリレベルではmain
IA-32上のコードのセクションは、経由してコンパイルgcc -S code.c
します
main:
pushl %ebp
movl %esp,%ebp
movl $99,%eax
popl %ebp
ret
これはamd64システムで処理できます(Linuxシステムでは、OpenBSDはamd64とは対照的に32ビットのバイナリをサポートしません。古いアーキテクチャとの後方互換性により、攻撃者はCVE-2014-8866や友人などにゆらぎを与えます)。一方、ビッグエンディアンMIPSシステムでは、 main
代わりに次のようにコンパイルされます。
main:
.frame $fp,8,$31
.mask 0x40000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-8
sw $fp,4($sp)
move $fp,$sp
li $2,99
move $sp,$fp
lw $fp,4($sp)
addiu $sp,$sp,8
j $31
nop
Intelプロセッサは何をすべきか分からないでしょうし、MIPSのIntelアセンブリも同様です。
QEMUまたは他のエミュレータを使用して外部コードを実行することもできます(おそらく非常にゆっくり)。
しかしながら!あなたのコードは非常にシンプルなコードなので、他のものよりも移植性の問題が少ないでしょう。プログラムは通常、時間とともに変化するライブラリ(glibc、opensslなど)を使用します。それらの場合、さまざまなライブラリの古いバージョンをインストールする必要がある場合もあります(たとえば、RedHatは通常、そのようなパッケージ名のどこかに「互換」を置きます)
compat-glibc.x86_64 1:2.12-4.el7.centos
または、おそらくglibcを使用する古い方法のABIの変更(アプリケーションバイナリインターフェイス)、またはC ++ 11または他のC ++リリースによる最近の変更について心配するかもしれません。ライブラリの問題を回避するために、静的(ディスク上のバイナリサイズを大幅に増やす)をコンパイルすることもできますが、古いバイナリがこれを実行したかどうかは、古いLinuxディストリビューションがほとんどすべてを動的にコンパイルしていたかどうか(RedHat:yes)によって異なります。一方、patchelf
動的な(ELFですが、おそらくa.out
フォーマットされていない)バイナリを再コンパイルして、他のライブラリを使用することができます。
しかしながら!プログラムを実行できることと、実際にそれを使用して何か有用なことを行うことは別のことです。古い32ビットIntelバイナリは、恐ろしくてバックポートされていないセキュリティ問題があるOpenSSLのバージョンに依存している場合、またはプログラムが最新のWebサーバーとまったく交渉できない可能性があります(最新のサーバーが古いプロトコルと古いプログラムの暗号を拒否する)、またはSSHプロトコルバージョン1がサポートされなくなる、または...