GNU/Linux >> Tutoriales Linux >  >> Linux

Linux:¿se ejecutará un ejecutable de Linux compilado en un "sabor" de Linux en otro diferente?

¿El ejecutable de un programa pequeño y extremadamente simple, como el que se muestra a continuación, que está compilado en un tipo de Linux, se ejecutará en un tipo diferente? ¿O sería necesario volver a compilarlo?

¿Importa la arquitectura de la máquina en un caso como este?

int main()
{
  return (99);
}

Respuesta aceptada:

Depende. Algo compilado para IA-32 (Intel de 32 bits) puede ejecutarse en amd64, ya que Linux en Intel conserva la compatibilidad con aplicaciones de 32 bits (con el software adecuado instalado). Aquí está tu code compilado en el sistema RedHat 7.3 de 32 bits (alrededor de 2002, gcc versión 2.96) y luego el binario copiado y ejecutado en un sistema Centos 7.4 de 64 bits (alrededor de 2017):

Código de archivo
-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 a Centos 7.4 (esencialmente RedHat Enterprise Linux 7.4) permanece en la misma familia de "distribución", por lo que probablemente tendrá una mejor portabilidad que pasar de una instalación aleatoria de "Linux desde cero" de 2002 a alguna otra distribución aleatoria de Linux en 2018 .

Algo compilado para amd64 no se ejecutaría en versiones de Linux de solo 32 bits (el hardware antiguo no conoce el hardware nuevo). Esto también es cierto para el nuevo software compilado en sistemas modernos destinados a ejecutarse en cosas antiguas, ya que las bibliotecas e incluso las llamadas al sistema pueden no ser portátiles hacia atrás, por lo que pueden requerir trucos de compilación, u obtener un compilador antiguo, etc., o posiblemente en su lugar. compilando en el sistema anterior. (Esta es una buena razón para mantener las máquinas virtuales de cosas antiguas).

La arquitectura importa; amd64 (o IA-32) es muy diferente de ARM o MIPS, por lo que no se espera que el binario de uno de ellos se ejecute en otro. En el nivel de ensamblaje, el main sección de su código en IA-32 se compila a través de gcc -S code.c a

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

que puede manejar un sistema amd64 (en un sistema Linux, OpenBSD por el contrario en amd64 no admite binarios de 32 bits; la compatibilidad con versiones anteriores de los arcos antiguos les da a los atacantes margen de maniobra, p. CVE-2014-8866 y amigos). Mientras tanto, en un sistema MIPS big-endian main en su lugar compila a:

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

con el que un procesador Intel no tendrá idea de qué hacer, y lo mismo ocurre con el ensamblaje de Intel en MIPS.

Posiblemente podría usar QEMU o algún otro emulador para ejecutar código extranjero (quizás muy, muy lentamente).

¡Sin embargo! Su código es un código muy simple, por lo que tendrá menos problemas de portabilidad que cualquier otra cosa; los programas suelen hacer uso de bibliotecas que han cambiado con el tiempo (glibc, openssl, …); para aquellos, también es posible que deba instalar versiones anteriores de varias bibliotecas (RedHat, por ejemplo, generalmente coloca "compat" en algún lugar del nombre del paquete para tales)

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

o posiblemente preocuparse por los cambios de ABI (interfaz binaria de aplicaciones) para cosas muy antiguas que usan glibc, o cambios más recientes debido a C++ 11 u otras versiones de C++. También se podría compilar estático (aumentando en gran medida el tamaño binario en el disco) para tratar de evitar problemas con la biblioteca, aunque si algún binario antiguo hizo esto depende de si la antigua distribución de Linux compilaba casi todo lo dinámico (RedHat:sí) o no. Por otro lado, cosas como patchelf puede reajustar la dinámica (ELF, pero probablemente no a.out) formato) binarios para usar otras bibliotecas.

Relacionado:Linux:¿no se pudo instalar perf en slackware 13.1?

¡Sin embargo! Ser capaz de ejecutar un programa es una cosa y hacer algo útil con él es otra. Los viejos binarios de Intel de 32 bits pueden tener problemas de seguridad si dependen de una versión de OpenSSL que tiene algún problema de seguridad horrible y no respaldado, o es posible que el programa no pueda negociar en absoluto con los servidores web modernos (como el moderno los servidores rechazan los protocolos antiguos y los cifrados del programa antiguo), o el protocolo SSH versión 1 ya no es compatible, o...


Linux
  1. Ejecute una máquina virtual Linux en Podman

  2. Linux:¿cómo probar si un binario de Linux se compiló como código independiente de la posición?

  3. ¿Comando que obligará a Linux a vaciar el caché de un archivo en un recurso compartido Nfs?

  4. Linux:¿los diferentes kernels de Linux/unix son intercambiables?

  5. Mejores prácticas para ejecutar el servicio de Linux como un usuario diferente

Restaurar un viejo MacBook con Linux

Cómo hacer un archivo ejecutable en Linux

Ejecutar archivos binarios en Linux

Cómo ejecutar Windows 95 en Linux

Cómo ejecutar múltiples comandos de Linux en un solo comando

¿Se ejecutará un ejecutable de Linux compilado en un tipo de Linux en otro diferente?