1.5 Using a Linker

Linkers are generally supplied with the compiler. CodeWarrior, Watcom, and GNU all supply linkers. Some linkers allow you to specify options and commands on the command line; some don't. All, however, support referencing a linker definition file, which contains the options and commands. Linker commands and options tell the linker how to create your program. For complete information, consult the documentation that comes with your linker.

1.5.1 Specifying a Linker Definition File

A linker definition file is useful when linker input consists of a large number of object files that you do not want to manually enter on the command line each time you link your program. Note that a linker definition file can also include other linker definition files.

The following is a sample linker definition file for the Watcom linker, WLINK:

  Format Novell NLM ’$(COMPOSITE_DESCRIPTION)’ 
  Name$(NLM_NAME).NLM 
  Option Copyright= ’$(COPYRIGHT_STRING)’ 
  Option NLMFlags= $(NLMFLAGS) 
  Option CaseExact 
  %if !%defined(OPTIMIZE) 
  Debug CodeView 
  Debug Novell 
  %endif 
  %foreach FILE in $(SOURCE_OBJECTS) 
  File$(OBJECT_DIR)\$(FILE) 
  %endfor 
  %if %defined(MORE_OBJECTS) 
  File$(MORE_OBJECTS) 
  %endif 
  %if %defined(PROFILE) 
  File WRuntime.Obj 
  %endif 
  Option Start= $(START_FUNC) 
  Option Exit= $(EXIT_FUNC) 
  Option Version= $(COMPOSITE_VERSION) 
  Option Map= $(NLM_NAME).Map 
  Option SymFile= $(NLM_NAME).Sym 
  Option NoDefaultLibs 
  Option Messages= $(MSG_PATH)\$(NLM_NAME).MSG 
  Import @CLIB.Imp 
  Export @$(NLM_NAME).Exp 
  Module $(MODULES)Format Novell NLM $(COMPOSITE_DESCRIPTION)  
  
  

For information about the prelude object file, see Section 2.9, NLM Startup.

The IMPORT directive shown in the example above enables your NLM to import (call) functions in other NLMs. When using the IMPORT directive, you have two choices for specifying the external functions you want to call:

  • List each function as an IMPORT entry in the linker definition file.

  • Place all the function names in an import file (.IMP) and specify that file as the IMPORT entry in the directive file (as shown with the example above).

For example, part of the NetWare API is CLIB.NLM. It runs in memory, and all the NLMs loaded on the same server can import its functions. To import a NetWare API function from CLIB.NLM, an NLM linker definition file can either list each function it wants to import or specify the CLIB.IMP file, which contains a list of functions exported by CLIB.NLM.

1.5.2 Linker Commands

The following table lists the NLM commands that can be placed in a linker definition file. Not all linkers support all of these commands. Some linkers support additional, linker-specific commands.

Linker Command

CodeWarrior Syntax

Open Watcom Syntax

GNU Syntax

AUTOUNLOAD

AUTOUNLOAD

OPTION AUTOUNLOAD

AUTOUNLOAD

CHECK

CHECK checkProcedure

OPTION CHECK=symbol_name

CHECK< procedure name>

CODESTART

Not supported

Not supported

CODESTART <map file code start offset (decimal or Xhex)>

COPYRIGHT

COPYRIGHT ["String"]

OPTION COPYRIGHT 'string'

COPYRIGHT ["String"]

CUSTOM

Not supported

OPTION CUSTOM=file_name

CUSTOM <custom data file path>

DATASTART

Not supported

Not supported

DATASTART <map file data start offset (decimal or Xhex)>

DATE

DATE month, day, 4-digit year

Not supported

DATE month day 4-digit year

DEBUG

DEBUG

DEBUG NOVELL

DEBUG

DESCRIPTION

DESCRIPTION "String"

FORMAT NOVELL 'description'

DESCRIPTION "String"

EXIT

EXIT exitProcedure

OPTION EXIT=symbol_name

EXIT <exit procedure name>

EXPORT

EXPORT symbolList | @symbolListFile

EXPORT entry_name {,entry_name} | @symbolListFile

