linker - recomendada - memoria virtual windows 8
reubicaciĆ³n de tiempo de carga y memoria virtual (1)
La reubicación en tiempo de carga y la compatibilidad con memoria virtual son dos conceptos diferentes. Casi todas las CPU y sistemas operativos en estos días tienen soporte para memoria virtual. El único punto realmente importante para entender sobre la memoria virtual es este: olvídese de las direcciones físicas. Esa es ahora una responsabilidad de hardware y sistema operativo y, a menos que esté escribiendo un sistema de paginación, puede olvidarse de las direcciones físicas. Todas las direcciones que utiliza un programa son direcciones virtuales. Esta es una gran ventaja y simplifica enormemente el modelo de programación. En los sistemas de 32 bits, esto simplemente significa que cada proceso obtiene su propio espacio de memoria de 4 GiB, que van desde 0x00000000
a 0xffffffff
.
An .exe
representa un proceso. Un enlazador produce .exe
desde archivos .obj
. Si bien ambos son archivos binarios, los archivos .obj
no son ejecutables porque no contienen las direcciones de todas las variables y funciones. Es el trabajo del vinculador proporcionar estas direcciones, que determina colocando estos archivos .obj
extremo a extremo y luego calculando las direcciones exactas de todos los símbolos (funciones y variables). Por lo tanto, el .exe
que se crea tiene todas las direcciones de funciones y variables "codificadas" en él. Pero aún se necesita una información crítica antes de poder crear .exe
. El enlazador debe tener conocimiento interno sobre dónde se cargará el .exe
en la memoria. ¿Será en la dirección 0x00000000
, o en 0xffff0000
, o en otro lugar? Por ejemplo, en Windows, todos los .exe
s siempre se cargan en una dirección de inicio absoluta de 0x00400000
. Esto se llama la dirección base. Cuando el enlazador genera las direcciones finales de los símbolos (funciones y variables), calcula los de esta dirección en adelante.
Ahora, los .exe
raramente necesitan ser cargados en cualquier otra dirección. Pero lo mismo no es cierto para .dll
s. .ddl
s son lo mismo que .exe
s (ambos están formateados en el formato de archivo ejecutable portátil (PE), que describe el diseño de la memoria, por ejemplo, dónde va el texto, dónde van los datos y cómo encontrar cuál). .dll
s también tiene una dirección preferida. Esto simplemente significa que el vinculador usa este valor cuando calcula las direcciones para símbolos dentro de .dll
. Si el .dll
se carga en esta dirección, entonces estamos todos configurados.
Pero si el .dll
no puede cargarse en esta dirección (digamos que era 0x10000000
) porque ya se había cargado algún otro .dll
en esta dirección, el cargador encontrará otro espacio en la memoria y cargará allí el .dll
. Sin embargo, las direcciones globales de funciones y símbolos en .dll
ahora son incorrectas. Por lo tanto, el cargador tiene que realizar una reubicación (también llamada "corrección"), en la que ajusta las direcciones de todos los símbolos y funciones globales para reflejar sus direcciones reales.
Para hacer este ajuste, el cargador debe poder encontrar todos esos símbolos en el .dll
. El archivo PE tiene una sección .reloc
que contiene el desplazamiento interno de todos los símbolos.
Por supuesto, hay otros detalles, por ejemplo, sobre cómo se puede usar la indirección cuando el compilador generó el código para que, en lugar de realizar llamadas directas, las llamadas sean indirectas y se acceda a las variables a través de ubicaciones de memoria conocidas en el encabezado de .exe
Finalmente, la esencia es esta: necesita reubicación (de algún tipo) para ajustar las direcciones en la llamada y saltar así como las instrucciones de acceso variable cuando el código no se carga en la posición (dentro del espacio de direcciones de 4 GiB) que se esperaba carga. Cuando el SO carga un .exe
, debe elegir un lugar adecuado en este espacio de direcciones de 4 GiB donde copiará el código y los fragmentos de datos de este .exe
en el disco.
Me pregunto qué significa realmente la reubicación en tiempo de carga en un sistema con soporte de memoria virtual. Estaba pensando que en un sistema con memoria virtual cada ejecutable tendrá direcciones comenzando desde cero y en tiempo de ejecución las direcciones se traducirán en direcciones físicas usando tablas de páginas. Por lo tanto, el ejecutable se puede cargar en cualquier lugar de la memoria sin necesidad de ninguna reubicación. Sin embargo, este artículo sobre bibliotecas compartidas menciona que el vinculador especifica una dirección en el ejecutable donde se debe cargar el archivo ejecutable (dirección de punto de entrada).
http://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries/
También hay muchos artículos sobre enlaces dinámicos que hablan de direcciones absolutas. ¿Está mal mi entendimiento?