The DCU32INT utility by Alexei Hmelnov.
Version 1.6 beta

----------------------------------------------------------------------------
E-Mail: [email protected]
http://monster.icc.ru/~alex/DCU/
----------------------------------------------------------------------------

Purpose.
--------

Parse Delphi 2.0-6.0 and Kylix 1.0 units (DCU) and convert their information
into the close to Pascal form.

DCU32INT stands for DCU32 INTerface, because this program can't extract
the complete Pascal source, but the extracted unit interface is almost
correct (see Compiler Information Loss Limitations section for exceptions).

This program is a by-product of the FlexT project (see
http://monster.icc.ru/~alex/FlexT/ for details), but
I have done my best to make it useful.

Changes from the version 1.0.
-------------------------

1. Delphi 6.0 and Kylix 1.0 units are supported now.
 Note, this feature is new and it was tested almost only on the
 .\LIB\*.dcu files (see Validity), so bug reports are welcome
 with the units, which were not parsed correctly, applied.
 Please send them to [email protected].
2. When analyzing Delphi 6 and Kylix DCU format, the data types
 of some fields were clarified. In particular, some byte fields
 become indices, because additional bits of their values were used.
 I believe, that the fields were indices in all the previous Delphi
 versions too, but I had not enough information to detect it.
 So I hope, that the new DCU specification become more precise.
 But, if somebody will encounter units of previous Delphi
 versions, which DCU32INT can't parse now, please, send them to me.
3. Some additional tables in the tail of DCU, which were ignored
 by version 1.0, are processed now. In particular, the program reports
 line numbers in the disassembled code, if the line numbers information is
 present.

Usage.
------
DCU32INT <Source file name> <Switches> [<Destination file name>]

Destination file may contain * to be replaced by the unit name or name and
extension. If * is the last char in the name, it will be replaced by
<Unit name>.int, else - by <Unit name>.
Destination file = "-" => write to stdout.

Switches (start with "/" or "-"):
-S<show flag>* - Show flags (-S - show all), default: (+) - on, (-) - off
   I(+) - show Imported names
   T(-) - show Type table
   A(-) - show Address table
   D(-) - show Data block
   F(-) - show fixups
   V(-) - show auxiliary Values
   M(-) - don't resolve class methods
   C(-) - don't resolve constant values
   d(-) - show dot types
   v(-) - show VMT for objects and classes
-I - interface part only
-U<paths> = Unit directories
-N<Prefix> = No Name Prefix ("%" - Scope char)
-D<Prefix> = Dot Name Prefix ("%" - Scope char)

The Scope char symbol will be replaced in the name by "T" for types "C" for
constants and so on (see source for details).

In general, there are two main ways to run the program:
- without the -S switch - to produce the most close to the original Pascal
 source output without superfluous details;
- with the -S switch to see a lot of additional information, which reflects
 the internal structure of the DCU file, e.g. the values of some fields of
 unknown purpose (You can try to guess what they mean), the data structures
 representing the VMT of classes, RTTI of data types or the table of
 addresses.
Of course, You can always select only a subset of additional information using
the -S<flags>.

Validity.
---------

The DCU32INT utility have passed successfully the "parse all .\LIB" test
for all the supported by it Delphi and Kylix versions, i.e. it have parsed
all units in the <DELPHI LOCATION>\LIB directory with no errors reported.
See alllib<N>.bat files for examples of running the DCU32INT to parse
all .\LIB.

This success doesn't mean, however, that the underlying DCU specification is
absolutely correct. So, please, send me your bug reports (see the section
"Home page" for details).

The Compiler Information Loss Limitations.
------------------------------------------

There are two kinds of limitations of the DCU32INT program:

1. The ones caused by some disadvantages in its implementation,
 which can be overcome later;
2. The ones caused by information loss in DCU after compiling Pascal
 source, which are inevitable.

Here we'll consider some of the latter limitations.

While converting Pascal source into DCU, Delphi compiler extracts from
source and stores into DCU only the information, which is necessary to
produce later an executable file and also, if required, a debug
information for this file. During this process the compiler performs
some simplifications, which cause information loss.

Examples:

1. Identifiers declared in implementation part and subroutines are discarded
 if the debug info checkbox doesn't checked.

2. Evaluation of expressions. Constant expressions are replaced by their
 values, so one can't determine, e.g. that CDM_FIRST = WM_USER+100,
 it will have the fixed value of $0464.

3. Resolution of rename types. The rename types (types, which are defined
 by declarations like THandle = integer), are replaced by their reference
 type, so all the references to the THandle type in the source code are
 replaced by the System.Integer type.

4. Merge of fields in the records with variants. The declaration like

 TVarRec = record
   case Byte of
     vtInteger:    (VInteger: Integer; VType: Byte);
     vtBoolean:    (VBoolean: Boolean);
   -----------------------------------------
 end;

 Is stored as

 TVarRec{88,7F9FF4C2}=record
   VInteger: Integer{F:2 Ofs:0};
   VType: Byte{F:2 Ofs:4};
   VBoolean: Boolean{F:2 Ofs:0};
   ----------------------------------
 end;

 where Ofs:_ is a field offset information. Of course, we can group
 the fields into cases according to their order and offsets (future work),
 but the information about case labels is lost here completely, and it can't
 be used, e.g. to display safely (Delphi version independent) the Variant
 type value using the TVarRec definition.

All the above mentioned limitations can be demonstrated by Delphi
browser and evaluator (those utilities are also limited by them).

So, the extracted Pascal code can cause some problems, if used in other
version of Delphi, than that, which produced the DCU.

Home page.
----------

The latest version of this program and all the related news will be available
at http://monster.icc.ru/~alex/DCU/

Please, send me (e-mail: [email protected]) bug reports (including the units
which were not parsed correctly), but first check:
 1. that you have the latest version of DCU32INT,
 2. that this bug was not already reported at
    http://monster.icc.ru/~alex/DCU/FAQ.htm (projected page name).