ELF, o Executable and Linkable Format, es un formato de archivo binario estándar utilizado en sistemas operativos tipo Unix (como Linux, Solaris, FreeBSD) para archivos ejecutables, código objeto reubicable, bibliotecas compartidas (shared libraries) y core dumps. Su estructura modular permite que el sistema operativo interprete y cargue correctamente el código y los datos de un programa en la memoria. Un archivo ELF se compone de una cabecera ELF, una tabla de cabeceras de programa (program header table) que describe cómo el sistema operativo debe cargar el archivo en memoria, y una tabla de cabeceras de sección (section header table) que describe las secciones del archivo para herramientas de enlace y depuración. Las secciones comunes incluyen .text (código ejecutable), .data (datos inicializados), .bss (datos no inicializados) y .rodata (datos de solo lectura).
ELF es el formato binario dominante en la mayoría de los sistemas operativos modernos basados en Unix. Por ejemplo, todos los ejecutables y bibliotecas en distribuciones de Linux (como Ubuntu, Red Hat, Alpine) están en formato ELF. Herramientas de desarrollo como GCC (GNU Compiler Collection) producen archivos ELF, y el linker ld los utiliza para combinar código objeto en ejecutables o bibliotecas compartidas. El cargador dinámico (dynamic linker/loader) del sistema operativo, como ld.so en Linux, es responsable de interpretar la estructura ELF en tiempo de ejecución para mapear las secciones del programa y sus dependencias (bibliotecas compartidas) en el espacio de direcciones del proceso. Incluso Android, que utiliza su propio formato ART para aplicaciones Java, se basa en ELF para sus componentes nativos y bibliotecas del sistema.
Para un Arquitecto de Sistemas, comprender ELF es fundamental porque impacta directamente en el rendimiento, la seguridad y la capacidad de depuración de las aplicaciones. La elección de cómo se enlazan las bibliotecas (estática vs. dinámica) afecta el tamaño del binario, el consumo de memoria y la facilidad de actualización. Los trade-offs incluyen: binarios estáticos (self-contained, pero más grandes y difíciles de parchear vulnerabilidades en dependencias) versus binarios dinámicos (más pequeños, comparten código, pero con sobrecarga de carga y posibles problemas de 'DLL Hell' o 'dependency hell'). La optimización del tamaño de los ejecutables (ej. stripping de símbolos de depuración) y la comprensión de cómo se mapean las secciones en memoria son cruciales para sistemas con recursos limitados o para hardening de seguridad (ej. Address Space Layout Randomization - ASLR, que reubica secciones ELF). Un conocimiento profundo de ELF permite diagnosticar problemas de carga de bibliotecas, optimizar el uso de memoria y diseñar sistemas robustos y eficientes.