c linux memory elf

¿Qué parte del archivo ELF se debe cargar en la memoria?



linux memory (1)

Un archivo ELF para ejecutables tiene un encabezado de programa (segmento) y un encabezado de sección, que puede verse a través de readelf -a , aquí hay un ejemplo:

Las dos imágenes de arriba son encabezado de sección y encabezado de programa (segmento), respectivamente. Se puede ver que un encabezado de segmento se compone de varios encabezados de sección, que se utilizan para cargar el programa en la memoria.

¿Solo es necesario que las secciones .text, .rodata, .data, .bss se carguen en la memoria?

¿Se utilizan para alinear todas las demás secciones del segmento (por ejemplo, .ctors, .dtors .jcr en el tercer segmento)?


Secciones y segmentos son dos conceptos completamente diferentes. Las secciones pertenecen a la semántica de los datos almacenados allí (es decir, para qué se utilizarán) y en realidad son irrelevantes una vez que se vincula un programa o biblioteca compartida, excepto para fines de depuración. Incluso podría eliminar los encabezados de sección por completo (o sobrescribirlos con basura aleatoria) y un programa aún funcionaría.

Los segmentos (es decir, las directivas de carga del encabezado del programa) son lo que el kernel y / o el enlazador dinámico realmente ven cuando se carga un programa. Por ejemplo, en su caso usted tiene dos directivas de carga. La primera causa que la primera 4k (1 página) del archivo se asigne en la dirección 0x08048000, e indica que solo se deben usar los primeros 0x4b8 bytes de esta asignación (el resto es la alineación). El segundo hace que los primeros 8k (2 páginas) del archivo se asignen en la dirección 0x08049000. La gran mayoría de eso es la alineación. Los primeros 0xf14 bytes no forman parte de la directiva de carga (solo alineación) y se perderán. A partir de 0x08049f14, se utilizan realmente 0x108 bytes asignados desde el archivo, y otros 0x10 bytes (para alcanzar el MemSize de 0x118) son rellenados por el cargador (kernel o enlazador dinámico). Esto se extiende hasta 0x0804a02c (en la segunda página asignada). El resto de la segunda página asignada no se utiliza / se desperdicia (pero malloc podría recuperarla para usarla como parte del montón).

Finalmente, mientras que los encabezados de sección no se utilizarán en absoluto, el programa puede usar el contenido de muchas secciones diferentes mientras se está ejecutando. Tenga en cuenta que los rangos de direcciones de .ctors y .dtors encuentran al principio de la segunda asignación de carga, por lo que el programa los asigna y puede acceder a ellos en tiempo de ejecución (el código de inicio / salida en tiempo de ejecución los utilizará para ejecutar constructores y destructores globales, si Se utilizó el código C ++ o "GNU C" con el atributo ctor / dtor). También tenga en cuenta que .data comienza en la dirección 0x0804a00c, en la segunda página asignada. Esto permite proteger la primera página de solo lectura después de aplicar las reubicaciones (la directiva RELRO en el encabezado del programa).