EXPORT <symbol list> | @<symbol list file>

FLAG OFF

FLAG OFF value

Not supported

FLAG OFF <decimal value>

FLAG ON

FLAG ON value

Flags can be specified one at a time.

OPTION NLMFLAGS=value

All flags must be specified in one NLMFLAGS command.

FLAG ON <decimal value>

HELP

HELP filePath

OPTION HELP=help_file

HELP <help file path>

HIDESYM

Not supported

Not supported

HIDESYM <symbol list> | @<symbol list file>

IMPORT

IMPORT symbolList | @symbolListFile

IMPORT external_name {,external_name}

IMPORT <symbol list> | @<symbol list file>

INPUT

Supported only by the command line

FILE obj_file{,obj_file}

INPUT <obj list> | @<obj list file>

LINKORDER

LINKORDER symbolList

Not supported

Not supported

MAP

Supported only by the command line.

OPTION MAP[=map_file]

MAP [map file name]

MESSAGES

MESSAGES filePath

OPTION MESSAGES=msg_file

MESSAGES <file path>

MODULE

MODULE NLMList | @NLMList

MODULE module_name{, module_name}

MODULE <NLM list>

MULTIPLE

MULTIPLE

OPTION MULTILOAD

MULTIPLE

NAMLEN

Not supported

OPTION NAMELEN=value

NAMELEN value

OS_DOMAIN

OS_DOMAIN

OPTION OSDOMAIN

OS_DOMAIN

OUTPUT

Not supported

NAME exe_file

OUTPUT <target file path>

PATH

Not supported

PATH path_name{;path_name}

PATH [search path; . . .]

PSEUDOPREEMPTION

PSEUDOPREEMPTION

OPTION PSEUDOPREEMPTION

PSEUDOPREEMPTION

REENTRANT

REENTRANT

OPTION REENTRANT

REENTRANT

SCREENNAME

SCREENNAME "name"

OPTION SCREENNAME 'name'

SCREENNAME "name"

STACK

STACK stackSize

OPTION STACK=n

STACK <stack size>

STACKSIZE

STACKSIZE stackSize

Not supported

STACKSIZE <stack size>

STAMPEDDATA

Not supported

Not supported

STAMPEDDATA "Stamp" <data file path>

START

START startProcedure

OPTION START=symbol_name

START <procedure name>

SYNCHRONIZE

SYNCHRONIZE

OPTION SYNCHRONIZE

SYNCHRONIZE

THREADNAME

THREADNAME threadName

OPTION THREADNAME 'thread_name'

THREADNAME <name>

TYPE

TYPE typeNumer

FORMAT NOVELL [number]

TYPE <number>

VERBOSE

Not supported

OPTION VERBOSE]

Not supported

VERSION

VERSION majorVersion minorVersion [revision]

OPTION VERSION=major[.minor [.revision]]

VERSION <major version>, <minor version> [, <revision>]

XDCDATA

XDCDATA rpcFilePath

OPTION XDCDATA=rpc_file

XDCDATA <file path>

AUTOUNLOAD

Specifies that the NetWare operating system should unload the NLM when none of its entry points is in use.

CHECK

Specifies the name of a function in the NLM to be executed when the console operator attempts to unload the NLM using the UNLOAD console command.

CODESTART

Specifies an offset to be added to each code symbol offset in the map file. This directive allows a developer to create a map file that compares closely to the values displayed by the NetWare internal debugger.

COPYRIGHT

Provides the copyright string that is displayed on the console screen when the NLM is loaded. If this option is not used, no copyright information is displayed.

