stringtranslate.com

Reubicación (informática)

La reubicación es el proceso de asignar direcciones de carga para código y datos dependientes de la posición de un programa y ajustar el código y los datos para reflejar las direcciones asignadas. [1] [2] Antes de la llegada de los sistemas multiproceso, y todavía en muchos sistemas integrados, las direcciones de los objetos son absolutas comenzando en una ubicación conocida, a menudo cero. Dado que los sistemas multiprocesamiento se vinculan y cambian dinámicamente entre programas, se hizo necesario poder reubicar objetos utilizando código independiente de la posición . Un enlazador generalmente realiza la reubicación junto con la resolución de símbolos , el proceso de búsqueda de archivos y bibliotecas para reemplazar referencias simbólicas o nombres de bibliotecas con direcciones utilizables reales en la memoria antes de ejecutar un programa.

La reubicación normalmente la realiza el enlazador en el momento del enlace , pero también puede realizarse en el momento de la carga mediante un cargador que la reubica , o en el momento de la ejecución mediante el propio programa que se está ejecutando . Algunas arquitecturas evitan la reubicación por completo al posponer la asignación de direcciones al momento de la ejecución; como, por ejemplo, en máquinas de pila con aritmética de direcciones cero o en algunas arquitecturas segmentadas donde cada unidad de compilación se carga en un segmento separado.

Segmentación

Los archivos de objeto se segmentan en varios tipos de segmentos o secciones de memoria. Algunos ejemplos de tipos de segmentos son el segmento de código (.text) , el segmento de datos inicializados (.data) , el segmento de datos no inicializados (.bss) u otros establecidos por el programador, como segmentos comunes o segmentos estáticos con nombre.

Mesa de reubicación

La tabla de reubicación es una lista de punteros creada por el traductor (un compilador o ensamblador ) y almacenada en el objeto o archivo ejecutable. Cada entrada en la tabla, o "corrección", es un puntero a una dirección absoluta en el código objeto que debe cambiarse cuando el cargador reubica el programa para que haga referencia a la ubicación correcta. Las correcciones están diseñadas para admitir la reubicación del programa como una unidad completa. En algunos casos, cada corrección en la tabla es en sí misma relativa a una dirección base de cero, por lo que las correcciones en sí mismas deben cambiarse a medida que el cargador se mueve a través de la tabla. [2]

En algunas arquitecturas, una corrección que cruza ciertos límites (como un límite de segmento) o que no está alineada con un límite de palabra es ilegal y el enlazador la marca como un error. [3]

DOS y Windows de 16 bits

Los punteros lejanos ( punteros de 32 bits con segmento :offset, utilizados para direccionar un espacio de memoria de 20 bits y 640 KB disponible para programas DOS ), que apuntan a código o datos dentro de un ejecutable DOS ( EXE ), no tienen segmentos absolutos, porque la dirección real del código o los datos depende de dónde se carga el programa en la memoria y esto no se sabe hasta que se carga el programa.

En cambio, los segmentos son valores relativos en el archivo EXE de DOS. Estos segmentos deben corregirse cuando el ejecutable se ha cargado en la memoria. El cargador de EXE utiliza una tabla de reubicación para encontrar los segmentos que deben ajustarse.

Windows de 32 bits

Con sistemas operativos Windows de 32 bits, no es obligatorio proporcionar tablas de reubicación para archivos EXE, ya que son la primera imagen cargada en el espacio de direcciones virtuales y, por lo tanto, se cargarán en su dirección base preferida.

Tanto para las DLL como para los EXE que optan por la aleatorización del diseño del espacio de direcciones (ASLR), una técnica de mitigación de vulnerabilidades introducida con Windows Vista , las tablas de reubicación vuelven a ser obligatorias debido a la posibilidad de que el binario se pueda mover dinámicamente antes de ejecutarse, aunque todavía sea lo primero que se carga en el espacio de direcciones virtuales.

Windows de 64 bits

Al ejecutar binarios nativos de 64 bits en Windows Vista y superiores, ASLR es obligatorio [ cita requerida ] y, por lo tanto, el compilador no puede omitir las secciones de reubicación.

