Module Definition Files for VxDs

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 Microsoft’s linkers long ago as a means to direct the building of segmented executables for OS/2 and Windows. Microsoft’s 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 Microsoft’s 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 Microsoft’s, 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.)

General Interpretation

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.

Leading White Space

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.

Comments

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.

Statements

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 statement’s 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.

Recognised Statements

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 statement’s beginning or of the current statement’s 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.

Unsupported Statements

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.

Ignored Statements

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.

Warnings and Errors

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]