Para poder entender por qué FreeBSD utiliza el formato elf(5) primero debe saber ciertas cosas sobre los tres formatos de ejecutables «dominantes» en UNIX®:
El formato objeto de UNIX® más antiguo y «clásico». Utiliza una cabecera corta y compacta con un número mágico al inicio que se usa frecuentemente para identificar el formato (vea a.out(5) para más información). Contiene tres segmentos cargados: .text, .data, y .bss además de una tabla de símbolos y una tabla de cadena («strings»).
COFF
El formato objeto de SVR3. La cabecera consiste en una tabla de sección, para que pueda tener más contenido además de las secciones .text, .data, y .bss.
Es el sucesor de COFF; dispone de secciones múltiples y valores posibles de 32-bits o 64-bits. Una gran desventaja: ELF fué también diseñado asumiendo que solamente existiría una ABI por cada arquitectura de sistema. Esa suposición es en realidad bastante incorrecta y ni siquiera en el mundo comercial SYSV (el cual tiene al menos tres ABIs: SVR4, Solaris y SCO) se puede dar por buena.
FreeBSD trata de solucionar este problema de alguna manera ofreciendo una herramienta para marcar un ejecutable ELF conocido con información acerca de la ABI con la que funciona. Si quiere más información consulte la página de manual de brandelf(1).
FreeBSD viene del campo «clásico» y ha
utilizado el formato a.out(5), una tecnología usada
y probada en muchas de muchas generaciones de versiones de
BSD hasta el inicio de la rama 3.X. Aunque era posible
compilar y ejecutar binarios nativos ELF
(y kernels) en un sistema FreeBSD desde algún tiempo
antes de esto, FreeBSD al principio se mantuvo
«contra corriente» y no cambió a
ELF como formato por defecto.
?Por qué? Bueno, cuando el mundo Linux
efectuó su dolorosa transición a
ELF no fué tanto por huir del formato
a.out
como por su inflexible mecanismo de
bibliotecas compartidas basado en tablas de saltos, que
hacía igual de difícil la construcción de
bibliotecas compartidas tanto para los desarrolladores como para
los proveedores.
Ya que las herramientas ELF
disponibles ofrecían una solución al problema de
las bibliotecas compartidas y eran vistas por mucha gente como
«la manera de avanzar», el costo
de migración fué aceptado como necesario y se
realizó la transición. El mecanismo de
bibliotecas compartidas de FreeBSD está diseñado de
manera más cercana al estilo del sistema de
bibliotecas compartidas de SunOS™ de Sun y, como tal, es
muy sencillo de utilizar.
Entonces, ?por qué existen tantos formatos diferentes?
En un tiempo muy, muy lejano, existía hardware simple.
Este hardware tan simple soportaba un sistema pequeño, simple.
a.out
era idóneo para el trabajo
de representar binarios en este sistema tan simple (un PDP-11). A
medida que la gente portaba UNIX® desde este sistema simple,
retuvieron el formato a.out
debido a que
era suficiente para los primeros portes de UNIX® a arquitecturas
como 68k de Motorola, VAXen, etc.
Entonces algún brillante ingeniero de hardware decidió
que si podía forzar al software a hacer algunos trucos
sucios podría sortear ciertos obstáculos del
diseño y permitir al núcleo de su CPU correr más
rápidamente. Aunque estaba hecho para trabajar con este nuevo
tipo de hardware (conocido entonces como RISC),
a.out
no estaba bien adaptado para este
hardware, así que varios formatos fueron desarrollados
para obtener un rendimiento mayor de este hardware que el
podía extraerse del limitado y simple formato
a.out
.
Así fué cómo COFF,
ECOFF y algunos otros formatos más
extraños fueron inventados y sus limitaciones exploradas hasta
que se fué llegando a la elección de
ELF.
Además, el tamaño de los programas estaba
volviendose gigante y los discos (y la memoria física)
eran relativamente pequeños, así que el concepto
de una biblioteca compartida nació. El sistema
VM también se volvió más sofisticado.
A pesar de que todos estos avances se hicieron utilizando
el formato a.out
, su utilidad se iba reduciendo
paulatinamente con cada nueva opción. Además,
la gente quería cargar cosas dinámicamente en el momento
de ejecución, o descartar partes de su programa después de
que el código de inicio se ejecutara para ahorrar memoria
principal y espacio de swap. Al volverse más sofisticados los
lenguajes, la gente empezó a ver la necesidad de introducir
código antes del inicio del programa de forma automática.
Se hicieron muchos hacks al formato a.out
para
permitir que todas estas cosas sucedieran y lo cierto es que por un
tiempo funcionaron. Pero a.out
no estaba
para solucionar todos estos problemas sin incrementar la carga
y complejidad del código. Aunque ELF
resolvía muchos de estos problemas, en ese momento hubiera sido
terrible dejar de lado un sistema que funcionaba,
así que
ELF tuvo que esperar hasta que fué más
doloroso permanecer con a.out
que migrar a
ELF.
De todas maneras, con el paso del tiempo las herramientas de compilación de las que FreeBSD derivó las suyas (en especial el ensamblador y el cargador) evolucionaron en dos árboles paralelos. El árbol FreeBSD FreeBSD añadió bibliotecas compartidas y corrigió algunos errores. La gente de GNU (que fueron quienes escribieron estos programas) los reescribió y añadieron una forma más simple de disponer de compiladores cruzados («cross compilers»), el uso de diferentes formatos, etc. Aunque mucha gente quería compiladores cruzados con FreeBSD como «blanco» no hubo suerte, porque los fuentes que que FreeBSD tenía para as y ld no estaban listos para cumplir esa tarea. La nueva cadena de herramientas GNU (binutils) soporta compilación cruzada, ELF, bibliotecas compartidas, extensiones C++, etc. Además, muchos proveedores están liberando binarios ELF y es algo muy bueno que FreeBSD los pueda ejecutar.
ELF es más expresivo que
a.out
y permite un sistema base más extensible.
Las herramientas ELF están mejor
mantenidas y ofrecen soporte de compilación cruzada,
muy importante para mucha gente.
ELF puede ser un poco más lento que
a.out
, pero tratar de medirlo puede ser
difícil. También existen numerosos detalles
que son diferentes entre los dos en cómo gestionan páginas,
cómo gestionan código de inicio, etc. Ninguna
es muy importante, pero las diferencias existen. Con el tiempo,
el soporte para a.out
será eliminado
del kernel GENERIC
y es muy posible que
se elimine del kernel la posibilidad de ejecutar tales binarios
una vez que la necesidad de usar programas
a.out
haya pasado.
Puede descargar éste y muchos otros documentos desde ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/
Si tiene dudas sobre FreeBSD consulte la
documentación antes de escribir a la lista
<questions@FreeBSD.org>.
Envíe sus preguntas sobre la documentación a
<doc@FreeBSD.org>.