When linking object files to create a VxD, it is typical practice to provide a module definition file. This is a text file that was introduced to Microsofts linkers long ago as a means to direct the building of segmented executables for OS/2 and Windows. Microsofts COFF linker, as supplied with such packages as Microsoft Visual C++ versions 4.0 and higher, and intended primarily for Win32 programming, supports a rich set of command-line options. In general, a command-line equivalent exists for every statement that is valid in a module definition file. This works well enough that module definition files are typically not needed for application-level programming.
Module definition files can be eliminated from most VxD projects also. There is a difficulty however, in that Microsofts LINK documentation largely ignores the special cases that apply when the linker is directed to build a VxD. Some module-definition statements are special to building VxDs and many more have special interpretations when a VxD is being built. These are typically not documented. The mapping of these statements to command-line options often involves undocumented features of those command-line options.
The documentation presented here aims to improve on Microsofts, especially for VxD programmers. Some general notes, below, apply to the handling of module definition files whatever type of executable is built. For particular module-definition statements however, the descriptions may sometimes confine themselves just to the case of building VxDs. To build a VxD, the linker must be given the /vxd switch on the command line.
All information presented here is based on analysis of the LINK.EXE from Microsoft Visual C++ version 4.0, unless otherwise stated. (No plans exist to update the analysis for later versions.)
A module definition file is treated as lines of single-character text up to but not including the first occurrence of the end-of-file character (1Ah). For the purpose of reading lines from the file, a line is understood as the sequence of not more than the next 4095 characters up to and including the next line-feed character or the last byte of the file.
The presence of a null byte or a DEL character (7Fh) complicates parsing from the very start. It is not usual to have these characters in a text file. Strange outcomes that may follow the presence of these characters in a module definition file are therefore of negligible consequence in practice, and it is assumed henceforth that the module definition file does not contain any of these characters.
On any given line, a terminating line-feed and as many as two carriage-returns imediately before it are ignored. In all that follows, a line is understood as ending immediately before such terminations.
On any given line, all leading white space is ignored. In all that follows, a line is understood as beginning only after leading white space has been ignored. White space is understood in the sense of the isspace macro in the standard C library: namely, spaces, tabs, carriage-returns and line-feeds, but also vertical tabs and form feeds.
On any given line, all characters from the first semicolon onwards are ignored, except in a few cases that are surely unintended. In all that follows, a line is understood as ending immediately before its first semicolon (if present). The semicolon thus serves to introduce comments. A line that consists just of a comment after white space is effectively empty.
The module definition file is interpreted as a set of statements. Each is introduced by a recognised statement tag, typically but not necessarily at the beginning of a line. Some statements may spread over lines, so that not all non-empty lines begin statements.
A non-empty statement consists of the statement tag, necessarily followed by a space or tab, and then by one or more definitions. A single-line statement supports just the one definition, which then comprises the statements arguments. For a multi-line statement, each definition except for the first is required to begin on a new line. In general, a multi-line statement ends where a new definition would be permitted but a recognised statement tag (to begin the next statement) is found instead.
Where a new statement is expected or permitted, the linker considers the text extending to the next space or tab. This token is then matched against the following recognised statement tags:
APPLOADER, CLIENTDATA, CODE, DATA, DESCRIPTION, EXETYPE, EXPORTS, FLAGS, FUNCTIONS, HEAPSIZE, IMPORTS, INCLUDE, LIBRARY, LOADHEAP, NAME, OBJECTS, OLD, PROTMODE, REALMODE, SECTIONS, SEGMENTS, STACKSIZE, STUB, VERSION, VXD
Matching is case sensitive.
These recognised keywords do not necessarily introduce supported statements. They serve merely for recognition of a new statements beginning or of the current statements end. If there is no recognised statement tag where a new statement is expected to begin, the linker raises the warning LNK4017, ignores the remainder of that line and looks for a new statement at the beginning of the next line.
The following statements are recognised but not supported:
APPLOADER, CLIENTDATA, FLAGS, LOADHEAP, OLD, REALMODE
The STUB statement joins this list when not building a VxD.
On encountering any of these where a new statement is expected or permitted, the linker raises the warning LNK4017, ignores the remainder of the current line and looks for a new statement at the beginning of the next line.
The following statements are recognised but ignored:
CODE, DATA, FUNCTIONS, INCLUDE, PROTMODE
On encountering any of these where a new statement is expected or permitted, the linker ignores the remainder of the current line and looks for a new statement at the beginning of the next line.
Module definition files are processed by having the linker re-run itself as the Library Manager to generate an export file in which command-line options equivalent to the statements of the module definition file are supplied as a directive. A fatal error generated during the processing of the module definition file therefore produces not just a message to describe the error in the module definition file but also the message
LINK : fatal error LNK1141: failure during build of exports file
When the linker prepares to re-run itself, it builds a new command line. Not all options on the original command line carry to the new command line. Among those that do not is the undocumented /ignore option. Warning numbers specified in a /ignore option are therefore not ignored while interpreting a module definition file.
This page was created on 8th May 1999. The last significant modification was on 12th May 1999.
Copyright © 1999. Geoff Chappell. All rights reserved.
[Home][Programming Samples][Application Notes][Security Notes][Editorial][Consultation][Contacts]