Formato ejecutable y enlazable

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
Un archivo ELF tiene dos vistas: el encabezado del programa muestra el segmentos utilizado en el tiempo de ejecución, mientras que el encabezado de la sección enumera el conjunto de secciones.

En informática, el formato ejecutable y enlazable (ELF, antes denominado formato de enlace extensible), es un formato de archivo estándar común para archivos ejecutables archivos, código objeto, bibliotecas compartidas y volcados de núcleo. Publicado por primera vez en la especificación para la interfaz binaria de aplicaciones (ABI) de la versión del sistema operativo Unix denominada System V Release 4 (SVR4), y luego en Tool Interface Standard, fue rápidamente aceptado entre diferentes proveedores de sistemas Unix. En 1999, el proyecto 86open lo eligió como el formato de archivo binario estándar para Unix y sistemas similares a Unix en procesadores x86.

Por diseño, el formato ELF es flexible, extensible y multiplataforma. Por ejemplo, admite diferentes endianness y tamaños de dirección, por lo que no excluye ninguna unidad central de procesamiento (CPU) o arquitectura de conjunto de instrucciones en particular. Esto ha permitido que muchos sistemas operativos diferentes lo adopten en muchas plataformas de hardware diferentes.

Diseño de archivo

Cada archivo ELF se compone de un encabezado ELF, seguido de los datos del archivo. Los datos pueden incluir:

  • Mesa de encabezado del programa, que describe cero o más segmentos de memoria
  • Tabla de encabezados de la sección, describiendo cero o más secciones
  • Datos a que se refieren las entradas en la tabla de encabezado del programa o tabla de encabezados de sección
Estructura de un archivo ELF con entradas clave destacadas

Los segmentos contienen información necesaria para la ejecución del archivo en tiempo de ejecución, mientras que las secciones contienen datos importantes para la vinculación y la reubicación. Cualquier byte en el archivo completo puede ser propiedad de una sección como máximo, y pueden ocurrir bytes huérfanos que no sean propiedad de ninguna sección.

00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|

00000010 02 00 3e 00 01 00 00 00 c5 48 40 00 00 00 00 00 |..>......H@.....|

Ejemplo de hexdump del encabezado del archivo ELF

Encabezado del archivo

El encabezado ELF define si usar direcciones de 32 bits o de 64 bits. El encabezado contiene tres campos que se ven afectados por esta configuración y compensan otros campos que los siguen. El encabezado ELF tiene una longitud de 52 o 64 bytes para binarios de 32 y 64 bits, respectivamente.

ELF header
OffsetTamaño (bytes)CampoPropósito
32-bit64-bit32-bit64-bit
0x004e_ident[EI_MAG0] a través de e_ident[EI_MAG3]0x7F seguido ELF()45 4c 46) en ASCII; estos cuatro bytes constituyen el número mágico.
0x041e_ident[EI_CLASS]Este byte está listo para cualquiera 1 o 2 para significar formato 32- o 64-bit, respectivamente.
0x051e_ident[EI_DATA]Este byte está listo para cualquiera 1 o 2 para significar poco o grande endianness, respectivamente. Esto afecta a la interpretación de campos de varios bytes empezando por offset 0x10.
0x061e_ident[EI_VERSION]Set to 1 para la versión original y actual de ELF.
0x071e_ident[EI_OSABI]Identifica el sistema operativo objetivo ABI.
ValorABI
0x00Sistema V
0x01HP-UX
0x02NetBSD
0x03Linux
0x04GNU Hurd
0x06Solaris
0x07AIX (Monterey)
0x08IRIX
0x09FreeBSD
0x0ATru64
0x0BNovell Modesto
0x0COpenBSD
0x0DOpenVMS
0x0EBorde sin parar
0x0FAROS
0x10FenixOS
0x11Nuxi CloudABI
0x12Stratus Technologies OpenVOS
0x081e_ident[EI_ABIVERSION]Especifica además la versión ABI. Su interpretación depende del objetivo ABI. Linux kernel (después de al menos 2.6) no tiene definición de ello, por lo que se ignora para los ejecutables vinculados estadísticamente. En ese caso, el offset y el tamaño de EI_PAD son 8.

