GNU/Linux >> Belajar Linux >  >> Linux

Linux – Akankah Linux yang Dapat Dieksekusi Dikompilasi Pada Satu "rasa" Linux Dijalankan Pada Yang Berbeda?

Akankah eksekusi dari program kecil yang sangat sederhana, seperti yang ditunjukkan di bawah ini, yang dikompilasi pada satu rasa Linux berjalan pada rasa yang berbeda? Atau perlu dikompilasi ulang?

Apakah arsitektur mesin penting dalam kasus seperti ini?

int main()
{
  return (99);
}

Jawaban yang Diterima:

Tergantung. Sesuatu yang dikompilasi untuk IA-32 (Intel 32-bit) dapat berjalan di amd64 karena Linux pada Intel mempertahankan kompatibilitas mundur dengan aplikasi 32-bit (dengan perangkat lunak yang sesuai diinstal). Ini code Anda dikompilasi pada sistem 32-bit RedHat 7.3 (sekitar 2002, gcc versi 2.96) dan kemudian biner disalin ke dan dijalankan pada sistem 64-bit Centos 7.4 (sekitar 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

RedHat 7.3 kuno hingga Centos 7.4 (pada dasarnya RedHat Enterprise Linux 7.4) tetap berada di keluarga "distribusi" yang sama, jadi kemungkinan akan memiliki portabilitas yang lebih baik daripada beralih dari beberapa instalasi "Linux dari awal" acak dari tahun 2002 ke beberapa distribusi Linux acak lainnya pada tahun 2018 .

Sesuatu yang dikompilasi untuk amd64 tidak akan berjalan pada rilis Linux 32-bit saja (perangkat keras lama tidak tahu tentang perangkat keras baru). Ini juga berlaku untuk perangkat lunak baru yang dikompilasi pada sistem modern yang dimaksudkan untuk dijalankan pada hal-hal lama, karena perpustakaan dan bahkan panggilan sistem mungkin tidak portabel mundur, jadi mungkin memerlukan trik kompilasi, atau mendapatkan kompiler lama dan sebagainya, atau mungkin sebaliknya. kompilasi pada sistem lama. (Ini adalah alasan yang baik untuk menyimpan mesin virtual dari barang-barang kuno.)

Arsitektur memang penting; amd64 (atau IA-32) sangat berbeda dari ARM atau MIPS sehingga biner dari salah satunya tidak diharapkan berjalan di yang lain. Pada tingkat perakitan main bagian kode Anda pada IA-32 dikompilasi melalui gcc -S code.c untuk

main:
    pushl %ebp
    movl %esp,%ebp
    movl $99,%eax
    popl %ebp
    ret

yang dapat ditangani oleh sistem amd64 (pada sistem Linux–OpenBSD sebaliknya pada amd64 tidak mendukung binari 32-bit; kompatibilitas mundur dengan lengkungan lama memang memberi ruang gerak bagi penyerang, mis. CVE-2014-8866 dan teman-teman). Sementara itu pada sistem MIPS big-endian main sebagai gantinya dikompilasi ke:

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

yang prosesor Intel tidak akan tahu apa yang harus dilakukan, dan juga untuk perakitan Intel di MIPS.

Anda mungkin dapat menggunakan QEMU atau emulator lain untuk menjalankan kode asing (mungkin sangat, sangat lambat).

Namun! Kode Anda adalah kode yang sangat sederhana, sehingga akan memiliki lebih sedikit masalah portabilitas daripada yang lainnya; program biasanya menggunakan perpustakaan yang telah berubah dari waktu ke waktu (glibc, openssl, ...); untuk mereka yang mungkin juga perlu menginstal versi lama dari berbagai perpustakaan (RedHat misalnya biasanya menempatkan "compat" di suatu tempat di nama paket untuk itu)

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

atau mungkin khawatir tentang perubahan ABI (Application Binary Interface) untuk hal-hal lama yang menggunakan glibc, atau perubahan yang lebih baru karena C++ 11 atau rilis C++ lainnya. Seseorang juga dapat mengkompilasi statis (sangat meningkatkan ukuran biner pada disk) untuk mencoba menghindari masalah perpustakaan, meskipun apakah beberapa biner lama melakukan ini tergantung pada apakah distribusi Linux lama mengkompilasi hampir semua dinamis (RedHat:ya) atau tidak. Di sisi lain, hal-hal seperti patchelf dapat rejigger dinamis (ELF, tapi mungkin tidak a.out format) binari untuk menggunakan perpustakaan lain.

Terkait:Linux – Gagal menginstal perf pada slackware 13.1?

Namun! Mampu menjalankan program adalah satu hal, dan benar-benar melakukan sesuatu yang berguna dengannya adalah hal lain. Binari Intel 32-bit lama mungkin memiliki masalah keamanan jika bergantung pada versi OpenSSL yang memiliki beberapa masalah keamanan yang mengerikan dan tidak didukung di dalamnya, atau program mungkin tidak dapat bernegosiasi sama sekali dengan server web modern (seperti server menolak protokol lama dan sandi program lama), atau protokol SSH versi 1 tidak lagi didukung, atau ...


Linux
  1. Perintah Yang Akan Memaksa Linux Untuk Membersihkan Cache Dari Satu File Pada Berbagi Nfs?

  2. Bagaimana cara menjalankan program dengan direktori kerja yang berbeda dari saat ini, dari shell Linux?

  3. Apakah ada perbedaan antara file biner yang dapat dieksekusi antara distribusi?

  1. Menyematkan ikon di executable Linux

  2. Gunakan versi PHP CLI yang berbeda yang dapat dieksekusi untuk satu perintah

  3. Bagaimana saya bisa menjalankan executable yang tidak dipercaya di linux dengan aman?

  1. Jalankan mesin virtual Linux di Podman

  2. Perintah Linux Sederhana yang Akan Memberitahu Saya Apa Itu Display Manager?

  3. Akankah executable Linux yang dikompilasi pada satu rasa Linux berjalan pada rasa yang berbeda?