Estructura de los archivos *.DCU


¡ Mira que he encontrado !

Para empezar parece conveniente leer que dice la ayuda acerca de la estructura de estos archivos. ¡Vamos alla!. Escribo en la casilla de busqueda "DCU" y leo

Compiler-generated project files
.DCU Unit object code
Compilation creates a .DCU file corresponding to each .PAS file in the project.

Bien, ahora voy a consultar en el libro del Sr. Charte, Programacion Delphi, cuenta que estos archivos los produce el compilador y que contienen codigo binario preparado para acelerar el enlace. En el libro La cara oculta de Delphi el Sr. Marteens nos cuenta que tienen un parecido a los archivos OBJ.

Archivos OBJ..., esto puede ser una pista.... Esta vez en la ayuda hay algo escrito, ahi nos dicen que deben respetar una estructura de ensamblador CONST DATA CODE.. bien ya sabemos algo, pues probablemente DCU tambien tenga esta estructura.

Vamos a mirar dentro. Aqui el mago va a necesitar una bola de cristal. Podemos usar un editor hexadecimal y ¿ que encontraremos ? montones de cifras y algunas palabras significativas... Hemos entrado en el mundo del compilador, estamos viendo el resultado de su trabajo, debemos pues repetar su territorio y sus leyes. De momento no las conocemos. Sabemos que su trabajo tiene un input desde nuestro lenguaje Delphi y que sus resultados serán usados por el linker hasta llegar a la CPU. No esta previsto que su contenido sea comprensible para el lector humano.

Vamos a buscar pues en que forma estan representadas las estructura de lenguaje Pascal dentro del archivo DCU. Vamos a necesitar informacion de los tipos basicos usados byte, word, string, etc. para entender la seccion "data" y tambien las instrucciones de CPU, su codigo hexadecimal, su longitud, etc para entender la seccion "code".

Vamos con la representacion del tipo dword, este tipo tiene una longitud de 4 bytes(32 bits) y la podemos ver en el siguiente ejemplo.

Estos es el listado de una unit vacia
unit Unit4;
interface
implementation
end.

Esto es el listado hexadecimal del Unit4.DCU compilado con Delphi2:
4853 5050 6000 0000 ADAB 4625 0070 0955 HSPP`.....F%.p.U
6E69 7434 2E70 6173 A6AB 4625 0064 0653 nit4.pas..F%.d.S
7973 7465 6D00 0000 0063 2805 556E 6974 ystem....c(.Unit
3480 0000 0000 0002 0263 4000 0000 6C02 4........c@...l.
C36D 0400 0304 0204 0490 020E 0091 0202 .m..............
1000 9200 9300 0094 0404 2000 0000 0061 .......... ....a

He estado haciendo listados de unit compiladas por mi con Delphi2 y todas parecen tener los primeros 4 bytes iguales HSPP 48535050h, un buen dia hice un listado de las units del "Cursillo de Delphi" de Jorge y tuve la sorpresa de encontrar que habia diferencias unas tenian el tipico HSPP pero otras A.QD 41865144h. Envie un mail comentando el tema y me contesto que las primera units estaban compiladas con Delphi2 y las ultimas con Delphi3. Confirmando que la estructura cambia de una versión a otra.

Vamos con los 4 bytes siguientes. Nos introduciran en el mundo de la representación binaria de los numeros usado por Intel para sus procesadores.

A la estructura de 8 bits se llama byte, si agrupamos 2 bytes tenemos una word (16 bits). Para el sistema Intel de ordenacion de bytes el primero, es el menos significativo LSB (Least significant byte) y el segundo el mas significativo MSB (Most significant byte) si agrupamos 4 bytes para formar una dword(32 bits) se vuelve a repetir la jugada, 1º y 2º forman una palabra y 3º y 4º otra. Los primera palabra es LSB y la segunda MSB. Dentro de la primera palabra el primer byte es LSB y el segundo MSB.

Ejemplo practico: 6000 0000

6000 LSB word

0000 MSB word, para poder introducir este codigo en una calculadora escribimos 0000 0060 y nos equivale a 96 bytes.

En la posicion offset =4, 6000 0000 equivale a 96 y es la longitud total del archivo unit4.dcu.

Los siguientes 4 bytes "ADAB 4625" estan en en offset 8. Estos bytes, en las units de \LIB tienen un valor fijo a FFFF FFFF, pero en una unidad cualquiera de las que he compilado, hay un numero progresivo que va aumentando las veces que quieras compilar un mismo archivo fuente. Es de suponer que tiene relacion con el factor tiempo. Tambien se puede observar que en el offset 18 es un numero previo:

offset8  =ADAB 4625 equivale 2546 ABAD
offset18 =A6AB 4625 equivale 2546 ABA6
Posiblemente 2546 ABA6 sea un codigo de tiempo de unit4.pas. y 2546 ABAD sea el codigo de unit4.dcu, posterior a unit4.pas


Investigando la posibilidad de que sea una variable del tipo TDateTime, la ayuda da un valor de 8 bytes para este tipo de datos, no parece que sea este tipo. Haciendo una compilacion a las 17:04:00 y otra a las 17:04:20 la diferencia en el contador era de 12 unidades. Tampoco parece que sea un contador de segundos. Esto necesita mas investigacion.

A partir de los siguientes bytes he podido observar que ahi donde hay texto, por ejemplo "Unit4.pas", "System" el byte previo contiene la longitud de caracteres, 09Unit4.pas, 06System.

Debe haber mas cosas, asi que si descubres alguna sera bienvenida tu noticia.

Saludos
jprunes@arrakis.es


Volver a la sección de Articulos