glibc 2.12+ en caso e_ident[EI_OSABI] == 3 trata este campo como versión ABI del linker dinámico: define una lista de características dinámicas del linker, trata e_ident[EI_ABIVERSION] como un nivel de características solicitado por el objeto compartido (librería ejecutable o dinámica) y se niega a cargarlo si se solicita una característica desconocida, es decir. e_ident[EI_ABIVERSION] es mayor que la mayor característica conocida.

0x097e_ident[EI_PAD]Bytes de padding reservados. Actualmente no utilizado. Debe llenarse de ceros e ignorarse cuando se lee.
0x102e_typeIdentifica el tipo de archivo objeto.
ValorTipoSignificado
0x00ET_NONEDesconocido.
0x01ET_RELRelocatable file.
0x02ET_EXECArchivo ejecutable.
0x03ET_DYNObjeto compartido.
0x04ET_COREArchivo básico.
0xFE00ET_LOOSRango incluido reservado. Sistema operativo específico.
0xFEFFET_HIOS
0xFF00ET_LOPROCRango incluido reservado. Procesador específico.
0xFFET_HIPROC
0x122e_machineEspecifica la arquitectura del conjunto de instrucciones objetivo. Algunos ejemplos son:
ValorISA
0x00No se ha establecido ninguna instrucción específica
0x01EN VIRTUD DE LOS 32100
0x02SPARC
0x03x86
0x04Motorola 68000 (M68k)
0x05Motorola 88000 (M88k)
0x06Intel MCU
0x07Intel 80860
0x08MIPS
0x09IBM System/370
0x0AMIPS RS3000 Little-endian
0x0B - 0x0DReservado para uso futuro
0x0EHewlett-Packard PA-RISC
0x0FReservado para uso futuro
0x13Intel 80960
0x14PowerPC
0x15PowerPC (64 bits)
0x16 S390, incluido S390x
0x17IBM SPU/SPC
0x18 - 0x23Reservado para uso futuro
0x24NEC V800
0x25Fujitsu FR20
0x26TRW RH-32
0x27Motorola RCE
0x28Arm (hasta Armv7/AArch32)
0x29Digital Alpha
0x2ASuperH
0x2BSPARC Version 9
0x2CProcesador integrado Siemens TriCore
0x2DArgonaut RISC Core
0x2EHitachi H8/300
0x2FHitachi H8/300 H
0x30Hitachi H8S
0x31Hitachi H8/500
0x32IA-64
0x33Stanford MIPS-X
0x34Motorola ColdFire
0x35Motorola M68HC12
0x36Fujitsu MMA Multimedia Accelerator
0x37Siemens PCP
0x38Sony nCPU integrado procesador RISC
0x39Denso NDR1 microprocesador
0x3AMotorola Star*Procesador de coches
0x3BProcesador Toyota ME16
0x3CSTMicroelectronics ST100 processor
0x3DAdvanced Logic Corp. Tiny J embebido procesador familia
0x3EAMD x86-64
0x3FSony DSP Procesador
0x40Digital Equipment Corp. PDP-10
0x41Digital Equipment Corp. PDP-11
0x42Siemens FX66 microcontrolador
0x43STMicroelectronics ST9+ 8/16 bit microcontroller
0x44STMicroelectronics ST7 8-bit microcontroller
0x45Microcontrolador Motorola MC68HC16
0x46Microcontrolador Motorola MC68HC11
0x47Microcontrolador Motorola MC68HC08
0x48Microcontrolador Motorola MC68HC05
0x49Gráficos de silicona SVx
0x4ASTMicroelectronics ST19 8-bit microcontroller
0x4BVAX digital
0x4CAxis Communications Procesador integrado de 32 bits
0x4DInfineon Technologies procesador integrado de 32 bits
0x4EElement 14 64-bit DSP Procesador
0x4FLSI Logic 16-bit DSP Processor
0x8CTMS320C6000 Familia
0xAFMCST Elbrus e2k
0xB7Arm 64-bits (Armv8/AArch64)
0xDCZilog Z80
0xF3RISC-V
0xF7Filtro de paquete de Berkeley
0x101 WDC 65C816
0x144e_versionSet to 1 para la versión original de ELF.
0x1848e_entradaEsta es la dirección de memoria del punto de entrada desde donde el proceso comienza a ejecutar. Este campo es de 32 o 64 bits de largo, dependiendo del formato definido anteriormente (byte 0x04). Si el archivo no tiene un punto de entrada asociado, entonces esto tiene cero.
0x1C0x2048e_phoffPuntos al inicio de la mesa de encabezado del programa. Por lo general sigue el encabezado del archivo inmediatamente después de éste, haciendo el offset 0x34 o 0x40 para los ejecutables ELF de 32 y 64 bits, respectivamente.
0x200x2848e_shoffPuntos al inicio de la tabla de encabezados de sección.
0x240x304e_flagsLa interpretación de este campo depende de la arquitectura de destino.
0x280x342e_ehsizeContiene el tamaño de este encabezado, normalmente 64 Bytes para 64-bit y 52 Bytes para formato 32-bit.
0x2A0x362e_phentsizeContiene el tamaño de una tabla de encabezado del programa.
0x2C0x382e_phnumContiene el número de entradas en la tabla de encabezados del programa.
0x2E0x3A2e_shentsizeContiene el tamaño de una tabla de cabecera de sección.
0x300x3C2e_shnumContiene el número de entradas en la tabla de encabezados de la sección.
0x320x3E2e_shstrndxContiene índice de la entrada de la tabla de encabezado de sección que contiene los nombres de las secciones.
0x34 0x40 Fin de la cabecera ELF (tamaño).

