Documentation for



Compares two COFF or ELF files or libraries for equality

USAGE [options] <file1> <file2> [<OFD cmd>]

OFD cmd stands for Object File Display utility. That is the name of the object file display utility from the toolset used to create the object files. Examples: ofd6x for C6000 or ofd55 for C5500. If given, the script runs the OFD command to create the XML version of the object file. Creating the XML in this manner avoids the need to create the XML files prior to running the script, while keeping the script itself device independent.

Other Perl scripts that work with OFD output typically allow you to directly pipe the output of the the OFD command into the script. This script does not work that way; it requires the OFD output from two files, not just one.

If you do not give an OFD command, then the script presumes the files are already in XML format.

For example ...

   % perl file1.obj file2.obj ofd6x

Or ...

   % ofd6x -x -o=file1.xml file1.obj
   % ofd6x -x -o=file2.xml file2.obj
   % perl file1.xml file2.xml


All of these options are disabled by default.

 --syms             : Compare symbols, relocations, and line number entries
 --dwarf            : Compare Dwarf debug sections
 --verbose          : Show raw data bytes that are different (if any)
 --config_file=file : Name file for specifying which sections to skip
 --quiet            : Suppress progress messages
 --cg_xml_version   : Print out the version of the cg_xml package in use

Except for --cg_xml_version, all the options can be abbreviated to a single letter, i.e. -q is equivalent to --quiet.


Recent releases of OFD support options for filtering the XML output down to what is strictly of interest. Filtering the XML in this way reduces the amount of data processed by this script, thus making it run faster. Sometimes much faster.

The exact OFD options to use with this script vary based on conditions detailed below. Note the fewer --obj_display option settings you use, the larger the XML file becomes, and the slower the script executes.

The options given below can be used when building the XML files as a separate step. You can also use those options on the invocation line. If you do that, you have to precede the OFD command with "--". The "--" breaks the command line in half; everything before is script options, everything after is OFD options. For example ...

  perl file1.out file2.out -- ofd6x --xml_indent=0 --obj_display=norawdata,nosymbols,nostrings,norelocs,nolnnos

Yes, that's a long command line. But it saves you from having to create 2 XML files in separate steps. Note OFD -x is not needed here, because always adds it when it invokes OFD. However, using the -x anyway does not cause any problems.

Default Options and Comparing .out Files

  -x --xml_indent=0 --obj_display=norawdata,nosymbols,nostrings,norelocs,nolnnos

Note this means the raw data will not appear in the XML. Thus the script opens the two .out files, reads the raw data directly, and then compares. It turns out this method of comparison is much faster than having the raw data encoded in the XML. Note each .out file must be available for access by the script.

Default Options and Comparing Libraries

  -x --xml_indent=0 --obj_display=nosymbols,nostrings,norelocs,nolnnos

Note the raw data must be kept in the XML in this case. There is no straightforward method for accessing the raw data from inside a library archive file.

Using the --syms Option and Comparing .out Files

  -x --xml_indent=0 --obj_display=norawdata,nostrings

The symbol table, relocation entries, and line number entries are kept for comparison.

Using the --syms Option and Comparing Libraries

  -x --xml_indent=0 --obj_display=nostrings

The symbol table, relocation entries, and line number entries are kept for comparison.


The script can automatically detect when libraries are being compared; no option is necessary.


By default the symbolic information is not compared. This includes the symbol table, the relocations, and the line number entries. Often such information can have slight differences that do not affect the execution of the underlying object code. Whether to compare this information is thus different from user to user.

Only globally defined symbols are compared. Other symbols, which includes function local and file static symbols, are ignored.


By default, the Dwarf debug information is not compared.

Dwarf information is represented in two forms by the OFD generated XML. It is encoded in the raw data of the Dwarf debug sections (which are named .debug_<something>). And, it can be explicitly represented in the XML if the -g option is used when invoking OFD.

Use the --dwarf flag to compare the raw data in the Dwarf debug sections.

The explicit representation of the Dwarf debug information (possibly present) in the XML is not examined. This is admittedly a crude approach. But it is the best we can do without a much more sophisticated approach. Comparing two Dwarf representations is like comparing two C programs. Even though they may appear quite different, they may represent the same thing.


Stabs debug information is encoded as a collection of cleverly arranged symbols in the symbol table, plus line number entries. No Dwarf-like sections contain stabs debug information. Because only globally defined symbols are ever compared, there is no way to compare Stabs debug information.


You can choose to not compare sections either by name, or by section header flags. Write a configuration file to specify which sections to skip, and supply the name of that file with the option --config_file=file_name.


 <property> = <value>

Valid syntax for a property includes: SKIP_BY_NAME, SKIP_BY_FLAG

If the property is SKIP_BY_NAME, the value need only be a string. Note it must match the name of an actual section to have any effect.

If the property is SKIP_BY_FLAG, valid values include: COPY, UDATA, TEXT, DATA, DUMMY, NOLOAD. Note UDATA stands for uninitialized data, i.e. the "bss" flag. Any section which has one of these flags set in the section header is skipped.

You can list multiple SKIP_BY_NAME and SKIP_BY_FLAG entries.

The configuration file may also contain empty space, blank lines, and comments that begin with '#'. Only simple error checking is done when processing the file. Poke holes in it, if you must.


 # Configuration File Example
 SKIP_BY_NAME = .one      # comments OK here too
 SKIP_BY_NAME = two       # sections do not have to start with '.'
 SKIP_BY_FLAG = COPY      # skip all sections that have the COPY flag set


Suppose you want to compare two files, and you know one file has an additional section named "extra" that you want to avoid comparing. So, you use the configuration file entry ...

 SKIP_BY_NAME = extra

to skip it. The file comparison will still fail. The file header includes a count of the number of sections in the file. This count is unaffected by which sections are skipped during comparison. Thus, this section count will be different between the files, even though the "extra" section is skipped.


Text based file comparison utilities like Unix diff can often adjust for differences found and usefully continue the comparison. Such is not the case for When a difference is found no attempt is made to somehow compensate for that difference.

For example, when the size of a section changes (presuming this section is loaded to target memory), this causes all sections after it in memory to begin on different addresses. Further, all symbolic references to these sections are different, which can show up as differences in any section.


Make sure that the OFD command is in your executables path.

This script was written using Perl version 5.8.3. It may not work with earlier revisions of Perl.

 Documentation for