The string must be enclosed in double quotation marks (") for CodeWarrior and GNU, but in single quotation marks (') for Open Watcom.

CUSTOM

Allows you to specify the path to a custom data file for use in the NLM. The size and offset of this file are recorded in the NLM header.

DATASTART

Specifies an offset to be added to the data offset in the map file. This directive allows a developer to create a map file that compares closely to the values displayed by the NetWare internal debugger.

DATE

Provides a timestamp for the NLM. The month must be a value between 1 and 12, the day between 1 and 31, and the year 4-digits between 1900 and 3000.

For GNU, the default value is today. GNU uses whitespace (space, tabs, or carriage returns) to separate the month, day, and year parameters. CodeWarrior uses whitespace or commas to separate the parameters.

DEBUG

Instructs the linker to generate debugging information in the executable file. DEBUG affects only files listed in the linker file after this directive.

The NetWare internal debugger uses this debug information. Other debuggers, such as the CodeWarrior debugger, do not use this information.

The Open Watcom linker allows you do specify two options:

     db_option ::= ONLYEXPORTS | REFERENCED
  

DESCRIPTION

Provides the description that is displayed on the console screen when the NLM is loaded. The string must be enclosed in double quotation marks (") for CodeWarrior and GNU. For Open Watcom, the string is enclosed in single quotation marks (').

The description can be no longer than 127 characters.

EXIT

Specifies the name of a symbol in the NLM where execution should stop. This procedure makes sure that all resources have been released and all threads have terminated before the NLM unloads. For CLIB NLMs, this should be the _Stop routine from the libcpre.o file.

EXPORT

Specifies a list of symbolic names for all variables and functions the NLM is making available to other NLMs. CodeWarrior and GNU allow the EXPORT directive to be followed by either a list of symbols or the name of a file. Open Watcom accepts only a list of symbols.

  • When followed by a list for CodeWarrior and GNU, each symbol must be separated by a comma or a whitespace character (tab, space, or carriage return). Each symbol that appears on a new line must be indented by whitespace. Open Watcom expects symbols to be separated by commas.

  • When followed by the name of a file, the filename must be preceded by the at (@) character. The file uses the same format as a symbol list.

FLAG OFF

Specifies how the NLM is loaded by clearing the specified bits in the NLM header. For a list of arguments, see FLAG ON and FLAG OFF Parameters.

FLAG ON

Specifies how the NLM is loaded by setting the specified bits in the NLM header. For a list of arguments, see FLAG ON and FLAG OFF Parameters.

HELP

Specifies the path to an internationalized help file that contains the default help screens for the NLM. The path must end with filename with a .HLP extension.

HIDESYM

Specifies a list of symbols to hide.

IMPORT

Specifies a list of symbolic names for variables and functions that other NLMs have defined and your NLM uses. The IMPORT command can be followed by either a list of symbols or the name of a file. CodeWarrior and GNU allow the IMPORT command to be followed by either a list of symbols or the name of a file. Open Watcom accepts only a list of symbols.

  • When followed by a list, each symbol must be separated by a comma or a whitespace character (tab, space, or carriage return). Each symbol that appears on a new line must be indented by whitespace. Open Watcom expects symbols to be separated by commas.

  • When followed by the name of a file, the filename must be preceded by the at (@) character. The file uses the same format as a symbol list.

INPUT

Specifies the object files that are to be linked. If no file extension is specified, a file extension of either .obj is assumed or the default for the environment. The INPUT command can be followed by either a list of symbols (supported by GNU and Open Watcom) or the name of a file (supported by GNU).

  • When followed by a list, each object file must be separated by a comma or a whitespace character (tab, space, or carriage return). Each file that appears on a new line must be indented by whitespace. Open Watcom expects file to be separated by commas.

  • When followed by the name of a file, the filename must be preceded by the at (@) character. The file uses the same format as a object file list.

LINKORDER

Specifies the functions and variables that the linker should link first. You do not need to list all the symbols in your program. Each symbol must be separated by a comma or whitespace character (tab, space, or carriage return).

MAP

Indicates that the linker should create a map file with the specified name. If no filename is specified, the name defaults to the name of the executable and a .map extension.

MESSAGES

Specifies the file path to an internationalized message file that contains the default messages for the NLM. The path must end with a filename with a .MSG extension.

MODULE

Specifies the NLMs that must be loaded before this NLM is loaded. These modules are loaded automatically when this NLM is loaded. An NLM that exports symbols that another NLM requires must be loaded before the dependent NLM is loaded.

Each NLM in the list must be separated by a comma or whitespace character (tab, space, or carriage return). Each NLM name that appears on a new line must be indented by whitespace. Open Watcom supports only a comma as a separator.

CodeWarrior also supports listing the modules in a file. When filename follows the MODULE command, the filename must be preceded by the at (@) character. The file uses the same format as a module list

MULTIPLE

Sets a flag in the NLM header indicating that this NLM can be loaded multiple times. If this flag is not set, the NLM cannot be loaded more than once.

NAMLEN

Specifies the maximum characters required to uniquely identify a symbol name. If any symbol fails to meet this condition, the symbol is treated as if it had been defined more than once.

GNU Note: Default is 31. Zero is no limit.

OS_DOMAIN

Sets a flag in the NLM header indicating that this NLM must be loaded in the memory space of the operating system. This prevent the NLM from being loaded into a protected address space.

OUTPUT

Provides the name of the output file for the linker. If no extension is specified, the linker creates an extension according to the NLM type that is specified with the TYPE command.

PATH

Specifies a search path for files used with the directives that take a path and a filename, such as CUSTOM, EXPORT, HELP, IMPORT, INPUT, MESSAGES, and XDCDATA. The parameter is a string that can be prepended to a filename to create a complete DOS path to the file. Therefore, the sting must end with a backslash (\). The current directory is not searched unless specified. The directories are searched in the order listed. For example:

     PATH .\;..\obj\;
  or
     PATH ; ..\obj\;
  

Both of these commands search the current directory and the obj directory which is one level up.

PSEUDOPREEMPTION

Sets a flag in the NLM header indicating that the NetWare operating system can forced the NLM to relinquish control if it does not do so on its own often enough.

The amount of time that is allowed to pass before the NLM is forced to relinquish control is set by the console command Set Pseudo Preemption Count. When the time limit is exceeded, the NLM is forced to relinquish control on the next file read or write system call.

REENTRANT

Sets a flag in the flags field of the NLM header indicating that this NLM is reentrant. If an NLM is reentrant, when it is loaded by the LOAD command more than once, the NLM is not loaded again, but the NLM can now be executed concurrently by multiple threads. In this case, only one copy of the NLM is in memory.

SCREENNAME

Specifies the name of the first screen of an NLM, which is created when the NLM is loaded and to which stdin, stdout, and stderr are wired. The screen name is displayed at the top of the console when Alt is pressed, and displayed in the list of current screens when Alt+Esc is pressed.

The screen name must be 71 characters or less.

If this directive is not used, or if NONE is specified, there is no initial screen. In this case, the developer must call CreateScreen to create a screen for the NLM. However, stdin, stdout, and stderr are not wired to this screen.

STACK

Specifies the stack size for the NLM in bytes. The minimum stack size is 2 KB. Over 32 KB is recommended. If no size is specified, the default is 16 KB.

NOTE:Many of the communications libraries require that the NLM threads stack size be increased beyond the 16 KB default to 32 KB or more. Consider increasing stack size if you encounter stack overflow abends.

This command is equivalent to the STACKSIZE command.

STACKSIZE

Specifies the stack size for the NLM in bytes. The minimum stack size is 2 KB. Over 32 KB is recommended. If no size is specified, the default is 16 KB.

NOTE:Many of the communications libraries require that the NLM threads stack size be increased beyond the 16 KB default to 32 KB or more. Consider increasing stack size if you encounter stack overflow abends.

This command is equivalent to the STACK command.

STAMPEDDATA

Causes the linker to create a custom data structure, which is named by the stamp parameter and filled by the data file.

START

Specifies the name of a symbol in the NLM where execution should start. This procedure tracks the state of the NLM and helps with the final cleanup function. For CLIB NLMs, this should always be _Prelude from the libcpre.o file.

SYNCHRONIZE

Sets a flag in the flags field of the NLM header indicating that when this NLM is loaded, the load process goes to sleep until the NLM calls SynchronizeStart. This prevents other console commands (particularly LOAD) from being processed while the NLM is loading.

THREADNAME

Specifies a prefix for NetWare to use to name the threads of the NLM. For example, if the prefix was Process, then threads created in the NLM would be named “Process1,” “Process2,” “Process3,” and so on. Thread names can be displayed in the CodeWarrior debugger and by using the .P option in the NetWare internal debugger.

The thread prefix should be 12 characters or less.

TYPE

Specifies the kind of service the NLM provides. For a list of supported values, see NLM Types.

VERBOSE

Causes the linker to produce additional information while linking.

VERSION

Specifies the version of the NLM. The version information is displayed on the console screen when the NLM loads. The major version and minor version numbers are required; the revision is optional.

The major version can be any number. The minor version can be 0 - 99. The revision can be 0 - 26, representing a - z. If the revision is greater than 26, it is set to 0.

XDCDATA

Specifies a path to a file containing Remote Procedure Call (RPC) descriptions for functions in the NLM. XDC data can be used to create an MT-safe NLM, funnel functions to processor 0, declare an NLM as MT unsafe, and mark an NLM as preemptible. You must use the mpkxdc tool to generate the XDC data file used by this command. For more information, see Section 6.4, Using MPKXDC.

FLAG ON and FLAG OFF Parameters

The following parameters can be ORed together. Some linkers allow the linker definition file to have multiple FLAG commands. Some of the FLAG parameters are the same as commands, for example: FLAG ON 0x00000001 is equivalent to REENTRANT. If you have duplicate or conflicting commands in the definition file, the last command entered is used to configure the NLM.

Value

Description

0x00000001

Specifies whether an NLM is reentrant. If this flag is set, more than one thread can execute the code of an NLM at the same time. It is equivalent to the REENTRANT linker command.

0x00000002

Specifies whether the NLM can be loaded multiple times. If set, more than one copy of the NLM can be loaded. It is equivalent to the MULTIPLE linker command.

0x00000004

Specifies whether the console command processor sleeps while this NLM loads. If this flag is set, the load process sleeps until the NLM calls the SynchronizeStart function. Besides the load console command, any other console commands are not processed while this NLM loads.

This flag is equivalent to the SYNCHRONIZE linker command.

0x00000008

Sets a flag in the NLM header indicating whether the NetWare operating system can forced the NLM to relinquish control if it does not do so on its own often enough. If set, the OS can force the NLM to relinquish control. If not set, the NLM must relinquish control or cause a CPU Hog abend.

This flag is equivalent to the PSEUDOPREEMPTION linker command.

0x00000010

Specifies whether the NLM is forced to load into the memory space of the operating system (ring 0). If set, the NLM cannot be loaded into protected address space.

This flag is equivalent to the OS_DOMAIN linker command.

0x00000020

Specifies whether the NLM can share code. If set, the NLM cannot share code with any other NLM.

0x00000040

Specifies whether the NLM is automatically unloaded when none of its entry points are in use.

This flag is equivalent to the AUTOUNLOAD linker command.

0x00000080

Specifies whether the NLM is hidden. If set, the NLM does not appear in module lists, such as those generated with the MODULES console command????

0x00000100

Specifies whether the NLM is digitally signed.

0x00000200

Specifies whether the NLM is forced to load into protected address space. If set, the NLM cannot be loaded into the memory space of the operating system (ring 0). It will only load in protected address space (ring 3), and no other command line parameters are needed to make it load protected.

0x00000400

Specifies whether the NLM is a shared library.

0x00000800

Specifies whether the NLM is can be restarted.

0x01000000

Specifies whether main can end and the NLM still stay resident in memory.

NLM Types

The following values can be used with the TYPE linker command to specify the type of service the NLM provides. Use one of the following for the number argument:

Value

Description

0

Generic module (the default and the most common designation)

1

LAN driver

2

Disk driver

3

Name space module

4

NLM utility application

5

Mirror server link module

6

OS module

7

Paged high OS module

8

Host adapter module

9

Custom device module

10

File system module

11

Real mode module

12

Ghost module

13

Normal SMP module

14

NIOS module

15

CIOS CAD module

16

CIOS CLS module

20 - 32

NICI (Novell International Cryptographic Infrastructure) modules