Encabezado del programa

La tabla de encabezado del programa le dice al sistema cómo crear una imagen de proceso. Se encuentra en el desplazamiento del archivo e_phoff y consta de entradas e_phnum, cada una con tamaño e_phentsize . El diseño es ligeramente diferente en ELF de 32 bits frente a ELF de 64 bits, porque las p_flags están en una ubicación de estructura diferente por motivos de alineación. Cada entrada está estructurada como:

Director del programa
OffsetTamaño (bytes)CampoPropósito
32-bit64-bit32-bit64-bit
0x004 p_typeIdentifica el tipo del segmento.
ValorNombreSignificado
0x00000PT_NULLIngreso de mesa de encabezado del programa no utilizado.
0x00001PT_LOADsegmento Loadable.
0x00000002PT_DYNAMICInformación de conexión dinámica.
0x00000003PT_INTERPInformación del intérprete.
0x00004PT_NOTEInformación auxiliar.
0x00005PT_SHLIBReservado.
0x00006PT_PHDRSegmento que contiene la tabla de encabezado del programa en sí.
0x00007PT_TLSThread-Local Plantilla de almacenamiento.
0x60000000PT_LOOSRango incluido reservado. Sistema operativo específico.
0x6FFFFPT_HIOS
0x70000000PT_LOPROCRango incluido reservado. Procesador específico.
0x7FFFFFPT_HIPROC
0x044p_flagsBanderas dependientes del segmento (posición para la estructura de 64 bits).
0x040x0848p_offsetOffset del segmento en la imagen del archivo.
0x080x1048p_vaddrDirección virtual del segmento en memoria.
0x0C0x1848P_paddrEn sistemas donde la dirección física es relevante, reservada para la dirección física del segmento.
0x100x2048p_fileszTamaño en bytes del segmento en la imagen del archivo. Puede ser 0.
0x140x2848p_memszTamaño en bytes del segmento en memoria. Puede ser 0.
0x184p_flagsBanderas dependientes del segmento (posición para estructura de 32 bits).
0x1C0x3048p_align0 y 1 especificar no alineación. De lo contrario debe ser un poder positivo e integral de 2, con p_vaddr equiparación p_offset modulus p_align.
0x20 0x38 Fin del programa Header (tamaño).

Encabezado de sección

