domingo, 16 de agosto de 2009

Archivos Ejecutables en Linux

Linux utiliza como archivos ejecutables , los ELF (Executable and Linkable Format) Este formato nos permite tener archivo binario separado en segmentos de datos y e encabezado ELF, que describe como es el archivo binario propiamente dicho. Cuando se ejecuta el programa, se ira cargando una cantidad determinada de segmentos (no necesariamente todo el ejecutable) que ira variando dependiendo de su ejecución. Así, no hace falta que todo el binario esté cargado en memoria al mismo tiempo.

De esta manera, la unidad de ejecución en Linux son los procesos. Cuando se ejecuta un programa, se crea un proceso nuevo en el que se ejecutara y que sera identificado por su PID (Process ID). El kernel permite, luego que un programa tenga varios procesos o varios threads. Además, soporta distintos mecanismos de comunicación y sincronización, entre los que podemos encontrar sockets, semáforos, memoria compartida y tuberías.

El formato ELF (Executable and Linkable Format) es un formato de archivo para ejecutables, código objeto, librerías compartidas y volcados de memoria. Fue desarrollado por el UNIX System Laboratory (USL) como parte de la ABI. En principio fue desarrollado para plataformas de 32 bits, a pesar de que hoy en día se usa en gran variedad de sistemas.
Es el formato ejecutable usado mayoritariamente en los sistemas tipo UNIX como GNU/Linux, BSD, Solaris, Irix. Existen otros formatos soportados en algunos de estos sistemas pero ELF es sin duda el más usado.
Dentro del formato ELF podemos distinguir varias partes.
En primer lugar la cabecera ELF, que contiene información general sobre el ejecutable. En él se indican las posiciones de las tablas de cabeceras de sección y cabeceras de programa.
Cada una de estas cabeceras indican dónde se encuentran los datos de cada una de las secciones. Las cabeceras de programa definen las regiones del ejecutable o librería que es necesario cargar para crear la imagen del proceso e iniciar su ejecución. Las cabeceras de sección contienen información importante para el enlazado y la relocalización.
Las secciones tienen nombres que suelen coincidir en todos los sistemas. Por ejemplo:
.data Contiene datos inicializados del programa.
.debug Contiene información para ayudar a la depuración.
.ctors Contiene punteros a constructores de C++.
.dtors Contiene punteros a destructores de C++.
.dynamic Contiene información relevante para el enlazado dinámico.
.dynsym Contiene la tabla de símbolos para el enlazado dinámico.
.fini Contiene código de finalización del programa.
.init Contiene código de inicialización del programa.
.shstrtab Contiene una tabla de strings con los nombres de las secciones.
.strtab Contiene una tabla de strings normalmente usada para nombrar los elementos de la tabla de símbolos.
.symtab Contiene una tabla de símbolos.
.text Contiene la parte ejecutable de un programa.
Readelf es un programa UNIX que muestra la información sobre un archivo ELF.
Está implementado bajo licencia GPL en las GNU Binary Utilities.