DLL Guide
DLL Guide
DLL Guide
Abstract
This guide describes how application programmers can use the DLL facilities provided
on TNS/E systems and recommends good practices in using them.
Product Version
T9050 at H06.01
Supported Release Version Updates (RVUs)
This publication supports J06.03 and subsequent J-series RVUs and H06.03 and
subsequent H-series RVUs, until otherwise indicated by its replacement publications.
Legal Notices
What’s New in This Manual vii
Manual Information vii
New and Changed Information vii
About This Manual ix
Purpose of This Manual ix
Who Should Read This Manual ix
How This Manual Is Organized ix
Related Reading ix
Notation Conventions x
HP Encourages Your Comments xiv
Hewlett-Packard Company—527252-006
i
Contents 2. Essential DLL Facility Controls
6. Example Code
Example One 6-2
Example Two 6-7
Tables
Table 4-1. Import Control Summary 4-12
Table A-1. Set Attributes A-7
Abstract
This guide describes how application programmers can use the DLL facilities provided
on TNS/E systems and recommends good practices in using them.
Product Version
T9050 at H06.01
Supported Release Version Updates (RVUs)
This publication supports J06.03 and subsequent J-series RVUs and H06.03 and
subsequent H-series RVUs, until otherwise indicated by its replacement publications.
Document History
Part Number Product Version Published
527252-002 T9050 February 2005
527252-003 T9050 May 2005
527252-004 T9050 July 2005
527252-005 T9050 August 2010
527252-006 T9050 April 2012
Related Reading
The following manuals (use H06.03 or later versions) form the set that you may need
to create and use DLLs:
eld Manual.
This contains details on options for the eld linker.
rld Manual.
This contains details on dynamic loading facilities.
eNOFT Manual.
This contains information on examining PIC object files on H-series systems.
TACL Reference Manual.
This contains information on loadfiles in processes and processes using
loadfiles.
Guardian Procedure Calls Reference Manual.
Guardian Procedure Errors and Messages Manual.
You will also be using a programming language, so choose from the following:
COBOL85 For Non-Stop Systems
C and C++ Programmer’s Guide
Guardian TNS/R Native C Library Calls Reference Manual
If you are using the OSS programming environment, you may need the following
manuals:
OSS Library Calls Reference Manual
OSS Shell and Utilities Manual
Notation Conventions
Hypertext Links
Blue underline is used to indicate a hypertext link within text. By clicking a passage of
text with a blue underline, you are taken to the location described. For example:
This requirement is described under Backup DAM Volumes and Physical Disk
Drives on page 3-2.
UPPERCASE LETTERS. Uppercase letters indicate keywords and reserved words. Type
these items exactly as shown. Items not enclosed in brackets are required. For
example:
MAXATTACH
lowercase italic letters. Lowercase italic letters indicate variable items that you supply.
Items not enclosed in brackets are required. For example:
file-name
computer type. Computer type letters within text indicate C and Open System Services
(OSS) keywords and reserved words. Type these items exactly as shown. Items not
enclosed in brackets are required. For example:
myfile.c
italic computer type. Italic computer type letters within text indicate C and Open
System Services (OSS) variable items that you supply. Items not enclosed in brackets
are required. For example:
pathname
{ } Braces. A group of items enclosed in braces is a list from which you are required to
choose one item. The items in the list can be arranged either vertically, with aligned
braces on each side of the list, or horizontally, enclosed in a pair of braces and
separated by vertical lines. For example:
LISTOPENS PROCESS { $appl-mgr-name }
{ $process-name }
ALLOWSU { ON | OFF }
| Vertical Line. A vertical line separates alternatives in a horizontal list that is enclosed in
brackets or braces. For example:
INSPECT { OFF | ON | SAVEABEND }
… Ellipsis. An ellipsis immediately following a pair of brackets or braces indicates that you
can repeat the enclosed sequence of syntax items any number of times. For example:
M address [ , new-value ]…
[ - ] {0|1|2|3|4|5|6|7|8|9}…
An ellipsis immediately following a single syntax item indicates that you can repeat that
syntax item any number of times. For example:
"s-char…"
Item Spacing. Spaces shown between items are required unless one of the items is a
punctuation symbol such as a parenthesis or a comma. For example:
CALL STEPMOM ( process-id ) ;
If there is no space between two items, spaces are not permitted. In this example, no
spaces are permitted between the period and any other items:
$process-name.#su-name
Line Spacing. If the syntax of a command is too long to fit on a single line, each
continuation line is indented three spaces and is separated from the preceding line by
a blank line. This spacing distinguishes items in a continuation line from items in a
vertical list of selections. For example:
ALTER [ / OUT file-spec / ] LINE
[ , attribute-spec ]…
!i and !o. In procedure calls, the !i notation follows an input parameter (one that passes data
to the called procedure); the !o notation follows an output parameter (one that returns
data to the calling program). For example:
CALL CHECKRESIZESEGMENT ( segment-id !i
, error ) ; !o
!i,o. In procedure calls, the !i,o notation follows an input/output parameter (one that both
passes data to the called procedure and returns data to the calling program). For
example:
error := COMPRESSEDIT ( filenum ) ; !i,o
!i:i. In procedure calls, in TAL or PTAL, the !i:i notation follows an input string parameter
that has a corresponding parameter specifying the length of the string in bytes. For
example:
error := FILENAME_COMPARE_ ( filename1:length !i:i
, filename2:length ) ; !i:i
Note that some interfaces count the pair as a single parameter for error-reporting
purposes, even though they constitute two separate parameters, and must be so
expressed in C or C++.
!o:i. In procedure calls, in TAL or PTAL, the !o:i notation follows an output buffer parameter
that has a corresponding input parameter specifying the maximum length of the output
buffer in bytes. For example:
error := FILE_GETINFO_ ( filenum !i
, [ filename:maxlen ] ) ; !o:i
Note that some interfaces count the pair as a single parameter for error-reporting
purposes, even though they constitute two separate parameters, and must be so
expressed in C or C++.
Bold Text. Bold text in an example indicates user input typed at the terminal. For example:
ENTER RUN CODE
?123
CODE RECEIVED: 123.00
The user must press the Return key after typing the input.
Nonitalic text. Nonitalic letters, numbers, and punctuation indicate text that is displayed or
returned exactly as shown. For example:
Backup Up.
lowercase italic letters. Lowercase italic letters indicate variable items whose values are
displayed or returned. For example:
p-register
process-name
[ ] Brackets. Brackets enclose items that are sometimes, but not always, displayed. For
example:
Event number = number [ Subject = first-subject-value ]
A group of items enclosed in brackets is a list of all possible items that can be
displayed, of which one or none might actually be displayed. The items in the list can
be arranged either vertically, with aligned brackets on each side of the list, or
horizontally, enclosed in a pair of brackets and separated by vertical lines. For
example:
proc-name trapped [ in SQL | in SQL file system ]
{ } Braces. A group of items enclosed in braces is a list of all possible items that can be
displayed, of which one is actually displayed. The items in the list can be arranged
either vertically, with aligned braces on each side of the list, or horizontally, enclosed in
a pair of braces and separated by vertical lines. For example:
obj-type obj-name state changed to state, caused by
{ Object | Operator | Service }
process-name State changed from old-objstate to objstate
{ Operator Request. }
{ Unknown. }
| Vertical Line. A vertical line separates alternatives in a horizontal list that is enclosed in
brackets or braces. For example:
Transfer status: { OK | Failed }
% Percent Sign. A percent sign precedes a number that is not in decimal notation. The
% notation precedes an octal number. The %B notation precedes a binary number.
The %H notation precedes a hexadecimal number. For example:
%005400
%B101111
%H2F
P=%p-register E=%e-register
A loadfile exports a symbol when it defines a symbol that can be used by another
loadfile. A loadfile imports a needed symbol when that symbol reference in the
program or DLL is or will be set to the value (address) of a symbol of the same name
exported by another loadfile. Thus, in Figure 1-1, Library K exports Joe and, after H is
loaded, H imports Joe.
In the rest of this document, the term library means a DLL that may be designed for
either public or private use.
Lib J
5000
H Lib K
1300
Call Joe()
Joe()
3000
Lib L
4000
H
Call 16300
15000
Lib K
Joe()
18000
Lib L
What is a DLL?
A DLL is a type of library that is constructed of PIC. When using DLLs on TNS/E, a
complete, executable application comprises one (main) program and zero or more
DLLs. The program is the root of the application, while the DLLs provide functions and
data needed by the program or other DLLs. DLLs allow you to structure your
applications in functional units (the DLLs). A DLL might be a library that supports a
single program, it might be available to a project or a group with common
computational needs, or it might be a library that is available to all users.
Figure 1-2 on page 1-4, shows an application comprising a program and the DLLs that
it requires in order to run. Some of these (A, B, and C) offer symbol definitions that the
program itself may need; others offer symbol definitions that the various libraries, but
not the program, may need.
A, B, and C might be libraries that, along with Program, constitute the basic logic of the
application. D and E might be libraries of supporting routines for A. F and G might be
more general purpose libraries.
A DLL is written as an ordinary program with no main procedure and is designated a
DLL in the course of construction.
A DLL can be a 32-bit, 64-bit, or neutral loadfile on a TNS/E OSS platform and 32-bit
loadfile on all other platforms. 64-bit and neutral DLLs are supported from
H06.24/J06.13 RVU onwards.
Program
DLL D DLL E
DLL F
DLL G
VST012.vsd
A new version of a DLL can be introduced without having to alter a program or DLL
that references it, even though the location of the referenced sites has changed.
This gives you great freedom to change a DLL.
A program and the DLLs loaded with it at process creation time can access each
other’s functions and data by simply referencing their symbolic names.
A running application can cause a DLL to be loaded dynamically and to make its
functions and data accessible.
Source
Compiler
Linker
Loader
Compilers
The TNS/E compilers translate source input into a linkfile. In addition to object code
and data, TNS/E compilers generate the following auxiliary information as part of their
linkfile output that is used by the linker:
A symbol table, which identifies all the symbols that this linkfile either makes
available to other code files or needs from other code files.
A relocation table, which points to all the places in the compiled code and data that
must be relocated by the linker. Each entry that refers to an external symbol
contains a pointer to the corresponding entry in the external symbol table.
Linker
The TNS/E PIC linker is named eld; it combines one or more PIC linkfiles to create a
PIC loadfile. In doing this, the linker manipulates both code and data, then places all of
the loadfile’s adjustable references in tables outside the code to make them available
to the loader. This process, called linking or executing a link, must be applied to
linkfiles after they have been compiled and before they can be loaded for execution.
You invoke the linker by a single command, eld, and control it by items you enter in its
command stream, which comprises the options, file names, and parameters that
modify the eld command.
Later, the loader brings together programs with their required libraries in structures like
that shown in Figure 1-2 on page 1-4. To enable the linker to find the required libraries
when it links a loadfile, the loadfile’s programmer must enter in the command stream
the names of libraries that can provide symbols that this loadfile needs. From these
names, the linker creates in the loadfile a libList, which lists the names and certain
attributes of each of these libraries. A library that is listed in a loadfile’s libList is said to
be directly referenced by that loadfile.
In simple compile-and-link operations, the compiler runs the linker automatically. When
it does this, the compiler tells the linker the names of certain standard libraries. If those
are the only libraries required, you need do nothing more. But if you require other
libraries, you can command the compiler to pass them to the linker, or, you can run the
linker yourself. In the latter case you must provide to the linker with the required library
names, including the ones the compiler would have automatically done for you.
The linker can run on a TNS/E machine in either the Guardian or OSS environment.
It can also run on Win32 support machines, usually in an ETK environment. In this
document, these support machines are called auxiliary systems. The object file
produced can only be run on TNS/E systems.
Loading
Once a program and its DLLs have been processed by the PIC linker, they can be
loaded for execution by a special library program (the run-time linker rld) that works
with the operating system. This combined facility of rld and the operating system that
loads programs and libraries into virtual memory for execution is called, in this
document, the loader.
FastLoad
Required libraries are not statically linked with the program. Instead, at load time, the
program and its DLLs are brought into virtual memory, and the loader resolves
references among them. The loader does not alter the stored file image of the loadfile;
rather, it changes only the loaded memory image of the loadfile’s tables and other
initialized data. So this load-time adjustment might be repeated every time a program
and its DLLs are loaded, although the FastLoad facility loads a preset loadfile without
having to rebind it.
Automatic Update
If rld has to rebind a loadfile and the loadfile import control is localized, it will update
the preset bindings in the loadfile with the cooperation of the NonStop operating
system. This is called automatic update. rld and the operating system only
automatically update loadfiles at process creation time. If a loadfile is loaded via a call
to dlopen(), the loadfile is not automatically updated.
Figure 1-4. Loadfiles and Their libLists (To Create the Structure in Figure 1-2)
DLL A DLL D
Lib D Lib G
Code Lib E
and Program
Data
Lib G
Lib A
libList Lib B DLL B DLL E
Lib C
Lib F Lib G
Lib F
DLL C
Lib F
VST014.vsd
DSM/SCM creates an initial registry file, listing all the public DLLs by name. This is an
edit file (filecode 101). Use DSM/SCM to add your public DLLs to those provided by
HP.
Entries to the file consist of a series of statements. The dll statement describes a public
DLL. In its simplest form, it is just a name, for example:
dll file ztestdll;
Here is another example; it contains the license attribute. A licensed DLL is one that
contains privileged code. Unless you use this attribute along with the value “1”, the
default is “0”, which means the DLL is unlicensed.
dll license 1, file privdll;
There are other attributes which are created automatically, for example the timestamps
that you and the tools can use for version control. Here are two examples, the
link_timestamp (from when the linker first created the DLL), and the update_timestamp
(from when the linker last updated the DLL, or when another tool rebases or presets it):
dll file zredll,
link_timestamp 2004-08-01 16:34:41.213592,
update_timestamp 2004-08-01 17:15:17.119634;
From these examples you can see that attributes can be in any order, attributes are
separated by commas, and statements are terminated by semicolons.
Import Controls
Import controls allow you to determine from which other loadfiles your loadfile can
import symbols. These controls take the form of attributes that you assign to your
loadfile. This topic is discussed in detail in Import Controls and SearchLists on
page 4-5. The three variants of import controls are:
Localized — A localized loadfile can import symbols from certain libraries in this
loadfile’s loadList. The choice of libraries is discussed in detail in The SearchList
for a Localized Loadfile on page 4-5.
Globalized — A globalized loadfile can import symbols from the program it is
loaded with and any loadfile in the program’s loadList.
Semi-globalized — A semi-globalized loadfile uses its own definition for any of its
symbol references when it offers such a definition, but imports other definitions
from the program it is loaded with and any loadfile in the program’s loadList.
In any case, if the symbol to be imported is defined only once in the collection of
loadfile candidates to supply imported symbols, that symbol is used to resolve your
loadfile’s need. Good practice normally avoids multiple definitions of the same symbol
in the loadfiles in a loadList, because of the danger that an imported symbol could be
resolved in an unexpected way. However, the library facility allows multiple definitions,
and symbol resolution in such cases is discussed in Import Controls and SearchLists
on page 4-5.
Localized symbol resolution is consistent with long standing conventions on NonStop
systems including TNS programs and user libraries, as well as native non-PIC
programs and SRLs in TNS/R. The linker’s default is to localize loadfiles. On the other
hand, globalized symbol resolution is an industry (UNIX) standard. One useful
consequence of globalized symbol resolution is that DLLs can import symbols from
their clients, including the program. Globalized symbol resolution can be especially
useful when multiple loadfiles define and use the same symbol and you want to ensure
that they all use the same one. If you declare all these loadfiles to be globalized, then
the loader will resolve all these imports to the same exported symbol. However, object
files using globalized or semi-globalized import are likely to take somewhat longer to
load, because the linker is unable to preset bindings for files not seen at link time.
An important advantage of dynamically loaded DLLs is that their names and their
symbols need not be known when the program is constructed. Using this facility, you
can add to an existing application a new DLL that provides new functionality without
even restarting the application.
You do not need to load infrequently used DLLs when the application is loaded.
Instead, you can load and use these DLLs when required and unload them when they
are no longer needed. They can be reloaded whenever necessary.
User Library
A program, but not a DLL, can be linked to one user library, which is a DLL having a
special relationship to the program. Instead of adding the user library’s name to the
program’s libList, the user-library name is recorded in the program loadfile as an
attribute called libname. However the linker and loader treat this DLL as if it were first
in the program’s libList, and a program’s loadList always begins with the user library if
there is one.
It should be noted that you can run two instances of the same program simultaneously
where each instance of the program uses a different user library.
The starting virtual addresses of the program text (code) and data segments are
system constants, set by the linker and enforced by the operating system. The linker
also sets "preferred" virtual addresses for the text and data of DLLs, either by default
or from command-string input. (DLL data immediately follows the text.) If the preferred
address ranges are available at load time (do not conflict with already loaded objects
or reserved areas), they are used; otherwise the operating system finds an available
address range for the DLL.
Like any other DLL, a user library can require other libraries. Figure 1-5 below shows a
User Library assigned to Program, and this User Library itself requires the library Lib H.
Program directly references the user library and hence indirectly references H.
You can assign a DLL as a user library to a program when you link or load that
program, or by a special linker command that allows you to change this assignment in
an existing program. More detail is provided in How to Set Run-Time Attributes of Your
Loadfile on page 5-6.
Figure 1-5. Loadfiles of Figure 1-4 with a User Lib and Its Library Added
DLL A DLL D
Lib D Lib G
Code Lib E
and Program
Data
Lib G
Lib A
libList Lib B DLL B DLL E
Lib C
Lib F Lib G
User Library
(DLL) Lib F
DLL C
Lib H
Lib F
Lib H
VST015.vsd
File name – A name of a file, which may or may not be an argument of an option.
In this document, a file name in the command stream that is not a part of an option
is said to be directly inserted in the command stream.
Parameter – A non-file-name argument of an option
The command stream comprises all the tokens that modify an eld command; these
are processed in the order they appear in the command stream. These tokens can
come from the command line or from command files that are referenced in the
command line. In this document, to insert an item means to make it a token in the
linker’s command stream either directly or as an option argument.
Herein, options are defined with the file names and parameters they require. Thus, in
the next paragraph, the -obey option is defined as -obey<filename> meaning that
<filename > is required when the option is declared.
-obey <filename> is a linker option that designates a command file containing
tokens to be incorporated into the linker’s command stream. The linker processes
these tokens in sequential order before it moves on to the next token on the command
line. Such a file is called an obey file. Obey files can be called from within an obey file.
The linker accepts -FL as a synonym for -obey. To use the standard input file as an
obey file, insert the -stdin option with no file names or parameters.
Option Types
Options fall into three categories:
Repeatable option - Each occurrence adds another element of information or
causes the linker to repeat an operation.
Toggle option - A set of options, usually a pair. One of the set turns on a
designated linker behavior, and that behavior remains in effect until the linker
encounters another member of the set in the command stream, which invokes a
different linker behavior. Command-stream processing begins with one behavior as
default, and the option members can be repeated in the command stream as many
times as needed.
One-time option - All other options, which can only appear once in a command
stream.
The order in which an option appears in the command stream makes no difference
except where specifically mentioned. However, when adding an option to the command
stream, be sure to avoid inserting it where it separates some other option from its
arguments.
Naming DLLs
Unlike programs, every DLL has an internal name that is also the name of the file
where that DLL is (to be) stored on the execution target; see Choosing a DLL Name on
page 2-6. This name is specified when the DLL is linked and is recorded in the DLL
itself. The -dllname option gives the DLL its internal name, independently of the
name of the file in which you store it. The -dllname option can be used to create an
arbitrary DLL name, for example, a fully qualified file name.
You may use -soname as a synonym for -dllname. (so stands for shared object.)
The following example might be used to link on a Win32 system, to give the resulting
DLL the name maindll, and to store it in a file named mainoutput.dll in a
directory named C:\myfiles\dlls.
eld linkfile1 linkfile2 -dll -dllname maindll &
-o C:\myfiles\dlls\mainoutput.dll
You also have three ways to give the DLL and its output file the same name:
The -o <filename> option, when used by itself, assigns <filename> to the
internal DLL name as well as the file. When using the -o option and <filename>
is a qualified file name, the DLL name is obtained by truncating <filename> to
remove the path or subvolume definition and yield the corresponding unqualified
name. See File-Name Qualification below.
The -dllname <filename> option, when used by itself, also assigns
<filename> to the file.
You can use both the -dllname and -o options with the same name in each.
The following example of the first option gives the resulting DLL the name mainout
and also stores it in a file named mainout.
eld linkfile1 linkfile2 -dll -o mainout
If you do not insert either a -dllname or a -o option, the linker will assign the same
default name to both the DLL and the output file. If the linker is running on a Guardian
host, that name is aout; otherwise, it is a.out.
File-Name Qualification
The linker distinguishes between:
An unqualified, or “simple” file name (also known as the file identifier), which
identifies a file within a directory or subvolume but which must be appended to the
directory or subvolume definition and expanded with file-name augmentation
according to the file system, as described in Augmenting Library Names
Automatically in Searches on page 5-2
A partially qualified file name, which identifies the file uniquely in the file system
where the name is used.
A fully qualified file name: for Guardian, has $vol.subvol.name, perhaps prefaced
by \system; for OSS, begins with /.
The linker identifies a qualified file name as one that contains:
On Guardian – a period, backward slash, or dollar sign
On OSS – a forward slash
On Win32 – a forward slash, a backward slash, or a colon
All other file names are regarded as unqualified.
For any stand-alone file name (specifying a linker input), the handling is much the
same:
Guardian - Apply the =_DEFAULTS DEFINE to fill in any system, volume, or subvol
that is missing. (This is a no-op for a fully qualified name). See also the MAP
DEFINES note below.
OSS - If it is "absolute" (begins with a /), take it as is; otherwise append it to the
current working directory.
Win32 - As above, except for drive: and \ issues.
The distinctions become more important for file names specified by the -lib (-l) option.
In this case, only unqualified names are subject to searching through the list of paths.
Partially or fully qualified names are treated as above.
eld Specifics
There are various items on the eld command line that are filenames. These include
the parameters of various options, such as -o, -l, -strip, etc., as well as
filenames that are just written directly on the command line. For such command line
items, eld checks if they begin with equal signs. If so, in the Guardian case, the linker
will immediately do the expansion of the DEFINE, so that all uses thereafter will be the
same as if the expanded name had been given originally (with one special case
described below). The expansion of the name should also be done in uppercase, and
the linker will put out an informational message. If the specified string cannot be
expanded as a MAP DEFINE, that is an error. And, on other platforms, such as the PC
or OSS, if a filename parameter begins with an equal sign, that is unconditionally an
error.
On the other hand, there are certain items on the command line that are not filenames,
although they look similar to filenames. In such cases, if the string starts with an equal
sign, that is always an error, even on Guardian. Examples of this include the names of
subvolumes specified in options such as -L and -rpath, and the DLL name specified
by the -soname option.
When it comes to parameters that are symbol names, no such rules apply. An equal
sign at the start of a symbol name has no special significance to the linker.
There is a special case. In the case of the -libname (or -set libname, or -change
libname) option, usually, it is an error if the parameter is not exactly of the form
$a.b.c. However, a DEFINE can be used for this, even though a DEFINE always
expands to the form \system.$a.b.c. In these contexts, after expanding the DEFINE,
the linker also removes the system name.
To: Action:
Specify the name of the file in which to Assign the file name with a -o option
store the result
Name the resulting DLL differently from Assign the DLL name with the -dllname
the output file option and the file name with a -o option.
Simultaneously give the same name to Assign the name with a -o option and do not
the output DLL and the file it is stored in use a -dllname option, or vice versa.
Linkfile Inputs
The linker’s main purpose is to combine linkfiles to produce a loadfile. You must insert
directly in the command stream the name of the linkfiles that are the primary inputs to
the link. The names of these linkfile inputs can be unqualified if the linkfile is in the
same subvolume or directory from which you invoke the linker or else they must be
fully qualified file names; they cannot be part of any option. These names can be
inserted anywhere as long as they do not separate another option from its parameters.
The linker always resolves symbol references in linkfiles being linked with symbol
definitions those linkfiles themselves provide. In particular, if a loadfile refers to a
symbol that it also exports, the linker binds that reference to that loadfile’s definition. If
the loadfile is localized, which the linker assigns by default, then at load time, the
loader will accept this resolution. If the loadfile is not localized, the loader may revise
the linker’s resolution, as discussed in Ambiguity Example 2 on page 4-9.
-all and -none are toggle options you can insert multiple times in the command
stream to set the mode for archives that are subsequently specified in the command
stream. You can also insert the same archive more than once in the command stream.
At the beginning of the command stream, the default mode is -none.
The following example brings into the link only those linkfiles in an archive called
archfile1 that resolve symbols at the time the linker has archfile1 open, since
-none is the undeclared mode at the beginning of the command stream.
eld linkfile1 linkfile2 archfile1 -dll -o mainout
If, instead, you want the linker to bring into the link all the linkfiles in
archfile1, insert the following:
eld linkfile1 linkfile2 -all archfile1 -dll -o mainout
In this case, -all remains in effect for the rest of the command stream that follows it.
While the archive is open (when -none is in effect), the linker searches for symbols
that are unresolved in the loadfiles seen so far, or specified by the -u option, or
unresolved in linkfiles selected from the archive. The archive can have indirectly
needed linkfiles. The linker finds them regardless of their order. (That is, the linker
makes multiple passes over the archive while it has it open, if necessary to resolve
symbols introduced by linkfiles in the archive.)
Library Inputs
In addition to linkfiles and archives, a loadfile being linked can also obtain symbol
definitions from existing loadable libraries. You must know which symbols the loadfile
you are creating will import from existing libraries, and tell the linker which libraries can
resolve those symbols by inserting their file names in the command stream. Using
these names, the linker opens the corresponding files and reads their internal names
to build the libList in the resulting loadfile. There it lists the libraries in the order that you
inserted them; these libraries are called your loadfile’s libListed libraries. Later, the
loader uses this libList on the execution target to find the libraries that will resolve your
loadfile’s symbol references and to build your loadfile’s loadList.
Thus, when linking your loadfile, the order in which you insert library names into the
linker’s command stream determines the order that the linker processes them and lists
them in your loadfile’s libList. The order of library names is unaffected by the mingling
in the command stream of other inserted tokens among these names.
Figure 1-4 on page 1-9 shows that when linking the program, the programmer inserted
the file names of DLLs A, B, and C, in that sequence. It also shows that:
A requires D and E.
Both D and E require G.
Both B and C require F.
To get these results, when A was linked, its programmer inserted first the names D
then E. When D and E were linked, their programmers inserted G. Likewise, when B
and C were linked, their programmers inserted F.
Library names can safely be inserted anywhere in the command stream, because their
symbols are made available as needed in the link regardless of their inserted position.
Also remember, when a TNS/E compiler invokes the linker for you, the compiler
automatically ensures that the object files are linked to any required standard run-time
libraries.
If the linker is given a qualified file name inserted directly in the command stream,
it opens the file in the normal way for the linker host platform.
If the linker is given an unqualified file name inserted directly in the command
stream, it opens a file of that name in the current directory or subvolume.
If an unqualified file name is used in a -lib option, the linker searches for that file
following prescribed search paths, as discussed in Where The Linker Searches for
Libraries and Archives on page 2-11.
If a partially or fully qualified file name is used in a -lib option, the linker does not
search; it applies the host-system defaults to a partially qualified file name, and
attempts to open the file.
The linker can look for the file among the public libraries.
appropriate to the linker platform and then attempt to open the resulting file. This is
described in Augmenting Library Names Automatically in Searches on page 5-2.
A -lib option cannot specify any of the primary linkfiles in a link; these must be
inserted separately in the command stream as qualified file names or unqualified
names if the files are in the current directory.
For Guardian, unless the -b static option is in effect, the linker searches in
$SYSTEM.ZDLL.
For Win 32, the linker does not search in any standard places.
You can have the linker skip steps 2 and 4 above by inserting the -nostdlib option
or its synonym -no_stdlib.In this event, the linker will search for libraries in places
specified by -first_L or -libvol options. -nostdlib is a one-time option that
applies to the linker only; it has no effect on subsequent loader operation.
The following example causes the linker to search for a library listed in a -lib option
first in a private subvolume, pvtsvol, before searching for it in the public libraries.
eld linkfile1 linkfile2 -lib dllfile1 &
-first_L pvtsvol -dll -o mainout
You may find it convenient to use a common search path that can work on different
linker platforms. The linker design supports this by allowing directory and subvolume
names for different platforms to be mixed in one search path definition. In this case, the
linker on one platform will find in its search path some directory or subvolume names
that are syntactically incorrect, because they are for the other platform. The linker
ignores these and searches only the ones it deems correct.
linkfile or loadfile. However, the compilation of the module that implements class foo
can contain
#define export_foo export$
ahead of the #include directive for this header file. As a result, this compilation will
define all the symbols associated with class foo, and mark them offered for export.
Re-Exported libraries
A DLL can also make available symbols exported by any library in its libList; that is, the
given DLL can re-export the other library. Thus, when a given DLL, call it A, re-exports
a library, B, any loadfile that has A in its libList can also use all the symbols offered for
export by B. When linking a given DLL, the programmer must designate which
libraries, if any, the given one is to re-export.
The fact that DLL A re-exports library B is only meaningful when a loadfile that has A in
its libList is localized, because if that loadfile is not localized, it has access to B’s
symbols anyway.
As an example, suppose that in Figure 1-5 on page 1-14, Program is localized. Then it
can only import symbols from User Library, A, B, and C, unless one of these four re-
exports libraries in its libList. Either B or C could re-export F, in which case Program
could use F’s symbols. And if A re-exported either D or E, Program could use the re-
exported library’s symbols. In the latter case, if the re-exported library (either D or E)
also re-exported G, then Program could use G’s symbols, as well. This is because re-
exportation is transitive, in that if Library X re-exports DLL Y and Y re-exports library Z,
then X re-exports Z. User Library could also re-export H for A’s use.
On the other hand, in Figure 1-5, if Program is globalized, then it can import symbols
from any libraries shown in that figure, regardless of which libraries are re-exported.
Alpha Alpha
Beta Beta
Gamma Gamma
DLL D
DLL A
VST021.vsd
Figure 2-1 on page 2-15 illustrates DLL D exporting symbols Alpha, Beta, and Gamma,
while its client, DLL A, imports those symbols. Suppose that you want to replace D with
two loadfiles, one which provides the Gamma definition and the other which provides
the Alpha and Beta definitions, and you do not want to affect D’s client loadfiles. You
can do this as follows.
1. Split the source for D to create the two new loadfiles: one that exports Alpha and
Beta, the other that exports Gamma.
2. Recompile and relink the new sources, and give one resulting loadfile (say the one
that exports Alpha and Beta) a new name, Y. Give the other loadfile the old name,
D. See Naming DLLs on page 2-3.
3. Set up D to re-export Y.
The result is shown in Figure 2-2 on page 2-16, where the dashed lines through D
indicate re-exportation. All the clients of D, like A, still get symbols Alpha, Beta, and
Gamma through D, so they need not be changed.
Alpha Alpha
Beta Beta
Gamma Gamma
DLL D DLL Y
(new) (new)
DLL A VST022.vsd
Figure 2-3. the New Symbol, Gamma, With New Function (Shaded), Replaces the
Old Gamma.
Alpha Alpha
Beta Beta
Gamma Gamma
X Gamma
DLL Y
DLL D (old D)
(new)
DLL A VST023.vsd
Because the search order for the linker and loader comes to D before Y (See Finding
Symbol Definitions on page 4-1), D’s Gamma masks Y’s. So without any change to the
users, all of those that formerly used old D’s Gamma will now get new D’s Gamma.
The -RLD_first_L option is rarely necessary, because the public libraries have
unique names that should not overlap those supplied by the user or other agencies.
It is more efficient to have the public libraries first on the path search list at load time,
because the set of public libraries can be searched very quickly using a table in
memory.
Floating-Point Type
1. If the -set floattype <value> option is inserted, the linker sets the floating-
point type of the output loadfile to <value>, where <value> can be ieee,
tandem, or neutral.
2. If the -set floattype <value> option is not inserted, then if the input
linkfiles do not contain a mixture of both ieee and tandem floating-point types,
the linker sets the floating-point type of the output loadfile to the one that is
represented. Input linkfiles of neutral floating-point type are ignored in this.
However, if all input linkfiles are neutral, then the linker sets the output loadfile to
neutral.
C++ Dialect
Each compiler identifies its language in the generated linkfiles. Three different versions
of the C++ language exist on HP NonStop systems; these dialects are called version1,
version2 and version3. They differ in language constructs and in their run-time support
libraries; they have slightly different "mangling" algorithms for function names.
Version1, the oldest, is obsolete and is not supported for PIC files (on TNS/R or
TNS/E). Version3 was new with G06.20; it complies with the ANSI standard.
For any language other than C++, the C++ dialect is defined to be neutral. The linker
and loader ensure that only one non-neutral C++ dialect appears in a loadfile or a
process, respectively.
SQL/MX Restriction
Public DLLs that support SQL/MX have cppdialect = version2. Therefore, SQL/MX
clients cannot yet use C++ version3.
4. By default, the linker uses only the linkfiles from an archive that resolve currently
unresolved symbols. [Selecting Linkfiles from Archives on page 2-7]
5. By default, the linker exports those symbols for which your compiler sets the
xport bit in the external symbol table. [Controlling Which Symbols Your Loadfile
Exports on page 5-5]
6. The linker builds a loadfile that, by default, re-exports no other DLLs. [How to Make
Your Loadfile Re-Export Symbols of Other DLLs on page 2-15]
7. If you specify an output file for the DLL you are linking but no DLL name, the linker
gives the resulting DLL the same name as the file. [Naming DLLs on page 2-3]
8. If you specify a DLL name for the DLL you are linking but no output file, the linker
gives the output file the same name as the DLL. [Naming DLLs on page 2-3]
9. If you specify neither a DLL name nor an output file for the DLL you are linking, the
linker gives them both the same name, as defined in Naming DLLs on page 2-3.
10. By default, the linker sets the system type of your loadfile as defined in Execution-
Target System Type on page 2-22. [How to Set Run-Time Attributes of Your
Loadfile on page 5-6.]
declared in a header file called dlfcn.h and defined in the loader’s library. Therefore,
any C or C++ source file that uses these functions must contain the following:
#include <dlfcn.h>
The same functions have pTAL external declarations in a file named hldfcn. Both
header files also define parameter types and constants for using with these functions.
These functions are implemented in the public library ZRLDDLL. This DLL does not
use any explicit public libraries. This library is not named in LIBCOBEY or libc.obey
(if one exists), and is not supplied automatically by the compiler driver when it runs the
linker for you. Therefore, you must name this library explicitly when building a loadfile
that calls any of these functions. If you run eld manually, you can add a -lib zrlddll
option in the command stream. If you let the compiler run the linker, you can provide
the option through the compiler command line; see Running the Linker Through the
Compiler on page 5-10.
The following summarizes the dynamic library function calls.
dlopen() loads and opens a specified DLL and the libraries in its loadList if they are
not loaded, and this function returns a handle for the named DLL.
dlsym() returns an address of a named symbol exported by a loadfile associated with
a dlopen handle. The calling process can assign that address to an appropriate
data or function pointer, which becomes a reference to that symbol.
dlclose() invalidates a dlopen handle and unloads any dynamically loaded libraries
not required by some other handle.
dlerror() provides a textual error message that describes any error arising from an
immediately preceding call to dlopen(), dlsym(), or dlclose().
dlresultcode() provides an enumerated result code for the last call to dlopen(),
dlsym(), or dlclose().
When the object_pathname parameter is zero, the loader does not load anything, but
returns a handle that enables dlsym() to search for symbols in the program and
libraries loaded with it. Furthermore, any running loadfile object_pathname can name
any currently loaded DLL as a dlopen target and get a handle to access the exported
symbols of that DLL and the libraries in its loadList.
In the following discussion, the loadfiles loaded prior to a dlopen() call are called the
prior operating load set. The prior operating load set includes the main program and its
initially loaded DLLs as well as any DLLs that were previously loaded dynamically. The
DLL named in a dlopen() is called the targeted DLL. That DLL and the libraries
loaded with it compose the added load set. The prior operating load set and the added
load set compose the new operating load set.
RTLD_NOW
This option performs all linking on the newly loaded library immediately.
RTLD_LAZY
This option is accepted to provide compatibility for UNIX, but is treated the same
as RTLD_NOW.
RTLD_GLOBAL
This option specifies that the newly loaded DLLs should be added to the
cumulative loadList, i.e. new libraries are added to the global set, which consists of
the program and libraries loaded initially by rld. This is the default.
RTLD_LOCAL
This option is accepted to provide compatibility for UNIX, but is treated the same
as RTLD_GLOBAL.
RTLD_NOLOAD
This option specifies that dlopen() should not load the target library, but should
provide a unique handle to it, if it is already loaded. This option causes dlopen()
to return a 0 if the library is not already loaded. Note that any handle returned by
dlopen() counts as a usage of the target library and until it is closed, the library
is not unloaded.
RTLD_VERBOSE(verbosity_level)
This option specifies the diagnostic output detail from calls to dynamic linking
functions regarding loading of library files, resolution of symbol names and search
details for files and symbols. The verbosity_level values are the same as
rld’s and are as follows:
0 - default (as though this specification is absent)
1 - none (no output to hometerm/stderr)
2 - warnings and errors
3 - also show files loaded
4 - also show symbol resolution
5 - same as 3, plus file search details
6 - same as 4, plus file search details
7 - same as 4, plus symbol search details
8 - all the above
dlopen() treats the mode parameter as the union of the above values and detects an
error if any other value is used. Valid combinations for the mode parameter include
both of the following:
Exactly one from the set of (RTLD_NOW | RTLD_LAZY | RTLD_NOLOAD)
No more than one from the set of (RTLD_GLOBAL | RTLD_LOCAL)
This means that if RTLD_NOLOAD is specified the user cannot set RTLD_NOW or
RTLD_LAZY, however, the user can, optionally, set RTLD_GLOBAL or RTLD_LOCAL.
Each valid combination can be combined with the verbosity level, via
RTLD_VERBOSE (verbosity_level) to create the mode parameter.
dlclose invalidates the handle and makes it unavailable for any other call that uses that
handle. If the specified handle is the last outstanding one for the referenced DLL and if
that DLL was dynamically loaded (by dlopen), the DLL is also unloaded. The following
is the parameter of a dlclose call:
dlopen_handle is a handle previously returned by a dlopen call.
Closing the last handle for the main program or for any DLLs that were loaded with the
main program does not unload any of these loadfiles. Also, if dlclose causes a loadfile
to be unloaded, then any DLL in its load set is also unloaded, unless that DLL also
belongs to the load set of the main program or to a DLL that still has an outstanding
handle for it. When dlclose unloads DLLs, the new operating load set becomes the old
operating load set less the unloaded DLLs.
Referencing code or data in a DLL using a handle that has been invalidated by dlclose
produces undefined results.
Issuing a dlopen that specifies a DLL previously unloaded by dlclose reloads that DLL
plus the libraries in its libList that are not already loaded, and establishes a new handle
to it.
There has never been a call to dlopen, dlclose, or dlsym in this process.
Otherwise, dlerror returns a pointer to a buffer that contains a null-terminated character
string containing only displayable characters and no trailing newline character. The
string is a read-only value that is overwritten by the occurrence of any subsequent
error in a dynamic library call, or by any call to dlopen, dlsym, or dlclose, so to preserve
or modify the string, a process should make its own copy of it.
The loader cannot recognize threads that may be used in a multi-threaded application.
Therefore, if you create such an application, you must ensure that no thread switch
occurs between a dynamic library call and the invocation of dlerror that retrieves
information about that call. Since the NonStop operating system supports only user-
level threads, this means that during this interval, you must avoid invoking functions
that can cause explicit thread switching.
Calling dlresultcode() does not reset the error code. dlerror() and
dlresultcode() can be called in either order; neither affects the value returned by
the other.
dlresultcode() is an HP NonStop operating system addition to the conventional
set of dynamic loading functions.
Thread Considerations
The loader is not aware of threads that may be used in a multi-threaded application.
Therefore, if you create such an application, you must ensure that no thread switch
occurs between a dynamic library call and the invocation of dlerror or dlresultcode that
retrieves information about that call. Because the NonStop operating system supports
only user-level threads, this means that during this interval, you must avoid invoking
functions that can cause explicit thread switching.
More elaborate conventions can have the DLL export a canonical "master" function
or data structure that describes the functions or data available in this library. The
application uses dlsym() to locate the "master" symbol. For example, an
exported data structure could contain a count and an array of substructures that
contain information about each available function, including a function pointer and
an encoding of its purpose, result and parameter types. Of course, these
descriptions are limited by the conventions established between application and
DLL programmers, but can be as flexible as the programmers make them.
Because these structures include the function pointer, the individual functions need
not be exported from the DLL; the application need not know their actual names or
use dlsym to find them.
All of this can be done without changing or even stopping and restarting the original
application.
Source
Compiler
Linker
Loader
The loadList
The loadList of a file consists of that file, the library files specified on its libList, the files
specified on their libLists, and so on. This is called the breadth-first transitive closure of
libLists. The linker develops the loadList of the loadfile being created. The loader, at
process creation time, develops the loadList of the program. For dynamic loading,
using dlopen(), the relevant loadList is that of the designated library file; that loadList
extends the operating load set of the program.
The linker or loader creates the loadList for a loadfile using the following algorithm:
1. [Initialize] To an empty loadList add the name of the designated file, and set a
pointer referring to this entry, making it the currently referenced loadfile.
2. If the designated file is the program and it has a user library, add the library name to
the loadList.
3. If the designated file has a non-empty libList, add the libList entries in the same
order they appear in the libList.
4. [Begin loop] If there is another loadList entry immediately following the referenced
loadfile, set the reference pointer to it. If there are no more loadList entries, the loadList
is finished.
5. Append to the loadList, in the same order, the libList entries of the referenced
loadfile that are not already on the loadList.
6. Return to step 4. [End loop]
For the program and loadfiles of Figure 1-5 on page 1-14, Figure 4-2 on page 4-3
shows the evolution of the globalized loadList and the pointer status for each loop run
in the foregoing algorithm at the end of steps 4 and 5. That figure shows only the first
few runs of the loop and the last. The resulting loadList, is shown at the bottom of the
figure.
Figure 4-2. Development of the Globalized SearchList for the Program and
Libraries based on Figure 1-5 on page 1-14
Algorithm step: 4 5
Program Program
UL UL
1st LoopRun A A
B B
C C
Program Program
UL UL
2nd LoopRun A A
B B
C C
D
Program Program
UL UL
A A
3rd LoopRun B B
C C
D D
Program Program
UL UL
A A
4th LoopRun
B B
C C
D D
Program Program
UL UL
A A
5th (last) LoopRun
B B
C C
D D
VST043.vsd
and libraries). Furthermore, the application of these concepts differs from one source
language to another.
In the C language, items declared within a function are local to that function and are
undefined (invisible) elsewhere. Items declared outside any function have global scope
and are visible in any function that does not hide that declaration with a local one of the
same name. (In languages with nested functions, such as Pascal, there are multiple
levels of nested scopes. In pTAL, a SUBPROC has a scope nested within that of the
PROC.)
The C language defines storage class (sometimes also called linkage); the two storage
classes that apply to global functions and data are extern and static. Global data
and functions with static linkage are visible to the functions within this compilation
unit, but are local to the compilation, and therefore to the linkfile that results from the
compilation. Global variables with no specified storage class are implicitly extern.
The explicit specification of extern linkage on an uninitialized variable declares the
variable but leaves it undefined; if there are references in this compilation, they must
be linked to a definition in another.
(The pTAL language has no explicit storage class. Everything is effectively extern
except SUBPROCs, which are static.)
When the linker combines multiple linkfiles to build a loadfile, global extern definitions
in one linkfile are available to satisfy references to an undefined symbol in another;
these items are considered global in the resulting loadfile. However, static global items
within each linkfile become local in the loadfile.
A key part of the linker's job is binding global references in one linkfile to definitions in
another. For C compilation units, the linker enforces the language requirement that a
given symbol have at most one definition in the loadfile. For some constructs common
in header files, the C++ language generates definitions in every compilation that
includes the header; the compiler marks these symbols to inform the linker that
multiple definitions are acceptable, and the linker is expected to bind all references to
one of them. Slightly different rules apply to some pTAL definitions, such as data
blocks: the linker will accept multiple definitions, as long as any initialized data is the
same in each.
If none of the linkfiles contributing to a loadfile defines a referenced symbol, it remains
undefined in the loadfile. In this case, it will need to be bound to a definition in some
other loadfile. In such a case, the referencing file is said to import the symbol, and the
defining loadfile is said to export it. In a DLL with globalized import control, it is also
possible for a symbol to be imported even though that symbol is offered for export; in
this case the definition in this DLL is said to be preempted by a definition in a loadfile
appearing earlier in the program's loadList.
Only some of the global symbols in the loadfiles can be shared with other loadfiles:
those that are offered for export, and those that are undefined (require import). There
are several ways that symbols become available for export. By default, the linker offers
for export only symbols that the compiler designates as exportable. With the C/C++
compilers, you can specify export or import of individual symbols, or of whole classes.
With the linker, you can export individual symbols, or you can cause all global symbols
in your loadfile to be exported, and then you can choose which symbols not to export.
See Controlling Which Symbols Your Loadfile Exports on page 5-5.
linking a localized loadfile and the loader uses when loading it. The algorithm is
illustrated in the example that comes after it.
1. [Initialize] To an empty searchList add the name of the localized loadfile being
linked and set a reference pointer pointing to this entry, making it the currently
referenced loadfile.
2. If the referenced loadfile is a program that has a user library, add the user library’s
name to the searchList.
3. If the referenced loadfile has a non-empty libList, add the libList entries from the
loadfile in the same order they appear in the libList.
4. [Begin loop] If there is another searchList entry immediately below the referenced
loadfile, set the reference pointer to it and make it the reference loadfile. If there
are no more searchList entries, the searchList is finished.
5. Append to the searchList, in the same order, the libList entries of the referenced
loadfile that are designated in the libList as re-exported and that are not already on
the searchList.
6. Return to step 4.
As an example of how the foregoing algorithm works, consider Figure 4-3 on page 4-7,
which shows Program and the libraries in its loadList. Program references the symbol
xray and DLLs C and D both export it. Assume that Program is a localized loadfile.
Program’s imported symbols are resolved by searching UL, A, B, and C in that order,
where UL stands for User Library. Suppose also, that UL does not re-export H, that A
re-exports D but not E, and that neither B nor C re-exports F. Figure 4-4 on page 4-9
shows the development of the localized searchList for Program following the algorithm
listed above. For each run through the loop, the rows in that figure show the situations
after the execution of algorithm steps 4 and 5.
Figure 4-3. The Loadfiles of Figure 1-5, Now Showing the Use and Availability of
the Global Symbol xray
Exports xray
DLL A DLL D
Imports xray
Lib D Lib G
Code Lib E
and Program
Data
Lib G
Lib A
libList Lib B DLL B DLL E
Lib C
Lib F Lib G
Exports xray
User Library
(DLL) DLL C Lib F
Lib H
Lib F
Lib H
VST042.vsd
The final searchList is shown at the bottom of Figure 4-4. This shows how to develop a
localized searchList for Program when A re-exports D and no other DLLs re-export.
The arrows point to the referenced libraries in the algorithm after the indicated loop
run.
Program will use C’s definition of xray, since C precedes D in the searchList. But,
assuming D is localized, D will use its own definition of xray.
If we change the conditions so that B re-exports F, then Program’s searchList becomes
Program, UL, A, B, C, D, F. If now D re-exports G, then Program’s searchList becomes
Program, UL, A, B, C, D, F, G. Then if User Library re-exports H, the searchList
becomes Program, UL, A, B, C, H, D, F, G. If E re-exports G, this has no effect on the
searchList, because E itself is not re-exported; hence, E does not appear on the
searchList.
Localized import gives the programmer tight control over how imported symbols are
resolved, which is consistent with previous conventions used on HP NonStop systems.
Localized import facilitates load-time optimizations, because the linker's search list is
the same as the loader's. Finally, localized import is necessary for security where PIC
programs and DLLs support license and privilege.
Ambiguity Example 1
Figure 4-3 on page 4-7 shows a case of symbol ambiguity when Program is globalized
and imports a symbol named xray, since both C and D export a symbol named xray.
In linking Program, the linker sees xray in both C and D. However, following the
globalized searchList (Program, UL, A, B, C, H, D, E, F, G), the linker encounters C’s
xray before it encounters D’s xray, so it resolves Program’s need with C’s definition.
Furthermore, if D is globalized and if it also references xray, then the loader assigns
C’s definition to D’s reference as well, preempting the linker’s original assignment of
D’s own definition to D’s reference. Thus, xray is defined the same for Program and
D. If C references xray, it will get its own definition, regardless of whether it is
localized or globalized, because it appears first in both searchLists.
Figure 4-4. Development of the Globalized SearchList for the Program and
Libraries in Figure 4-3
Algorithm step: 4 5
Program Program
UL UL
1st LoopRun A A
B B
C C
H
Program Program
UL UL
2nd LoopRun A A
B B
C C
H H
D
E
Program Program
UL UL
A A
3rd LoopRun B B
C C
H H
D D
E E
F
Program
UL
A
B
C
H
9th (last) LoopRun D
E
F
G
VST044.vsd
Ambiguity Example 2
When linking a DLL, the programmer might not know about the program or the other
DLLs that could ultimately be bound together to create an executable set. In Figure 4-5
on page 4-10, the programmer of globalized DLL B links it to another globalized library,
called F, that exports the symbol definition of john that B should use. Thus, there
appears to be no ambiguity, and the resolution of john should be simple. But, because
B is globalized, the loader sees it differently.
Exports john
DLL B Lib F
Lib F
Exports john
DLL A DLL D
Lib D Lib G
Program Lib E
Imports john
Lib G
Lib A
Lib B DLL B DLL E
Lib C
Lib F Lib G
Exports john
User Library
(DLL) DLL C Lib F
Lib H
Lib F
Lib H
When loading Program, the loader’s picture is shown in the lower part of Figure 4-5,
which includes DLL B and Lib F as they were linked in the upper part of the figure.
Program requires A, B, and C, and it turns out that john is exported by both A and F.
Recall that imported symbols for every globalized loadfile are resolved using Program’s
globalized searchList, which is Program, UL, A, B, C, H, D, E, F, and G. Because the
loader encounters A’s definition of john before F’s and because B is globalized, the
loader satisfies B’s need with A’s definition, not F’s. If B’s programmer expected
otherwise, there is a surprise in store.
Perhaps more surprising, if a DLL references its own global symbol definition, one
might think that this definition would always be used to satisfy this DLL. However, as
we saw earlier in Ambiguity Example 1 on page 4-8, the loader can preempt the
linker’s setting and decide to import that symbol. So, if a DLL is globalized, any of its
references might be satisfied by a symbol of the same name in some other loadfile.
Therefore, in the above example, if F references john in addition to offering it for
export, then because F is globalized, the loader binds F’s reference to A’s definition
instead of F’s.
B’s and F’s programmers can avoid this substitution by declaring both B and F to be
localized. This assures that in resolving B’s imported symbols, the linker and the loader
use B’s localized searchList (in this case: F); it also assures that F uses its own
definition of john. Note, however, that if any other globalized loadfile in the list needs
john, it still gets the definition from A. So, for example, if B is localized and F is
globalized, B uses F’s definition of john, but F uses A’s.
Ambiguity Caution
The UNIX environment standardizes on globalized import controls, and hence, accepts
symbol ambiguity; but it can be dangerous and is often undesirable, because a symbol
might be resolved in a way that the programmer did not anticipate. Like UNIX, TNS/E
permits ambiguity in the globalized case, and the loader issues no warning about it. On
the other hand, this mechanism ensures that all globalized loadfiles in a process will
consistently use the same definition for a given symbol.
the loadfile itself. That range comprises the loadfile’s LibList, the loadfiles that those
loadfiles re-export, and so on.
C++ Considerations:
Globalized (Gblzd) Symbols
Constructs in the C++ language can generate symbols that might have multiple
definitions (for example, one in every compilation unit that includes a particular header
file). The compiler marks these symbols so that the linker can recognize them and pick
one definition for use throughout the resulting loadfile. The linker also marks them so
that the loader can recognize them and pick one definition for use throughout the
process.
Here are a few of the situations that give rise to such symbols:
Functions declared inline for which the compiler defines an out-of-line procedure
Elaborations of template functions or classes
Compiler-generated variable names used to identify types for run-time type
checking, including throw and catch of exceptions
The compiler generates these symbols as needed; programmer's cannot explicitly
define them in source.
For correct function of the C++ program and libraries, it is important that a single
definition be used throughout the process. For example, an exception can be thrown
and caught in different loadfiles only if they agree on the exception class type.
These special symbols are called globalized symbols, often abbreviated gblzd. The
overloading of the term globalized arises because these symbols unconditionally have
globalized semantics: the loader picks one definition for this symbol and binds all
references to it. It does so regardless of the import control for the referencing loadfile.
One must carefully distinguish the term globalized symbols (these symbols that
automatically get special treatment) from globalized import (selected by the user at link
time).
These gblzd symbols reside in a separate symbol table in PIC loadfiles.
Alpha Alpha
Beta Beta
Gamma Gamma
DLL Y VST046.vsd
The symbol Gamma, provided by the existing Library D, is intercepted for selected
calling loadfiles (including DLL A). These selected loadfiles must be relinked to put DLL
X in their libLists and remove Library D. Hence, their Gamma references are bound to
the definition in DLL X. The new function that modifies the original Gamma goes into X
and Y, and Y accesses Library D to get the original Gamma function, so you do not have
to rewrite it. Calls to Gamma from unmodified calling loadfiles continue to go directly to
Library D.
To create this library intercept you:
1. Relink the calling modules (such as A) that are to use the intercepted Gamma in
order to replace D in their liblists with X. These calling loadfiles must be localized.
2. Write a new localized DLL X that contains the new (intercept) function and offers
the intercepted symbol, Gamma. Make X re-export D, so the other symbols D offers
are available to the callers.
3. So that you do not have to rewrite the original Gamma definition, the new function in
DLL X needs to pass control to Gamma in DLL D. But DLL X cannot call Gamma in
DLL D directly, because X’s reference to Gamma would be resolved to X’s own
definition of Gamma. Hence, you introduce an intermediary DLL, Y, which
references Gamma. Y must be localized and have D in its liblist. If for some reason
X must be in Y’s liblist, then be sure that D precedes it in that list.
4. Instead of calling Gamma, X calls Joe to pass the information to Y. Y’s definition of
Joe converts this to a call for Gamma in D.
the linker can only be looking for archives, and even if -allow_missing_libs has
been inserted, the linker will terminate in error if it doesn’t find the specified archive file.
Data Definitions
The linker accepts multiple data-item definitions of the same symbol in input linkfiles
when both of the following are true:
An item is defined in more than one file, and the compiler has marked every
instance of this symbol to allow multiple definition (so this will become a gblzd
symbol; see C++ Considerations: Globalized (Gblzd) Symbols on page 4-12 .
The linker can determine that they are the same size and that their initial values (if
any) are the same.
Otherwise, the linker treats multiple definitions of a data item in input linkfiles as an
error.
Procedure Definitions
Multiple procedure definitions of the same symbol are permitted when the compiler
generates and appropriately labels the duplicates. In this case, the linker checks that
the attributes of the duplicated procedures are identical except for EDITLINE. If the
others are not identical, the linker declares an error.
Data Definitions
When the linker accepts duplicate data-item definitions of a symbol in linkfiles, it
chooses the instance to use according to the following priority:
1. An instance that is initialized over one that is not.
2. An instance which retains its symbol-table information over one that has been
stripped of this information.
3. An instance that come from the following sources in preferred order: C, C++, pTAL,
COBOL.
4. The first instance the linker finds in processing the linkfiles.
Procedure Definitions
When the linker accepts a duplicate procedure definition of a symbol in linkfiles, it
selects the instance to use from the first version of the procedure it finds in processing
the linkfiles.
loadfile being linked is globalized or semi-globalized, the linker searches for libraries
and their symbols following a searchList that is identical to this loadfile’s loadList.
Until the linker finds a library that offers a symbol that the output loadfile needs, it
considers that symbol unresolved. After searching the libraries described above and
looking in the millicode libraries, if the linker cannot find an exported symbol to match
an imported one in the output loadfile, it will respond as specified by <parameter>. If
error is specified, the linker terminates and reports an error; if warn is specified, the
linker issues a warning message and continues; if ignore is specified, the linker does
not attempt to find matching symbols. If you do not specify -unres_symbols, the
default on TNS/E is to ignore unresolved symbols.
Also, when linking on a system other than the execution target, such as an auxiliary
system, be aware that certain libraries may be unavailable. This may cause an
inevitable error or warning if either is specified.
Also note that if you insert the option, -unres_symbols and also allow missing
libraries, then -unres_symbols automatically defaults to ignore.
__INIT__
Alphabetical order of procedure names.
__sti__
The order in which eld sees the procedures.
__std__
The reverse of the order in which eld sees the procedures.
__TERM__
Reverse alphabetical order of procedure names.
As the names suggest, these procedures are called during the initialization (__INIT__
and __sti__) and termination of a process (__std__ and __TERM__). These
procedures are called without the program explicitly calling them.
iniTerm lists corresponding to these procedures, and places pointers (ctors and
dtors addresses) to them in the tandeminfo segment of the object file.
cppdialect
sets the C++ dialect of the output loadfile. The values are cppneutral or v2 or
v3.
See also C++ Dialect on page 2-20.
float_lib_overrule
inhibits float-type checking of the program and the libraries from which the program
imports symbols. Possible values are on or off, and the default is off. See
Checking the Floating-Point Types of Liblisted Libraries on page 2-20.
floattype
sets the floating-point type of the output loadfile. Possible values are ieee,
tandem, and neutral. See Setting the Floating-Point Type of a Loadfile Being
Linked on page 2-19.
heap_max
has a numeric (hexadecimal) value with a default of zero (0).
highpin
has possible values of on and off. The default is on.
highrequestors
has possible values of on and off. The default is on.
incomplete
has only one possible value, on. If this is not specified, and an import library is
being created, it is a complete import library.
inspect
has possible values of on and off. The default is on.
libname
is the name of a DLL to be the user library of the PIC program being linked. See
Specifying a User Library for a Program on page 2-12.
mainstack_max
has a numeric (hexadecimal) value with a default of zero (0).
oktosettype
has possible values of on and off. The default is off.
pfsize
is a number. It is accepted for compatibility with TNS/R systems, but is ignored.
process_subtype
has a numeric value with a default of zero (0).
rld_unresolved
has possible values of error, warn, and ignore, and the default is error. If
error is set (or by default), then an unresolved symbol encountered by the
loader (rld) will result in its error termination. If the loader cannot resolve a symbol
that references data, an error occurs regardless of the setting of
rld_unresolved.
However, if the loader cannot resolve a symbol that references code, and if warn
or ignore is set, it searches for a symbol definition named
UNRESOLVED_PROCEDURE_CALLED_. If this definition is found, the symbol is
bound to this definition and either a message is put out if warn is set or no
message is put out if ignore is set.
By default, the loader finds this function defined in the system library. If invoked, it
generates a non-deferrable SIGILL signal. You can provide your own function if
you wish; the loader searches normally for this symbol, so it will use any definition
found in the searchList of the loadfile containing the unresolved reference.
runnamed
has possible values of on and off. The default is off.
saveabend
has possible values of on and off. The default is off.
space_guarantee
has a (hexadecimal) numeric value with a default of zero (0).
systype
sets the system type of the loadfile being linked. Possible values are OSS and
Guardian. See Execution-Target System Type on page 2-22.
Note. The systype attribute has no meaning for a DLL. A DLL can be used by a
Guardian process, or an OSS process, or both, depending on how the various parts of it
were written and compiled. You must have this information about the DLL to use it
appropriately.
Segmenting Loadfiles
The linker produces the output loadfile in two segments, text and data.
The linker can be directed to produce two data segments - one for constant data
(the constant data segment) and one for variable data (the data variable segment).
Also, if the input linkfile contains PRIV code, the linker will also produce a gateway
segment.
-t address
this is a hexadecimal number that sets the starting address of the text segment
(headers and code).
-d address
this is a hexadecimal number that sets the starting address of the data segment.
In both cases, the linker rounds up address to a virtual memory page boundary. If
-t, but not -d, is inserted, then -t specifies the starting address of the entire
contiguous DLL. By inserting -d, you can cause the DLL to load in two separate
regions.
By default, the loader loads the text and data of a DLL into a contiguous virtual-
memory area, starting with the text (including code) section. This area is chosen to
avoid memory interference with other loaded files. These linker-assigned addresses
are called the preferred addresses; if this address range for a DLL is available, the
loader will use it.
If -t, but not -d, is inserted, then -t specifies the preferred starting address of the
entire contiguous DLL. By inserting -d, you can cause the linker to assign the two DLL
segments to disjoint address ranges. If you do that, the loader will reject the DLL.
In general, you should not use the -d option because it may result in the creation of
an object file that the operating system will refuse to load.
In contrast to a DLL, a program is always divided into two separate regions. For a
program, the default for -t is 0x70000000 and for -d is 0x08000000. If a non-default
value is specified, the loader will reject the program.
Summarizing these two options: -t is useful to specify a preferred address for a DLL,
so that it will not overlap the preferred address ranges of other DLLs that will appear in
the same process; with non-overlapping address ranges the DLLs will load slightly
faster. Otherwise, -t and -d are useful only in unusual circumstances that are beyond
the scope of this manual.
You can insert multiple -change options, where each must be followed by the name
of the affected loadfile, even if the loadfile is the same in each case. These options are
executed one at a time in the order inserted.
Your user ID must have write access to the file to execute the -change option on it.
Link-Time Operation
Running the Linker Through the Compiler
The C and C++ compilers can run the linker for you, saving you a separate step in
straightforward situations. In each case, the compiler automatically names many of the
appropriate input files and library files in the linker command stream. These are:
The usual C libraries
The usual C++ runtime libraries and cppinit module for the selected dialect version,
for C++
CCPLMAIN or ccplmain.o
The compiler does not automatically include more specialized libraries, such as those
for tools.h++, or the loader library (ZRLDDLL).
Guardian
CCOMP and CPPCOMP will run the linker when building a program, if you add the
RUNNABLE pragma to the command line. For example:
ccomp /in myprogc/ myprog; suppress,runnable,call_shared,symbols
These compiler drivers will also run the linker when building a DLL, if you use the
SHARED rather than the CALL_SHARED option. For example:
ccomp /in mylibc/ mylib;suppress,shared,symbols
This example compiles a program that uses that DLL:
ccomp /in myprog2c/ myprog2;suppress,runnable, &
call_shared,symbols,search "mylib"
The search pragma causes the “mylib” to be included in the linker command stream.
A more flexible way to add linker commands through the compiler command line is the
pragma LINKFILE. For example, suppose that you create an edit file named obeyrld
that contains one line:
-lib zrlddll
Then the following example will link a program that requires the dynamic loader library
(in addition to the usual libraries that are provided automatically):
ccomp /in mydynpc/ mydynp;suppress,runnable, &
call_shared,symbols,linkfile "obeyrld"
DLL Programmer’s Guide for TNS/E Systems—527252-006
5-10
Advanced DLL Facility Controls Naming Intermediate Linker Output Files
OSS
The c89 or c99 compiler will run the linker for each module it compiles, unless the -c
option is present. It is somewhat more flexible in allowing you to specify linker
commands to the compiler:
The -L and -l options are passed straight through, with their arguments.
Several other linker options are recognized in -W form; run c89 or c99 with no
command input to see a list.
The -Weld=args option passes args into the eld command stream. For example:
Automatic Messages
The linker reports on its operation using messages that appear in an output listing.
These are reported with a message identifier that indicates the message’s severity as
follows:
Message-Control Options
The appearance of these messages is controlled by the following options:
-verbose tells the linker to show all messages.
-warn tells the linker to show all fatal-error, error, and warning messages, plus
messages requested by command-stream options, as described in the next
subsection.
-no_verbose tells the linker to show all fatal error and error messages, plus
messages requested by command-stream options, as described in the next
subsection. -noverbose is a synonym for -no_verbose.
The default is -no_verbose, except on Guardian, where the default is -verbose.
If -verbose or -warn is in effect, then when a linking operation finishes, the linker
puts out a completion message that covers the entire process and indicates how many
of each type of message (error, warn, or information) were generated during the linking
process.
-map tells the linker to report the virtual addresses and sizes of the segments and the
sections, within each segment, of a loadfile being built. Further, the linker shows
the library and file names of all liblisted libraries. -m is a synonym for -map.
Load-Time Operation
To load a program and its DLLs, the system is commanded simply to load the program.
The loader automatically ensures that the program’s entire loadList is loaded and that
all symbols are resolved with proper bindings.
In either case, the loader’s search path that was defined at link time is augmented as
follows, where the paths identified at link-time were steps 2, 3, 6, and 7, as described
in The Link-Time-Defined Search Path of the Loader on page 2-17.
1. The directories or subvolumes specified at load time by
_RLD_FIRST_LIB_PATH.
2. The directories or subvolumes specified in -RLD_first_L options at link
time
3. The public libraries (DLLs)
4. The directory or subvolume that stores the program being loaded
5. The directories or subvolumes specified by _RLD_LIB_PATH at load time
6. The directories or subvolumes specified in -RLD_L options at link time
7. Following default locations:
32-bit process:
For OSS: /lib, /usr/lib, /usr/local/lib, and
/G/SYSTEM/ZDLL in the order of the paths specified here.
For Guardian: $SYSTEM.ZDLL
64-bit process:
For OSS: /lib64, /usr/lib64, /usr/local/lib64, /lib,
/usr/lib, /usr/local/lib, /G/SYSTEM/YDLL, and
/G/SYSTEM/ZDLL in the order of the paths specified here.
You can prevent the loader’s search path for your loadfile from deviating from what you
set up at link time, that is, restrict the loader’s search path to steps 2, 3, 6, and 7
above. You do this by having inserted the -limit_runtime_paths option in the
linker’s command stream; see The Link-Time-Defined Search Path of the Loader on
page 2-17.
Example One
This example shows the use of a main program, mainstrc, and a library called
mystrngc. Both will be compiled using ccomp, then linked using eld. mystrngc will be
loaded as a DLL.
char s[100];
/***********************************************************
| main: given a list of strings, print out them reversed
| argv[1]...argv[argc-1] point to strings
|
| if no string passed, put out usage message and quit.
| for each string
| reverse it
| display it
|
\***********************************************************/
int main(int argc, char *argv[]) {
char **ppStr;
int strLeft;
int outcome;
getchar( );
} /* of proc main */
char *pBegin;
char *pEnd;
char c;
strcpy(r, s);
pBegin = r;
pEnd = r + strlen(r);
while (--pEnd > pBegin )
{
c = *pBegin;
*pBegin++ = *pEnd;
*pEnd = c;
}
return (0);
} /* StrRev */
No errors reported.
No warnings reported.
1 informational message reported.
Elapsed Time: 00:00:01
No errors reported.
No warnings reported.
4 informational messages reported.
Elapsed Time: 00:00:02
Example Two
This example was created using TNS/R tools, thus uses ld instead of eld as the
linker. The use of the dynamic loader rld is the same on either TNS/R or TNS/E.
This session demonstrates dynamic loading. We create and compile a program and a
DLL, but don’t load the DLL with the program. We invoke the loader from inside the
process with a dlopen() call.
If you set breakpoints in Visual Inspect just before and after executing such calls, and
use the new TACL command LOADEDFILES, you can see the process in action.
/***********************************************************
| main:
|
\***********************************************************/
int main(int argc, char *argv[]) {
int result = 0;
union {
int resCode;
short err[2];
} res;
result = dlclose(dlopenHandle);
dlopenHandle = 0;
dlopenHandle = dlopen("NotThere",RTLD_NOW);
if (dlopenHandle == 0) {
res.resCode = dlresultcode( );
printf("dlopen of a non-existent dll returns result %i\n"
,res.resCode);
printf("\terror( %i,%i)\n"
,res.err[0], res.err[1]);
printf( "%s\n", dlerror( ) );
return (1);
}
return 0;
} /* of proc main */
LD reported 0 errors.
LD reported 0 warnings.
LD reported 16 informational messages.
Next, the main executable file is built. Note that the main program does not use -l to
refer to hellodll at link time.
ld maino -o mainexe -obey $SYSTEM.SYSTEM.libcobey -L $OSS.NSKAPAT4
$SYSTEM.SYSTEM.CCPPMAIN -l ZRLDSRL
LD (T0429G09 - 30APR2003)
(C)2003 Hewlett Packard Development Company, L.P.
LD reported 0 errors.
LD reported 0 warnings.
LD reported 14 informational messages.
We also ran the program under Visual Inspect and set breakpoints before and after the
call to Hellodll. In both those places we used a new TACL command LOADEDFILES to
see which files had been loaded at that point. The output from that VI and TACL
session is simple, but nevertheless demonstrates a useful capability in more complex
situations.
LOADEDFILES (and new option for STATUS that shows which process uses a
specified file) is fully documented in the TACL Reference Manual (for G06.20 and
later).
You can use the process name with LOADEDFILES, but can also refer to it by cpu,
number which we do in this TACL example.
status *,user,pri
Comment: This is after the first dlopen() ;note the appearance of the DLL.
Comment: This is after the first dlclose();note the disappearance of the DLL.
SRL \DLLQA.$SYSTEM.SYS00.ZCRTLSRL
SRL \DLLQA.$SYSTEM.SYS00.ZOSSKSRL
SRL \DLLQA.$SYSTEM.SYS00.ZOSSFSRL
SRL \DLLQA.$SYSTEM.SYS00.ZOSSESRL
Total No. of Loadedfiles = 13
-alf <filename>
Rebase or rebind an existing loadfile (or both), recreating the file.
-all
Use all members from archives.
-allow_duplicate_procs
Do not consider it an error if there are multiple definitions of procedures with the
same name.
-allow_missing_libs
Do not consider it an error if a -l option cannot be resolved, except in situations
where -b static is in effect. See Allowing Missing Libraries on page 2-12 .
-allow_multiple_mains
Do not consider it an error if more than one procedure has the MAIN attribute.
See Designating the Main Entry Point of Your Program on page 5-4.
-ansistreams
At runtime, the program will use the ANSI version of C I/O.
See Changing Run-Time Options for C and C++ Programs on page 5-15.
-call_shared
Create a program. See Choosing to Create a Program or a DLL on page 2-3.
-check_registry <filename>
Use the specified DLL registry to tell where the DLL being built must be placed in
memory.
-d <hexadecimal number>
Use the specified value as the starting address of the data (constant) segment.
See Specifying the Preferred Location of a Loadfile in Virtual Memory on page 5-8.
-data_resident
This is a special option that may be used when building a “proto-process”, also
known as a “sysgen process”.
-dll
This is a synonym for -shared.
-dllname
This is a synonym for -soname.
-e <symbol name>
Use the address of the specified procedure as the main entry point.
See Designating the Main Entry Point of Your Program on page 5-4.
-error_unresolved
This is a synonym for -unres_symbols error.
-export
This is a synonym for -exported_symbol.
-export_all
Export all symbols that you might normally want to have exported without naming
them explicitly. See Controlling Which Symbols Your Loadfile Exports on page 5-5.
-export_not
This is a synonym for -hidden_symbol.
-first_L <filename>
The specified directory or subvolume is one of the places where the linker will look
for DLLs and archives before it looks for public DLLs. See Where The Linker
Searches for Libraries and Archives on page 2-11.
-FL
This is a synonym for -obey.
-grow_percent <number>
Leave the specified percentage of slack space in virtual memory for each of the
text and data segments of this DLL.
-import_lib <filename>
Build a complete or incomplete import library with the specified filename in addition
to creating a new DLL.
-import_lib_stripped <filename>
Build a complete or incomplete import library with the specified filename in addition
to creating a new DLL, and strip the DWARF symbol table from the import library.
-include_whole
This is a synonym for -all.
-L <filename>
The specified directory or subvolume is one of the places where the linker will look
for DLLs and archives, after it looks for public DLLs. The “-L” must be specified in
uppercase. See Where The Linker Searches for Libraries and Archives on
page 2-11.
-l <filename>
Use the specified filename to locate a DLL or archive. The “-l” must be specified
in lowercase. See Libraries the Linker Searches For and Opens on page 2-10.
-lib
synonym for -l. This usage may be preferred because it is not case-sensitive and
therefore cannot be confused with -L.
-libname
This is a synonym for -set libname.
-libvol
This is a synonym for -L.
-limit_runtime_paths
If this is specified then rld will not permit the user to override the places specified
at link time for where DLLs may be found.
See The Link-Time-Defined Search Path of the Loader on page 2-17.
-local_libname <filename>
Use the specified filename as the name of the user library that can be used to
resolve references in this program at link time.
-m
This is a synonym for -map.
-make_implicit_lib
Mark the DLL being created as an implicit library.
-make_import_lib <filename>
Create a complete or incomplete import library with the specified filename, to
represent the other DLL or DLLs whose filenames are found in the command
stream.
-map
Produce a map showing how memory has been laid out. See Command Stream
Requests for Linker Messages on page 5-12.
-must_preset
Consider it an error if presetting fails.
-must_use_iname
eld reports an error if the linker is not able to delete an existing file of the same
name when creating an import library.
-must_use_oname
eld reports an error if the linker is not able to delete an existing file of the same
name when creating its main output object file.
-must_use_rname
eld reports an error if the linker is not able to delete an existing file of the same
name when it is recreating a private DLL registry.
-no_include_whole
This is a synonym for -none.
-none
Only include archive members in the link if they satisfy needed references.
-no_optional_lib
Do not consider later DLLs in the command stream to be optional.
-no_preset
Do not preset the loadfile being created.
-no_reexport
Do not re-export DLLs found after this point in the command stream.
-nostdfiles
At runtime, do not automatically open the standard C I/O files.
See Changing Run-Time Options for C and C++ Programs on page 5-15.
-no_stdfiles
This is a synonym for -nostdfiles.
-nostdlib
Do not look in the standard places for DLLs and archives. See Where The Linker
Searches for Libraries and Archives on page 2-11.
-no_stdlib
This is a synonym for -nostdlib.
-noverbose
This is a synonym for -no_verbose.
-no_verbose
Do not show warnings or informational messages unless they are requested by a
linker option. See Message-Control Options on page 5-12.
-o <filename>
Use this as the name of the output object file. See Choosing the Output File on
page 2-3.
-obey <filename>
Use the specified file as an obey file. See Direct Use of the Linker on page 2-1.
-optional_lib
Consider later DLLs in the command stream to be optional.
-public_registry <filename>
Use the specified file as the public DLL registry file.
-r
Create a linkfile rather than a loadfile.
-reexport
Re-export DLLs found after this point in the command stream. See How to Make
Your Loadfile Re-Export Symbols of Other DLLs on page 2-15.
-rld_first_L <path>
The string specified by <path> should be a list of directories or subvolumes
separated by colons. At runtime, the specified directories or subvolumes are
places where rld will look for DLLs before it looks for public DLLs. SeeThe Link-
Time-Defined Search Path of the Loader on page 2-17.
-rld_L <path>
The string specified by <path> should be a list of directories or subvolumes
separated by colons. At runtime, the specified directories or subvolumes are
places where rld will look for DLLs after it looks for public DLLs. See The Link-
Time-Defined Search Path of the Loader on page 2-17.
-rpath
This is a synonym for -rld_L.
-s
Omit the DWARF symbol table when creating the output file.
-shared
Create a DLL. See Choosing to Create a Program or a DLL on page 2-3 .
-show_multiple_defs
Put information into the listing about symbols that are defined in more than one of
the input linkfiles. See Command Stream Requests for Linker Messages on
page 5-12.
-soname <filename>
Specify the DLL name for the DLL being created. See Naming DLLs on page 2-3 .
-stdin
Use the standard input file as an obey file. See Direct Use of the Linker on
page 2-1.
-strip <filename>
Remove the DWARF symbol table from an existing loadfile or import library.
-t <hexadecimal number>
Use the specified value as the starting address of the text segment of the loadfile
being built. See Specifying the Preferred Location of a Loadfile in Virtual Memory
on page 5-8.
-temp_i <filename>
Use the specified filename as the name of the intermediate file during the creation
of an import library.
-temp_o <filename>
Use the specified filename as the name of the intermediate file during the creation
of the linker’s main output object file. See Naming Intermediate Linker Output Files
on page 5-11.
-temp_r <filename>
Use the specified filename as the name of the intermediate file during the
recreation of a DLL registry.
-u <symbol name>
Consider the specified symbol to be needed when deciding which files to take from
archives. See Availability of Linkfiles from Archives on page 2-8.
-ul
Create a user library. In effect, this option is a synonym for -shared plus
-export_all. See Controlling Which Symbols Your Loadfile Exports on
page 5-5.
-update_registry <filename>
Use the specified DLL registry to suggest where the DLL being built may be placed
in memory and update it with the location chosen.
-verbose
Show all messages. See Message-Control Options on page 5-12.
-warn
Show all error and warning messages. See Message-Control Options on
page 5-12.
-warning_unresolved
This is a synonym for -unres_symbols warn.
-x
Omit the DWARF symbol table when creating the output file.
-y <symbol name>
Provide information about how this symbol is mentioned in the ELF symbol tables of
the linker’s input files. See Command Stream Requests for Linker Messages on
page 5-12.
Big endian. This term describes a method of storing data so that the most significant byte
appears in a lower-numbered location in memory. As with TNS/R, TNS/E data
structure is big endian. Code on the TNS/E platform is always little endian.
Bundle. This term describes a three-instruction-wide 128-bit word used by Intel to facilitate
parallel processing of code instructions.
Code file. A file comprising instructions that can be executed or emulated by a computer.
Native code files can be either linkable (linkfiles) or loadable (loadfiles). Object files
and binaries are other names for code files.
Client (of a loadable library). A loadfile that uses functions or data from a library.
Default. The choice made when the user does not direct otherwise.
DLL file. This is a PIC library loadfile with symbols that can be referenced by another
loadfile to resolve symbolic references at link time and/or runtime. It is therefore a
loadfile that offers functions or data for use by other loadfiles. For TNS/E, DLLs replace
SRLs commonly associated with the TNS/R architecture. The object file linker eld
generates DLLs for TNS/E (as does ld for the TNS/R DLLs). In UNIX, this type of file
is known as a shared object file or dynamic shared object (DSO).
Dynamic loading. Loading and opening DLLs under programmatic control after the
program is loaded and execution has begun.
EDIT Line Number. The conventional source line numbering convention is where the
source lines are numbered sequentially using integers starting at 1. The Guardian
EDIT text file (file code "101") uses a source line number convention where the lines
are assigned numbers that have three places after the decimal point, and can be
sparse within all such possible numbers.
ELF. This term stands for "executable and link format" and describes an extensible file
structure that can deal with various target platforms. Like TNS/R, TNS/E uses the ELF
file structure with Tandem extensions. However TNS/E is ELF all-inclusive whereas
TNS/R uses both ELF and COFF file structures. All TNS/E compiler/assemblers,
linkers, and loaders generate object files with this file structure.
Explicit library. Any library that is named in the libList of any client loadifle or is a user
library of a client program.
Export. To provide a symbol definition for use by other loadfiles. A loadfile offers for export
a symbol definition for use by other loadfiles that need a data item or function
having that symbolic name.
Gateway. For every callable function there is a gateway; all calls to the function jump first to
the gateway, which effects the transition to privileged state if the caller is not
already privileged. There are two types of gateway pages, those that promote to
kernel and those that promote to executive level.
Globalized symbol. An exported symbol generated by the C++ compiler that may have
multiple definitions, of which the linker and loader must assure only one is used
throughout the process.
Hybrid file. This term describes a 'pseudo-DLL' that contains non-PIC text to allow a PIC
process to call (as inputs) when building or relinking a program or DLL file. Hybrids do
not exist in TNS/E.
Implicit library. A library supplied by HP that is available in the read-only and execute-only
globally mapped address space shared by all processes without being specified to the
linker or loader. The public libraries on TNS/E replace System Code, System Library,
and millicode. These libraries are called implicit because every loadfile is implicitly a
user of them. Contrast with public DLLs, which are explicit because a loadfile explicitly
asks to use a public DLL, although it does not specify where to find the public DLL.
See also System library. and Public Libraries.
Implicit library import library (imp-imp). An import library that can be used by the Linker
as a proxy for a set of implicit libraries. See Import library and Zimpimp file.
Import. To refer to a symbol definition from another loadfile. A loadfile imports a symbol
definition when it needs a data item or function having that symbolic name.
Import control. The characteristic of a loadfile that determines from which other loadfiles it
can import symbol definitions. The programmer sets a loadfile’s import control at link
time. That import control can be localized, globalized, or semiglobalized. A loadfile’s
import control governs the way the linker and loader construct that loadfile’s searchList
and affects the search only for symbols required by that loadfile.
Import library. This term describes one type of a loadfile whereby only enough parts of the
file are contained therein to allow the linker to resolve references, but not enough to
expose its source code; i.e., exports the symbols of the DLL . It is a file that can be
used by the Linker as a proxy for one or more DLLs, but that cannot actually be loaded
and run. It is useful in cross-linking. See Implicit library import library (imp-imp) and
Zimpimp file.
Indirect reference (of a loadfile). A library in a loadfile’s searchList that is not named in its
libList.
iniTerm Lists. Lists of initialization and termination functions used in the support of runtime
dynamically-loaded libraries on the HP NonStop operating system.
Instance. A particular case of a class of items, objects, or events. For example, a process is
defined as one instance of the execution of a program; multiple processes might
be executing the same program simultaneously. Also, instance data refers to global
data of a program or library; each process has its own instance of this data.
Library. Generically, a collection of functions and data offered for use by clients. Libraries
can exist as source files, linkable object files, archives (aggregated of linkfiles), and
loadable object files. See also Loadable Library..
LibList. The list of libraries to be loaded along with a loadfile. However, it may not be the
complete list of loadfiles that must be loaded; see loadList definition below.When
linking the loadfile, the linker constructs the libList from the names of libraries
specified in the linker's command stream; it stores the libList within the loadfile.
Libname. An attribute of a program loadfile, which can be set by the linker, specifying the
name of a user library to be loaded with this program.
Linker. A utility whose basic function is to process one or more linkfiles to create a loadfile.
Linker platform. The system on which the linker executes. Also called host or host
platform.
LIC. Library Import Characterization: A data string that characterizes the information used
by a linker or loader to bind the global symbols of a particular loadfile. If the same
loadfile is bound on two occasions, and its LIC has not changed, the two bindings are
the same. Thus it is possible to reuse a set of bindings if it has the same LIC as that
determined for this loadlfile in the presence of the other loadfiles with which it is being
loaded.
Linkfile. This term describes the output of the compiler and input to the linker. This object
file has accompanying tables required to build it into a PIC loadfile and can be all or
part of a loadfile. The code of a linkfile is not executable until linked. In the default
mode, the linker processes one or more linkfiles to produce a loadfile. This term is
synonymous with the term "relinkable" in TNS/R .
Loader. A programming utility that transfers a program into memory so it can run. The
mechanism that brings loadfiles into memory for execution, maps them into virtual
address space, and resolves symbol references among them. Synonyms include
run-time loader and run-time linker. The loader for TNS and for TNS/R native programs
and libraries that are not position-independent code (PIC) is part of the operating
system. For PIC loadfiles and all TNS/E native programs, the loader called rld works
with the operating system to load programs and libraries.
Loadfile. This term describes the input to the runtime loader and default output of the linker.
This object file may contain name references to symbols that exist in other loadfiles in
the same process. Such references are typically resolved when the loadfiles are
brought into memory by the runtime loader rld . This term is synonymous with the
term "executable" file. An executable object code file is one that is ready for loading
into memory and executing on the computer. Loadfiles are further classified as
executable programs (containing a main routine at which to begin execution of that
program) or executable libraries (supplying routines or variables to multiple programs
or separately loaded libraries). A TNS code file might be both a loadfile and a linkfile.
Native code files are never both. Contrast with Linkfile.
LoadList. A list of all the libraries that must be loaded for a given loadfile to execute. A
loadfile’s loadList includes all the libraries in the given loadfile’s libList plus all the
libraries in those loadfiles’ libLists, and so on. It does not include the implicit libraries.
The loadList order is the sequence in which these loadfiles are to be loaded when they
are not already loaded by a previous operation. The loadList of the program includes
all the loadfiles present in the process, in the order they were loaded.
Loadable Library. A loadfile that offers functions and data to other loadfiles. In this
document, DLLs are such libraries. A library cannot be invoked externally, for
example, by a RUN command; instead, it is invoked by calls or data references
from client loadfiles. In TNS/E, functions and data can also be obtained from the
system library and millicode.
Loader Library. A public library for loading PIC programs and libraries. It works in close
cooperation with the operating system. It is called "rld" when loading a program
and its libraries at process creation time. It also exports a set of functions for
dynamic loading.
MCB. The Master Control Block. This contains global information such as the product
version number, valid file types, language dialects and floating point types that may be
used.
Millicode library. Low-level library routines. Although separate from it, the millicode can be
considered an adjunct of the system library.
Neutral loadfile. This can be loaded with either a 32-bit or 64-bit program.
PIC. This term stands for 'position independent code' and describes a nomenclature
associated with DLLs whereby PIC text contains references do not have to be resolved
at link time. PIC is executable code that need not be modified to run at different virtual
addresses. External reference addresses appear only in a data area that can be
modified by the loader; they do not appear in PIC code. PIC code is even more
position independent than one might imagine from the term; it can be simultaneously
mapped to different addresses for different processes in the same CPU. PIC
introduces several new elements into ELF files, some of which are adapted from the
Intel LP64 ELF structure. TNS/E supports only PIC files. TNS/R supports PIC and non-
PIC file types.
Program. This term describes one type of loadfile that is capable of being run on the
system. This is the main program and there can only be one program associated with a
process.
Public Libraries. A set of libraries (offering widely-used functions) that are managed as part
of the system, available to all users of the system, and in large part supplied by HP,
although it is possible for customers and third parties to provide DLLs to be added to
the public DLLs. A loadfile must explicitly reference a public library in order to access it.
Preempt. When the linker’s binding of a symbolic reference to a symbol defined in the
same DLL is rebound by the loader to a definition in another loadfile.
Re-exported library. A library whose symbols are made available by another DLL to any
localized client of that DLL. Re-export is an attribute of the DLL's libList entry for
that library. This attribute is specified by the DLL's programmer and recorded by
the linker as a DLL is built. It affects only localized clients of the DLL. This feature
allows a symbol to be moved from one DLL to another without relinking clients of
the original DLL.
Re-exporting is transitive; i.e., if A re-exports B and B re-exports C, then A re-
exports C. Thus, re-exported libraries can re-export other libraries to form a
succession of re-exported libraries of arbitrary length.
Region. The Itanium® architecture divides the address space into eight regions, indexed
by the high-order three bits of the 64-bit address. TNS/E initially implements just two,
regions 0 and 7: region 0 is mapped per-process; region 7 is shared by all processes.
Sign extension places “negative” 32-bit addresses in region 7. Note that the high bit of
the 32-bit address on TNS/E determines global addressing, and privilege is an attribute
of the page; the MIPS architecture on TNS/R is just the opposite.
Relocation. the process of assigning load addresses to the different parts of a program,
adjusting the code and data in the program to reflect the assigned addresses.
SearchList. For each loadfile, a list that specifies which libraries to examine, and in which
order, to locate symbol definitions needed by that loadfile. The linker and loader
construct the loadfile's searchList in accordance with that loadfile's import control,
which is set at link time. The system library and millicode are appended to every
Sections and Segments. The TNS/E object file is organized into contiguous items called
sections. There is an array of ELF section headers that contains the type and name of
each of these section items. A section is not required to be present if it would not
contain any useful information for a given object file. In loadfiles, some of the sections
are further organized in segments that get loaded into virtual memory.
Strip(ped) file. These are files do not have debugging information; i.e., DWARF symbol
table, in it. Stripping can be done on any object file. It is still possible for the linker to
process a linkfile that has been stripped because the DWARF symbol table does not
contain any essential information to it. An import library can be stripped even if the
corresponding DLL is not stripped.
Symbol Resolution. When a program is built from multiple subprograms, the references
from one subprogram to another are made using symbols. For example a main
program might use a square root routine called sqrt and the math library defines
sqrt. A linker resolves the symbol by noting the location assigned to sqrt in the
math library and patches the caller’s object code so the call instruction refers to that
location.
Semi-globalized. An import control characteristic of a loadfile that allows the loadfile first to
obtain symbols from its own definitions and then to obtain others as for a
globalized loadfile. Thus, a semi-globalized loadfile cannot have its symbol
references to itself preempted. See also SearchList..
Symbol. The symbolic name of a function or data item. Symbols are defined in loadfiles
and referenced in the same or other loadfiles.
System library. TNS/E library routines required to access TNS/E operating system
functions. (Similar for TNS/R.) The loader automatically searches the system
library for definitions that satisfy a loadfile’s unresolved symbols after searching all
the loadfiles in the loadfile’s searchList.
TNS/E. The hardware platform based on the Itanium™ architecture and the HP NonStop
operating system and software that are specific to that platform. All code is PIC.
TNS/R. The hardware platform based on the MIPS™ architecture and the HP NonStop
operating system and software that are specific to that platform. Code may be PIC
or non-PIC.
TLB. Translation Lookaside Buffer: a cache of page table entries, where each entry
designates the physical memory page corresponding to a range of virtual addresses.
Information within the entry can make the translation unique to the accessing process.
Unless the appropriate TLB entry is present, the page cannot be accessed; typically
the processor generates a fault to allow software to find and load the missing entry
from a memory-management structure.
TNS/E object file format. This object file format is an amalgam of Intel IA-64 code
architecture and the HP NonStop operating system extensions.
TNS/E object files are categorized into three types of files: linkfiles, loadfiles, and
import libraries. The following are key differences between TNS/R and TNS/E
platforms:
Platform TNS/R TNS/E
Processor MIPS RISC Itanium
Architecture SGI Intel IA-64
Programming 32-bit (ILP32) 32-bit (ILP32)
model
and in future:
64-bit LP64
Object type ELF and COFF ELF exclusive
Debugging Third-Eye DWARF2
symbols
Compiler SGI w/ HP Intel w/ HP
Backend extensions extensions
Linker, PIC ld eld
User library. A loadable library; primarily a legacy feature for NonStop systems. For PIC
programs, a user library is a DLL treated as if it were the first library in the program's
libList and therefore is searched first for symbols required by the program. However, a
user library does not appear in the program's libList; instead, its name is recorded in
the program's loadfile as the libname attribute. A program can be associated with at
most one user library; the association can be specified using the linker at link time or in
a later change command, or at run time using the process creation interfaces. (The
/LIB.../ option to the RUN command in TACL uses these interfaces.)
VHPT. Virtual Hash Page Table: an Itanium® architecture feature that can supply missing
TLB entries without generating faults.
VPROC. The version procedure identifier used to identify which version of the product you
are using.
what was previously called the system library. See also Implicit library import library
(imp-imp).
Zreg file. This is the name of the public DLL registry file, which lists the names of all the
public DLLs.
H LibList Glossary-3
libList 1-7, 2-9
handle 3-2 order of libraries listed 2-9
invalidate 3-7 libListed libraries 2-9
main program 3-5 Libname Glossary-3
open 3-5 Library Glossary-3
highpin 5-7 library 1-1
highrequestors 5-7 inputs to a link 2-9
Hybrid file Glossary-2 missing 2-12
library names, where to insert 2-9
I library-name augmentation 5-2
implicit libraries 4-13 LIC Glossary-3
Implicit library Glossary-2 link 1-6
Implicit library import library (imp- Linker Glossary-3
imp) Glossary-2 linker 1-6, 2-2
Import Glossary-2 command stream 1-7
Import control Glossary-2 common search path for different
import control 1-11 platforms 2-12
default 1-12 completion message 5-12
Import library Glossary-2 controls 1-7, 2-1, 5-1
import symbol 1-2 defaults list 2-22
include <dlfcn.h> 3-2 distinguishes among files that it
include-file for dynamic loading 3-2 opens 2-10
indirect reference error. See error, linker
depth of 1-9 invoking 2-1
Indirect reference (of a loadfile) Glossary-3 messages 5-11
indirectly referenced library 1-8 message-control options 5-12
infrequently used DLL 3-1 option 2-1, 5-1
insert 2-2 option paramenter 2-2
inspect 5-7 options 2-1
Instance Glossary-3
options list, see Appendix A
intercept DLL, see DLL
order of processing libraries 2-9
intercepting an exported symbol 4-13
platform 2-1
intermediate file naming 5-11
search for libraries 2-10
intrnal name of a DLL 2-3
invalidate handle 3-7 search path 2-11
invoking the linker 2-1 token 2-1
I/O files, see C/C++ I/O files Linker platform Glossary-3
Linkfile Glossary-3
L
ld, see linker
DLL Programmer’s Guide for TNS/E Systems—527252-006
Index-3
Index M
V
VHPT Glossary-7
VPROC Glossary-7
W
warning of ambiguity, see ambiguity
warning
where the linker searches for files
See linker, search path
where to insert library names 2-9
X
xport bit in external symbol table 2-13
Z
Zimpimp file Glossary-7
Zreg file 1-10, Glossary-8
Special Characters