Offset Tamaño (bytes) Campo Propósito
32-bit 64-bit 32-bit 64-bit
0x00 4 sh_name Un offset a una cadena en el .shstrtab sección que representa el nombre de esta sección.
0x04 4 sh_type Identifica el tipo de este encabezado.
Valor Nombre Significado
0x0 SHT_NULL Sección de cabecera de la mesa
0x1 SHT_PROGBITS Datos del programa
0x2 SHT_SYMTAB Signatura
0x3 SHT_STRTAB Mesa de montaje
0x4 SHT_RELA Entradas de reubicación con adiciones
0x5 SHT_HASH Signatura de la tabla
0x6 SHT_DYNAMIC Información dinámica de enlace
0x7 SHT_NOTE Notas
0x8 SHT_NOBITS Espacio del programa sin datos (bss)
0x9 SHT_REL Entradas de traslado, sin adiciones
0x0A SHT_SHLIB Reservado
0x0B SHT_DYNSYM Tabla de símbolo de enlace dinámico
0x0E SHT_INIT_ARRAY Array de constructores
0x0F SHT_FINI_ARRAY Array of destructors
0x10 SHT_PREINIT_ARRAY Array of pre-constructors
0x11 SHT_GROUP Grupo de sección
0x12 SHT_SYMTAB_SHNDX Índices de sección ampliados
0x13 SHT_NUM Número de tipos definidos.
0x60000000 SHT_LOOS Comience el sistema operativo específico.
... ... ...
0x08 4 8 sh_flags Identifica los atributos de la sección.
Valor Nombre Significado
0x1 SHF_WRITE Writable
0x2 SHF_ALLOC Ocupa la memoria durante la ejecución
0x4 SHF_EXECINSTR Ejecución
0x10 SHF_MERGE Podría ser fusionado.
0x20 SHF_STRINGS Contiene cuerdas nula-terminadas
0x40 SHF_INFO_LINK 'sh_info' contiene índice SHT
0x80 SHF_LINK_ORDER Orden Preserve después de combinar
0x100 SHF_OS_NONCONFORMING Manejo específico no estándar del sistema operativo requerido
0x200 SHF_GROUP Sección es miembro de un grupo
0x400 SHF_TLS Sección mantiene datos locales de rosca
0x0FF00000 SHF_MASKOS OS-specific
0xF0000000 SHF_MASKPROC Procesador específico
0x4000000 SHF_ORDERED Requisitos especiales de orden (Solaris)
0x8000000 SHF_EXCLUDE La sección queda excluida a menos que se haga referencia o se asigne (Solaris)
0x0C 0x10 4 8 sh_addr Dirección virtual de la sección en memoria, para secciones cargadas.
0x10 0x18 4 8 sh_offset Offset de la sección en la imagen del archivo.
0x14 0x20 4 8 sh_size Tamaño en bytes de la sección en la imagen del archivo. Puede ser 0.
0x18 0x28 4 sh_link Contiene el índice de sección de una sección asociada. Este campo se utiliza para varios fines, dependiendo del tipo de sección.
0x1C 0x2C 4 sh_info Contiene información adicional sobre la sección. Este campo se utiliza para varios fines, dependiendo del tipo de sección.
0x20 0x30 4 8 sh_addralign Contiene la alineación necesaria de la sección. Este campo debe ser un poder de dos.
0x24 0x38 4 8 sh_entsize Contiene el tamaño, en bytes, de cada entrada, para secciones que contienen entradas de tamaño fijo. De lo contrario, este campo contiene cero.
0x28 0x40 End of Section Header (size).

Herramientas

  • readelf es una utilidad binaria Unix que muestra información sobre uno o más archivos ELF. GNU Binutils proporciona una implementación de software libre.
  • elfutils proporciona herramientas alternativas a GNU Binutils puramente para Linux.
  • elfdump es un comando para ver la información ELF en un archivo ELF, disponible bajo Solaris y FreeBSD.
  • objdump proporciona una amplia gama de información sobre archivos ELF y otros formatos de objetos. objdump utiliza la biblioteca descriptor de archivos binario como back-end para estructurar los datos ELF.
  • El Unix file la utilidad puede mostrar cierta información sobre los archivos ELF, incluyendo la arquitectura del conjunto de instrucciones para la cual se pretende el código en un archivo de objeto relocatable, ejecutable o compartido, o en el que se produjo un basurero ELF.

Aplicaciones

Sistemas similares a Unix

El formato ELF ha reemplazado a los formatos ejecutables más antiguos en varios entornos. Ha reemplazado los formatos a.out y COFF en sistemas operativos similares a Unix:

  • Linux
  • Solaris / Illumos
  • IRIX
  • FreeBSD
  • NetBSD
  • OpenBSD
  • Redox
  • DragonFly BSD
  • Syllable
  • HP-UX (excepto los programas PA-RISC de 32 bits que siguen utilizando SOM)
  • QNX Neutrino
  • MINIX

