GNU/Linux >> Linux の 問題 >  >> Linux

Linux – Linuxの1つの「フレーバー」でコンパイルされたLinux実行可能ファイルは、別の「フレーバー」で実行されますか?

Linuxのあるフレーバーでコンパイルされた、以下に示すような小さくて非常に単純なプログラムの実行可能ファイルは、別のフレーバーで実行されますか?または、再コンパイルする必要がありますか?

このような場合、マシンアーキテクチャは重要ですか?

int main()
{
  return (99);
}

承認された回答:

場合によります。 Linux on Intelは32ビットアプリケーション(適切なソフトウェアがインストールされている)との下位互換性を維持しているため、IA-32(Intel 32ビット)用にコンパイルされたものがamd64で実行される場合があります。これがあなたのコードです RedHat 7.3 32ビットシステム(2002年頃、gccバージョン2.96)でコンパイルされ、バイナリがCentos 7.4 64ビットシステム(2017年頃)にコピーされて実行されます:

-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 RedHat7.3からCentos7.4(基本的にはRedHat Enterprise Linux 7.4)は同じ「ディストリビューション」ファミリーにとどまっているため、2002年のランダムな「LinuxfromScratch」インストールから2018年のその他のランダムなLinuxディストリビューションに移行するよりも移植性が高い可能性があります。 。

amd64用にコンパイルされたものは、32ビットのみのリリースのLinuxでは実行されません(古いハードウェアは新しいハードウェアを認識しません)。これは、古い古いもので実行することを目的とした最新のシステムでコンパイルされた新しいソフトウェアにも当てはまります。ライブラリやシステムコールでさえ後方移植性がない可能性があるため、コンパイルのトリックや古いコンパイラの入手などが必要になる場合があります。古いシステムでコンパイルします。 (これは、古代の古いものの仮想マシンを維持するのに十分な理由です。)

アーキテクチャは重要です。 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システムの場合-amd64のOpenBSDとは対照的には処理しません 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」を配置します)

compat-glibc.x86_64                     1:2.12-4.el7.centos

または、glibcを使用する古いもののABIの変更(アプリケーションバイナリインターフェイス)、または最近のC++11または他のC++リリースによる変更について心配することもできます。ライブラリの問題を回避するために静的にコンパイルする(ディスク上のバイナリサイズを大幅に増やす)こともできますが、古いバイナリがこれを行ったかどうかは、古いLinuxディストリビューションがほとんどすべてを動的にコンパイルしていたかどうか(RedHat:はい)によって異なります。一方、 patchelfのようなもの 動的に再調整できます(ELFですが、おそらく a.outではありません format)他のライブラリを使用するためのバイナリ。

関連:Linux – slackware 13.1にperfをインストールできませんか?

でも!プログラムを実行できることと、実際にそれを使って何か役立つことをすることは別のことです。古い32ビットIntelバイナリは、バックポートされていない恐ろしいセキュリティ問題が含まれているOpenSSLのバージョンに依存している場合、またはプログラムが最新のWebサーバーとまったくネゴシエートできない場合(最新のように)、セキュリティの問題が発生する可能性があります。サーバーが古いプロトコルと古いプログラムの暗号を拒否する)、またはSSHプロトコルバージョン1がサポートされなくなった、または…


Linux
  1. PodmanでLinux仮想マシンを実行する

  2. ディスプレイマネージャが何であるかを教えてくれるシンプルなLinuxコマンド?

  3. Linux – Linuxバイナリが位置独立コードとしてコンパイルされたかどうかをテストする方法は?

  1. LinuxがNfs共有上の1つのファイルのキャッシュをフラッシュするように強制するコマンド?

  2. Linux –異なるLinux / UNIXカーネルは交換可能ですか?

  3. Linux で信頼できない実行可能ファイルを安全に実行するにはどうすればよいですか?

  1. Linux –LinuxでMacOs Xアプリケーションを実行しますか?

  2. Linux サービスを別のユーザーとして実行するためのベスト プラクティス

  3. Linux の 1 つのフレーバーでコンパイルされた Linux 実行可能ファイルは、別の Linux で実行されますか?