Formato de archivo de objeto común
El formato de archivo de objeto común ( COFF ; formato de archivo de objeto general alemán ) es un formato binario para programas y archivos de objeto. Fue introducido por AT&T para el sistema operativo Unix System V y ahora se usa principalmente en el formato PE para Windows basado en él (ver Portable Executable ). "Cof", "obj" o " lib " se utilizan a menudo para las extensiones de archivo, si existen y además de las extensiones utilizadas para PE .
historia
El formato a.out se utilizó originalmente para archivos ejecutables en Unix . Sin embargo, esto no fue compatible con los desarrollos modernos, como la información de depuración incorporada o las bibliotecas dinámicas . Por lo tanto, AT&T desarrolló el formato de archivo de objeto común para la versión 3 del sistema Unix V. Dado que el COFF original estaba limitado en términos de diseño, se desarrollaron diferentes variantes entre los fabricantes de Unix (por ejemplo, XCOFF de IBM para AIX , ECOFF de SGI y otros). Con la versión 4 de System V en 1989, AT&T reemplazó COFF con el nuevo formato ELF (formato ejecutable y de enlace) desarrollado junto con Sun Microsystems .
caracteristicas
COFF hizo posible incrustar información de depuración directamente en un archivo binario. Las bibliotecas se pueden vincular dinámicamente y manejarse como archivos separados, por lo que no es necesario que se conviertan en una parte inmutable y no intercambiable de un archivo de programa. Para ello, todas las direcciones de las entradas de reubicación se cargan en la memoria virtual de la aplicación en relación con la dirección real de la sección. Esta dirección necesita de la sección solo para que el tiempo de compilación ya esté configurado en la programación. Los formatos desarrollados según COFF también tienen estas capacidades.
utilizar
Las versiones modernas de Unix y Linux ya no son compatibles con COFF, pero todavía se usa para sistemas integrados . En Windows NT (y versiones anteriores), la variante COFF Portable Executable (PE, a veces también PE / COFF) es el formato de archivo estándar para bibliotecas y ejecutables, pero esta variante difiere ligeramente del COFF original.
estructura
Un archivo COFF consta de varias partes. Comienza con el encabezado del archivo y un encabezado opcional . A esto le siguen una serie de secciones , que constan de un encabezado, una sección de datos y un área para entradas de números de línea y un área para entradas de reubicación. Una tabla de símbolos y una tabla de cadenas de caracteres siguen al final del archivo .
Encabezado de archivo
El encabezado del archivo está al principio de un archivo. Allí se almacenan datos que describen la estructura de todo el archivo. Esto incluye el número mágico , que es diferente para las diferentes variantes ( PE , XCOFF , etc.), una marca de tiempo de Unix con la hora en que se creó el archivo y la posición y el tamaño de otras secciones. Además de utilizar Flag varias propiedades del archivo a definir (por ejemplo, si es ejecutable).
struct filehdr {
unsigned short f_magic; /* Magische Zahl */
unsigned short f_nscns; /* Anzahl der Sektionen in der Datei */
long f_timdat; /* Zeitstempel der Erstellung */
long f_symptr; /* Zeiger zur Symboltabelle */
long f_nsyms; /* Größe der Symboltabelle */
unsigned short f_opthdr; /* Größe der "optional header" */
unsigned short f_flags; /* Flags */
};
Encabezado opcional
El encabezado opcional contiene datos diferentes según la variante COFF. A menudo se utiliza para otra información necesaria para la ejecución (por ejemplo, la dirección de entrada). Dado que puede tener diferentes longitudes, su tamaño se almacena en el "Encabezado de archivo".
Encabezado de sección
El encabezado de la sección contiene datos sobre una sección, en particular su tamaño y dónde debe cargarse en la memoria virtual . Para archivos ejecutables, generalmente el comienzo de la memoria, es decir H. la primera sección se carga en la dirección 0; esto puede ser diferente para los datos vinculados. También contienen un puntero y el tamaño de las entradas del número de línea y las entradas de reubicación.
struct sectionhdr {
char s_name[8]; /* Name der Sektion */
unsigned long s_paddr; /* Speicheradresse, an die diese Sektion geladen werden soll*/
unsigned long s_vaddr; /* virtuelle Adresse, an die diese Sektion geladen werden soll */
unsigned long s_size; /* Größe der Sektion (inklusive Header)*/
unsigned long s_scnptr; /* Zeiger zu den Daten dieser Sektion */
unsigned long s_relptr; /* Zeiger zu den Relokationseinträgen dieser Sektion */
unsigned long s_lnnoptr; /* Zeiger zu dem Zeilennummerneinträgen dieser Sektion */
unsigned short s_nreloc; /* Anzahl der Relokationseinträge */
unsigned short s_nlnno; /* Anzahl der Zeilennummerneinträge */
unsigned long s_flags; /* Flags */
};
Sección de datos
La sección de datos puede tener diferentes longitudes. Contiene los datos reales en el archivo. Suelen ser instrucciones en código de máquina , espacio para variables y datos que se requieren para la ejecución; en resumen, el programa real.
Entrada de reubicación
Una entrada de reubicación define dónde se pueden encontrar los símbolos en la sección de datos. Esto se define individualmente para cada símbolo.
typedef struct reloc{
unsigned long r_vaddr; /* Adresse für die Relokation */
unsigned long r_symndx; /* Symbol, für das die Relokation gilt */
unsigned short r_type; /* Type der Relokation*/
};
Entrada de número de línea
Una entrada de número de línea define qué línea en el código fuente corresponde a qué instrucción en el código de máquina. Esto es especialmente importante para depurar aplicaciones. Cada sección tiene su propia tabla de números de línea. Las líneas se cuentan individualmente para cada función en la sección.
typedef struct lineno{
union l_addr{
unsigned long l_symndx; /* Index des Namens der Funktion */
unsigned long l_paddr; /* Adresse der Zeilennummer */
};
unsigned short l_lnno; /* Zeilennummer */
};
Los números de línea se incrementan desde 0 al comienzo de cada función. Para una línea en la que comienza una l_lnno = 0función, se l_symndxcrea una entrada con y el símbolo de la función como . Para cada línea adicional en la función, se crea una entrada con el número de líneas desde el inicio de la función como l_lnnoy la dirección de la primera instrucción de esta línea como l_paddr.
Tabla de símbolos
La tabla de símbolos contiene información sobre los símbolos del archivo. Los símbolos son, por ejemplo, B. Funciones o variables que pueden ser utilizadas por otros programas. El tamaño y la posición de la tabla de símbolos se especifican en el encabezado del archivo . La tabla de símbolos consta de entradas del formulario
typedef struct sysent{
union e {
char e_name[8]; /* Name des Symbols */
struct e {
unsigned long e_zeroes; /* Falls 0, ist der Name des Symbols in der Zeichenkettentabelle angelegt*/
unsigned long e_offset; /* Position des Symbols in der Zeichenkettentabelle */
};
};
unsigned long e_value; /* Wert (in der Regel Adresse) des Symbols */
short e_scnum; /* Sektion */
unsigned short e_type; /* Datentyp */
unsigned char e_sclass; /* Speicherklasse */
unsigned char e_numaux; /* Anzahl zusätzlicher Einträge*/
};
El nombre del símbolo se e_nameguarda si tiene ocho caracteres o menos. De lo contrario, se almacena en la tabla de cadenas de caracteres, luego se almacena e_zeros = 0e e_offsetindica la posición de esta entrada en la tabla de cadenas de caracteres. El "valor" del símbolo se e_valueguarda en. Esta suele ser la dirección en la que se almacena este símbolo, que a su vez depende del tipo de datos y la clase de almacenamiento en la que se e_sclassalmacena. e_typedefine el tipo de datos del símbolo. Puede ser un tipo elemental (int, float, etc.) o un tipo compuesto (estructura, unión). Además, el símbolo puede definir un valor, un puntero, un campo ("matriz") o una función que devuelve este valor. e_classdefine la clase de almacenamiento, es decir, dónde y cómo se almacena el símbolo (por ejemplo, puede ser un símbolo externo, un argumento de función, una variable global o estática, etc.). Pueden seguir entradas adicionales dependiendo del tipo de símbolo. También se e_numauxindica el número de estas entradas .
Tabla de cuerdas
La tabla de cadenas sigue al archivo al final. Comienza con un número entero en el que se almacena la longitud de la tabla. Entonces todas las cuerdas se suceden. Para leer una cadena de caracteres, debe conocer su posición y puede comenzar a leer en este punto. Las cadenas terminan en cero .
Evidencia individual
- ↑ Common Object File Format Texas Instruments, consultado el 8 de marzo de 2014
- ↑ Información general sobre SCO System V Release 3 ( Memento de la original, del 9 de marzo de 2014 en el Archivo de Internet ) Información: El archivo de enlace se inserta de forma automática y sin embargo no ha sido comprobado. Verifique el enlace original y de archivo de acuerdo con las instrucciones y luego elimine este aviso. HP, consultado el 8 de marzo de 2014
- ^ IBM de formato de archivo de objeto XCOFF , consultado el 8 de marzo de 2013
- ↑ Especificación de formato de archivo de objeto / tabla de símbolos Compaq / HP, consultado el 8 de marzo de 2014
- ↑ Typer de Ejecutable ( Memento de la original, del 9 de marzo de 2014 en el Archivo de Internet ) Información: El archivo de enlace se inserta de forma automática y sin embargo no ha sido comprobado. Verifique el enlace original y de archivo de acuerdo con las instrucciones y luego elimine este aviso. Linux.org, consultado el 8 de marzo de 2014
- ↑ PE y COFF Specification , Microsoft Developer Network, consultado el 8 de marzo de 2014
enlaces web
- DJGPP COFF Spec : más detalles sobre una implementación de COFF
- MIPS COFF como tipos de datos C
- Información de Microsoft COFF