Adopción no Unix

ELF también ha visto cierta adopción en sistemas operativos que no son de Unix, como:

  • OpenVMS, en sus versiones Itanium y amd64
  • BeOS Revision 4 y posterior para ordenadores basados en x86 (donde sustituyó el formato ejecutable portátil; la versión PowerPC se mantuvo con Formato ejecutable Preferente)
  • Haiku, una reimplementación de código abierto de BeOS
  • RISC OS
  • Stratus VOS, en las versiones PA-RISC y x86
  • SkyOS
  • Fuchsia OS
  • Z/TPF
  • HPE NonStop OS
  • Deos

Microsoft Windows también usa el formato ELF, pero solo para su subsistema de Windows para el sistema de compatibilidad con Linux.

Consolas de juegos

Algunas videoconsolas también usan ELF:

  • PlayStation Portable, PlayStation Vita, PlayStation (consol), PlayStation 2, PlayStation 3, PlayStation 4, PlayStation 5
  • GP2X
  • Dreamcast
  • GameCube
  • Nintendo 64
  • Wii
  • Wii U

PowerPC

Otros sistemas (operativos) que se ejecutan en PowerPC que utilizan ELF:

  • AmigaOS 4, el ejecutable ELF ha reemplazado el anterior formato Extended Hunk (EHF) que se utilizó en Amigas equipado con tarjetas de expansión de procesador PPC.
  • MorphOS
  • AROS
  • Café OS (El sistema operativo funcionó en Wii U)

Teléfonos móviles

Algunos sistemas operativos para teléfonos móviles y dispositivos móviles utilizan ELF:

  • Symbian OS v9 utiliza E32 Formato de imagen que se basa en el formato de archivo ELF;
  • Sony Ericsson, por ejemplo, el W800i, W610, W300, etc.
  • Siemens, las plataformas SGOLD y SGOLD2: de Siemens C65 a S75 y BenQ-Siemens E71/EL71;
  • Motorola, por ejemplo, el E398, SLVR L7, v360, v3i (y todo el teléfono LTE2 que tiene el parche aplicado).
  • Bada, por ejemplo, el Samsung Wave S8500.
  • Nokia teléfonos o tabletas que ejecutan el Maemo o el Meego OS, por ejemplo, el Nokia N900.
  • Android utiliza ELF .so (objeto compartido) bibliotecas para la Interfaz Nativa Java. Con Android Runtime (ART), el predeterminado desde Android 5.0 "Lollipop", todas las aplicaciones se compilan en binarios ELF nativos en la instalación.

Algunos teléfonos pueden ejecutar archivos ELF mediante el uso de un parche que agrega código ensamblador al firmware principal, que es una característica conocida como ELFPack en la cultura de modificación clandestina. El formato de archivo ELF también se usa con Atmel AVR (8 bits), AVR32 y con arquitecturas de microcontrolador Texas Instruments MSP430. Algunas implementaciones de Open Firmware también pueden cargar archivos ELF, sobre todo la implementación de Apple utilizada en casi todas las máquinas PowerPC que produjo la empresa.

Especificaciones

  • Genérico:
    • Aplicación del sistema V Interfaz binaria Edición 4.1 (1997-03-18)
    • Actualización del sistema V ABI (octubre de 2009)
  • AMD64:
    • Sistema V ABI, Suplemento AMD64
  • Arm:
    • ELF para la arquitectura ARM
  • IA-32:
    • Sistema V ABI, Intel386 Suplemento Procesador de Arquitectura
  • IA-64:
    • Convenciones de software de itanio y guía de tiempo de ejecución (septiembre de 2000)
  • M32R:
    • M32R ELF ABI Suplemento Versión 1.2 (2004-08-26)
  • MIPS:
    • System V ABI, MIPS RISC Processor Supplement
    • MIPS EABI documentation (2003-06-11)
  • Motorola 6800:
    • Motorola 8 y 16 bits ABI
  • PA-RISC:
    • ELF Supplement for PA-RISC Versión 1.43 (6 de octubre de 1997)
  • PowerPC:
    • Sistema V ABI, Suplemento PPC
    • PowerPC Aplicación incorporada Interfaz binaria 32-Bit Implementación (1995-10-01)
    • 64-bit PowerPC ELF Aplicación Suplemento de interfaz binaria Versión 1.9 (2004)
  • RISC-V:
    • RISC-V ELF Especificación
  • SPARC:
    • Sistema V ABI, SPARC Suplemento
  • S/390:
    • S/390 32bit ELF ABI Suplemento
  • zSeries:
    • zSeries 64bit ELF ABI Suplemento
  • Symbian OS 9:
    • E32Image formato de archivo en Symbian OS 9

