1.6 Using a Linker Definition File

All of the LibC linkers support a linker definition file. On the command line or in the linker definition file, it is important to specify the functions that are used to start, stop, and check unload status. The libcpre.o file contains these functions. The linker definition file should contain the following commands (the syntax used is for the CodeWarrior .def file):

  START   _LibCPrelude
  EXIT    _LibCPostlude
  CHECK   _LibCCheckUnload
  

The check unload function is optional and is needed only for NLM applications that provide services for other NLM applications and therefore cannot be unloaded while a dependent NLM is still running.

NOTE:If you do not want to use the predefined functions for starting, stopping, or unload checking, you can write your own. Your versions should never be declared in the linker definition file, but always in the _LibC* functions. These _LibC* functions look for the customized functions and execute them. This allows your application to consume routines that customize the startup and exit operations while allowing LibC to handle all of the complex standard procedures for these operations. For the function prototypes, see _NonAppStart, _NonAppStop, and _NonAppCheckUnload in Volume 2.

To specify a linker definition file to the CodeWarrior command-line linker, use the following switch:

-commandfile mynlm.def

1.6.1 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.

Table 1-4 Compiler Syntax for the Linker 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 within 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} | @symbolListFile

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

INPUT

Supported on the command line

FILE obj_file{,obj_file}

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

LINKORDER

LINKORDER symbolList

Not supported

Not supported

MAP

Supported on 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. For LibC NLM applications, this should always be _LibCCheckUnload from the libcpre.o file.

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 time stamp for the NLM. The month must be a value between 1 and 12, the day between 1 and 31, and the four year digits between 1900 and 3000.

For GNU, the default value is today. GNU uses whitespace characters (space, tabs, or carriage returns) to separate the month, day, and year parameters. CodeWarrior uses whitespace characters 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 LibC NLM applications, this should be the _LibCPostlude 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 NLM applications. 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 a whitespace character. 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.

GNU expects the value to be a decimal value; CodeWarrior accepts hexadecimal values.

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.

GNU expects the value to be a decimal value; CodeWarrior and Open Watcom accept decimal or hexadecimal values.

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 NLM applications 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 a whitespace character. 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 a whitespace character. 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 that has a .msg extension.

MODULE

Specifies the NLM applications 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 a whitespace character. 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 number of 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 and 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 you press Alt, and displayed in the list of current screens when you press Alt+Esc.

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 OpenScreen 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 LibC NLM applications, this should always be _LibCPrelude 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 preemptive. You must use the mpkxdc tool to generate the XDC data file used by this command. For more information, see MPKXDC Tool.

1.6.2 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; others require that all parameters be ORed together in one FLAG command. 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. These parameters are defined in the netware.h file.

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 force 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. Special tools from the Novell security team are needed to sign the NLM. Signing ensures that an NLM cannot be replaced by another NLM.

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. When set, the NLM is forced to load in protected address space (ring 3). If the address space faults., the NLM is removed from memory and the address space is shut down and then restarted with the module.

0x00001000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x00002000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x00004000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x00008000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA

0x00010000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x00020000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x00040000

Reserved for internal use.

0x00080000

Reserved for internal use.

0x00100000

Reserved for internal use.

0x00200000

Reserved for internal use.

0x00400000

Specifies that the NLM is coded to use full POSIX semantics. This flag is available on NetWare 6.5 SP1 or later, NetWare 6.0 SP5 or later, and NetWare 5.1 SP6 or later. For more information, see Section 13.2, POSIX Path Semantics.

0x00800000

Specifies a UTF-8 string type. If set, all NKS, POSIX, and ANSI assume strings are in UTF-8 format.

0x01000000

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

0x02000000

Specifies a Unicode* string type. If set, all NKS function assume strings are in Unicode format. POSIX and ANSI functions do not accept Unicode strings.

If specified with 0x00400000 (want POSIX semantics), indicates that the user, who loads the NLM, should be prompted for a name and password and does not set the string type for the NKS functions.

0x04000000

Specifies whether the storage driver is a hotswap driver.

0x08000000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x10000000