Sistemas tipo Unix

El formato ejecutable y enlazable (ELF) y el formato de biblioteca compartida utilizados por la mayoría de los sistemas tipo Unix permiten definir varios tipos de reubicación. [4]

Procedimiento de reubicación

El enlazador lee la información del segmento y las tablas de reubicación en los archivos de objeto y realiza la reubicación mediante:

Ejemplo

El siguiente ejemplo utiliza la arquitectura MIX de Donald Knuth y el lenguaje ensamblador MIXAL. Los principios son los mismos para cualquier arquitectura, aunque los detalles pueden cambiar.

Véase también

Referencias

  1. ^ "Tipos de código de objeto". Manual de referencia del cargador de aplicaciones iRMX 86 (PDF) . Intel . págs. 1-2–1-3. Archivado (PDF) del original el 2020-01-11 . Consultado el 2020-01-11 . […] El código absoluto y un módulo de objeto absoluto son códigos que han sido procesados ​​por LOC86 para ejecutarse solo en una ubicación específica de la memoria. El cargador carga un módulo de objeto absoluto solo en la ubicación específica que debe ocupar el módulo. El código independiente de la posición (comúnmente conocido como PIC) se diferencia del código absoluto en que el PIC se puede cargar en cualquier ubicación de memoria. La ventaja del PIC sobre el código absoluto es que el PIC no requiere que reserve un bloque específico de memoria. Cuando el cargador carga el PIC, obtiene segmentos de memoria iRMX 86 del grupo del trabajo de la tarea que realiza la llamada y carga el PIC en los segmentos. Una restricción que afecta a PIC es que, como en el modelo de segmentación PL/M-86 COMPACT […], puede tener solo un segmento de código y un segmento de datos, en lugar de dejar que las direcciones base de estos segmentos, y por lo tanto los segmentos mismos, varíen dinámicamente. Esto significa que los programas PIC tienen necesariamente menos de 64K bytes de longitud. El código PIC se puede producir mediante el control BIND de LINK86. El código localizable en tiempo de carga (comúnmente conocido como código LTL) es la tercera forma de código objeto. El código LTL es similar a PIC en que el código LTL se puede cargar en cualquier lugar de la memoria. Sin embargo, al cargar código LTL, el cargador cambia la parte base de los punteros para que los punteros sean independientes del contenido inicial de los registros en el microprocesador. Debido a esta corrección (ajuste de las direcciones base), el código LTL se puede utilizar en tareas que tienen más de un segmento de código o más de un segmento de datos. Esto significa que los programas LTL pueden tener más de 64K bytes de longitud. FORTRAN 86 y Pascal 86 generan automáticamente código LTL, incluso para programas cortos. El código LTL se puede generar mediante el control BIND de LINK86. […]
  2. ^ ab Levine, John R. (2000) [octubre de 1999]. "Capítulo 1: Enlaces y cargas y Capítulo 3: Archivos de objetos". Enlaces y cargadores. La serie Morgan Kaufmann sobre ingeniería de software y programación (1.ª ed.). San Francisco, California, EE. UU.: Morgan Kaufmann . p. 5. ISBN 1-55860-496-0. OCLC  42413382. Archivado desde el original el 5 de diciembre de 2012. Consultado el 12 de enero de 2020 .Código: [1][2] Erratas: [3]
  3. ^ Borland (1999-09-01) [1998-07-02]. "Artículo de Borland n.º 15961: Cómo lidiar con los mensajes de 'Desbordamiento de reparación'". community.borland.com . Base de datos de información técnica - Producto: Borland C++ 3.1. TI961C.txt n.º 15961. Archivado desde el original el 7 de julio de 2008 . Consultado el 15 de enero de 2007 .
  4. ^ "Formato ejecutable y enlazable (ELF)" (PDF) . skyfree.org . Especificación de formatos portátiles de Tool Interface Standards (TIS), versión 1.1. Archivado (PDF) desde el original el 24 de diciembre de 2019 . Consultado el 1 de octubre de 2018 .

Lectura adicional