Linux Standard Base (LSB) complementa algunas de las especificaciones anteriores para las arquitecturas en las que se especifica. Por ejemplo, ese es el caso de System V ABI, AMD64 Supplement.

86abierto

86open fue un proyecto para llegar a un consenso sobre un formato de archivo binario común para Unix y sistemas operativos similares a Unix en la arquitectura común x86 compatible con PC, para alentar a los desarrolladores de software a migrar a la arquitectura. La idea inicial era estandarizar un pequeño subconjunto de Spec 1170, un predecesor de Single UNIX Specification, y GNU C Library (glibc) para permitir que los archivos binarios no modificados se ejecutaran en los sistemas operativos x86 similares a Unix. El proyecto se designó originalmente como "Spec 150".

El formato finalmente elegido fue ELF, específicamente la implementación de ELF en Linux, después de que resultó ser un estándar de facto compatible con todos los proveedores y sistemas operativos involucrados.

El grupo comenzó conversaciones por correo electrónico en 1997 y se reunió por primera vez en las oficinas de la Operación Santa Cruz el 22 de agosto de 1997.

El comité directivo estaba formado por Marc Ewing, Dion Johnson, Evan Leibovitch, Bruce Perens, Andrew Roach, Bryan Wayne Sparks y Linus Torvalds. Otras personas en el proyecto fueron Keith Bostic, Chuck Cranor, Michael Davidson, Chris G. Demetriou, Ulrich Drepper, Don Dugger, Steve Ginzburg, Jon "maddog" Hall, Ron Holt, Jordan Hubbard, Dave Jensen, Kean Johnston, Andrew Josey, Robert Lipe, Bela Lubkin, Tim Marsland, Greg Page, Ronald Joe Record, Tim Ruckle, Joel Silverstein, Chia-pi Tien y Erik Troan. Los sistemas operativos y las empresas representadas fueron BeOS, BSDI, FreeBSD, Intel, Linux, NetBSD, SCO y SunSoft.

El proyecto avanzó y, a mediados de 1998, SCO comenzó a desarrollar lxrun, una capa de compatibilidad de código abierto capaz de ejecutar binarios de Linux en OpenServer, UnixWare y Solaris. SCO anunció el soporte oficial de lxrun en LinuxWorld en marzo de 1999. Sun Microsystems comenzó a admitir oficialmente lxrun para Solaris a principios de 1999 y luego pasó al soporte integrado del formato binario de Linux a través de Solaris Containers for Linux Applications.

Dado que los BSD admitieron durante mucho tiempo los binarios de Linux (a través de una capa de compatibilidad) y los principales proveedores de Unix x86 agregaron soporte para el formato, el proyecto decidió que Linux ELF era el formato elegido por la industria y "declaró[ d] sí mismo disuelto" el 25 de julio de 1999.

FatELF: binarios universales para Linux

FatELF es una extensión de formato binario ELF que agrega capacidades binarias gruesas. Está dirigido a Linux y otros sistemas operativos similares a Unix. Además de la abstracción de la arquitectura de la CPU (orden de bytes, tamaño de palabra, conjunto de instrucciones de la CPU, etc.), existe la ventaja potencial de la abstracción de la plataforma de software, por ejemplo, binarios que admiten múltiples versiones ABI del kernel. A partir de 2021, FatELF no se ha integrado en el núcleo principal de Linux.

Contenido relacionado

Tabla de picadillo

Páginas del servidor activo

Location HTTP

El campo de encabezado de Location de HTTP se devuelve en las respuestas de un servidor HTTP en dos...
Más resultados...
Tamaño del texto:
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save