Reserved for internal use. NLM applications should use XDC data. See XDCDATA.

0x20000000

Specifies whether the NLM can be unloaded. If set, the NLM is unloaded only when the server is brought down. This module cannot be unloaded from the console or by another NLM calling the UnloadModule function.

0x40000000

Specifies a debugging environment that enables strict memory management and allows the internal debugger (and any other registered debugger) to be informed about specific events such as module load or unload.

WARNING:This flag should only be set during development and should never be set for a production module.

0x80000000

Reserved for internal use. NLM applications should use XDC data.

1.6.3 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

1.6.4 MPKXDC Tool

The mpkxdc tool creates an XDC file referenced by the loader in a NetWare 5.x or 6.x server. As an NLM loads, the XDC file specifies four designations for an NLM and its exported API functions:

  • NLM is MP safe and can run on any processor.

  • Designated functions are MP safe, but all others must be funneled to P0.

  • NLM is generally MP unsafe and is limited directly to P0.

  • NLM is preemptive (meaning, all functions become potentially blocking).

To use mpkxdc:

  1. If some but not all exported API functions in an NLM are MP safe (can be run on any processor), create an apilist.api file that lists either the API functions that are MP safe or those that are not MP safe.

    This file contains a list of API functions, one per line without leading or trailing whitespace characters or trailing commas. Lines beginning with # are ignored as comments. Blank lines or lines with leading whitespace characters are also ignored.

  2. Prior to compiling, run mpkxdc.exe using the following syntax:

      mpkxdc [option] [apilist.api] filename.xdc 
      

    The following table explains available choices for option parameter.

    Option

    Explanation

    -n

    Generates XDC data, declaring an entire NLM to be MT safe. Threads created for an NLM thus marked can run on any available processor automatically. All routines and exported API functions are also considered MT safe. All new NLM applications should be written for this option.

    Usage: mpkxdc -n filename.xdc

    -f

    Generates XDC data, declaring only a specified set of API functions in an NLM to be MT unsafe. With this option, only API functions listed are funneled, and all other exported API functions are considered MT safe.

    Usage: mpkxdc -f apilist.api filename.xdc

    -u

    Generates XDC data, declaring the NLM to be MT unsafe, although it also has the effect of declaring that the NLM will deal with multithreading/multiprocessing issues itself. This option is solely for performance needs and is discouraged because it carries many risks. Although using this option and declaring some of the exported functions to be MT unsafe are not mutually exclusive, such a combination can have serious implications.

    Even though a given NLM has -u XDC data, a thread executing in that NLM can be outside the CNB. The thread might have entered the NLM through an exported MT safe API function or might have exited the CNB within that NLM. While outside the CNB, if such a thread were to call an MT unsafe function, results would be unpredictable—for performance reasons, the kernel attempts to short-circuit the funneling wrapper while resolving the imports of an NLM that has -u XDC data.

    In most cases, the -u flag is used to simply indicate that the NLM is legacy and does not contain any MT safe code. With very careful scrutiny, some NLM applications may be found to benefit from having some of their exports marked MT safe, if performance considerations demand and sufficient examination reveals that the above listed caveats have been carefully considered.

    This option is not compatible with -n or -p.

    Usage: mpkxdc -u filename.xdc

    -p

    Generates XDC data, declaring the NLM as being preemptive. This means that any thread executing in the code section of the NLM can be preempted (assuming the thread has not programmatically entered a critical section). This has to be used carefully—a nonblocking function in the NLM may become blocking because a thread executing it can be preempted.

    Usage: mpkxdc -p filename.xdc

    -h

    Displays the help screen for the mpkxdc tool. This option in not compatible with any other option.

    The filename.xdc file is your name for the file to which mpkxdc.exe outputs XDC data for reference by your NLM at load time.

  3. In the linker definition file, include the following line (the syntax is for the Watcom linker):

      OPTION XDCDATA=<filename.xdc>
      

If the mpkxdc tool is not included with your linker, it is available from Novell in the NLM and NetWare Libraries for C (including CLIB and XPLAT) SDK. Download the software, and you will find the mpkxdc tool in the ...\nwsdk\tools directory.