Enlazador (informática)
En informática, un enlazador o editor de enlaces es un programa de sistema informático que toma uno o más archivos de objetos (generados por un compilador o un ensamblador) y los combina en un solo archivo ejecutable, archivo de biblioteca u otro "objeto" expediente.
Una versión más simple que escribe su salida directamente en la memoria se llama cargador, aunque la carga generalmente se considera un proceso separado.
Resumen
Los programas de computadora generalmente se componen de varias partes o módulos; estas partes/módulos no necesitan estar contenidos dentro de un solo archivo de objeto y, en tales casos, se refieren entre sí por medio de símbolos como direcciones en otros módulos, que se asignan a direcciones de memoria cuando se vinculan para su ejecución.
Si bien el proceso de vinculación está destinado a combinar en última instancia estas partes independientes, existen muchas buenas razones para desarrollarlas por separado en el nivel de fuente. Entre estas razones se encuentran la facilidad de organizar varias piezas más pequeñas en un todo monolítico y la capacidad de definir mejor el propósito y las responsabilidades de cada pieza individual, lo cual es esencial para administrar la complejidad y aumentar la capacidad de mantenimiento a largo plazo en la arquitectura de software.
Normalmente, un archivo de objeto puede contener tres tipos de símbolos:
- símbolos definidos "externo", a veces llamados símbolos "públicos" o "entrada", que permiten que sea llamado por otros módulos,
- símbolos "externos" indefinidos, que hacen referencia a otros módulos donde se definen estos símbolos, y
- símbolos locales, utilizados internamente dentro del archivo objeto para facilitar la reubicación.
Para la mayoría de los compiladores, cada archivo de objeto es el resultado de compilar un archivo de código fuente de entrada. Cuando un programa comprende varios archivos de objetos, el enlazador combina estos archivos en un programa ejecutable unificado, resolviendo los símbolos a medida que avanza.
Los enlazadores pueden tomar objetos de una colección llamada biblioteca o biblioteca en tiempo de ejecución. La mayoría de los enlazadores no incluyen toda la biblioteca en la salida; incluyen solo los archivos a los que hacen referencia otros archivos de objetos o bibliotecas. Por lo tanto, la vinculación de bibliotecas puede ser un proceso iterativo, con algunos módulos referenciados que requieren la vinculación de módulos adicionales, y así sucesivamente. Las bibliotecas existen para diversos propósitos, y una o más bibliotecas del sistema suelen estar vinculadas de forma predeterminada.
El enlazador también se ocupa de organizar los objetos en el espacio de direcciones de un programa. Esto puede implicar reubicar el código que asume una dirección base específica en otra base. Dado que un compilador rara vez sabe dónde residirá un objeto, a menudo asume una ubicación base fija (por ejemplo, cero). La reubicación del código de máquina puede implicar la reorientación de saltos, cargas y almacenamientos absolutos.
La salida ejecutable del enlazador puede necesitar otro pase de reubicación cuando finalmente se cargue en la memoria (justo antes de la ejecución). Este paso generalmente se omite en el hardware que ofrece memoria virtual: cada programa se coloca en su propio espacio de direcciones, por lo que no hay conflicto incluso si todos los programas se cargan en la misma dirección base. Este pase también se puede omitir si el ejecutable es un ejecutable independiente de la posición.
En algunas variantes de Unix, como SINTRAN III, el proceso realizado por un enlazador (ensamblar archivos de objetos en un programa) se denominaba cargar (como cargar código ejecutable en un archivo). Además, en algunos sistemas operativos, el mismo programa maneja los trabajos de vinculación y carga de un programa (vinculación dinámica).
Enlace dinámico
Muchos entornos de sistemas operativos permiten la vinculación dinámica, aplazando la resolución de algunos símbolos indefinidos hasta que se ejecuta un programa. Eso significa que el código ejecutable aún contiene símbolos no definidos, además de una lista de objetos o bibliotecas que proporcionarán definiciones para estos. Al cargar el programa, también se cargarán estos objetos/bibliotecas y se realizará un enlace final.
Este enfoque ofrece dos ventajas:
- Las bibliotecas frecuentemente utilizadas (por ejemplo, las bibliotecas del sistema estándar) deben almacenarse en un solo lugar, no duplicadas en cada archivo ejecutable, lo que ahorra un espacio limitado de memoria y disco.
- Si un error en una función de biblioteca es corregido por reemplazar la biblioteca o el rendimiento es mejorado, todos los programas que lo utilizan dinámicamente se beneficiarán de la corrección después de reiniciarlos. Los programas que incluyeron esta función por vinculación estática tendrían que ser reenlazados primero.
También hay desventajas:
- Conocido en la plataforma Windows como "DLL hell", una biblioteca actualizada incompatible romperá los ejecutables que dependían del comportamiento de la versión anterior de la biblioteca si la versión más reciente no es compatible correctamente con el revés.
- Un programa, junto con las bibliotecas que utiliza, podría ser certificado (por ejemplo, en cuanto a corrección, requisitos de documentación o rendimiento) como un paquete, pero no si los componentes pueden ser reemplazados (esto también argumenta contra actualizaciones automáticas del sistema operativo en sistemas críticos; en ambos casos, el sistema operativo y las bibliotecas forman parte de un cualificado medio ambiente).
Los entornos cerrados o virtuales pueden permitir que los administradores de sistemas mitiguen o compensen estas ventajas y desventajas individuales.
Enlace estático
La vinculación estática es el resultado de que el vinculador copie todas las rutinas de biblioteca utilizadas en el programa en la imagen ejecutable. Esto puede requerir más espacio en disco y memoria que el enlace dinámico, pero es más portátil, ya que no requiere la presencia de la biblioteca en el sistema donde se ejecuta. La vinculación estática también evita el "infierno de DLL", ya que cada programa incluye exactamente las versiones de rutinas de biblioteca que requiere, sin conflicto con otros programas. Un programa que usa solo unas pocas rutinas de una biblioteca no requiere que se instale toda la biblioteca.
Reubicación
Como el compilador no tiene información sobre el diseño de los objetos en el resultado final, no puede aprovechar instrucciones más cortas o más eficientes que exigen la dirección de otro objeto. Por ejemplo, una instrucción de salto puede hacer referencia a una dirección absoluta o un desplazamiento desde la ubicación actual, y el desplazamiento podría expresarse con diferentes longitudes según la distancia al objetivo. Al generar primero la instrucción más conservadora (generalmente la variante relativa o absoluta más grande, según la plataforma) y agregar sugerencias de relajación, es posible sustituir instrucciones más cortas o más eficientes durante el enlace final. Con respecto a las optimizaciones de salto, esto también se denomina dimensionamiento de salto automático. Este paso se puede realizar solo después de que todos los objetos de entrada hayan sido leídos y asignados direcciones temporales; el pase de relajación del enlazador posteriormente reasigna direcciones, lo que a su vez puede permitir que ocurran más relajaciones potenciales. En general, las sucesiones sustituidas son más cortas, lo que permite que este proceso converja siempre a la mejor solución dado un orden fijo de objetos; si este no es el caso, las relajaciones pueden entrar en conflicto y el enlazador debe sopesar las ventajas de cualquiera de las opciones.
Si bien la relajación de las instrucciones suele ocurrir en el momento del enlace, la relajación del módulo interno ya puede tener lugar como parte del proceso de optimización en el momento de la compilación. En algunos casos, la relajación también puede ocurrir en el momento de la carga como parte del proceso de reubicación o en combinación con técnicas dinámicas de eliminación de códigos muertos.
Editor de enlaces
En entornos de mainframe IBM System/360 como OS/360, incluido z/OS para los mainframes z/Architecture, este tipo de programa se conoce como editor de vínculos. Como su nombre lo indica, un editor de enlaces tiene la capacidad adicional de permitir la adición, reemplazo y/o eliminación de secciones individuales del programa. Los sistemas operativos como OS/360 tienen un formato para módulos de carga ejecutables que contienen datos complementarios sobre las secciones componentes de un programa, de modo que se puede reemplazar una sección de programa individual y se pueden actualizar otras partes del programa para que las direcciones reubicables y otras referencias puedan ser corregido por el editor de enlaces, como parte del proceso.
Una ventaja de esto es que permite mantener un programa sin tener que conservar todos los archivos de objetos intermedios o sin tener que volver a compilar las secciones del programa que no han cambiado. También permite que las actualizaciones del programa se distribuyan en forma de pequeños archivos (originalmente barajas de cartas), que contienen solo el módulo objeto que se va a reemplazar. En dichos sistemas, el código objeto tiene la forma y el formato de imágenes de tarjetas perforadas de 80 bytes, de modo que las actualizaciones se pueden introducir en un sistema utilizando ese medio. En versiones posteriores de OS/360 y en sistemas posteriores, los módulos de carga contienen datos adicionales sobre las versiones de los módulos de componentes, para crear un registro rastreable de actualizaciones. También permite agregar, cambiar o eliminar una estructura superpuesta de un módulo de carga ya vinculado.
El término "editor de vínculos" no debe interpretarse como que implica que el programa funciona en un modo interactivo con el usuario como un editor de texto. Está destinado a la ejecución en modo por lotes, con los comandos de edición proporcionados por el usuario en archivos organizados secuencialmente, como tarjetas perforadas, DASD o cinta magnética, y las cintas se usaron a menudo durante la instalación inicial del sistema operativo.
Edición de enlaces (nomenclatura de IBM) o consolidación o colección (nomenclatura ICL) se refiere al editor de enlaces o el acto del consolidador de combinar las diversas piezas en un binario reubicable, mientras que la carga y reubicación en un binario absoluto en la dirección de destino normalmente se considera un paso separado.
Implementaciones comunes
En sistemas Unix y similares a Unix, el enlazador se conoce como "ld". Orígenes del nombre "ld" son "cargadores" y "Editor de enlaces". El término "cargador" se utilizó para describir el proceso de carga de símbolos externos de otros programas durante el proceso de vinculación.
Enlazador GNU
El enlazador GNU (o GNU ld) es la implementación de software libre del proyecto GNU del comando ld de Unix. GNU ld ejecuta el enlazador, que crea un archivo ejecutable (o una biblioteca) a partir de archivos objeto creados durante la compilación de un proyecto de software. Se puede pasar un guión de enlace a GNU ld para ejercer un mayor control sobre el proceso de enlace. El enlazador GNU es parte de GNU Binary Utilities (binutils). Se proporcionan dos versiones de ld en binutils: la tradicional GNU ld basada en bfd y una "optimizada" Versión solo ELF llamada oro.
La línea de comandos y la sintaxis de la secuencia de comandos del enlazador de GNU ld es el estándar de facto en gran parte del mundo similar a Unix. El enlazador del proyecto LLVM, lld, está diseñado para ser compatible y puede usarse directamente con el compilador GNU. Otro reemplazo directo, el molde, es una alternativa altamente paralelizada y más rápida que también es compatible con las herramientas GNU.