Following is a discussion of the SCO UNIX System V/386 Development
System Release 3.2 binary types and conversions.
1. COFF and OMF/x.out
The SCO UNIX System V/386 Development System Release 3.2 supports two file
formats for object modules, libraries and executable binaries. They are:
COFF (AT&T "Common Object File Format") and OMF/x.out (XENIX). "OMF/x.out"
refers to the fact that object files and libraries use one format (OMF or
"Object Module Format") while fully linked executables use another (x.out).
Both formats are fully supported by software generation and maintenance tools
and by the SCO UNIX kernel for runtime support. The Microsoft C compiler can
generate either COFF or OMF/x.out binaries depending on command line options.
Additional tools that provide common functionality for both formats, such as
"ar" and "ld," utilize a front-end that executes the appropriate binary
specific tools relative to the file types provided as command line arguments.
The remainder of development system utilities are specific to either COFF or
OMF/x.out file manipulation. They include most standard AT&T tools as well as
those for complete XENIX cross-development. In general, these tools can not
be used in a symmetrical fashion.
With the exception of a few cases, all libraries supplied in the SCO UNIX
System V/386 Development System Release 3.2 are distributed in both COFF
and OMF versions so that system calls and library services are readily
available for linking into either binary type. It should be noted, however,
that non-386 COFF binaries are not supported by either the development tools
or the kernel. The full range of OMF/x.out non-386 binaries are still fully
supported for backward compatibility on older SCO products. In addition,
the SCO UNIX System V/386 Development System Release 3.2 includes the AT&T
Portable C Compiler ("rcc"), assembler ("as"), and linker ("ld") for
generating COFF binaries. Some further comments on their usage are found
below.
The development system provides full debugger support for both binary formats
when compiled appropriately. "adb" and "codeview" can debug either binary
type while AT&T "sdb" is COFF specific. Currently, an x.out version of "sdb"
is not distributed.
2. Conversion Tools
In order to support COFF binaries, the SCO UNIX System V/386 Development
System Release 3.2 utilizes two translation or conversion tools. They
are: "cvtomf" and "cvtcoff". "cvtomf" is used to convert OMF relocatable
object files produced by pass three of the Microsoft compiler to COFF
relocatable object files. As such, "cvtomf" may be considered an optional
fourth pass of the compiler used for COFF generation. It will fully translate
OMF object files to COFF files, including symbolic debug data when used with
"-g". "cvtcoff" performs conversions in the opposite direction, and not only
handles relocatable object files, but COFF archives and executables as well.
These are converted to the appropriate OMF or x.out format files with symbolic
debug data conversions for fully linked executables only. "cvtcoff" was used
under SCO XENIX Development System Release 2.3 ("coffconv") to support the
linkage of COFF objects and archives into x.out binaries. Its use under SCO
UNIX System V/386 Development System Release 3.2 is largely restricted to
Codeview for translating COFF symbolic debug data into x.out format. It is
also used by the Microsoft compiler to translate COFF modules produced by the
AT&T assembler ("as") when an x.out binary is requested on the command line.
The important fact to stress about both conversion programs is that they are
used by specific development system tools in a transparent manner. Although
they can be executed in a "stand-alone" fashion, they were not necessarily
designed for this purpose. There are some serious cautions that accompany
conversion cases not covered above, and in general, manual use of either
"cvtomf" or "cvtcoff" is not recommended.
3. Incompatibilities Between COFF and OMF/x.out Binaries
Although the source code used to produce the binary is identical, COFF and
OMF/x.out binaries may have different link or runtime characteristics. This
is the result of two historical facts: (1) differences in kernel services
between SCO XENIX and traditional AT&T kernels; and (2) differences between
SCO XENIX and AT&T library interfaces. In order to support both COFF and
OMF/x.out binaries, the SCO kernel makes some distinctions between the binary
types at runtime and may provide different functionality in some cases. The
most notable case concerns file locking. COFF files traditionally provided
only advisory locking, while OMF/x.out binaries under XENIX traditionally used
mandatory locking. In addition, system call parameter values for lockf(S) and
fcntl(S) are different in some cases between SCO XENIX and AT&T System V.
Therefore, the kernel interprets these parameters differently depending on
the binary type, and in order to preserve functionality and provide binary
support for both COFF and x.out executables. In addition to kernel services,
there are some differences between OMF and COFF libraries. This is not
necessarily a case of functional differences, but a difference between
structure layout (for example, size and alignment) and perhaps parameter
values.
These differences are transparent to the developer because the standard
header files (/usr/include/* and /usr/include/sys/*) have been merged and
provide code conditional to the binary format being produced. The Microsoft
compiler provides a manifest constant ("M_XOUT" or "M_COFF") to signal the
binary format being produced and these direct header files to provide the
correct code in cases where COFF and OMF/x.out libraries and/or kernel
services differ. In this way, structures, function parameter values, and
variable types are automatically compatible with library functions and system
calls particular to the binary type.
This creates a serious problem for binary format translations after any kind
of compilation. Objects and libraries built using one format may contain
binary values (for example, function parameters and structure offsets)
specific to that binary format. After conversion, however, these files
will be linked with incompatible libraries. In addition, at runtime, the
kernel will make functional decisions based on the final binary type, not
the original binary type that produced the code. A concrete example of this
problem again comes from file locking. The value for read lock requests is
different for COFF and OMF/x.out. An object that uses this value and is
compiled as COFF will contain the COFF specific value. This is then
translated to OMF and linked. At runtime, the kernel will interpret the
lock request from an "OMF/x.out perspective" and create the wrong lock type.
The following is a list of SCO UNIX System V/386 Development System Release
3.2 header files that contain #ifdef clauses using M_COFF and/or M_XOUT.
Any source code using these files, and/or the related system calls or library
routines, should definitely not be converted after compilation of any kind.
File Description
-------------------------------------------------------------
a.out.h - COFF vs. x.out binary formats
core.h - core file analysis
lockcmn.h - file lock requests for x.out binaries
mon.h - monitor(S) and profiling data, e.g. "mon.out"
tinfo.h - terminfo curses
curses.h - if this includes <tinfo.h>
sys/fcntl.h - fcntl(S) and lockf(S) file lock requests
sys/locking.h - locking(S) system call
sys/shm.h - shared memory segments (IPC)
sys/signal.h - signals: see SIGPOLL
sys/utsname.h - uname(S) system call
4. General Incompatibilities Between COFF and OMF/x.out
The two fundamental areas of incompatibility between COFF and x.out files,
regardless of binary code differences and conversion issues, are AT&T
shared libraries and file locking. Only COFF files have the capability of
utilizing shared libraries. Other than the fact that shared libraries are
COFF format files themselves, only COFF executables provide a well-defined
mechanism for requesting the use of one or more shared libraries at load time.
For conversions, any COFF executable that uses shared libraries will not
properly translate to an x.out executable. "cvtcoff" will explicitly warn
the user in this circumstance. It is doubtful that x.out binaries will ever
be augmented to share this capability.
These two binary formats also receive different kernel handling for file
locking. Under SCO XENIX Development System prior to Release 2.3, all
file locking was mandatory. AT&T System V, on the other hand, provided
only advisory locking. With SCO XENIX Development System Release 2.3,
when COFF runtime support was first incorporated into the SCO kernel, a
mechanism was created for selecting either type of locking for x.out
binaries ("ld -L" and fixhdr(C)). COFF binaries were given advisory locking,
by default, for compatibility reasons. If either binary uses locking(S), an
SCO XENIX specific lock system call, all locks are mandatory. Most
importantly, COFF binaries do not provide the mechanism for requesting
either type of lock at load time. This issue affects conversions, in that
code logic dependent on one type of file locking may not be appropriate under
the other type of locking. Conversions between COFF and OMF/x.out may
introduce this problem with unexpected results.
5. Recommendations
Because of the aforementioned conversion problems, the general recommendation
for developers is to select the desired binary format for objects, archives,
and executables before any source code compilation. In terms of one binary
format versus the other, the choice is up to the developer and may depend on a
number of factors such as: format of existing objects and libraries; use of
shared libraries; debugging services during development; executable size;
portability from or to other host or target environments. For developers
making libraries available as part of their products, it would be ideal to
provide both OMF and COFF objects/archives and allow the customer to determine
the type of binary they want to produce. In this case, it is definitely
recommended that each archive be produced by a separate compilation from
source code. Conversion of objects and libraries, using the conversion tools,
after compilation is not recommended. For code, using the specific services
listed above, conversion after compilation is out of the question.
6. Conversion Utilities - Usage
cvtomf [-g] [-o output] file [file . . .]
Translates OMF relocatable object files to COFF relocatable
object files.
By default, the OMF filename is used for the COFF file, for example, the
original OMF file is lost. "-o file" allows a user specified name for the
COFF file but may be used only when translating one OMF file.
"-g" will translate symbolic debug data from OMF to COFF format, if it is
present in the OMF file.
Note: Symbolic data will not translate properly if the OMF file contains
multiple modules. For example, if it is produced by incremental linkage
using "ld -r" (ldr).
cvtomf will translate multiple files if provided on the command line.
Note: cvtomf was designed to be used by the Microsoft C compiler driver.
It is possible to introduce serious binary incompatibilities in
the resulting COFF file that adversely affect runtime behavior.
cvtcoff [-gv] [-o output] file
Translates a COFF relocatable object file, library, or executable
to the corresponding OMF/x.out format file.
By default, the translated version will be named "x.out." Use "-o"
for a user-specified file name.
"-g" will translate COFF symbolic debug data to the corresponding
x.out format. Note that this option is only valid for executables,
for example, it is not valid for relocatable objects or archives.
Executables utilizing shared libraries will translate but will not
execute properly. cvtcoff issues a warning in the event that this
is attempted.
Note: cvtcoff was designed to be used by the Microsoft linker and
Codeview. It is possible to introduce serious binary incompatibilities
in the resulting OMF/x.out file that adversely affect runtime behavior.
7. AT&T Portable C Compiler
The solution to binary incompatibilities between COFF and OMF/x.out binaries
is largely solved by merged header files. The success of this is dependent
on a variety of manifest constants provided by the Microsoft compiler and used
during pre-processing. It is important to realize that the AT&T compiler
("rcc") does NOT automatically provide the same set of constants. Therefore,
the developer must manually provide these if any standard header files are
used by source modules compiled with "rcc." See "cc -d" to produce a list of
these constants.
8. Backwards Compatibility
In order to conveniently support SCO XENIX cross-development both for SCO
UNIX and SCO XENIX target environments, the 3.2 compiler provides command
line options for selecting different levels of backwards compatibility.
The prime issue is to use only those kernel services (system calls) provided
by the target operating system. The OMF libraries are partitioned so that
system call extensions added with SCO XENIX Development System Release 2.3
and SCO UNIX System V/386 Release 3.2 may be selectively linked or excluded.
It is important to note that COFF development does not provide the same
service. COFF binaries utilizing either 3.2 system calls (see
"/lib/386/Slib3.2.a") or "cxenix" system calls (see "/lib/libx.a") will not
run properly under SCO XENIX Development System Release 2.3. SCO XENIX
releases prior to 2.3 do not support the execution of COFF binaries at all.
|