Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial
Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under
vendor's standard commercial license. The information contained herein is subject to change without notice. The only warranties for HP products
and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as
constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein. UNIX is a registered
trademark of The Open Group.
Itanium® is a trademark of Intel Corporation in the U.S. and other countries.
Contents
About This Document...................................................................................13
This document discusses the most recent product information on HP-UX Linker and Libraries Version
B.11.72 for HP 9000 systems and Version B.12.57 for Integrity systems that are running HP-UX
11i v1, HP-UX 11i v2, and HP-UX 11i v3.
Intended Audience
This document is intended for developers who want to compile, link, and build applications using
the HP C/ANSI C Developer's Bundle on HP 9000 or HP Integrity systems.
Document conventions and symbols
Table 1 (page 13) lists the conventions and symbols used in this white paper.
Table 1 Document conventions
ElementConvention
Cross-reference links and email addressesMedium blue text:
Website addressesMedium blue, underlined text
(http://www.hp.com)
Bold font
Monospace font
Monospace, italic font
Monospace, bold font
• Key names
• Text typed into a GUI element, such as into a box
• GUI elements that are clicked or selected, such as menu and list items,
buttons, and check boxes
Text emphasisItalic font
• File and directory names
• System output
• Code
• Text typed at the command line
• Code variables
• Command-line variables
Emphasis of file and directory names, system output, code, and text typed
at the command line
CAUTION:Indicates that failure to follow directions can result in damage to equipment or data.
IMPORTANT:Provides clarifying information or specific instructions.
NOTE:Provides additional information.
Related Information
The following documents provide more information:
•HP-UX Linker, Libraries, and Tools Versions B.11.72 and B.12.57 Release Notes
•Improving program startup with fastbind: White paper
The HP-UX Linker web page is at:
http://www.hp.com/go/linker
Intended Audience13
HP Encourages Your Comments
HP encourages your comments concerning this document. We are committed to providing
documentation that meets your needs. Send any errors found, suggestions for improvement, or
compliments to:
feedback@fc.hp.com
Include the document title, manufacturing part number, and any comment, error found, or suggestion
for improvement you have concerning this document.
Document Organization
This guide is organized into the following chapters:
This document is organized as follows:
•“Compiling and Linking Programs on HP-UX” (page 16)
This chapter describes the process of compiling and linking programs on HP-UX. An example
is used to illustrate the process. The sections here describe the process of creating an executable
file and explain how ld creates an executable file from one or more object files. This chapter
also describes the conventions for using libraries with ld, describes the process of loading
and binding programs at run time, and explains the thread-safe features of linker. In addition,
it explains the means by which you can control how the linker links your programs or libraries.
•“Determining How to Link Programs or Libraries (Linker Tasks)” (page 27)
This chapter describes the tasks you can perform using the Compiler commands and Linker
commands. The tasks help you determine how the linker must link your program or library.
•“Linker Tools for Itanium-Based Systems” (page 53)
This chapter describes the linker toolset available for IA systems. The linker toolset provides
several tools to help you find symbols, display and modify object files, and determine link
order.
•“Linker Tools for PA-RISC Systems” (page 69)
This chapter describes the linker toolset available for PA-RISC systems. The linker toolset
provides several tools to help you find symbols, display and modify object files, and determine
link order.
•“Linker Toolset Differences Between PA-RISC and Itanium-Based Systems” (page 79)
This chapter describes some of the linker toolset differences between PA-RISC and Itanium-based
systems. This chapter also describes linker options specific to PA64 mode, symbols reserved
by linker, system library location, changes to the library name extension, and dynamic path
searching for shared libraries.
•“Creating and Using Libraries” (page 89)
This chapter provides an overview of shared and archived libraries, explains creating and
using libraries on HP-UX, and describes how to use shared libraries for programs in IA.
•“Shared Library Management Routines” (page 136)
This chapter explains shared library header files, initializers for shared libraries, and the
various shared library management routines.
14
•“Writing and Generating Position-Independent Code” (page 185)
This chapter is applicable to only PA-RISC 32-bit applications. The chapter explains relocatable
object code, absolute object code, and position-independent code. The chapter also explains
how to generate position-independent code.
•“Using Mapfiles” (page 191)
This chapter explains how to use mapfiles. The mapfile option, which is an advanced feature
of the linker toolset, is intended for use in system programming.
•“Improving Your Application Performance” (page 202)
This chapter explains how you can use linker to improve the performance of your applications.
This chapter discusses options to improve TLB hit rates, incremental linking, profile-based
optimization, and other ways to improve application performance.
•Glossary
The glossary provides definitions of terms listed alphabetically.
Document Organization15
1 Compiling and Linking Programs on HP-UX
This chapter describes the process of compiling and linking a program.
DescriptionSection
Provides an overview of compiling on HP-UX.“Compiling Programs on HP-UX: An Example”
(page 16)
Describes how ld creates an executable file from one or more object.“Linking Programs on HP-UX” (page 21)
Describes conventions for using libraries with ld.“Linking with Libraries” (page 23)
Describes the process of loading and binding programs at run time.“Running the Program” (page 25)
Describes the thread-safe features.“Linker Thread-Safe Features” (page 26)
Compiling Programs on HP-UX: An Example
This chapter addresses the following:
•“Overview” (page 16)
•“Looking Inside a Compiler” (page 18)
•“Compiler-Linker Interaction” (page 19)
Overview
To create an executable program, you compile a source file containing a main program. For
example, to compile an ANSI C program named sumnum.c, shown below, use this command
(-Aa says to compile in ANSI mode):
$ cc -Aa sumnum.c
The compiler displays status, warning, and error messages to standard error output (stderr). If
no errors occur, the compiler creates an executable file named a.out in the current working
directory. If your PATH environment variable includes the current working directory, you can run
a.out as follows:
$ a.out
Enter a number: 4
Sum 1 to 4: 10
The process is essentially the same for all HP-UX compilers. For instance, to compile and run a
similar FORTRAN program named sumnum.f:
$ f90 sumnum.f
//Compile and link sumnum.f.
... //The compiler displays any messages here.
$ a.out
//Run the program.
...
//Output from the program is displayed here.
Program source can also be divided among separate files. For example, sumnum.c could be
divided into two files: main.c, containing the main program, and func.c, containing the function
sum_n. The command for compiling the two together is:
$ cc -Aa main.c func.c
main.c:
func.c:
16Compiling and Linking Programs on HP-UX
Notice that cc displays the name of each source file it compiles. This way, if errors occur, you
know where they occur. Also, the diagnostics mention the name of the source file.
#include <stdio.h>
/* contains standard I/O defs */
int sum_n( int n )
/* sum numbers from n to 1 */
{
int sum = 0;
/* running total; initially 0 */
for (; n >= 1; --n)
/* sum from n to 1 */
sum += n;
/* add n to sum */
return sum;
/* return the value of sum */
}
int main()
/* begin main program
*/
{
int n;
/* number to input from user */
printf("Enter a number: ");
/* prompt for number */
scanf("%d", &n);
/* read the number into n */
printf("Sum 1 to %d: %d\\n", n, sum_n(n)); /* display the sum */
}
Generally speaking, the compiler reads one or more source files, one of which optionally contains
a main program, and outputs an executable named a.out by default unless a name is specified,
as shown in Figure 1.
Compiling Programs on HP-UX: An Example17
Figure 1 High-level View of the Compiler
Looking Inside a Compiler
On the surface, it appears as though an HP-UX compiler generates an a.out file by itself. Actually,
an HP-UX compiler is a driver that calls other commands to create the a.out file. The driver
performs different tasks (or phases) for different languages, but two phases are common to all
languages:
1.For each source file, the driver calls the language compiler to create an object file. (See also
“What is an Object File?” (page 18))
2.The HP-UX linker (ld) links the specified object files to create either a reusable object file, also
called a shared library, or an executable, which is named a.out by default unless a name
is specified. (See also “Compiler-Linker Interaction” (page 19).)
Figure 2 summarizes how a compiler driver works.
Figure 2 Looking Inside a Compiler
The C, aC++, and Fortran90 compilers provide the -v (verbose) option to display the phases a
compiler is performing.
What is an Object File?
An object file is basically a file containing machine language instructions and data in a form that
the linker can use to create an executable program. Each routine or data item defined in an object
file has a corresponding symbol name by which it is referenced. A symbol generated for a routine
18Compiling and Linking Programs on HP-UX
or data definition can be either a local definition or global definition. Any reference to a symbol
outside the object file is known as an external reference.
To keep track of where all the symbols and external references occur, an object file has a symbol
table. The linker uses the symbol tables of all input object files to match external references to
global definitions.
Local Definitions
A local definition is a definition of a routine or data that is accessible only within the object file in
which it is defined. Such a definition cannot be accessed from another object file. Local definitions
are used primarily by debuggers, such as adb. More important for this discussion are the global
definitions and external references.
Global Definitions
A global definition is a definition of a procedure, function, or data item that can be accessed by
code in another object file. For example, the C compiler generates global definitions for all variable
and function definitions that are not static. The FORTRAN compiler generates global definitions
for subroutines and common blocks. In Pascal, global definitions are generated for external
procedures, external variables, and global data areas for each module.
External References
An external reference is an attempt by code in one object file to access a global definition in
another object file. A compiler cannot resolve external references because it works on only one
source file at a time. Therefore, the compiler simply places external references in an object file's
symbol table; the matching of external references to global definitions is left to the linker or loader.
Compiler-Linker Interaction
As described in “Looking Inside a Compiler” (page 18), the compilers automatically call the linker
to create an executable file. To see how the compilers call ld, run the compiler with the -v (verbose)
option.
For example, compiling a C program to produce an IPF 32-bit share-bound application, produces
the output below:
$ cc -v main.c func.c -lm
main.c:
/opt/ansic/lbin/ecom -ia64abi all -architecture 32 -ext on -lang c \
-exception off -sysdir /usr/include - inline_power 1 -link_type dynamic \
-fpeval float - tls_dyn on -target_os 11.23 --sys_include /usr/include \
This example shows that the cc driver calls the actual C compiler (/opt/ansic/lbin/ecom)
for each source file. Then the driver calls the linker (/usr/ccs/bin/ld) on the object files
created by the compiler (main.o and func.o).
The next-to-last line in the above example is the command line that the compiler used to invoke the
linker, /usr/ccs/bin/ld. When building a share-bound executable, the startup functions are
handled by the dynamic loader dld. By default, the dynamic loader is found in /usr/lib/hpux32.
Thus, in most cases, the ld command does not include crtO.o. In the ld command line, ld
combines the two object files created by the compiler (main.o and func.o). It also searches the
libm (-lm) and libc (-lc) libraries.
On PA-RISC systems, the same compile command invokes the PA32 linker. The output is shown
below.
$ cc -Aa -v main.c func.c -lm
cc: CCOPTS is not set.
main.c:
/opt/langtools/lbin/cpp.ansi main.c /var/tmp/ctmAAAa10102 \
-D__unix -D_PA_RISC1_1
cc: Entering Preprocessor.
/opt/ansic/lbin/ccom /var/tmp/ctmAAAa10102 func.o -O0 -Aa
cc: LPATH is /usr/lib/pa1.1:/usr/lib:/opt/langtools/lib:
/usr/ccs/bin/ld /opt/langtools/lib/crt0.o -u main main.o func.o -lm -lc
cc: Entering Link editor.
The next-to-last line in the above example is the command line the compiler used to invoke the
PA32 mode linker, /usr/ccs/bin/ld. In this command, ld combines a startup file (crt0.o)
and the two object files created by the compiler (main.o and func.o) Also, ld searches the
libm and libc libraries.
For PA64 and IPF executables, the startup functions are handled by the dynamic loader. In most
cases, the ld command line does not include crt0.o.
20Compiling and Linking Programs on HP-UX
Linking Programs on HP-UX
•“The crt0.o Startup File” (page 21)
•“The a.out File” (page 22)
•“Magic Numbers (PA-RISC ONLY)” (page 22)
•“File Permissions” (page 23)
The HP-UX linker (ld) creates an executable file, shared library, or combines the object files to
create another relocatable object file. In doing so, it matches external references to global definitions
contained in other object files or libraries. It revises code and data to reflect new addresses. This
process is known as relocation. If the input files contain debugger information, ld updates this
information appropriately. The linker places the resulting executable code in a file named, by
default, a.out.
In the C program example, (see “Compiling Programs on HP-UX: An Example” (page 16) ) main.o
contains an external reference to sum_n, which has a global definition in func.o.
The linker (ld) matches the external reference to the global definition, allowing the main program
code in a.out to access sum_n (see Figure 3 (page 21)).
Figure 3 Matching the External Reference to sum_n
If the linker (ld) cannot match an external reference to a global definition, it displays a message
to standard error output. If, for instance, you compile main.c without func.c, the linker (ld)
cannot match the external reference to sum_n and displays this output:
$ cc -Aa main.c
ld: Unsatisfied symbol "func1" in file main.o
1 errors.
The crt0.o Startup File
Notice that in the PA32 example in “Compiler-Linker Interaction” (page 19) the first object file on
the linker command line is /opt/langtools/lib/crt0.o, even though this file was not specified
on the compiler command line. This file, known as a startup file, contains the program's entrypoint. The program's entry point is is the location at which the program starts running after HP-UX
loads it into memory to begin execution. The startup code does such things as retrieving command
line arguments into the program at run time, and activating the dynamic loader to load any required
shared libraries. In the C language, it also calls the routine _start in libc which, in turn, calls
the main program as a function.
Linking Programs on HP-UX21
The linker uses four startup files:
•32-bit PA is /opt/langtools/lib/crt0.o
•64-bit PA is /opt/langtools/lib/pa_64/crt0.o
The linker uses this startup file when it is in compatibility mode (+compat) or it is in default
standard mode (+std) with the -noshared option.
•32-bit IPF is /opt/langtools/lib/hpux32/crt0.o
The linker uses this startup file when it is in default standard mode (+std) with the -noshared
option.
•64-bit IPF is /opt/langtools/lib/hpux64/crt0.o
The linker uses this startup file when it is in default standard mode (+std) with the -noshared
option.
If the -p profiling option is specified on the compile line, the compilers link with -L
/usr/ccs/lib/libp -lprof. If the-G profiling option is specified, the compilers link with
/usr/ccs/lib/lip -lgprof.
PA-RISC ONLY:
If the linker option -I is specified to create an executable file with profile-based optimization, in
32-bit mode icrt0.o is used, and in 64-bit mode the linker inserts
/usr/ccs/lib/pa20_64/fdp_init.o. If the linker options -I and -b are specified to create
a shared library with profile-based optimization, in 32-bit mode scrt0.o is used, and in 64-bit
mode, the linker inserts /usr/ccs/lib/pa20_64/fdp_init-sl.o. In 64-bit mode, the linker
uses the single 64-bit crt0.o to support these options.
For details on startup files, see crt0(3).
The Program's Entry Point
For archive-bound (using the -complete compiler option or the -noshared linker option)
executables, the entry point is the location at which execution begins in the a.out file. The entry
point is defined by the symbol $START$ in crt0.o. In share-bound executables, the entry point
is defined by the symbol $START$ in the dynamic loader (dld.so).
The a.out File
The information contained in the resulting a.out file depends on which architecture the file was
created on and what options were used to link the program. In any case, an executable a.out
file contains information that HP-UX needs when loading and running the file. For example: Is it a
shared executable? Does it reference shared libraries? Is it demand-loadable? Where do the text
(code), data, and bss (uninitialized data) segments reside in the file? For details on the format of
this file, see a.out(4).
Magic Numbers (PA-RISC ONLY)
In 32-bit mode, the linker records a magic number with each executable program that determines
how the program should be loaded. There are three possible values for an executable file's magic
number:
SHARE_MAGICThe program's text (code) can be shared by processes; its data cannot be
shared. The first process to run the program loads the entire program into virtual
memory. If the program is already loaded by another process, then a process
shares the program text with the other process.
DEMAND_MAGICAs with SHARE_MAGIC the program's text is shareable but its data is not.
However, the program's text is loaded only as needed - that is, only as the
pages are accessed. This improves process startup time since the entire
22Compiling and Linking Programs on HP-UX
program does not need to be loaded; however, it can degrade performance
throughout execution.
EXEC_MAGICNeither the program's text nor data is shareable. In other words, the program is
an unshared executable. Usually, it is not desirable to create such unshared
executables because they place greater demands on memory resources.
By default, the linker creates executables whose magic number is SHARE_MAGIC. Table 2 (page
23) shows which linker option to use to specifically set the magic number.
Table 2 32-bit Mode Magic Number Linker Options
Use the optionTo set the magic number to
-nSHARE_MAGIC
-qDEMAND_MAGIC
-NEXEC_MAGIC
An executable file's magic number can also be changed using the chatr command (see “Changing
a Program's Attributes with chatr(1)” (page 53) ). However, chatr can only toggle between
SHARE_MAGIC and DEMAND_MAGIC; it cannot be used to change from or to EXEC_MAGIC. This
is because the file format of SHARE_MAGIC and DEMAND_MAGIC is exactly the same, while
EXEC_MAGIC files have a different format. For details on magic numbers, refer to magic(4).
In 64-bit mode, the linker sets the magic number to the predefined type for ELF object files
(\177ELF). The value of the e_type field in the ELF object file header specifies how the file should
be loaded.
File Permissions
If linker errors do not occur, the linker gives the a.out file read/write/execute permissions to all
users (owner, group, and other). If errors occur, the linker gives read/write permissions to all users.
Permissions are further modified if the umask is set (see umask(1)). For example, on a system with
umask set to 022, a successful link produces an a.out file with read/write/execute permissions
for the owner, and read/execute permissions for group and others:
$ umask
022
$ ls -l a.out
-rwxr-xr-x
1 michael
users
74440 Apr
4 14:38 a.out
Linking with Libraries
•“Library Naming Conventions” (page 24)
•“Default Libraries” (page 24)
•“Link Order” (page 24)
In addition to matching external references to global definitions in object files, the linker (ld)
matches external references to global definitions in libraries. A library is a file containing object
code for subroutines and data that can be used by other programs. For example, the standard C
library, libc, contains object code for functions that can be used by C, C++, FORTRAN, and
Pascal programs to do input, output, and other standard operations.
Linking with Libraries23
Library Naming Conventions
By convention, library names have the form:
libname. suffix
nameis a string of one or more characters that identifies the library.
suffixis .a if the library is an archive library, .sl if the library is a PA-RISC shared library,
or .so if the library is a shared library. (The suffix can be .sl for an IPF shared library.
This naming convention is not recommended, but it is supported for backwards
compatibility with PA-32 and PA-64.)
Typically, library names are referred to without the suffix. For instance, the standard C library is
referred to as libc.
Default Libraries
A compiler driver automatically specifies certain default libraries when it invokes ld. For example,
cc automatically links in the standard library libc, as shown by the -lc option to ld in this example:
Following are the default search paths for the libraries:
•On Itanium systems, ld searches for libraries in the directory /usr/lib/hpux32 for 32-bit
executables and /usr/lib/hpux64 for 64-bit executables.
•On PA-RISC systems, ld searches for libraries in the directory /usr/lib/ for 32-bit
executables and /usr/lib/pa20_64/ for 64-bit executables.
If the -p or -G compiler profiling option is specified on the command line, the compiler directs the
linker to also search:
/usr/lib/libp (for PA32)
/usr/lib/pa20__64/libp (for PA64)
/usr/lib/hpux32/libp (for IPF 32-bit)
/usr/lib/hpux64/libp (for IPF 64-bit)
The default order can be overridden with the LPATH environment variable, the -L linker option,
specifies $ORIGIN in the library path, or the +origin option. These are described in Changing
the“Changing the Default Library Search Path with -L, LPATH, and $ORIGIN” (page 30) .
Link Order
The linker searches libraries in the order in which they are specified on the command line - the
link order. Link order is important in that a library containing an external reference to another
library must precede the library containing the definition. This is why libc is typically the last
24Compiling and Linking Programs on HP-UX
library specified on the linker command line: because the other libraries preceding it in the link
order often contain references to libc routines and so must precede it.
NOTE:If multiple definitions of a symbol occur in the specified libraries, ld does not necessarily
choose the first definition. It depends on whether the program is linked with archive libraries,
shared libraries, or a combination of both. Depending on link order to resolve such library definition
conflicts is risky because it relies on undocumented linker behavior that may change in future
releases. (See also “Caution When Mixing Shared and Archive Libraries” (page 118).)
Running the Program
•“Loading Programs: exec” (page 25)
•“Binding Routines to a Program” (page 25)
•“Deferred Binding is the Default” (page 25)
An executable file is created after the program has been compiled and linked. The next step is to
run or load the program.
Loading Programs: exec
When you run an executable file created by ld, the program is loaded into memory by the HP-UX
program loader, exec. This routine is actually a system call and can be called by other programs
to load a new program into the current process space. The exec function performs many tasks;
some of the more important ones are:
•Determining how to load the executable file by looking at its magic number. (See also“The
a.out File” (page 22).)
•Determining where to begin execution of the program - that is, the entry point - For examples
in share-bound executables in dld.so, in archive-bound executables in crt0.o. (See also
“The crt0.o Startup File” (page 21).)
•When the program uses shared libraries, the crt0.o startup code invokes the dynamic loader,
which in turn attaches any required shared libraries. If immediate binding was specified at
link time, then the libraries are bound immediately. If deferred binding was specified, then
libraries are bound as they are referenced. (See also “What are Shared Libraries?” (page
91).)
For details on exec, see the exec(2) page in the HP-UX Reference.
Binding Routines to a Program
Since shared library routines and data are not actually contained in the a.out file, the dynamic
loader must attach the routines and data to the program at run time. Attaching a shared library
entails mapping the shared library code and data into the process's address space, relocating
any pointers in the shared library data that depend on actual virtual addresses, allocating the bsssegment, and binding routines and data in the shared library to the program.
The dynamic loader binds only those symbols that are reachable during the execution of the
program. This is similar to how archive libraries are treated by the linker; namely, ld pulls in an
object file from an archive library only if the object file is needed for program execution.
Deferred Binding is the Default
To accelerate program startup time, routines in a shared library are not bound until referenced.
(Data items are always bound at program startup.) This deferred binding of shared library routines
distributes the overhead of binding across the execution time of the program and is especially
expedient for programs that contain many references that are not likely to be executed. In essence,
deferred binding is similar to demand-loading.
Running the Program25
Linker Thread-Safe Features
The dynamic loader (dld) and its application interface library (libdl) are thread-safe.
Also, the linker toolset provides thread local storage support in:
•ld - the link editor
•crt0.o - the program startup file
Thread local storage (also called thread-specific data) is data specific to a thread. Each thread
has its own copy of the data item.
NOTE:Use of the __thread keyword in a shared library prevents that shared library from being
dynamically loaded, that is, loaded by an explicit call to shl_load().
For More Information:
•See your HP compiler documentation to learn how to create thread local storage data items
with the _thread compiler directive.
•See Programming with Threads on HP-UX for information on threads.
Shared library loading and unloading in multi-threaded applications
The dynamic loader serializes all calls to dlopen, dlclose, shl_load, and shl_unload using
a pthread mutex lock. A thread executing dlopen holds this lock, and another thread that wants
to execute dlclose (for example), even on a different shared library, must wait for the dlopen
in the first thread to release the lock after it is done.
Developers, who use these routines in multi-threaded applications (or shared libraries) and also
use mutex locks for synchronizing threads should take note of this behavior to avoid deadlock
situations. One example of such a situation is when a shared library initializer creates a new thread
that calls dlopen - this would invariably lead to a deadlock in a multi-threaded application. A
less trivial example could be as follows. Suppose thread A of an application calls dlopen to load
a shared library, libA. Now this shared library has an initializer initA that wants to obtain a
mutex lock M. But M is currently held by thread B of the application. Further, thread B wants to
load another library, libB and then release the mutex lock M. Now thread B would call either
dlopen or shl_load, either of which waits for the dld mutex lock to be released by the dlopen
called by thread A. In turn, thread A waits for mutex lock M to be released before it can finish
dlopen and release the dld mutex lock. This results in a deadlock.
26Compiling and Linking Programs on HP-UX
2 Determining How to Link Programs or Libraries (Linker
Tasks)
You have a great deal of control over how the linker links your program or library by using ld
command-line options. This chapter describes the tasks you can perform to determine how programs
and libraries must link by using the Compiler commands and Linker commands.
•“Using the Compiler to Link” (page 28)
“Changing the Default Library Search Path with -Wl, -L” (page 28)◦
◦“Getting Verbose Output with -v” (page 29)
◦“Passing Linker Options from the Compiler Command with -Wl” (page 29)
◦“Renaming the Output File with -o” (page 29)
◦“Specifying Libraries with -l” (page 29)
◦“Suppressing the Link-Edit Phase with -c” (page 30)
•“Using Linker Commands” (page 30)
“Linking with the crt0.o Startup File” (page 30)◦
◦“Changing the Default Library Search Path with -L, LPATH, and $ORIGIN” (page 30)
◦“Using $ORIGIN” (page 31)
◦“Changing the Default Shared Library Binding with -B” (page 32)
◦“Improving Shared Library Performance with -B symbolic” (page 34)
◦“Choosing Archive or Shared Libraries with -a” (page 36)
◦“Linking Shared Libraries with -dynamic” (page 36)
◦“Linking Archived Libraries with -noshared” (page 37)
◦“Exporting Symbols with +e” (page 37)
◦“Exporting Symbols with +ee” (page 38)
◦“Exporting Symbols from main with -E” (page 38)
◦“Hiding Symbols from Export with +hideallsymbols” (page 39)
◦“Hiding Symbols with -h” (page 39)
◦“ Not Recording Link Time Paths with +nodefaultrapth” (page 41)
◦“Moving Libraries after Linking with +b” (page 41)
◦“Moving Libraries After Linking with +s and SHLIB_PATH” (page 43)
◦“Ignoring Dynamic Path Environment Variables with +noenvvar” (page 43)
◦“Controlling Archive Library Loading with +[no]forceload” (page 44)
◦“Passing Linker Options in a file with -c” (page 44)
◦“Passing Linker Options with LDOPTS” (page 44)
27
◦“Specifying Libraries with -l and -l:” (page 45)
◦“Flagging Unsatisfied Symbols with +[no]allowunsats” (page 45)
◦“Stripping Symbol Table Information from the Output File with -s and -x” (page 46)
◦“Controlling Output from the Unwind Table with +strip unwind” (page 46)
◦“Using the IPF Linker with +compat or +std” (page 46)
◦“Linking in PA-64 Mode with +std” (page 48)
◦“Linking in PA-32 Mode with +compat” (page 48)
◦“Changing Mapfiles with -k and +nodefaultmap” (page 48)
◦“Selecting Verbose Output with +vtype” (page 48)
◦“Turning on the linkage table protection with +protect” (page 50)
◦“Allocating Storage for Uninitialized Data with +nobss” (page 50)
◦“Initializing Floating Point Environment with +FP ” (page 50)
◦“Allocating Storage for Hidden Common Symbols with +alloc_hidden_commons” (page
51)
◦“Turn Off Linker Warnings with -w” (page 52)
◦“Preserving Compiler Generated Relocation Sections with -emit_relocs” (page 52)
Using the Compiler to Link
In many cases, you use your compiler command to compile and link programs. Your compiler uses
options that directly affect the linker.
Changing the Default Library Search Path with -Wl, -L
The -L libpath option to ld augments the default search path; that is, it causes ld to search the
specified libpath before the default places. The C compiler (cc), the C++ compiler (CC), the POSIX
FORTRAN compiler (fort77), and the HP Fortran 90 compiler (f90) recognize the -L option and
pass it directly to ld. However, the HP FORTRAN compiler (f77) and Pascal compiler (pc) do not
recognize -L; it must be passed to ld with the -Wl option.
Example Using -Wl, -L
For example, to make the f77 compiler search /usr/local/lib to find a locally developed
library named liblocal, use this command line:
$ f77 prog.f -Wl,-L,/usr/local/lib -llocal
(The f77 compiler searches /opt/fortran/lib and /usr/lib as default directories.)
To make the f90 compiler search /usr/local/lib to find a locally developed library named
liblocal, use this command line:
$ f90 prog.f90 -L/usr/local/lib -llocal
(The f90 compiler searches /opt/fortran90/lib and /usr/lib as default directories.) For
the C compiler, use this command line:
$ cc -Aa prog.c -L /usr/local/lib -llocal
The LPATH environment variable provides another way to override the default search path. For
details, see “Changing the Default Library Search Path with -L, LPATH, and $ORIGIN” (page 30)
28Determining How to Link Programs or Libraries (Linker Tasks)
Getting Verbose Output with -v
The -v option makes a compiler display the verbose information. This is useful for viewing how
the compiler calls ld. For example, using the -v option with the C compiler shows that it
automatically links with libc.
$ cc -v himom.c
/opt/ansic/lbin/ecom -ia64abi all -architecture 32 -ext on -lang c \
-exception off -sysdir /usr/include -inline_power 1 -link_type dynamic \
-fpeval float -tls_dyn on -target_os 11.23 -- sys_include /usr/include \
Passing Linker Options from the Compiler Command with -Wl
The -Wl option passes options and arguments to ld directly, without the compiler interpreting the
options. Its syntax is:
-Wl,arg1 [,arg2]...
where each argn is an option or argument passed to the linker. For example, to make ld use the
archive version of a library instead of the shared, you must specify -a archive on the ld
command line before the library.
Example Using -Wl
The command for instructing the linker to use an archive version of libm from the C commandline is:
$ cc -Aa mathprog.c -Wl,-a,archive,-lm,-a,default
The command for instructing the linker to use an archive version of libm is:
$ $ ld /opt/langtools/lib/crt0.o mathprog.o -a archive -lm
-a default -lc
Renaming the Output File with -o
The -o name option causes ld to name the output file name instead of a.out. For example, to
compile a C program prog.c and name the resulting file sum_num:
$ cc -Aa -o sum_num prog.c //Compile using -o option.
$ sum_num //Run the program.
Enter a number to sum: 5
The sum of 1 to 5: 15
Specifying Libraries with -l
Sometimes programs call routines not contained in the default libraries. In such cases you must
explicitly specify the necessary libraries on the compile line with the -l option. The compilers pass
-l options directly to the linker before any default libraries, such as libc.
For example, if a C program calls library routines in the curses library (libcurses), you must
-u main -lc
cc: informational note 413: Entering Link editor.
Linking with the crt0.o Startup File in 32-bit mode (PA-RISC)
Notice also, in the above example, that the compiler linked cursesprog.o with the file
/opt/langtools/lib/crt0.o. This file contains object code that performs tasks which must
be executed when a program starts running - for example, retrieving any arguments specified on
the command line when the program is invoked. For details on this file, see “The crt0.o Startup
File” (page 21)
Suppressing the Link-Edit Phase with -c
The -c compiler option suppresses the link-edit phase. That is, the compiler generates only the .o
files and not the a.out file. This is useful when compiling source files that contain only subprograms
and data. These may be linked later with other object files, or placed in an archive or shared
library. The resulting object files can then be specified on the compiler command line, just like
source files. For example:
$ f90 -c func.f //Produce .o for func.f.
$ ls func.o
func.o
$ f90 main.f func.o //Compile main.f with func.o
$ a.out //Run it to verify it worked.
Using Linker Commands
This section describes linker commands for the 32-bit and 64-bit linker
NOTE:Unless otherwise noted, all examples show 32-bit behavior.
Linking with the crt0.o Startup File
In default mode, you need not include crt0.o on the link line. However, you must include crt0.o
on the link line for all fully archive links (ld -noshared) and in compatibility mode (+compat).
You need not include the crt0.o startup file on the ld command line for shared bound links. The
dynamic loader does some of the startup duties previously done by crt0.o.
See “The crt0.o Startup File” (page 21), and crt0(3) manpage for more information.
Changing the Default Library Search Path with -L, LPATH, and $ORIGIN
You can change or override the default linker search path by using the LPATH environment variable,
the -L linker option, or the +origin linker option.
Overriding the Default Linker Search Path with LPATH
The LPATH environment variable allows you to specify which directories ld should search. If
LPATH is not set, ld searches the default directory /usr/lib. If LPATH is set, ld searches only
the directories specified in LPATH; the default directories are not searched unless they are specified
in LPATH.
If set, LPATH must contain a list of colon-separated directory path names that ld must search. For
example, to include /usr/local/lib in the search path after the default directories, set LPATH
as follows:
30Determining How to Link Programs or Libraries (Linker Tasks)
Augmenting the Default Linker Search Path with -L
The -L option to ld also allows you to add additional directories to the search path. If -L libpath
is specified, ld searches the libpath directory before the default places.
For example, suppose you have a locally developed version of libc, which resides in the directory
/usr/local/lib. To make ld find this version of libc before the default libc, use the -L
option as follows:
$ ld prog.o -L /usr/local/lib -lc
If LPATH is set, then the -L option specifies the directories to search before the directories specified
in LPATH.
Augmenting the Default Linker Search Path with +origin
The +origin option to ld instructs the linker to search for the library in the directory from which
the object module originated.
The +origin option only applies to the shared library specified directly afterwards, for example,
libc.so or -lc.
At runtime, if the dynamic loader cannot find the library listed in the path specified by $ORIGIN,
it attempts to search paths according to the search path algorithm described above.
The syntax is as follows:
$ ld main.o +origin -lc
or
$ ld main.o +origin /usr/lib/hpux32/libc.so
Using $ORIGIN
You can use the $ORIGIN string in LD_LIBRARY_PATH, SHLIB_PATH, RUNPATH (the embedded
path or RPATH), or in the path of a shared library in the shared library list. If the DF_ORIGIN flag
is set, the loader determines the path of the current load module when the load module is first
loaded. If the DF_ORIGIN flag is not set, the loader determines the path of the current load module
when the loader first encounters $ORIGIN, whether it is in LD_LIBRARY_PATH, SHLIB_PATH,
RUNPATH, or the shared library name in the shared library list.
To add $ORIGIN to the environment variables LD_LIBRARY_PATH or SHLIB_PATH, place
$ORIGIN in the value of these environment variables. To add $ORIGIN to the RUNPATH, use the
linker options +b or -L. To add $ORIGIN to the path of a shared library in the shared library list,
use the linker option +origin.
+origin -lx
or
+origin shared_library_name
(You can use only the +origin option before the -l option or the name of a shared library.) The
option causes the linker to add $ORIGIN before the shared library name in the shared library list
and set the DF_ORIGIN flag for the output module. At runtime, the dynamic loader determines the
directory of the parent module (object module, shared library, or executable) and replaces $ORIGIN
for that directory name. For example,
$ ld main.o +origin libx.so -L -lc
Using Linker Commands31
NOTE:You can use $ORIGIN in SHLIB_PATH/LD_LIBRARY_PATH only for programs on PA32
systems.
While the +origin option is available, the recommended way to specify $origin is in the
embedded path with the +b option. For example,
$ ld main.o -lc +b $ORIGIN
If you use +b,\$ORIGIN; the $ORIGIN only affects libraries that are subject to dynamic path
lookup; that is, the library shared_library_name is specified with -l or with no embedded /
character. If you use +origin shared_library_name, the library is located using $ORIGIN,
which is recorded in the full library name.
Changing the Default Shared Library Binding with -B
You might want to force immediate binding - that is, force all routines and data to be bound at
startup time. With immediate binding, the overhead of binding occurs only at program startup,
rather than across the program's execution. One useful characteristic of immediate binding is that
it causes any possible unresolved symbols to be detected at startup time, rather than during program
execution. Another use of immediate binding is to get better interactive performance, but in this
case the program startup may take a little longer.
$ ld -B immediate prog.o -lc
Example Using -B immediate
To force immediate binding, link an application with the -B immediate linker option. For example,
to force immediate binding of all symbols in the main program and in all shared libraries linked
with it, you can use this ld command:
$ ld -B immediate prog.o -lc
Nonfatal Shared Library Binding with -B nonfatal
The linker also supports nonfatal binding, which is useful with the -B immediate option. Like
immediate binding, nonfatal immediate binding causes all required symbols to be bound at program
startup. The main difference from immediate binding is that program execution continues even if
the dynamic loader cannot resolve symbols. Compare this with immediate binding, where unresolved
symbols cause the program to abort.
To use nonfatal binding, specify the -B nonfatal option along with the -B immediate option
on the linker command line. The order of the options is not important, nor is the placement of the
options on the line. For example, the following ld command uses nonfatal immediate binding:
$ ld prog.o -B nonfatal -B immediate -lc
Note that the -B nonfatal modifier does not work with deferred binding because a symbol
must be bound by the time a program actually references or calls it. A program attempting to call
or access a nonexistent symbol is a fatal error.
Restricted Shared Library Binding with -B restricted
The linker also supports restricted binding, which is useful with the -B deferred and -Bnonfatal options. The -B restricted option causes the dynamic loader to restrict the search
for symbols to those that were visible when the library was loaded. If the dynamic loader cannot
find a symbol within the restricted set, a run-time symbol-binding error occurs and the program
aborts.
The -B nonfatal modifier alters this behavior slightly: If the dynamic loader cannot find a
symbol in the restricted set, it looks in the global symbol set (the symbols defined in all libraries)
to resolve the symbol. If it still cannot find the symbol, then a run-time symbol-binding error occurs
and the program aborts.
32Determining How to Link Programs or Libraries (Linker Tasks)
When is -B restricted most useful? Consider a program that creates duplicate symbol definitions
by either of these methods:
•The program uses shl_load with the BIND_FIRST flag to load a library that contains symbol
definitions that are already defined in a library that was loaded at program startup.
•The program calls shl_definesym to define a symbol that is already defined in a library
that was loaded at program startup.
If such a program is linked with -B immediate, references to symbols are bound at program
startup, regardless of whether duplicate symbols are created later by shl_load or
shl_definesym.
But what happens when, to take advantage of the performance benefits of deferred binding, the
same program is linked with -B deferred? If a duplicate, more visible symbol definition is
created prior to referencing the symbol, it binds to the more visible definition, and the program
may run incorrectly. In such cases, -B restricted is useful, because symbols bind the same
way as they do with -B immediate, but the actual binding is still deferred.
Direct Shared Library Binding with -B direct
The linker also supports direct binding, which creates a direct link between symbol references and
shared libraries by recording the name of the resolved shared library during symbol resolution.
This information is used during runtime to quickly resolve symbols without searching through all
currently-loaded libraries.
The -B direct option implicitly turns on symbolic binding and disables dependent shared library
processing.
Direct binding can be disabled during runtime by setting the LD_NODIRECTBIND environment
variable.
Shared Library Binding with -B group
Group binding marks the shared library so that it behaves as if loaded with RTLD_GROUP flag to
dlopen(). This does not affect the dependent shared libraries.
NOTE:You can use the libraries built with the -B group option only with the dld.sl in version
B.11.37 or later.
Lazydirect Shared Library Binding with -B lazydirect
Lazydirect binding only records direct bind information to shared libraries that are marked for lazy
loading. See +[no]lazyload.
Shared Library Binding with -B nodelete
Nodelete binding marks the shared library so that an explicit unload using dlclose or shl_load
returns success silently without detaching the shared library from the process. Subsequently, the
shared library handle is valid only for shl_findsym. It stays invalid for dlsym, dlclose, and
shl_unload until the next explicit load using shl_load or dlopen.
NOTE:You can use the libraries built with the -B nodelete option only with the dld.sl in
version B.11.37 or later.
-B nodirect
Nodirect binding precludes direct binding. Only a "direct hint" is recorded for references to libraries
marked for lazy loading. This is the default behavior.
Using Linker Commands33
Improving Shared Library Performance with -B symbolic
The linker supports the -B symbolic option which optimizes call paths between procedures when
building shared libraries. It does this by building direct internal call paths inside a shared library.
In linker terms, import and export stubs are bypassed for calls within the library.
The benefit of using -B symbolic option is that it helps improve application performance and
the resulting shared library is slightly smaller. The -B symbolic option is useful for applications
that make a lot of calls between procedures inside a shared library, and when these same
procedures are called by programs outside of the shared library.
NOTE:The -B symbolic option applies only to function references in a shared library.
Example Using -B symbolic
For example, to optimize the call path between procedures when building a shared library called
lib1.s, use -B symbolic as follows:
$ ld -B symbolic -b func1.o func2.o -o lib1.s
NOTE:The +e option overrides the -B symbolic option. For example, when you use +e
symbol, only symbol is exported and all other symbols are hidden. Similarly, if you use +ee symbol,
only symbol is exported, but other symbols exported by default remain visible.
Since all internal calls inside the shared library are resolved inside the shared library, user-supplied
modules with the same name are not seen by routines inside the library. For example, you cannot
replace internal libc.sl malloc() calls with your own version of malloc() if libc.sl was
linked with -B symbolic.
Comparing -B symbolic with -h and +e
Similar to the -h (hide symbol) and +e (export symbol) linker options, -B symbolic optimizes
call paths in a shared library. However, unlike -h and +e, all functions in a shared library linked
with -B symbolic are also visible outside of the shared library.
Case 1: Building a Shared Library with -B symbolic
Suppose you have two functions to place in a shared library. The convert_rtn() calls
gal_to_liter().
1.Build the shared library with -b. Optimize the call path inside the shared library with -B
2.Two main programs link to the shared library. The main1 calls convert_rtn() and main2
calls gal_to_liter().
$ cc -Aa main1.c libunits.sl -o main1
$ cc -Aa main2.c libunits.sl -o main2
Figure 4 (page 35) shows that a direct call path is established between convert_rtn() and
gal_to_liter() inside the shared library. Both symbols are visible to outside callers.
34Determining How to Link Programs or Libraries (Linker Tasks)
Figure 4 Symbols Inside a Shared Library Visible with -B symbolic
Case 2: Building a Shared Library with -h or +e
The -h (hide symbol) and +e (export symbol) options can also optimize the call path in a shared
library for symbols that are explicitly hidden. However, only the exported symbols are visible
outside of the shared library.
For example, you can hide the gal_to_liter symbol, as shown:
In both cases, main2 cannot to resolve its reference to gal_to_liter() because only the
convert_rtn() symbol is exported, as shown below in Figure 5 (page 35).
Figure 5 Symbol Hidden in a Shared Library
Using Linker Commands35
Choosing Archive or Shared Libraries with -a
If both an archive and shared version of a particular library reside in the same directory, ld links
with the shared version. Occasionally, you might want to override this behavior.
As an example, suppose you write an application that runs on a system on which shared libraries
may not be present. Since the program cannot run without the shared library, it would be best to
link with the archive library resulting in executable code that contains the required library routines.
See also“Caution When Mixing Shared and Archive Libraries” (page 118)
Option Settings to -a
The -a option tells the linker what kind of library to link with. It applies to all libraries (-l
options) until the end of the command line or until the next -a option. Its syntax is:
-a {archive | shared | default | archive_shared | shared_archive}
The different option settings are:
-a archiveSelect archive libraries. If the archive library does not exist, ld generates an
error message and does not generate the output file.
-a ar-a shared chiveSelect shared libraries. If the shared library does not exist, ld
generates an error message and does not generate the output file.
-a defaultThis is the same as -a shared_archive.
-a archive_sharedSelect the archive library if it exists; otherwise, select the shared library.
If the library is not found in either version, ld generates an error
message and does not generate the output file.
-a shared_archiveSelect the shared library if it exists; otherwise, select the archive library.
If the library is not found in either version, ld generates an error
message and does not generate the output file.
The -a shared and -a archive options specify only one type of library to use. An error results
if that type is not found. The other three options specify a preferred type of library and an alternate
type of library if the preferred type is not found.
CAUTION:You must avoid mixing shared libraries and archive libraries in the same application.
For more information, see “Caution When Mixing Shared and Archive Libraries” (page 118)
Example Using -a
The following command links with the archive versions of libcurses, libm, and libc:
$ ld /opt/langtools/lib/hpux32/crt0.o prog.o -a archive -lcurses -lm -lc
Linking Shared Libraries with -dynamic
Use the -dynamic option to instruct the linker to look for shared libraries first and then archive
libraries. The linker outputs a share-bound executable.
This option is on by default.
For example:
$ ld main.o -dynamic -L. -lbar -lc
is the same as:
$ ld main.o -L. -lbar -lc
If you specified an archive library, the linker links it in, but the resulting executable is still a
share-bound executable. This is true even if the linker finds no shared libraries at link time.
36Determining How to Link Programs or Libraries (Linker Tasks)
Linking Archived Libraries with -noshared
Use the -noshared option if you need to link with all archive libraries. The linker outputs an
archive-bound executable.
NOTE:You cannot link in shared libraries if you specify this option.
In the following example, the linker only looks for:
/usr/lib/hpux32/libfoo.a and /user/lib/hpux32/libc.a:
If you specify a shared library libbar.so with this option, the linker displays the error message:
ld: The shared library "libbar.so" cannot be processed in a static link.
Fatal error.
Exporting Symbols with +e
The +e option allows you to hide and export symbols. Exporting a symbol makes the symbol a
global definition, which can be accessed by other object modules or libraries. The +e option
exports the symbol and hides from export all other global symbols not specified with +e. In essence,
-h and +e provide two different ways to do the same thing.
The syntax of the +e option is:
+e symbol
Example Using +e
Suppose you want to build a shared library from an object file that contains the following symbol
definitions as displayed by the nm command:
$ nm -p sem.o
0000000000 U $global$
1073741824 d $THIS_DATA$
1073741864 b $THIS_BSS$
0000000004 cS sem_val
0000000000 T check_sem_val
0000000036 T foo
0000000000 U printf
0000000088 T bar
0000000140 T sem
In this example, check_sem_val, foo, bar, and sem are all global definitions. To create a
shared library where check_sem_val is a hidden, local definition, you could use either of the
following commands:
How do you decide whether to use -h or +e? In general, use -h if you simply want to hide a few
symbols. And use +e if you want to export a few symbols and hide a large number of symbols.
You must not run -h and +e options on the same command line. For instance, suppose you specify
+e sem. This exports the symbol sem and hides all other symbols. Any additional -h options
becomes unnecessary. If both -h and +e are used on the same symbol, the -h overrides the +e
option.
Using Linker Commands37
The linker command line gets lengthy and difficult to read if several such options are specified. In
fact, you exceed the maximum HP-UX command line length if you specify too many options. To
get around this, use ld linker option files, described under “Passing Linker Options in a file with
-c” (page 44) . You can specify any number of -h or +e options in this file.
You can use -h or +e options when building a shared library (with -b), combining .o files ( with
-r), and when linking to create an a.out file.
Emitting debug information in a separate file
Valid for executable and shared library links with +noobjdebug option. Instructs the linker to
dump all debug information in a separate file specified in filename and not include them in the
executable. The HP debugger (WDB 6.2 and later) supports the separate debug information file
during debugging. This option is useful to create an executable without debug information and
retain the debug information for later use. It also helps to reduce the size of the executable.
Use the +dbgfile option to create a separate debug information file. This option takes a filename
as an argument.
The following example shows the result of creating a separate debug information file using the
+dbgfile option.
Example 1 Create a separate debug information file using +dbgfile option
In this example, the name of the separate debug information file is a.out.dbg and it is provided
as the argument to the linker option +dbgfile. This creates a file by name a.out.dbg which
contains all the debug information.
Linker gives out information about the debug file in the executable, and the debugger automatically
picks up the debug information file. As seen through the elfdump output, all the .debug_ sections
are in a.out.dbg file.
This feature is available only on Integrity systems.
Exporting Symbols with +ee
Like the +e option, the +ee option allows you to export symbols. However, this option, the option
does not alter the visibility of other symbols in the file. It exports the specified symbol, and does
not hide any of the symbols exported by default.
Exporting Symbols from main with -E
In PA-32 mode, the linker exports from a program only those symbols that were imported by a
shared library. For example, if a shared executable's libraries do not reference the program's main
routine, the linker does not include the main symbol in the a.out file's export list. Normally, this
is a problem only when a program calls shared library management routines (described in “Shared
Library Management Routines” (page 136)). To make the linker export all symbols from a program,
invokeld with the -E option.
In IPF/PA-64 mode, the behavior is specified by -E is the default behavior. The +e option allows
you to be more selective about which symbols are exported, resulting in better performance. For
more information on +e, see “Exporting Symbols with +e” (page 37).
38Determining How to Link Programs or Libraries (Linker Tasks)
Hiding Symbols from Export with +hideallsymbols
Use the +hideallsymbols option to hide all symbols to prevent the linker from exporting them
in a shared link. In the following example, main() exports func() and test(). If you use
+hideallsymbols, the linker cannot export the following routines in the a.out.
$ ld main.o +hideallsymbols -L. -lfoo -lc
$ elfdump -t a.out
a.out:
...
.symtab
index Type Bind Other Sect Value Size Name
1 FUNC LOCL 0 0xb 0x4000000000001104 0 test
...
10 FUNC LOCL 0 0xb 0x4000000000001200 0 func
Hiding Symbols with -h
The -h option allows you to hide symbols. Hiding a symbol makes the symbol a local definition,
accessible only from the object module or library in which it is defined. Use -h if you want to hide
a few symbols
You can use -h option when building a shared library (with -b) and when linking to create an
a.out file. When combining .o files with -r, you can use the -h option.
The syntax of the -h option is: -h symbol The -h option hides symbol. Other global symbols
remain exported unless hidden with -h.
Example Using -h
Suppose you want to build a shared library from an object file that contains the following symbol
definitions as displayed by the nm command:
$ nm -p sem.o
0000000000 U $global$
1073741824 d $THIS_DATA$
1073741864 b $THIS_BSS$
0000000004 cS sem_val
0000000000 T check_sem_val
0000000036 T foo
0000000000 U printf
0000000088 T bar
0000000140 T sem
In this example, check_sem_val, foo, bar, and sem are all global definitions. To create a
shared library where check_sem_val is a hidden, local definition, you can do the following:
$ ld -b -h check_sem_val sem.o
Tips on Using -h
You must not run -h and +e options on the same command line. For instance, suppose you specify
+e sem. This exports the symbol sem and hides all other symbols. Additional -h options becomes
unnecessary. If both -h and +e are used on the same symbol, the -h overrides the +e option.
The linker command line gets lengthy and difficult to read if several such options are specified. In
fact, you exceed the maximum HP-UX command line length if you specify too many options. To
get around this, use ld linker option files, described under “Passing Linker Options in a file with
-c” (page 44) . You can specify any number of -h or +e options in this file.
Using Linker Commands39
Hiding and Exporting Symbols When Building a Shared Library
When building a shared library, you may want to hide a symbol in the library for the following
reasons:
•When building a shared library, you may want to hide a symbol in the library for the following
reasons:
•Hiding a symbol ensures that the definition can only be accessed by other routines in the same
library. When linking with other object modules or libraries, the definition is hidden from them.
•When linking with other libraries (to create an executable), hiding a symbol ensures that the
library uses the local definition of a routine rather than a definition that occurs earlier in the
link order.
Exporting a symbol is necessary if the symbol must be accessible outside the shared library. But
remember that, by default, most symbols are global definitions anyway, so it is not necessary to
explicitly export symbols. In C, all functions and global variables that are not explicitly declared
as static have global definitions, while static functions and variables have local definitions.
In FORTRAN, global definitions are generated for all subroutines, functions, and initialized common
blocks.
When using +e, be sure to export any data symbols defined in the shared library that is used by
another shared library or the program, even if these other files have definitions of the data symbols.
Otherwise, your shared library uses its own private copy of the global data, and another library
or the program file cannot see any change.
One example of a data symbol that must be exported from a shared library is errno. The errno
data symbol is defined in every shared library and program; if this definition is hidden, the value
of errno is not be shared outside of the library.
Hiding Symbols when Combining .o Files with the -r Option
The -r option combines multiple .o files, creating a single .o file. The reasons for hiding symbols
in an .o file are the same as the reasons listed above for shared libraries. However, a performance
improvement occurs only if the resulting .o file is later linked into a shared library.
Hiding and Exporting Symbols when Creating an a.out File
In PA-32 mode, the linker exports all of a program's global definitions that are imported by shared
libraries specified on the linker command line. For example, given the following linker command,
all global symbols in crt0.o and prog.o that are referenced by libm or libc are automatically
exported:
$ ld /usr/ccs/lib/crt0.o prog.o -lm -lc
With libraries that are explicitly loaded with shl_load, this behavior may not always be sufficient
because the linker does not search explicitly loaded libraries (they aren't even present on the
command line). You can work around this using the -E or +e linker option.
As mentioned previously in the section “Exporting Symbols from main with -E” (page 38) , the -E
option forces the export of all symbols from the program, regardless of whether they are referenced
by shared libraries on the linker command line. The +e option allows you to be more selective in
what symbols are exported. You can use +e to limit the exported symbols to only those symbols
you want to be visible.
For example, the following ld command exports the symbols main and foo. The symbol main
is referenced by libc. The symbol foo is referenced at run time by an explicitly loaded library
not specified at link time:
When using +e, be sure to export any data symbols defined in the program that may also be
defined in explicitly loaded libraries. If a data symbol that a shared library imports is not exported
from the program file, the program uses its own copy while the shared library uses a different copy
40Determining How to Link Programs or Libraries (Linker Tasks)
if a definition exists outside the program file. In such cases, a shared library may update a global
variable needed by the program, but the program would never see the change because it is
referencing its own copy.
One example of a data symbol that should almost always be exported from a program is errno.
The errno data symbol is defined in every shared library and program; if this definition is hidden,
the value of errno is not shared outside of the program in which it is hidden.
In IPF/PA-64 mode, the behavior specified by -E is the default behavior.
Not Recording Link Time Paths with +nodefaultrapth
By default, the linker records the link time paths of dependent shared libraries in the resultant
executables and shared libraries. In 32-bit mode, link time paths are recorded as a part of the
library name in the shared library list. In 64-bit mode, link time paths are recorded as embedded
path (unless embedded path is defined explicitly using +b option).
The linker can be told not to record any link time paths by specifying the +nodefaultrpath
option at link time. This option applies only to libraries specified with -l on the linker command
line (for example, -lfoo). Link time paths will still be recorded for libraries whose full path name
is specified (for example, /usr/contrib/lib/libfoo.sl) on the link line.
By default (i.e., if no other paths are specified) the 32 bit dld.sl searches for libraries in the
current directory and the 64 bit dld.sl searches in the /lib/pa20_64 and/usr/lib/pa20_64 directories. So if +nodefaultrpath is specified at link time and the
application needs libraries that are not present in above paths, care must be taken to provide the
paths of these libraries using either SHLIB_PATH, LD_LIBRARY_PATH or embedded path.
Moving Libraries after Linking with +b
A library can be moved even after an application has been linked with it. This is done by providing
the executable with a list of directories to search at run time for any required libraries. One way
you can store a directory path list in the program is by using the +b path_list linker option.
Note that dynamic path list search works only for libraries specified with -l on the linker command
line (for example, -lfoo). It does not work for libraries whose full path name is specified (for
example, /usr/contrib/lib/libfoo.sl). However, it can be enabled for such libraries with
the -l option to the chatr command (see “Changing a Program's Attributes with chatr(1)” (page
53) ).
Specifying a Path List with +b
The syntax of the +b option is:
+b path_list
where path_list is the list of directories you want the dynamic loader to search at run time. For
example, the following linker command causes the path .:/app/lib to be stored in the executable.
At run time, the dynamic loader searches for libfoo, libm, and libc in the current working
directory (.), and then in the directory /app/lib
If path_list is only a single colon, the linker constructs a path list consisting of all the directories
specified by -L, followed by all the directories specified by the LPATH environment variable. For
instance, the following linker command records the path list as /app/lib:/tmp:
On PA32 systems, if multiple +b options appear on the link line, the output file records the +b
option that is specified first.
Using Linker Commands41
On PA32 systems, double colon (::) refers to the location in which the libraries were found at link
time. For example, the following linker command instructs the dynamic loader to search for libfoo,
libm, and libc first in the current working directory (.), then in the directory /app/lib, and
lastly in the location in which the libraries were found at link time (::).
NOTE:The double colon (::) feature is available only for PA32 systems.
Concatenating Search Paths Specified by Multiple +b path_list on PA64 and Integrity Systems
On PA64 systems and Itanium-based systems, the +[no]concatrpath option enables or disables
the concatenation of search paths specified by multiple +b path_list at link time.
If +noconcatrpath option is specified, only the path that is specified by the last +b path_list
option on the command line is recorded. The default is + noconcatrpath
. The following example illustrates the use of +[no]concatrpath option with +b:
$ cat output/lib1.c
#include <stdio.h>
void lib1() {
printf("lib1 in output\n");
}
$ cc -b output/lib1.c -o output/lib1.sl
$ cat input/lib1.c
#include <stdio.h>
void lib1() {
printf("lib1 in input\n");
}
$ cc -b input/lib1.c -o input/lib1.sl
$ cat main.c
#include <stdio.h>
void lib1();
int main() {
lib1();
return 0;
}
$ cc -c main.c
If +concatrpath is specified, the linker record all the +b pathlist entries, as follows:
Whether specified as a parameter to +b or set as the value of the SHLIB_PATH environment
variable, the path list is simply one or more path names separated by colons (:), just like the syntax
of the PATH environment variable. An optional colon can appear at the start and end of the list.
Absolute and relative path names are allowed. Relative paths are searched relative to the program's
current working directory at run time.
Remember that a shared library's full path name is stored in the executable. When searching for
a library in an absolute or relative path at run time, the dynamic loader uses only the base name
of the library path name stored in the executable. For instance, if a program is linked with
42Determining How to Link Programs or Libraries (Linker Tasks)
/usr/local/lib/libfoo.sl, and the directory path list contains /apps/lib:xyz, the
dynamic loader searches for /apps/lib/libfoo.sl, then ./xyz/libfoo.sl.
The full library path name stored in the executable is referred to as the default library path. To
cause the dynamic loader to search for the library in the default location, use a null directory path
().
NOTE:The use of null directory path () is PA32 specific.
When the loader comes to a null directory path, it uses the default shared library path stored in
the executable. For instance, if the directory path list in the previous example was
/apps/lib::xyz, the dynamic loader searches for /apps/lib/libfoo.sl,
/usr/local/lib/libfoo.sl, then ./xyz/libfoo.s.
If the dynamic loader cannot find a required library in any of the directories specified in the path
list, it searches for the library in the default location () recorded by the linker.
Moving Libraries After Linking with +s and SHLIB_PATH
A library can be moved even after an application has been linked with it. Linking the program
with +s, enables the program to use the path list defined by the SHLIB_PATH environment variable
at run time.
Specifying a Path List with +s and SHLIB_PATH
When a program is linked with +s, the dynamic loader gets the library path list from the
SHLIB_PATH environment variable at run time. This is especially useful for application developers
who do not know where the libraries reside at run time. In such cases, they can have the user or
an install script set SHLIB_PATH to the correct value.
For more information:
•“The Path List” (page 42)
provides additional details about the path list to SHLIB_PATH.
•“Moving Libraries after Linking with +b” (page 41)
provides another way to move libraries.
Ignoring Dynamic Path Environment Variables with +noenvvar
Use the +noenvvar option to instruct the dynamic loader not to look at the environment variables
relating to dynamic path searching at runtime. It ignores LD_LIBRARY_PATH, SHLIB_PATH, and
$ORIGIN environment variables. This option is on by default in PA32 mode and in programs
linked with ld +compat. It is off by default with ld +std.
For example, if libbar.so has dependent library libfee.so that is found in ./ at link time,
but is moved to /tmp by runtime:
Controlling Archive Library Loading with +[no]forceload
Use the +[no]forceload option to control how the linker loads object files from an archived
library. The +forceload instructs the linker to load all object files from an archive library. The
+noforceload option instructs the linker to only load those modules from an archive library that
is needed. The mode you select, either by default or explicitly, remains active until you change it.
The +noforceload option is the default. In the following example, main() references foo(),
which is a module in mylib.a. The function foo() does not reference any other module in
mylib.a and libc.a. If mylib.a contains foo.o and bar.o, then only foo.o is linked.
$ ld /opt/langtools/lib/hpux32/crt0.o main.o +forceload mylib.a -lc +vtype libraries
...
Selecting mylib.a[foo.o] to forcibly load
Selecting mylib.a[bar.o] to forcibly load
Passing Linker Options in a file with -c
The -c file option causes the linker to read command line options from the specified file. This is
useful if you have many -h or +e options to include on the ld command line, or if you have to
link with numerous object files. For example, suppose you have over a hundred +e options that
you need when building a shared library. You can place them in a file named eopts and force the
linker to read options from the file as follows:
NOTE:The linker ignores lines in that option file that begin with a pound sign (#). You can use
such lines as comment lines or to temporarily disable certain linker options in the file. For instance,
the following linker option file for an application contains a disabled -O option:
# Exporting only the "compress" symbol resulted
# in better run-time performance:
+e compress
# When the program is debugged, remove the pound sign
# from the following optimization option:
# -O
Passing Linker Options with LDOPTS
If you use certain linker options all the time, you may find it useful to specify them in the LDOPTS
environment variable. The linker inserts the value of this variable before all other arguments on the
linker command line. For instance, if you always want the linker to display verbose information
(-v) and a trace of each input file (-t), set LDOPTS as follows:
Thereafter, the following commands would be equivalent:
$ ld -u main prog.o -lc
$ ld -v -t -u main prog.o -lc
44Determining How to Link Programs or Libraries (Linker Tasks)
Specifying Libraries with -l and -l:
To direct the linker to search a particular library, use the -lname option. For example, to specify
libc, use -lc; to specify libm, use -lm; to specify libXm, use -lXm.
Specifying Libraries (-l)
When writing programs that call routines not found in the default libraries linked at compile time,
you must specify the libraries on the compiler command line with the -lx option. For example, if
you write a C program that calls POSIX math functions, you must link with libm.
The x argument corresponds to the identifying portion of the library path name - the part following
lib and preceding the suffix .a or .sl. For example, for the libm.sl or libm.a library, x is
the letter m:
$ cc -Aa mathprog.c -lm
The linker searches libraries in the order in which they are specified on the command line (that is,
the link order). In addition, libraries specified with -l are searched before the libraries that the
compiler links by default.
Using the -l: option
The -l: option works just like the -l option with one major difference: -l: allows you to specify
the full base name of the library to link with. For instance, -l:libm.a causes the linker to link
with the archive library /opt/langtools/lib/hpux32/libm.a, regardless of whether -a
shared was specified previously on the linker command line.
The advantage of using this option is that it allows you to specify an archive or shared library
explicitly without having to change the state of the -a option. (See also “Caution When Mixing
Shared and Archive Libraries” (page 118) .)
For instance, suppose you use the LDOPTS environment variable (see “Passing Linker Options with
LDOPTS” (page 44) ) to set the -a option that you want to use by default when linking. Depending
on what environment you are building an application for, you may set LDOPTS to -a archive
or -a shared. You can use -l: to ensure that the linker always links with a particular library
regardless of the setting of the -a option in the LDOPTS variable.
Example Using -l:
For example, even if LDOPTS were set to -a shared, the following command links with the
archive libfoo.a in the directory /usr/mylibs, the archive libm.a and libc.a:
$ ld /opt/langtools/lib/hpux32/crt0.o -u main prog.o -L/usr/mylibs \
-l:libfoo.a -l:libc.a -l:libm.a
Flagging Unsatisfied Symbols with +[no]allowunsats
Use the +allowunsats option to instruct the linker to not flag unsatisfied symbols at link time.
This is the default for relocatable (-r) and shared library builds (-b), and is the default behavior
in PA-32 mode.
Use the +noallowunsat option to instruct the linker to flag as an error any unsatisfied symbol
in the resulting output file. The linker still creates a.out, but the file does not have any execute
permission bits set. This is the default for program files (same behavior as in PA-32 mode).
For example, where main() references functions foo() and bar(). The bar() resides in
libbar and foo() resides in libfoo
$ ld main.o +allowunsats -L. -lbar -lc
ld: (warning) Unsatisfied symbol "foo".
1 warning.
Using Linker Commands45
The +allowunsats option still causes the linker to emit a warning message and output a.out.
If you do not specify the option and the linker finds an unsatisfied symbol, the linker displays an
error message and a non-executable a.out.
$ ld main.o -L. -lbar -lc
ld: Unsatisfied symbol "foo".
1 error.
Stripping Symbol Table Information from the Output File with -s and -x
The a.out file created by the linker contains symbol table, relocation, and (if debug options were
specified) information used by the debugger. Such information can be used by other commands
that work on a.out files, but is not actually necessary to make the file run. The ld command
provides two command line options for removing such information and, thus, reducing the size of
executables:
-sStrips all such information from the file. The executable becomes smaller, but difficult or
impossible to use with a symbolic debugger. You can get much the same results by running
the strip command on an executable (see strip(1)). In some cases, however, -s rearranges
the file to save more space than strip.
-xStrips only local symbols from the symbol table. It reduces executable file size with only a
minimal effect on commands that work with executables. However, using this option may still
make the file unusable by a symbolic debugger. These options can reduce the size of
executables drastically. Note, also, that these options can also be used when generating
shared libraries without affecting shareability.
Controlling Output from the Unwind Table with +strip unwind
Use the +stripunwind option to suppress output of the unwind table.
In the HP-UX 11.0 release, the linker toolset supports extended features for linking in PA-64 mode.
Since compatibility with the previous linker toolset is a high priority, on Itanium-based system the
linker uses much of the old behavior in the new toolset. The Itanium-based system linker includes
two options to allow you to instruct the linker to link in one of the following modes:
•Compatibility mode, with the +compat option, to create a link and operation in PA-32 mode.
Because of some object file format restrictions, the mode is not completely compatible with
the style of the PA-32 linker.
•Standard mode, with the +std option, set by default in the linker on Itanium-based system,
to create a link and load operation in PA-64 mode. This mode uses the new behaviors and
features of the PA-64 linker.
Using the Linker with +compat for Compatibility Mode
The +compat option instructs the linker to do a PA-32 link.
When you use the +compat option, the linker:
•Uses PA-32 shared library internal name processing.
•Lists all dependent shared libraries in a DT_HP_NEEDED entry the dynamic table using the
PA-32 shared library naming conventions. These dependent libraries are recorded as
46Determining How to Link Programs or Libraries (Linker Tasks)
compatibility-mode libraries even if they are really created as standard mode dependent
libraries.
•Does not use embedded paths at link time to find dependent libraries.
•Considers the order of ld, +b and +s.
The +b option first means dld looks at the RPATH first when searching for dependent
◦
shared libraries. To get the default RPATH, you must specify ld +b. This instructs the
linker to construct a default RPATH consisting of the -L directories and LPATH.
◦The +s option first means the dynamic loader looks at the SHLIB_PATH environment
variable first when searching for dependent shared libraries. You must specify ld +s to
force the dynamic loader to use SHLIB_PATH to search for shared libraries at runtime.
At runtime, the dynamic loader does a PA-32 load for all compatibility-mode dependent shared
libraries. The dynamic loader:
•Does dynamic path searching for compatibility-mode dependent shared libraries that have
the dynamic path selected (set in the DT_HP_NEEDED entry if the shared library was specified
with -l).
•Uses SHLIB_PATH only if you specify ld +s (or chatr+s) for compatibility-mode shared
libraries.
•Allows RPATH inheritance from ancestors to children when searching for dependent
compatibility-mode shared libraries specified with ld -l. This is only allowed in an a.out
that was linked with +compat. If a.out was linked in standard mode with +std option,
no library (even a compatibility mode shared library) uses embedded RPATH inheritance.
•Allows dynamic path searching on shared libraries loaded by shl_load routines, if the
DYNAMIC_FLAG is passed to shl_load().
•Does a depth-first search of all compatibility-mode dependent libraries.
•Looks at RPATH or SHLIB_PATH first, depending on the ld +b/+s ordering for all ld -l
dependent shared libraries. Next, the dynamic loader looks at whichever has second
precedence, and then looks for the shared library as specified in the dynamic load entry.
•Looks for the dynamic table entry as if the dynamic path bit is not set.
Using the Linker with +std for Standard Mode
The +std option instructs the linker to do a standard mode PA-64 link. This is currently the default.
This default may change in future releases.
When you use +std, the linker:
•Assumes -dynamic was passed to ld. The linker looks for shared libraries first. The output
executable is a shared executable.
•All dependent shared libraries are output in the dynamic table in a DT_NEEDED entry. These
dependent shared libraries are recorded as standard mode shared libraries.
•The ld +b and +s ordering is ignored. The ld +s option is on by default.
•Uses de facto standard internal name processing for dependent shared libraries.
•Uses embedded RPATHs at link time to find dependent shared libraries.
•If you do not specify ld +b, the linker uses a default RPATH consisting of the -L directories,
LPATH, and the default directories /usr/lib/hpux32:/opt/langtools/lib/hpux32
for 32-bit applications and /usr/lib/hpux64:/opt/langtools/lib/hpux64 for 64-bit
applications.
Using Linker Commands47
At runtime, the dynamic loader does a PA-64 load for all standard mode dependent shared libraries.
The dynamic loader:
•Does dynamic path searching only for standard-mode shared libraries in the DT_NEEDED
entry of the dynamic table which do not contain a path. For those standard-mode dynamic
libraries that contain paths, dld looks for the library as specified.
•Looks for the shared library as specified in the DT_NEEDED dynamic table entry if it contains
a path.
•Looks at LD_LIBRARY_PATH and SHLIB_PATH environment variables at runtime by default
when doing dynamic path searching for standard-mode shared libraries.
•Does not allow RPATH inheritance from ancestors to children (only allowed from parent to
child).
•Does a breadth-first search for all standard-mode dependent shared libraries.
•Looks at the environment variables first, followed by RPATH, and the default directories by
default when doing dynamic path searching for standard-mode dependent shared libraries.
Linking in PA-64 Mode with +std
Use the +std option to instructs the linker to do a PA-64 link. This is the default mode. For more
information, see “Using the IPF Linker with +compat or +std” (page 46).
Linking in PA-32 Mode with +compat
Use the +compat option to instruct the linker to do a PA-32 link. For more information, see “Using
the IPF Linker with +compat or +std” (page 46).
Changing Mapfiles with -k and +nodefaultmap
The linker automatically maps sections from input object files onto output segments in executable
files. These options to the ld command allow you to change the linker's default mapping.
Use the -k filename option to provide a memory map.
The linker uses the file specified by filename as the output file memory map. The +nodefaultmap
option used with -k option prevents the linker from concatenating the default memory map to the
map provided by filename. If you specify +nodefaultmap, the linker does not append the default
mapfile to your mapfile. If you do not specify +nodefaultmap with -k, the linker appends the
output file to the default mapfile.
NOTE:In most cases, the linker produces a correct executable without the use of the mapfile
option. The mapfile option is an advanced feature of the linker toolset intended for systems
programming use, not application programming use. When using the mapfile option, you can
create executable files that do not execute.
For more information on mapfiles and examples using these options, see “Using Mapfiles” (page
191).
Selecting Verbose Output with +vtype
Use the +vtype option to get verbose output about specified elements of the link operation. The
following values specify the typeTable 3 (page 48):
Table 3 values specify the type
DescriptionParameter
files
48Determining How to Link Programs or Libraries (Linker Tasks)
Dump information about each input section added to the output file.
$ ld main.o +vtype sections -L. -lfile1 -lfile2 -lc
main.o:
section .note NOTE 240 4 added to note segment
section .note NOTE 48 4 added to note segment
section .IA_64.unwind_info PROGBITS A 28 4
added to text segment
section .text PROGBITS AX 112 16 added to text
segment
section .IA_64.unwind UNWIND A 12 4 added to
text segment
section .rodata PROGBITS A 9 8 added to text
segment
section .HP.opt_annot PROGBITS A 25 8 added to
text segment
Dump information about global symbols referenced/defined from/in the input files.
$ ld main.o +vtype symbols -L. -lfile1 -lfile2 -lc
main.o:
main is DEFINED GLOBAL FUNC
printf is UNDEF GLOBAL FUNC
lib1_func is UNDEF GLOBAL FUNC
lib2_func is UNDEF GLOBAL FUNC
./libfile1.so:
printf is UNDEF GLOBAL FUNC
_DYNAMIC is DEFINED GLOBAL OBJECT
lib1_func is DEFINED GLOBAL FUNC
...
all
Dump all of the above. Same as -v.
$ ld main.o +vtype all -L. -lfile1 -lfile2 -lc
Loading main.o:
main.o:
main is DEFINED GLOBAL FUNC
printf is UNDEF GLOBAL FUNC
lib1_func is UNDEF GLOBAL FUNC
lib2_func is UNDEF GLOBAL FUNC
main.o:
section .note NOTE 240 4 added to note segment
section .note NOTE 48 4 added to note segment
section .IA_64.unwind_info PROGBITS A 28 4
added to text segment
section .text PROGBITS AX 112 16 added to text
segment
section .IA_64.unwind UNWIND A 12 4 added to
text segment
section .rodata PROGBITS A 9 8 added to text
segment
section .HP.opt_annot PROGBITS A 25 8 added to
text segment
Loading ./libfile1.so:
./libfile1.so:
...
Using Linker Commands49
Table 3 values specify the type (continued)
DescriptionParameter
procelim
procelim
Dump information about the sections that have been rejected by the +Oprocelim option.
$ ld main.o +Oprocelim +vtype procelim -L. -lfile1 -lfile2
Deleting 236 bytes in section file.note
Eliminated 0K of dead code and data, 0 global, 0 local and 0 hidden
symbols
Turning on the linkage table protection with +protect
You can use the +protect option to turn on the linkage table protection mode. When you turn
on this option, the linker aligns the linkage table within page boundaries so that no other data
resides in the same page. During runtime, the pages containing the linkage table is marked
READ_ONLY.
The +protect option turns on immediate binding. For more information about immediate binding,
see “Changing the Default Shared Library Binding with -B” (page 32).
The following options are not compatible with the +protect option:
•+mergeseg
•+filter
•+lazyload
Creating read-only text segment in MPAS executable
By default, text segment in MPAS executable would be mapped private to the process. With the
+mpas_rotext option, it is possible to build MPAS executable to support read-only text segment
that is mapped shared. By setting the kernel tunable 'mpas_readonly_text' to value 1, the MPAS
executable built with +mpas_rotext option runs with read-only text segment. This also helps to
improve memory usage because the text segment is shared.
NOTE:The kernel patch PHKL_41355 must be installed to make use of this feature.
Allocating Storage for Uninitialized Data with +nobss
When the loader loads a shared library, the loader must ensure that the data segment and bss
are mapped adjacent to each other in memory. This may involve repeated calls to mmap() and
munmap(). When shared libraries are frequently loaded and unloaded, application performance
may be affected.
You can use the new +nobss linker option to include the bss data of the shared library in its data
segment. When you build programs with the +nobss option, the number of mmap and munmap
calls at load time are minimal. However, the use of +nobss option increases the disk size of the
shared library. HP recommends the use of +nobss option only when the frequent loading and
unloading of shared libraries affect the application performance.
Initializing Floating Point Environment with +FP
You can use the +FP option to specify how the run time environment for floating point operations
must be initialized at program startup and used at link time.
The following table describes the Table 4 (page 51).
50Determining How to Link Programs or Libraries (Linker Tasks)
Table 4
flags
that are supported
Use the flagTo
VEnable trap on invalid floating-point operations.
vDisable trap on invalid floating-point operations.
ZEnable trap on divide by zero.
zDisable trap on divide by zero.
OEnable trap on floating-point overflow.
oDisable trap on floating-point overflow.
UEnable trap on floating-point underflow.
uDisable trap on floating-point underflow.
IEnable trap on floating-point operations that produce inexact results.
iDisable trap on floating-point operations that produce inexact results.
DEnable sudden underflow (flush to zero) of denormalized values.
dDisable sudden underflow (flush to zero) of denormalized values.
All trapping behaviors are disabled by default.
In addition to the flags, you can specify values for the rounding mode. The following values are
available:
•RN
Round to nearest. This is the default value.
•RU
Round upward toward +infinity.
•RD
Round downward toward -infinity
•RZ
Round toward zero, that is, truncate.
For more information on the +FP option, see the HP-UX Floating Point Guide.
Allocating Storage for Hidden Common Symbols with +alloc_hidden_commons
You can use the +alloc_hidden_commons option in combination with the -r option to force
the allocation of storage for hidden common symbols. The -r option is used to produce a relocatable
object file that can be used in subsequent link commands. By default, storage is not allocated for
common symbols when linking with -r. The -d option can be use with -r to force the allocation
of storage for all common symbols. The +alloc_hidden_commons option provides finer control
by allocating storage for hidden common symbols. If -d and +alloc_hidden_commons are
both specified in the same link command, the -d option will take precedence.
The +alloc_hidden_commons option provides a safer alternative to -d, because it only allocates
storages for common symbols that are not visible in subsequent links. This prevents any problems
that might result from allocating storage for non-hidden commons, and provides consistent handling
of hidden commons and hidden data.
Using Linker Commands51
Turn Off Linker Warnings with -w
In some build processes you might want to improve parsing of build output by ignoring linker
warnings. You can turn off linker warnings with the -w option.
Preserving Compiler Generated Relocation Sections with -emit_relocs
The -emit_relocs option enables the linker to preserve compiler-generated relocation sections
in the output binary. The input relocation information is stored in the executable, or the shared
library. This information provides the necessary support for third-party programming tools to perform
post-link instrumentation.
The following example illustrates that the compiler generated relocation sections (such as
.rela.text, and .rela.IA64_64.unwind) are copied to the output binary with
The compiler generated relocation sections are not copied to the output binary if -emit_relocs
is not used.
52Determining How to Link Programs or Libraries (Linker Tasks)
3 Linker Tools for Itanium-Based Systems
This chapter describes the linker toolset for Itanium-based system. This toolset provides several tools
to help you find symbols, display and modify object files, and determine link order. These tools
are specific to ELF (executable and linking format) object file type. The following lists Table 5 (page
53).
Table 5 Linker toolset for Itanium-Based systems
DescriptionTool
chatr
nm
elfdump
ldd
pldd
pstack
size
strip
fastbind
lorder
Displays or modifies the internal attributes of an object file. See “Changing a Program's Attributes
with chatr(1)” (page 53)
Displays the symbol table of an object file. See “Viewing Symbols in an Object file with nm(1)”
(page 56)
Displays the contents of an ELF object file. See “Viewing the Contents of an Object File with
elfdump(1)” (page 58)
Lists dynamic dependencies of executable files and shared libraries. “Viewing Library Dependencies
with ldd(1)” (page 60)
Lists the dynamic libraries linked into each process, including shared objects explicitly attached
using dlopen/shl_load.See “Listing Dynamic Libraries with pldd(1)” (page 61)
Prints a stack trace (hex+symbolic) for each lwp in each process and core file. See “Printing a
Stack Trace with pstack(1)” (page 62)Example 2 “Using the nm command”
Prints sizes of object file elements. See “ Viewing the Size of Object File Elements with size(1)”
(page 65)
Strips symbol and debugging information from an object file, executable, or archive library. See
“Reducing Storage Space with strip(1)” (page 65)
Improves start-up time of programs that use shared libraries. See“Improving Program Start-up with
fastbind(1)” (page 66)
Finds ordering relationship for an object library. See “Finding Object Library Ordering Relationships
with lorder(1)” (page 77)
ltrace
Traces inter-module procedure calls. See “Tracing Inter-Module Procedure Calls with ltrace(1)”
(page 67)
Changing a Program's Attributes with chatr(1)
The chatr command (see chatr(1)) allows you to change various program attributes that were
determined at link time. When run without any options, chatr displays the attributes of the specified
file. The following summarizes the options you can use to change various attributes:
The chatr command supports two different command syntaxes. One is provided for the easy
manipulation of simple files. Use it to modify files that have only a single text segment and data
segment. The second command syntax allows you to specify selected segments to modify.
The following sections list the additional IPF/PA-64 mode options for the chatr command. See
the chatr(1) manpage for more information about formats.
The following summarizes the options you can use to change various attributes:
Table 6 options to change various attributes
path lists are provided (see +s and +b).
Use the optionTo do this
-l libnameIndicate that the specified shared library is subject to run-time path lookup if directory
-sPerform operations silently.
Changing a Program's Attributes with chatr(1)53
Table 6 options to change various attributes (continued)
complement of the -Z option.)
default, share_magic, exec_magic, shmem_magic, and mpas. The default value is
currently equivalent to share_magic. In order to set the mode to any value other than
the default, the binary must be built with the -N compiler option to ensure that the text
and data segments are contiguous.
be used to locate shared libraries needed by the program. The two flag values, enable
and disable, respectively enable and disable use of the embedded path list. However,
you cannot use disable on an ELF file, and a warning message is issued. If +b enable
and +s enable are both specified, the order in which they appear determines which
search path is used first. See the +s option.
it is denoted by the +c flag for the segment listing in the chatr output.
by the +c flag for the segment listing in the chatr output.
Use the optionTo do this
-zEnable run-time dereferencing of null pointers to produce a SIGSEGV signal. (This is the
-B immediateUse immediate binding for all libraries loaded at program start-up.
-B deferredUse deferred binding for all libraries loaded at program start-up.
-ZDisable run-time dereferencing of null pointers. (This is the complement of the -z option.)
+as modeControl the address space model to be used by the kernel. Possible values for mode are
+b flagControl whether the embedded path list stored when the program (if any) was built can
+c flagFormat 2 only: Enable or disable the code bit for a specified segment. If this is enabled,
+cd flagEnable or disable the code bit for the file's data segment(s). If this is enabled, it is denoted
by the +c flag for the segment listing.
debugger and set breakpoints in its dependent shared libraries. For shared libraries, this
flag makes the text segment mapped private and writable.
(such as the stack or heap).
disable. See the "Restricting Execute Permission on Stacks" section of the chatr(1)
manpage for additional information related to security issues.
symbol import/export entries. The two flag values, enable and disable, respectively enable
and disable use of the global symbol table hash mechanism. The default is disable.
value can vary between 1 and MAXINT. The default value is 1103. Use this option with
+gst enable. This option works on files linked with the +gst option.
on ccNUMA (Coherent Non-Uniform Memory Architecture) systems. The flag value may
be either enable or disable. When enabled, the data segment uses interleaved memory.
When disabled (the default), the data segment uses cell local memory. This behavior is
inherited across a fork() but not an exec. For more information on ccNUMA, see
pstat_getlocality(2).
on and off, respectively.
+ci flagEnable or disable the code bit for the file's text segments(s). If this is enabled, it is denoted
+dbg flagEnable or disable the ability to run a program, and, after it is running, attach to it with a
+dz flagFormat 2 only: Enable or disable lazy swap allocation for dynamically allocated segments
+es flagControl the ability of user code to execute from stack with the flag values, enable and
+gst flagControl whether the global symbol table hash mechanism is used to look up values of
+gstsize sizeRequest a particular hash array size using the global symbol table hash mechanism. The
+id flagControls the preference of physical memory for the data segment. This is important only
+k flagRequest kernel assisted branch prediction. The flags, enable and disable, turn this request
default library path stored in the executable.
enabled, it is denoted by the +m flag for the segment listing in the chatr output.
54Linker Tools for Itanium-Based Systems
+l libnameDo not subject a library to path list lookup, even if path lists are provided. That is, use
+m flagFormat 2 only: Enable or disable the modification bit for a specified segment. If this is
Table 6 options to change various attributes (continued)
is denoted by the +m flag for the segment listing in the chatr output.
Use the optionTo do this
+md flagEnable or disable the modification bit for the file's data segment(s). If this is enabled, it
Enable or disable the automatic preloading of librtc.so runtime library for the specified
executable to support runtime memory leak checking. The +mem_check option also directs
the loader to map all shared library text into the private address space of the process.
segments of shared libraries loaded at program start-up are merged into a single block.
Data segments for each dynamically loaded library are merged with the data segments
of its dependent libraries. Merging of these segments increases run-time performance by
allowing the kernel to use larger size page table entries.
denoted by the +m flag for the segment listing in the chatr output.
absolute path of the load module directory. Enabling the flag instructs the dynamic loader
to calculate the absolute path of the parent module (object module, shared library, or
executable) when it is first loaded. The loader then uses this path for all occurrences of
$ORIGIN. If there are no occurrences of $ORIGIN, you should disable the DF_ORIGIN
flag, to avoid calculating the absolute path. By default, if $ORIGIN is not present, the
DF_ORIGIN flag is disabled.
16K, 64K, 256K, 1M, 4M, 16M, 64M, 256M, 1G, 4G, D, and L are supported. A size
of D results in using the default page size. A size of L results in using the largest page
size available. The actual page size may vary if the requested size cannot be fulfilled.
See the +pd option for additional information.
+mem_check
<enable|disable>
+mergeseg flagEnable or disable the shared library segment merging features. When enabled, all data
+mi flagEnable or disable the modification bit for the file's text segment(s). If this is enabled, it is
+o flagEnable or disable the DF_ORIGIN flag to control use of $ORIGIN in calculating the
+p sizeFormat 2 only: Set the page size for a specified segment.
+pd sizeRequest a particular virtual memory page size that must be used for data. Sizes of 4K,
+pi sizeRequest a particular virtual memory page size that should be used for text (instructions).
disable this request. If this request is enabled, it is denoted by the +r flag for the segment
listing in the chatr output.
SHLIB_PATH environment variables can be used to locate shared libraries needed by
the program. The two flag values, enable and disable, respectively enable and disable
use of the environment variable. If both +s and +b are used, their relative order on the
command line indicates which path list is searched first. See the +b option.
modifications.
segment (using Format 2). The flags enable and disable, this request. Cannot be used
with non-data segments.
enabled, the dynamic loader (see dld.so(5)) automatically invokes caliper upon program
execution to collect profile information.
Disable linkage table protection. Once you disable, you cannot use +protect to enable
linkage table protection. You have to relink the executable to turn on the linkage table
protection.
+r flagRequest static branch prediction when executing this program. The flags enable and
+s flagControl whether the directory path list specified with the LD_LIBRARY_PATH and
+sa addressFormat 2 only: Specify a segment using an address for a set of attribute modifications.
+sallFormat 2 only: Use all segments in the file for a set of attribute modifications.
+si indexFormat 2 only: Specify a segment using a segment index number for a set of attribute
+z flagEnable or disable lazy swap on all data segments (using Format 1) or on a specific
+I flagEnable or disable dynamic instrumentation by /opt/langtools/bin/caliper. If
+protect disable
flag
Changing a Program's Attributes with chatr(1)55
Viewing Symbols in an Object file with nm(1)
The nm(1) command displays the symbol table of each specified object. The file can be a
relocatable object file or an executable object file, or an archive of relocatable or executable
object files.
The nm command provides three general output formats: the default (neither -p nor -P specified),
-p, and -P. See the nm(1) man page for a detailed description of the output formats.
-r.
format or the -p format. Equivalent to -td.
weak symbols. Only takes effect with -p and/or -P.
Use the optionTo do this
-APrefix each output line with the name of the object file or archive file. Equivalent to
-CDemangle C++ names before printing them.
-dDisplay the value and size of a symbol in decimal. This is the default for the default
-eDisplay only external and static symbols. This option is ignored (see -f).
-fDisplay full output. This option is in force by default.
-gDisplay only external (global) symbol information.
-hDo not display the output header data.
-lDistinguish between weak and global symbols by appending * to the key letter of
the default. To turn off this option, use -N.
Display information in a blank-separated output format. Each symbol name is preceded
by its value (blanks if undefined) and one of the letters. Lower case letters indicate
local values. Upper case letters indicate global values.
absolute
a, A
bss symbol
b, B
common symbol
c, C
data symbol
d, D
milli symbol
m, M
no type
n, N
section region
r, R
-nSort symbols by name, in ascending collation order before they are printed. This is
-NDisplay symbols in the order in which they appear in the symbol table.
-oDisplay the value and size of a symbol in octal. Equivalent to -t o.
-p
text symbol
t, T
undefined symbol
u, U
manpage for format information. Note that -p is not compatible with -P.
56Linker Tools for Itanium-Based Systems
-PDisplay information in a portable output format to standard output. See the nm(1)
-A.
d
Display the value and size of a symbol in decimal. This is the default for the default
format or the -p format. Equivalent to -d.
o
Display the value and size of a symbol in octal. Equivalent to
-o.
x
Display the value and size of a symbol in hexadecimal. This is the default for the -P
format. Equivalent to -x.
format. Equivalent to -t x.
-rPrefix each output line with the name of the object file or archive file. Equivalent to
-sPrint the section index instead of the section name (ELF only).
-t formatDisplay each numeric value in the specified format. The format can be one of:
-uDisplay undefined symbols only.
-UPrint the usage menu.
-vSort symbols by value before they are printed.
-VDisplay the executing version of the nm command on standard error.
-xDisplays the value and size of a symbol in hexadecimal. this is the default for the -P
Viewing Symbols in an Object file with nm(1)57
Example 2 Using the nm command
•Display which object files have undefined references for the symbol leap:
nm -rup *.o | grep leap
•Display which object files have a definition for the text symbol leap:
•To view the symbols defined in an object file, use the nm command. The following 32-bit mode
example shows output from running nm -p on the func.o and main.o object files.
$ nm -p func.o
0000000000 u
0000000000 r .HP.opt_annot
0000000000 r .IA_64.unwind_info
0000000000 r .text
0000000000 a func.c
0000000000 T sum_n //Global definitions of sum_n.
$ nm -p main.o
0000000000 U $global$ //Other symbols created from compiling.
0000000000 u
0000000000 r .HP.opt_annot
0000000000 r .IA_64.unwind_info
0000000000 r .data
0000000000 r .sdata
0000000000 r .text
0000000000 a main.c
0000000000 T main //Global definition of main.
0000000000 U printf
0000000000 U scanf
0000000000 U sum_n
Viewing the Contents of an Object File with elfdump(1)
The elfdump(1) command displays information contained in ELF format object files, archives,
and shared libraries. Use the following options to select the information you want to display:
option has the same effect as elfdump -dc-dl.
used to generate the file as well as the link time.
and microloader). Only shared bound executables have this string. To change the setting,
use the ld+interp command.
Use the optionTo view this
-aArchive headers from an archive library.
-cString table(s).
-dThe .note section which contains the compilation unit dictionary and linker footprint. This
-dcThe compilation unit dictionary of the .note section.
-dcThe linker footprint of the .note section. The linker footprint has information on the linker
-fFile header.
-gGlobal symbols from an archive.
-hSection headers.
+interpThe run-time interpreter path name for a.out (usually the location of the dynamic loader
the +objdebug option. The object dictionary entry contains the name of the object file that
contributed to a particular section, the relative offset within the section, size of the object
file's contribution, and attributes of the entry.
58Linker Tools for Itanium-Based Systems
-jThe object dictionary for one or more executable files, if the source file was compiled with
-kThe CTTI section headers according to the directory member relationship.
ld+ild command).
the ld +ild command).
the ld +ild command).
option. This option is useful in verifying the data stored in the symbol table.
Use the optionTo view this
-LThe .dynamic section in shared libraries and dynamically linked program files.
+linkmapThe .linkmap section, which is only created when the incremental linker is used (with the
+linkmap_bssThe .linkmap_bss section, which is only created when the incremental linker is used (with
+linkmap_fileThe .linkmap_file section, which is only created when the incremental linker is used (with
-oOptional headers (program headers).
-rRelocations.
+objdebugSections beginning with .objdebug_ as a string table.
-sSection contents.
-tSymbol table entries.
-txDumps the value of st_shndx in symbol table, in addition to information dump from -t
-tvPrints versioned symbols.
-uUsage message.
-UUnwind table.
-VVersion number for elfdump.
The elfdump command provides the following additional options to modify your selections:
Causes elfdump toModifiesOption
-c, -r, -s, -t-C
-h, -s-D num
-h, -s+D num2
-r-D num
-r+D num2
all-H
-h, -r, -s-n name
-t-n name
Demangle C++ symbol names before displaying them.
• With -H, ignored.
• With -n name, display the symbol whose unmangled name matches
name, and prints its symbol name as a demangled name.
Display the section whose index is num.
Display the sections in the range 1 to num2.
• With -D, display the sections in the range num to num2.
Display the relocation whose index is num.
Display only the relocations which apply to the section(s) in the range.
Select output format in hexadecimal, octal, or decimal.
Display information about the section specified by name.
Display information about the symbol entry specified by name.
all-p
-k-q
-c, -t+s name
-h,-o-S
-t-T num
Suppress title printing.
Suppress printing CTTI section headers.
Display the section specified by name.
Display headers in short format.
Display the symbol whose index is num.
Viewing the Contents of an Object File with elfdump(1)59
Causes elfdump toModifiesOption
-t+T num2
-k-v
Display the symbols in the range 0 to num2.
• With-T, display the symbols in the range num to num2.
Verify the CTTI section headers before printing.
Viewing Library Dependencies with ldd(1)
The ldd(1) command lists the dynamic dependencies of executable files or shared libraries. The
ldd command displays verbose information about dynamic dependencies and symbol references:
•Executable
All shared libraries loaded as a result of executing the file.
•Shared library
All shared libraries loaded as a result of loading the library.
The ldd command uses the same algorithm as the dynamic loader (/usr/lib/hpux32/dld.so
and /usr/lib/hpux64/dld.so) to locate the shared libraries.
The ldd command does not list shared libraries explicitly loaded using dlopen(3C) or
shl_load(3X). The ldd command prints the record of shared library path names to stdout. It
prints a list of symbol resolution problems to stderr
Table 7 Symbol resolution problems to stderr
Use the optionTo do this
-dCheck reference to data symbols.
-rCheck reference to data and code symbols.
-sDisplays the search path used to locate the shared libraries.
-vDisplay all dependency relationships
-y, <symbol>Find names of module which refers and defines the symbol
.
60Linker Tools for Itanium-Based Systems
Example 3 Using the ldd command
•By default, ldd prints simple dynamic path information, including the dependencies recorded
in the executable (or the shared library) followed by the physical location where the dynamic
loader finds these libraries.
•The -v option causes ldd to print the dependency relationships along with the dynamic path
information.
$ ldd -v a.out
find library=./libx.so; required by a.out
./libx.so => ./libx.so
find library=libc.so.1; required by a.out
libc.so.1 => /usr/lib/hpux32/libc.so.1
find library=libdl.so.1; required by usr/lib/hpux32/libc.so.1
libdl.so.1 => /usr/lib/hpux32/libdl.so.1
•The -r option to causes it to analyze all symbol references and print information about
unsatisfied code and data symbols.
$ldd -r a.out
./libx.sl => ./libx.sl
libc.so.1 => /usr/lib/hpux32/libc.so.1
libdl.1 => /usr/lib/hpux32/libdl.so.1
symbol not found: val1 (./libx.so)
symbol not found: count (./libx.so)
symbol not found: func1 (./libx.so)
symbol not found: func2 (./libx.so)
•The -y, <symbol> option can be used to point out the module from which the specified
symbol is being resolved. It can also be used to point out modules that refer to the specified
symbol.
$ ldd -y,bar a.out
libx.so => ./libx.so
libc.so.1 => /usr/lib/hpux32/libc.so.1
libdl.so.1 => /usr/lib/hpux32/libdl.so.1
bar (data) : needed by a.out; found in ./libx.so
bar (data) : needed by ./libx.so; found in ./libx.so
$ ldd -y,foo a.out
libx.so => ./libx.so
libc.so.1 => /usr/lib/hpux32/libc.so.1
libdl.so.1 => /usr/lib/hpux32/libdl.so.1
foo (code) : needed by a.out; found in ./libx.so
foo (code) : needed by ./libx.so; found in ./libx.so
Listing Dynamic Libraries with pldd(1)
Given a process ID (PID) or a corefile, the pldd command prints a list of shared libraries loaded
including those loaded explicitly with dlopen() and shl_load(). The pldd command works
by attaching to the process to read its memory. Mismatch between executable and corefile may
result in unpredictable behavior. The pldd command searches for the executable file in the current
Listing Dynamic Libraries with pldd(1)61
directory and $PATH. The executable path can be specified along with the pid/corepath, separated
by a colon (:) character. Use the -h option to print the usage menu.
The following exit values are returned:
0: Successful operation
non-zero: An error has occurred.
Use the following options to view information for your specified files.
Use the optionTo
-hPrint the usage menu
-lPrint the start and end addresses of text and data segment mappings for the shared libraries
The –l option can be used to print the start and end address of text and data segment mappings
of each shared library used by the process.
Example 4 Executing ‘pldd –t XXXXX’ gives the following information
Given the PID of a running process or the full path to a corefile, the pstack command prints the
stack trace for each lwp thread in the process. To obtain symbol information, pstack searches load
modules (executable/shared libraries) in the current directory, $PATH, $LD_LIBRARY_PATH, and
$SHLIB_PATH. The executable path can be specified along with the PID/core-file-path, separated
by a colon (:) character. If a load module is not found, symbol information for frames in that module
is not displayed.
The pstack command works by attaching to the running process and reading its registers, memory,
and stack. Mismatch between executable and corefile may result in unpredictable behavior.
The following exit values are returned:
0:Successful operation
non-zero: An error has occurred.
Use the following options to view information for your specified files:
Table 8 Options to view information specified files
Print stack upto a specified level
62Linker Tools for Itanium-Based Systems
Use the optionTo view this
-hPrint the usage menu
-level (with level
parameter)
-t (with thread id)Print stack of only one thread using suspending execution of other threads
The -level n option can be used to print n levels of procedure calls. Without this option, pstack
normally prints the complete procedure stack. With this option, pstack can be restricted to print
'n' levels in the procedure stack. With this option, pstack can be restricted to print only n levels of
procedure calls in the procedure stack.
The following example shows the result of running pstack for a process id 3975.
On HP-UX 11i v3 Integrity systems, the -t <thread id> can be used to print stack trace of the
target thread alone. Only the execution of the target thread is suspended while other threads
continue to execute. The following example shows the usage if -t <thread id> option is used
to print the default output for a sample threaded process.
Printing a Stack Trace with pstack(1)63
Example 7 Printing the default output for a sample threaded process
A special argument -1 enables you to trace the calling process without entering the PID of the
process. Hence, you can skip the process of finding the PID by using this argument on a calling
process.
The example below shows the usage of special argument -1 that can be used to run pstack on
the calling process. In this case, the calling process is the shell itself.
Viewing the Size of Object File Elements with size(1)
The size(1) command produces section size information for each section in your specified
object files. It displays the size of the text, data, and bss (uninitialized data) sections with the total
size of the object file. If you specify an archive file, the information for all archive members is
displayed. Use the following options to view information for your specified files:
with its name, size, and virtual address.
Reducing Storage Space with strip(1)
Use the optionTo view this
-dSizes in decimal (default).
-fSize of each allocatable section.
-FSize and permission bits of each loadable segment.
-nSizes of nonloadable segments or nonallocatable sections.
-oSizes in octal.
-UDisplay the usage message.
-VVersion information about the size command.
-vVerbose list of the subspaces in the object files. Each subspace is listed on a separate line
-xSizes in hexadecimal.
The strip(1) command removes the symbol table and line number information from object files,
including archives. Thereafter, no symbolic debugging access is available for that file. The purpose
of this command is to reduce file storage overhead consumed by the object file. Use this command
on production modules that have been debugged and tested. The effect is nearly identical to using
the -s option of ld. You can control the amount of information stripped from the symbol table by
using the following options:
Viewing the Size of Object File Elements with size(1)65
Table 9 Options to control the amount of information stripped
Use the optionTo
-lStrip line number information only; do not strip any symbol table information.
-rSame as the -x option. Obsolete.
-uStrip the unwind information and annotations.
-UPrint the usage message.
-VPrint the version of the strip command to stderr.
-xStrip the debug information and line number table.
NOTE:The -l and -x options are synonymous because the symbol table contains only static
and external symbols. Either option strips only symbolic debugging information and unloadable
data.
If there are any relocation entries in the object file and any symbol table information is to be
stripped, strip issues a message and terminates without stripping the specified file unless the -r
option is used. If you execute strip on an archive file (see ar(4)), it removes the archive symbol
table. The archive symbol table must be restored by executing ar with its s operator (see ar(1))
before the ld command (see ld (1)) can use the archive. The strip command issues appropriate
warning messages when this situation occurs.
Improving Program Start-up with fastbind(1)
The fastbind(1) command prepares an incomplete executable for faster program start-up. It
can improve the start-up time of programs that use shared libraries (incomplete executables) by
storing information about needed shared library symbols in the executable file. The fastbind
command performs analysis on the symbols used to bind an executable and all of its dependent
shared libraries, and stores this information in the executable file. The next time the executable is
run, the dynamic loader (/usr/lib/hpux32/dld.so for 32-bit or /usr/lib/hpux64/dld.so
for 64-bit) detects that this information is available, and uses it to bind the executable instead of
using the standard search method for binding the symbols. The fastbind command writes the
fastbind information in the executable file. Hence, you must have write permission on the
executable file. If the executable file being analyzed is being run as another process or the file is
locked against modifications by the kernel, the fastbind command fails. If the shared libraries
that an executable is dependent on are modified after the fastbind information is created, the
dynamic loader silently reverts to standard search method for binding the symbols. The fastbind
information can be re-created by running the fastbind command on the executable again. The
fastbind command automatically erases the old fastbind information and generates the new
one.
was in before you ran fastbind on it.
Use the optionTo do this
-nRemove the fastbind information from the executable, returning it to the same state it as
information, it generates an error message and does not modify the executable file. However,
when you invoke fastbind with the -u option, fastbind allows unresolved symbols.
The PA-32-bit mode fastbind command does not work with EXEC_MAGIC executables. The
fastbind command effectively enforces the binding modes bind-restricted and bind-immediate.
For example, consider an executable linked bind-deferred, which calls a function foo() defined
in an implicitly loaded library. Before the actual call is made, if it explicitly loads a shared library
(using shl_load(3X) with BIND_FIRST) having a definition for foo() when foo() is finally
66Linker Tools for Itanium-Based Systems
-uNormally, if fastbind detects any unsatisfied symbols while building the fastbind
called, it is resolved from the explicitly-loaded library. But after running fastbind, the symbol foo()
is resolved from the implicitly-loaded library. For more information about fastbind and how to
improve program start-up time, see “Improving Shared Library Start-Up Time with fastbind” (page
222) .
Example 10 Example
•To run fastbind on the executable file a.out:
$fastbind a.out
•To later remove the fastbind information from the executable file a.out
$fastbind -n a.out
Finding Object Library Ordering Relationships with lorder(1)
The lorder command finds the ordering relation for an object library. You can specify one or more
object or archive library files (see ar(1)) on the command line or read those files from standard
input. The standard output is a list of pairs of object file names, meaning that the first file of the
pair refers to external identifiers defined in the second. You can process the output with tsort to
find an ordering of a library suitable for one-pass access by ld (see tsort(1) and ld(1)).
The linker ld is capable of multiple passes over an archive in the archive format and does not
require that you use lorder when building an archive. Using the lorder command may, however,
allow for a slightly more efficient access of the archive during the link-edit process. The symbol
table maintained by ar allows ld to randomly access symbols and files in the archive, making the
use of lorder unnecessary when building archive libraries (see ar(1)). The lorder command
overlooks object files whose names do not end with .o, even when contained in library archives,
and attributes their global symbols and references to some other file.
Example 11 Examples
•Build a new library from existing .o files:
$ar cr library `lorder *.o | tsort`
•When creating libraries with so many objects that the shell cannot properly handle the *.o
expansion, the following technique may prove useful:
$ls |grep '.o$'|lorder|tsort|xargs ar cq library
Tracing Inter-Module Procedure Calls with ltrace(1)
The ltrace(1) command traces inter-module procedure calls. ltrace can be invoked as follows:
$ /usr/ccs/bin/ltrace [ltrace options] executable [-a <arguments to the
executable>]
On executing the above command, a log is generated in the file logfile.txt in the current working
directory. In case the log file already exists, it is appended with the output of the current ltrace
invocation. For each call made in the application, the following line is added into the logfile:
NOTE:The arguments are printed in the logfile only if a debug version of a library is being
traced. To re-direct the output of the logfile.txt to an alternate file mylogfile, use the following
command:
$/usr/ccs/bin/ltrace -f mylogfile ./a.out
In case of multiple invocations through the same command line, such as:
$ /usr/ccs/bin/ltrace ./a.out ./b.out
Finding Object Library Ordering Relationships with lorder(1)67
The output from each of the execution is appended to the log file.
To generate a log when a program $ ./a.out arg1 arg2 arg3 .. argn is executed, use the following
command syntax:
$/usr/ccs/bin/ltrace ./a.out -a "arg1 arg2 arg3 .. argn"
For example:
$/usr/ccs/bin/ltrace /usr/bin/ls -a "-ltr"
The above-mentioned command has the effect of tracing all inter-module procedure calls when
/usr/bin/ls -ltr command is executed.
NOTE:ltrace does not need the debug version of the library libc as it already includes
prototype information for some of the most commonly used libc procedures. For the remaining
libc procedures, only the execution is reported.
68Linker Tools for Itanium-Based Systems
4 Linker Tools for PA-RISC Systems
This chapter describes the linker toolset, which provides several tools to help you find symbols,
display and modify object files, and determine link order. Some of these tools are specific to a
particular object file type. Others are available in both 32-bit and 64-bit mode. The following table
lists the linker toolset.
DescriptionModeTool
32-bit/64-bitchatr
32-bit/64-bitnm
64-bitelfdump
32-bit/64-bitldd
32-bit/64-bitsize
32-bit/64-bitstrip
32-bit/64-bitfastbind
32-bit/64-bitlorder
Displays or modifies the internal attributes of an object file. See “Changing a
Program's Attributes with chatr(1)” (page 69) .
Displays the symbol table of an object file. See “Viewing Symbols in an Object
file with nm(1)” (page 71) .
Displays the contents of an ELF object file. See “Viewing the Contents of an Object
File with elfdump(1)” (page 72)
Lists dynamic dependencies of executable files and shared libraries. “Viewing
library dependencies with ldd(1)” (page 74).
Prints sizes of object file elements. See “Viewing the Size of Object File Elements
with size(1)” (page 75)
Strips symbol and debugging information from an object file, executable, or
archive library. See “Reducing Storage Space with strip(1)” (page 76)
Improves startup time of programs that use shared libraries. See. “Improving
Program Start-up with fastbind(1)” (page 76)
Finds ordering relationship for an object library. See “Finding Object Library
Ordering Relationships with lorder(1)” (page 77)
Displays the contents of a SOM object file. See the odump(1).32-bitodump
Changing a Program's Attributes with chatr(1)
The chatr command (seechatr(1)) allows you to change various program attributes that were
determined at link time. When run without any options, chatr displays the attributes of the specified
file.
Using chatr for 32-bit Program Attributes
The following table summarizes the options you can use to change various attributes:
32-bit mode only: Set the file's magic number to SHARE_MAGIC.
32-bit mode only: Set the file's magic number to DEMAND_MAGIC.
32-bit mode only: Change the file's magic number from EXEC_MAGIC to
SHMEM_MAGIC.
32-bit mode only: Change the file's magic number from SHMEM_MAGIC to
EXEC_MAGIC.
Use immediate binding for all libraries loaded at program startup.
Use deferred binding for all libraries loaded at program startup.
Use nonfatal binding. Must be specified with -B immediate or -B deferred.
Use restricted binding. Must be specified with -B immediate or -B deferred.
Use the optionTo
-n
-q
-M
-N
-B immediate
-B deferred
-B nonfatal
-B restricted
Changing a Program's Attributes with chatr(1)69
Enable run-time use of the path list specified with the +b option at link time.
Use the optionTo
+b enable
If +b enable and +s enable are both
specified, the order in which they appear
determines which search path is used
first.
Disable run-time use of the path list specified with the +b option at link time.
Enable the use of the SHLIB_PATH environment variable to perform run-time
path list lookup of shared libraries.
Disable the use of the SHLIB_PATH environment variable to perform run-time
path list lookup of shared libraries.
32-bit mode only: Use default library path stored in the executable even if
path lists are provided. That is, prevent a library from looking up a path list.
32-bit mode only: Subject a library to path list lookup if directory path lists
are provided. Useful for libraries that were specified with a full path name
at link time.
Set the virtual memory page size for data segments.
Set the virtual memory page size for instructions.
Assist branch prediction on PA-RISC 2.0 systems. Programs must be linked
with +Ostaticprediction.
Request static branch prediction.
Disable linkage table protection. Once you disable, you cannot use +protect
to enable linkage table protection. You have to relink the executable to turn
on the linkage table protection.
Enable or disable the automatic preloading of librtc.sl runtime library for the
specified executable to support runtime memory leak checking. The
+mem_check option also directs the loader to map all shared library text
into the private address space of the process.
+b disable
+s enable
+s disable
+l libname
-l libname
+pd size
+pi size
+k
+r
+protect disable
+mem_check <enable|disable>
Using chatr for 64-bit Program Attributes
In 64-bit mode, chatr supports two different command syntaxes. One is compatible with the
32-bit command. Use it to modify files that have only a single text segment and data segment. The
second command syntax allows you specify selected segments to modify. The following sections
list the additional 64-bit mode options for the chatr command.
Table 10 For the 32-bit compatible syntax
the complement of the -Z option.)
Use the optionTo
+mdSet the modification bit for the file's data segment(s).
+miSet the modification bit for the file's text segment(s).
+cdSet the code bit for the file's data segment(s).
+ciSet the code bit for the file's text segment(s).
+zEnable lazy swap on all data segments. Do not use with non-data segments.
-zEnable run-time dereferencing of null pointers to produce a SIGSEGV signal. (This is
70Linker Tools for PA-RISC Systems
Table 11 For the 64-bit only syntax
the stack or heap).
use with non-data segments.
the complement of the -Z option.)
Viewing Symbols in an Object file with nm(1)
The nm command displays the symbol table of each specified object. The file can be a relocatable
object file or an executable object file, or an archive of relocatable or executable object files. The
nm command provides three general output formats: the default (neither -p nor -P specified), -p,
and -P. See the nm(1) man page for a detailed description of the output formats.
Use the optionTo
+cSet the code bit for a specified segment.
+dzEnables or disables lazy swap allocation for dynamically allocated segments (such as
+mSet the modification bit for a specified segment.
+pSet the page size for a specified segment.
+siIdentify a segment using a segment index number.
+saIdentify a segment using an address.
+sallUse all segments in the file for a set of attribute modifications.
+zEnable lazy swap on a specific segment (using the second command syntax). Do not
-zEnable run-time dereferencing of null pointers to produce a SIGSEGV signal. (This is
or the -p format. Equivalent to -t d.
symbols. Only takes effect with -p and/or -P.
To turn off this option, use -N.
its value (blanks if undefined) and one of the letters. A absolute B bss symbol C common
symbol D data symbol R section region S tstorage symbol (32-bit mode SOM files only) If the
symbol is local (nonexternal), the type letter is in lowercase. If the symbol is a secondary
definition, the type letter is followed by the letter S. Note that -p is not compatible with -P. T
text symbol U undefined
Use the optionTo
-APrefix each output line with the name of the object file or archive file. Equivalent to -r.
-C64-bit mode ELF files only: Demangle C++ names before printing them.
-dDisplay the value and size of a symbol in decimal. This is the default for the default format
-eDisplay only external and static symbols. This option is ignored (see -f).
-fDisplay full output. This option is in force by default.
-gDisplay only external (global) symbol information.
-hDo not display the output header data.
-lDistinguish between weak and global symbols by appending * to the key letter of weak
-nSort symbols by name, in ascending collation order, before they are printed. This is the default.
-NDisplay symbols in the order in which they appear in the symbol table.
-oDisplay the value and size of a symbol in octal. Equivalent to -t o.
-pDisplay information in a blank-separated output format. Each symbol name is preceded by
compatible with -P.
-PDisplay information in a portable output format to standard output. Note that -p is not
-q32-bit mode SOM files only: Silence some warning messages.
Viewing Symbols in an Object file with nm(1)71
value and size of a symbol in decimal. This is the default for the default format or the -p
format. Equivalent to -d. o Display the value and size of a symbol in octal. Equivalent to -o.
x Display the value and size of a symbol in hexadecimal. This is the default for the -P format.
Equivalent to -x.
and place an asterisk as the last character in the displayed name to mark it as truncated. If
-A or -r is also specified, the file prefix is truncated first. By default, nm prints the entire name
of the symbols listed. Because object files can have symbol names with an arbitrary number
of characters, a name that is longer than the width of the column set aside for names overflows
its column, forcing every column after the name to be misaligned.
Equivalent to -t x.
Example 12 Viewing Symbols in an Object file with nm(1)
Use the optionTo
-rPrefix each output line with the name of the object file or archive file. Equivalent to -A.
-t formatDisplay each numeric value in the specified format. The format can be one of: d Display the
-T32-bit mode SOM files only: Truncate every name that would otherwise overflow its column
-uDisplay undefined symbols only.
-UPrint the usage menu.
-vSort symbols by value before they are printed.
-VDisplay the executing version of the nm command on standard error.
-xDisplays the value and size of a symbol in hexadecimal. This is the default for the -P format.
•Display which object files have undefined references for the symbol "leap":
$ nm -rup *.o | grep leap
•Display which object files have a definition for the text symbol "leap":
•To view the symbols defined in an object file, use the nm command. The following 32-bit mode
example shows output from running nm -p on the func.o and main.o object files.
$ nm -p func.o
1073741824 d $THIS_DATA$
1073741824 d $THIS_SHORTDATA$
1073741824 b $THIS_BSS$
1073741824 d $THIS_SHORTBSS$
0000000000 T sum_n //Global definitions of sum_n.
$ nm -p main.o
0000000000 U $global$ //Other symbols created from compiling.
1073741824 d $THIS_DATA$
1073741872 d $THIS_SHORTDATA$
1073741872 b $THIS_BSS$
1073741872 d $THIS_SHORTBSS$
0000000000 T main //Global definition of main.
0000000000 U printf
0000000000 U scanf
0000000000 U sum_n
The first column shows the address of each symbol or reference. The last column shows the
symbol name. The second column denotes the symbol's type: T indicates a global definition.
U indicates an external reference. d indicates a local definition of data. b indicates a local
definition of uninitialized data (bss). Thus, a global definition of sum_n is found in func.o.
An external reference to sum_n is found in main.o. External references to the C printf
and scanf routines are found in main.o. For details on the use of nm, see nm(1).
Viewing the Contents of an Object File with elfdump(1)
NOTE:The elfdump command works on 64-bit executables or shared libraries.
72Linker Tools for PA-RISC Systems
The elfdump command displays information contained in ELF format object files, archives, and
shared libraries. Use the following options to select the information you want to display:
Use the optionTo view
-tSymbol table entries.
-aArchive headers from an archive library.
-cString table(s).
-fFile header.
-gGlobal symbols from an archive.
-hSection headers.
-LThe .dynamic section in shared libraries and dynamically linked program files.
-oOptional headers (program headers).
-rRelocations
-sSection contents.
-UUnwind table.
-tvVersioned symbols.
The elfdump command provides the following additional options to modify your selections:
Causes elfdump toModifiesOption
Select output format in hexadecimal, octal, or decimal.all-H
Suppress title printing.all-p
Display headers in short format.-h,-o-S
Demangle C++ symbol names before displaying them.-c, -r, -s, -t-C
• With -H, ignored.
• With -n name, display the symbol whose unmangled name matches
name, and prints its symbol name as a demangled name.
Display the section whose index is num.-h, -s-D num
-h, -s+D num2
Display the sections in the range 1 to num2.
• With -D, display the sections in the range num to num2.
Display the relocation whose index is num.-r-D num
Display only the relocations which apply to the section(s) in the range.-r+D num2
Display the section specified by name.-c, -t+s name
Display information about the section specified by name.-h, -r, -s-n name
Display information about the symbol entry specified by name.-t-n name
Display the symbol whose index is num.-t-T num
-t+T num2
Display the symbols in the range 0 to num2.
• With-T, display the symbols in the range num to num2.
Viewing the Contents of an Object File with elfdump(1)73
Viewing library dependencies with ldd(1)
The ldd command lists the dynamic dependencies of executable files or shared libraries. The
ldd command displays verbose information about dynamic dependencies and symbol references:
Executable All shared libraries that are loaded as a result of executing the file. Shared library All
shared libraries that are loaded as a result of loading the library. The ldd command uses the same
algorithm as the dynamic loader (/usr/lib/dld.sl and /usr/lib/pa20_64/dld.sl) to
locate the shared libraries. The ldd command does not list shared libraries explicitly loaded using
dlopen(3C) or shl_load(3X). The ldd command prints the record of shared library path
names to stdout. It prints the optional list of symbol resolution problems to stderr.
Table 12 optional list of symbol resolution problems to stderr
libraries and report unsats. By default the smartbind mechanism in dld.sl only binds
libraries whose symbols are explicitly referenced.
Use the optionTo do this
-b32-bit mode only: Used in conjunction with -d and/or -r, force dld.sl to bind all dependent
-dCheck reference to data symbols.
-rCheck reference to data and code symbols.
-sDisplay the search path used to locate the shared libraries.
-vDisplay all dependency relationships.
-y, <symbol>Find names of module which refers and defines the symbol.
74Linker Tools for PA-RISC Systems
Example 13 Viewing library dependencies with ldd(1)
•By default, ldd prints simple dynamic path information, including the dependencies recorded
in the executable (or the shared library) followed by the physical location where the dynamic
loader finds these libraries.
•The -v option causes ldd to print the dependency relationships along with the dynamic path
information.
$ ldd -v a.out
find library=./libx.sl; required by a.out
./libx.sl => ./libx.sl
find library=libc.2; required by a.out
libc.2 => /lib/pa20_64/libc.2
find library=libdl.1; required by /lib/pa20_64/libc.2
libdl.1 => /lib/pa20_64/libdl.1
•The -r option to causes it to analyze all symbol references and print information about
unsatisfied code and data symbols.
$ ldd -r a.out
./libx.sl => ./libx.sl
libc.2 => /lib/pa20_64/libc.2
libdl.1 => /lib/pa20_64/libdl.1
symbol not found: val1 (./libx.sl)
symbol not found: count (./libx.sl)
symbol not found: func1 (./libx.sl)
symbol not found: func2 (./libx.sl)
•The -y, <symbol> option can be used to point out the module from which the specified
symbol is being resolved. It can also be used to point out modules that refer to the specified
symbol.
$ ldd -y,bar a.out
libx.so => ./libx.so
libc.so.1 => /usr/lib/hpux32/libc.so.1
libdl.so.1 => /usr/lib/hpux32/libdl.so.1
bar (data) : needed by a.out; found in ./libx.so
bar (data) : needed by ./libx.so; found in ./libx.so
$ ldd -y,foo a.out
libx.so => ./libx.so
libc.so.1 => /usr/lib/hpux32/libc.so.1
libdl.so.1 => /usr/lib/hpux32/libdl.so.1
foo (code) : needed by a.out; found in ./libx.so
foo (code) : needed by ./libx.so; found in ./libx.so
Viewing the Size of Object File Elements with size(1)
The size command produces section size information for each section in your specified object
files. It displays the size of the text, data and bss (uninitialized data) sections with the total size of
Viewing the Size of Object File Elements with size(1)75
the object file. If you specify an archive file, the information for all archive members is displayed.
Use the following options to display information for your specified files:
with its size, physical address, and virtual address.
Reducing Storage Space with strip(1)
The strip command removes the symbol table and line number information from object files,
including archives. Thereafter, no symbolic debugging access is available for that file. The purpose
of this command is to reduce file storage overhead consumed by the object file. Use this command
on production modules that have been debugged and tested. The effect is nearly identical to using
the -s option of ld. You can control the amount of information stripped from the symbol table by
using the following options:
Use the optionTo display
-dSizes in decimal (default).
-oSizes in octal.
-xSizes in hexadecimal.
-VVersion information about the size command.
-vVerbose list of the subspaces in the object files. Each subspace is listed on a separate line
-f64-bit mode only: Size of each allocatable section.
-F64-bit mode only: Size and permission bits of each loadable segment=.
-n64-bit mode only: Sizes of non loadable segments or non allocatable sections.
-UPrint the usage menu
Use the optionTo
-lStrip line number information only; do not strip any symbol table information.
-xDo not strip static or external symbol information.
-r32-bit mode only: Reset the relocation indexes into the symbol table. This option allows strip
to be run on relocatable files, in which case the effect is also to strip only symbolic
debugging information and unloadable data.
-VPrint the version of the strip command to stderr.
NOTE:The -l and -x options are synonymous because the symbol table contains only static
and external symbols. Either option strips only symbolic debugging information and unloadable
data.
If there are any relocation entries in the object file and any symbol table information is to be
stripped, strip issues a message and terminates without stripping the specified file unless the -r
option is used.
If you execute strip on an archive file (see ar(4)), it removes the archive symbol table. The archive
symbol table must be restored by executing ar with its s operator (see ar(1)) before the ld
command (see ld (1)) can use the archive. strip issues appropriate warning messages when
this situation occurs.
Improving Program Start-up with fastbind(1)
The fastbind(1) command prepares an incomplete executable for faster program start-up. It
can improve the start-up time of programs that use shared libraries (incomplete executables) by
storing information about needed shared library symbols in the executable file.
76Linker Tools for PA-RISC Systems
The fastbind command performs analysis on the symbols used to bind an executable and all
of its dependent shared libraries, and stores this information in the executable file. The next time
the executable is run, the dynamic loader (/usr/lib/dld.sl for 32-bit mode or
/usr/lib/pa20_64/dld.sl for 64-bit mode) detects that this information is available, and
uses it to bind the executable instead of using the standard search method for binding the symbols.
Because fastbind writes the fastbind information in the executable file, you must have write
permission on the executable file. If the executable file being analyzed is being run as another
process or the file is locked against modifications by the kernel, the fastbind command fails.
If the shared libraries that an executable is dependent on are modified after the fastbind information
is created, the dynamic loader silently reverts to standard search method for binding the symbols.
The fastbind information can be re-created by running fastbind on the executable again. The
fastbind command automatically erases the old fastbind information and generate the new one.
Use the optionTo
-nRemove the fastbind information from the executable, returning it to the same state it as was in
before you ran fastbind on it.
-uNormally, if fastbind detects any unsatisfied symbols while building the fastbind information,
it generates an error message and does not modify the executable file. When you invoke
fastbind with the -u option however, it allows unresolved symbols.
The 32-bit mode fastbind command does not work with EXEC_MAGIC executables.
The fastbind command effectively enforces the binding modes bind-restricted and bind-immediate.
For example, consider an executable linked bind-deferred, which calls a function foo() defined
in an implicitly loaded library. Before the actual call is made, if it explicitly loads a shared library
(using shl_load(3X) with BIND_FIRST) having a definition for foo() when foo() is finally
called, it is resolved from the explicitly-loaded library. But after running fastbind, the symbol
foo() is resolved from the implicitly-loaded library.
For more information about fastbind and performance, see “Improving Shared Library Start-Up
Time with fastbind” (page 222) .
Example 14 Improving Program Start-up with fastbind(1)
•To run fastbind on the executable file a.out:
$ fastbind a.out
•To remove the fastbind information from the executable file a.out:
$ fastbind -n a.out
Finding Object Library Ordering Relationships with lorder(1)
The lorder command finds the ordering relation for an object library. You can specify one or
more object or archive library files (see ar(1)) on the command line or read those files from
standard input. The standard output is a list of pairs of object file names, meaning that the first file
of the pair refers to external identifiers defined in the second.
You can process the output with tsort to find an ordering of a library suitable for one-pass access
by ld (see tsort(1) and ld(1)). The linker ld is capable of multiple passes over an archive
in the archive format and does not require that you use lorder when building an archive. Using
the lorder command may, however, allow for a slightly more efficient access of the archive
during the link-edit process.
The symbol table maintained by ar allows ld to randomly access symbols and files in the archive,
making the use of lorder unnecessary when building archive libraries (see ar(1)).
Finding Object Library Ordering Relationships with lorder(1)77
The lorder command overlooks object files whose names do not end with .o, even when contained
in library archives, and attributes their global symbols and references to some other file.
Example 15 Finding Object Library Ordering Relationships with lorder(1)
•Build a new library from existing .o files:
$ ar cr library `lorder *.o | tsort`
•When creating libraries with so many objects that the shell cannot properly handle the *.o
expansion, the following method may prove useful:
$ ls |grep '.o$'|lorder|tsort|xargs ar cq library
78Linker Tools for PA-RISC Systems
5 Linker Toolset Differences Between PA-RISC and
Itanium-Based Systems
This chapter describes some of the linker toolset differences between PA-RISC and Itanium-based
systems. This chapter discusses the following topics:
•“Linker Toolset Compatibility with De Facto Industry Standards” (page 79)
•“PA-RISC Changes in Hardware Compatibility” (page 79)
•“Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)” (page 80)
•“Run-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)” (page 82)
•“PA64 Mode Linker Options” (page 82)
•“Linker-Defined Symbols” (page 82)
•“Dynamic Path Searching for Shared Libraries” (page 83)
•“System Libraries - Locations and Library Name Extension” (page 87)
Linker Toolset Compatibility with De Facto Industry Standards
The HP-UX linker and dynamic loader provide linking and loading behaviors found widely across
the Unix industry (SVR4 (System V Release 4) standards). The following linker behaviors are
compliant with de facto industry standard:
•ELF object file format and libelf(3E) routines
•Dynamic path searching
•Library-level versioning
•The dl* family of dynamic loading routines
•Breadth-first symbol searching
The HP-UX 11i v1.5 release maintains the following compatibility behaviors to make transition
from PA-32 to IPF mode easier:
•Creation of default run-time path environment variable (RPATH) if no ld +b is seen on the link
line, to improve transition from the PA-32 linker.
•Theld +compat option for compatibility with PA-32 linking and loading behavior.
ELF Object File Format
Starting with the HP-UX 11.0 release, the linker toolset supports the ELF (executable and linkingformat) object file format. The linker toolset provides new tools to display and manipulate ELF files.
The libelf(3E) library routines provide access to ELF files. The command elfdump(1) displays contents
of an ELF file. For more information about the structure of ELF object files, see the HP-UX Software
Transition Kit (STK) available at:
http://devrsrc1.external.hp.com/STK/index.html
PA-RISC Changes in Hardware Compatibility
The HP-UX 10.20 release introduced HP 9000 systems based on the PA-RISC 2.0 architecture.
Also, beginning with that release, HP compilers by default generate executable code for the PA-RISC
architecture of the machine on which you are compiling. In previous releases, the compilers
generated PA-RISC 1.0 code on all HP 9000 Series 800 servers and PA-RISC 1.1 code on Series
700 workstations. HP compilers now, by default, generate PA-RISC 1.1 code on 1.1 systems and
2.0 code on 2.0 systems. Using the +DAportable compiler option provides compatibility of code
between PA-RISC 1.1 and 2.0 systems. Note that the HP-UX 10.10 release is the last supported
Linker Toolset Compatibility with De Facto Industry Standards79
release for PA-RISC 1.0 systems, so code generated by the HP-UX 10.20 release of HP compilers
is not supported on PA-RISC 1.0 systems.
NOTE:The +DA1.0 option will be obsolete in a future release. You can achieve better
performance on PA-RISC 1.1 and 2.0 systems by not using this option.
PA-RISC 2.0 Compatibility
The instruction set on PA-RISC 2.0 is a superset of the instruction set on PA-RISC 1.1. As a result,
code generated for PA-RISC 1.1 systems run on PA-RISC 2.0 systems. However, code generated
for PA-RISC 2.0 systems does not run on PA-RISC 1.1 or 1.0. If you have enabled the
+vcompatwarnings, the linker displays the following hardware compatibility warning whenever
it links in any PA-RISC 2.0 object files:
/usr/ccs/bin/ld: (Warning) At least one PA 2.0 object file
(sum.o) was detected. The linked output may not run on PA 1.x
system.
If you try to run a PA-RISC 2.0 program on a 1.1 system, you see a message like:
$ a.out
ksh: ./a.out: Executable file incompatible with hardware
In this example, the +DAportable compiler option can be used to create code compatible with
PA-RISC 1.1 and 2.0 systems.
PA-RISC Architectures and Their System Models
The HP 9000 PA-RISC (Precision Architecture Reduced Instruction Set Computing) Series 700/800
family of workstations and servers has evolved from the following versions of PA-RISC architecture:
Table 13 Versions of PA-RISC architecture
PA-RISC 1.0
PA-RISC 1.1
PA-RISC 2.0
The original version of PA-RISC was first introduced on Series 800 servers. The following Series
were included: 840, 825, 835/SE, 845/SE, 850, 855, 860, 865, 870/x00, 822, 832, 842,
852, 890, 808, 815, 635, 645.
The second version of PA-RISC was first introduced on Series 700 workstations. Newer Series
800 systems also use this version of the architecture. The following Series were included: 700,
705, 710, 712, 715, 720, 725, 730, 735, 750, 755, B132L, B160L, B132L+, B180L, C100,
C110, J200, J210, J210XC, 742i, 742rt, 743i, 743rt, 745i, 747i, 748i, 8x7, D (except Dx70,
Dx80), E, F, G, H, I, K (except Kx50, Kx60, Kx70), T500, T520.
This is the latest version of PA-RISC. The following Series are included: B2600/C3000, C160,
C180, C180XP, C200, C240, J280, J282, J2240, Dx70, Dx80, Kx50, Kx60, Kx70, T600,
V2200.
For More Information
•See your compiler online help or documentation for more information on the +DA option.
•See the file /opt/langtools/lib/sched.models for a complete list of model numbers
and their architectures. Use the command model to determine the model number of your
system.
Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)
This section summarizes the significant PA32 (System Object Module (SOM) file) features, behavior,
and options that linker does not support in PA64 mode and Itanium-based 32-bit and 64-bit mode
(Executable and Linking Format (ELF) file format). The following table summarizes the differences
in option, behavior, and toolset between PA-32 and IPF/PA-64 bit modes (IPF (64-bit and 32-bit)
and PA-64):
80Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
Table 14 Differences in options between PA-32 and IPF/PA-64 bit modes
DescriptionOption
Specifies incremental loading. IPF applications must use shared libraries instead.-A name
Does parameter type checking. This option is unsupported.-C n
Generates an initial program loader header file. This option is unsupported.-S
-T
-q, -Q, -n
-N
+objdebug mode
+nosrcpos
Save data and relocation information in temporary files to reduce virtual memory
requirements during linking. This option is unsupported.
Generates an executable with file type DEMAND_MAGIC, EXEC_MAGIC, and SHARE_MAGIC
respectively. These options have no effect and are ignored in IPF (32 bit and 64 bit) and
PA-64.
Causes the data segment to be placed immediately after the text segment. This option is
accepted but ignored in 64-bit mode. If this option is used because your application data
segment is large, then the option is no longer needed in 64-bit mode. It can be used in
32-bit and IPF applications. If this option is used because your program is used in an
embedded system or other specialized application, consider using mapfile support with
the -k option.
Specifies pathname for compiling I-SOMs to SOMs. This option is unsupported.+cgpathname
In IPF (32-bit and 64-bit), the compiler option +objdebug is the default. When used with
-g, the +objdebugoption leaves debug information in the object files instead of copying
it to the executable file at link time, resulting in shorter link times and smaller executables.
The +noobjdebug option can be used to override the +objdebug option and copy all
debug information to the executable file.
In IPF (32-bit and 64-bit), the +srcpos option is the default. The +srcpos option causes
the compiler to generate part of the debug information even when the -g compiler option
is not specified. The +srcpos option also causes part of the debug information to be
always copied over to the executable file resulting in larger executables. The +srcpos
option enables users to profile programs using tools like CXperf and HP Caliper, or compiler
options like +I and +P, even in the absence of -g compilation. The linker option
+nosrcpos can be used to override the +srcpos option and strip the associated debug
information during link time. The +nosrcpos option can also be used with -g+objdebug
to fully enforce the +objdebug mode (i.e., leaving the debug information in the object
files).
Table 15 Differences in behavior between PA-32 and IPF/PA-64 bit modes
DescriptionBehavior
Share library suffix
Intra-library versioning
Duplicate code and data symbols
In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In
IPF (32-bit and 64-bit), the shared libraries are suffixed with .so. For
compatibility, the IPF linker also supports the .sl suffix.
Specified by using the HP_SHLIB_VERSION pragma (C and aC++) or
SHLIB_VERSION directive (Fortran90). In PA-32 mode, the linker lets
you version your library by object files. IPF or PA-64 applications must
use SVR4 library-level versioning instead.
Code and data cannot share the same namespace in IPF mode. You must
rename the conflicting symbols.
These options are unsupported.All internal and undocumented linker options
Table 16 Differences in Toolset between PA-32 and IPF/PA-64 bit modes
DescriptionToolset
The odump tool that displays information about a SOM object file is not supported.odump
Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)81
Run-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)
IPF applications (32-bit and 64-bit) and PA-64 applications use a run-time dynamic loading model
similar to other SVR4 systems. Following are two main areas where the IPF/PA-64 program startup
differs from PA 32-bit mode:
Table 17 Main areas where the IPF/PA-64 program startup differs from PA 32-bit mode
libraries
Run time path environment variables
+bpath_list and -Ldirectories
interaction
PA64 Mode Linker Options
This section describes the PA64 mode linker options.
Table 18 PA64 mode linker options
ActionOption
-dynamic
Forces the linker to create a shared executable. The linker looks for shared libraries first and
then archived libraries. This option is on by default when you compile in PA64 mode.
PA-32 Mode BehaviorLinker and Loader Functions
Ordering is significant.+s and +bpath_list ordering
Depth-first search order.Symbol searching in dependent
No run time environment variables
by default. If +s is specified, then
SHLIB_PATH is available.
-Ldirectories recorded as absolute
paths in executables.
IPF (32-bit and 64-bit) and PA-64 Mode
Behavior
Ordering is insignificant by default. Use
+compat to enforce ordering.
Breadth-first search order. Use +compat to
enforce depth first ordering.
LD_LIBRARY_PATH and SHLIB_PATH are
enabled by default. Use +noenvvar or
+compat to turn off run-time path
environment variables.
-Ldirectories are not recorded in
executables. Add all directories specified in
-L to +b path_list.
Forces the linker to create a fully bound archive program.-noshared
-k filename
+[no]allowunsats
+hideallsymbols
+nodefaultmap
+noenvvar
+std
Allows you to control the mapping of input section in the object file to segments in the output
file.
Enables/disables forced loading of all the object files from archive libraries. The linker accepts
but ignores this option in 32-bit mode. It creates an executable (a.out).
Hides all symbols from being exported.+compat
Instructs the linker not to load the default mapfile. See the -k option.+[no]forceload
Instructs the dynamic loader not to look at the LD_LIBRARY_PATH and SHLIB_PATH
environment variables at runtime.
Instructs the dynamic loader not to look at the LD_LIBRARY_PATH and SHLIB_PATH
environment variables at runtime.
Instructs the linker to use SVR4 compatible linking and loading behaviors. Default for PA64
mode.
Instructs the linker to use SVR4 compatible linking and loading behaviors. Default for PA64
mode.
Instructs the linker not to output the unwind table.+stripunwind
Produces verbose output about selected link operations.+vtype type
Linker-Defined Symbols
This section describes the symbol names that linker reserves in PA64 mode (ELF). If an application
uses any of these symbols, linker displays an error message.
82Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
Table 19 Symbol names
Largest architecture revision level used by any compilation unit__SYSTEM_ID
Initial value of FPU status register._FPU_STATUS
DefinitionSymbol
_end
__TLS_SIZE
Address of first byte following the end of the main program's data segment; identifies the beginning
of the heap segment.
Size of the Thread Local Storage segment required by the program. This symbol is not reserved
in PA32 (SOM).
Beginning of the text segment.__text_start
End of the text segment._etext
Beginning of the data segment.__data_start
End of initialized data._edata
Global pointer value. This symbol is not reserved in PA32 (SOM).__gp
Beginning of the .init section.__init_start
End of the .init section.__init_end
Beginning of the .fini section.__fini_start
End of the .fini section.__fini_end
Beginning of the unwind table. This symbol is not reserved in PA32 (SOM).__unwind_start
End of the unwind table. This symbol is not reserved in PA32 (SOM).__unwind_end
Dynamic Path Searching for Shared Libraries
Dynamic path searching is the process that enables you to specify the location of shared libraries
at run time. In PA-32 mode, you can enable run-time dynamic path searching of shared libraries
in the following ways:
•By linking the program with +s, enabling the program to use the path list defined by the
SHLIB_PATH environment variable at run time.
•By storing a directory path list in the program with the linker option +b path_list.
If +s or +b path_list is enabled, all shared libraries specified with the -l library or -l:library linker
options are subject to a dynamic path lookup at run time.
In IPF, the dynamic path searching behavior has changed (same as PA-64 mode):
•The +s dynamic path searching option is enabled by default. It is not enabled by default in
PA-32 mode.
•The LD_LIBRARY_PATH environment variable is available in addition to the SHLIB_PATH
environment variable.
•An embedded run-time path list called RUNPATH may be stored in the executable. If +b
path_list is specified at link time, these directories are added to RUNPATH. If +b path_list is
not specified, the linker creates a default RUNPATH consisting of:
1.directories in the -L option (if specified), followed by
2.directories in the LPATH environment variable (if specified).
•By default, the linker ignores the ordering of the +b path_list and +s options.
•At run time, the dynamic loader searches directory paths in the following order:
dynamic path (if set using dlsetlibpath())1.
2.LD_LIBRARY_PATH (if set)
Dynamic Path Searching for Shared Libraries83
3.SHLIB_PATH (if set)
4.RUNPATH
5.the default location /usr/lib/hpux32 for 32-bit programs and /usr/lib/hpux64
for 64-bit programs.
6.current working directory (dlopen and dlopene only)
84Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
Example 16 Specifying library paths in PA-32 mode and IPF/PA-64 mode
The following are examples of specifying library paths in PA-32 mode and IPF/PA-64 mode (IPF
(32-bit and 64-bit) and PA-64):
•Linking to libraries by fully qualifying paths. The library does not contain SONAME specified
by the linker +h option when building the shared library: In this example, the program is
linked with /opt/myapp/mylib.sl:
$ cc main.o /opt/myapp/mylib.sl
Perform 32-bit link.
$ cc +DD64 main.o /opt/myapp/mylib.sl
Perform 64-bit link.
At run-time, in both 32-bit and 64-bit mode, the dynamic loader only looks in /opt/myapp
to find mylib.sl.
•Linking to libraries using -l library or -l:library options:
In this example, the +s option is not explicitly enabled at link time. Both 32-bit and 64-bit
versions of a shared library called libfoo.sl exist in the default location.
◦PA-32 and IPF 32-bit mode example:
$ cc main.o -lfoo -o main
Perform 32-bit link.
With the +DD32 default, when linked in PA-32 mode, main aborts at run time if
libfoo.sl is moved from /usr/lib. This is because the absolute path name of the
shared library /usr/lib/libfoo.sl is stored in the executable.
When linked in IPF 32-bit mode, main does not abort at run time if libfoo.sl is moved
from /usr/lib/hpux32 as long as LD_LIBRARY_PATH or SHLIB_PATH is set and
point to libfoo.sl.
◦PA-64 and IPF 64-bit mode example:
$ cc +DD64 main.o -lfoo -o main
Perform 64-bit link.
When linked in IPF or PA-64 mode, main does not abort at run time if libfoo.sl is
moved, as long as LD_LIBRARY_PATH or SHLIB_PATH is set and point to
libfoo.sl.
•Linking to libraries using -L and +b path_list:
The -L option is used by the linker to locate libraries at link time. The +b option is used to
embed a library path list in the executable for use at run time.
◦PA-32, IPF 32-bit mode example:
$ cc main.o -L. -Wl,+b/var/tmp -lme
Link the program.
$ mv libme.sl /var/tmp/libme.sl
Move libme.sl.
$ a.out
Run the program.
Dynamic Path Searching for Shared Libraries85
In PA-32 mode, the dynamic loader searches paths to resolve external references in the
following order:
1./var/tmp to find libme.sl found
2./var/tmp to find libc.sl not found
3./usr/lib/libc.sl found
In IPF 32-bit mode, the dynamic loader searches paths to resolve external references in
the following order:
1.LD_LIBRARY_PATH (if set) to find libme.sl not found
2.SHLIB_PATH (if set) to find libme.sl not found
3./var/tmp to find libc.sl not found
4.LD_LIBRARY_PATH (if set) to find libc.so not found
5.SHLIB_PATH (if set) to find libc.so not found
6./var/tmp to find libc.so not found
7./usr/lib/hpux32/libc.so found
◦PA-64, IPF 64-bit mode example:
$ cc +DD64 main.o -L. -Wl,+b/var/tmp -lme
Link the program.
$ mv libme.sl /var/tmp/libme.sl
Move libme.sl.
$ a.out
Run the program.
The dynamic loader searching order is the same in PA-64 and IPF (32-bit and 64-bit).
The dynamic loader searches paths to resolve external references in the following order:
1.LD_LIBRARY_PATH (if set) to find libme.sl not found
2.SHLIB_PATH (if set) to find libme.sl not found
3./var/tmp to find libme.sl found
4.LD_LIBRARY_PATH (if set) to find libc.so/libc.sl not found
5./var/tmp to find libc.so/libc.sl not found
6./var/tmp to find libc.so/libc.sl not found
7./usr/lib/pa20_64/libc.sl (PA-64) or /usr/lib/hpux64/libc.so (IPF 64-bit) found
Symbol Searching in Dependent Libraries
In IPF (32-bit and 64-bit) and PA-64 mode, the dynamic loader searches shared libraries using a
breadth-first search order. Breadth-first symbol searching is used on all SVR4 platforms.
86Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
In PA-32 mode, the dynamic loader searches shared libraries using a depth-first search order. The
diagram below illustrates a sample program with shared libraries and compares the two search
methods:
a.out
|
|-----------------|
| |
lib1 lib2
|
lib3
Breadth-first search list: a.out -> lib1 -> lib2 -> lib3
Depth-first search list: a.out -> lib1 -> lib3 -> lib2
The commands to build the libraries and the executable in "Search Order of Dependent Libraries"
are shown:
$ ld -b lib2.o -o lib2.s
$ ld -b lib3.o -o lib3.s
$ d -b lib1.o -L. -l3 -o lib1.s
$ cc main.o -Wl,-L. -l1 -l2 -o main
In PA-32 mode, if a procedure called same_name() is defined in both lib3 and lib2, main
calls the procedure defined in lib3. In PA-64 and IPF (32-bit and 64-bit), main calls the procedure
in lib2.
System Libraries - Locations and Library Name Extension
This section describes the system library locations and changes to the library name extension.
System Library Location
IPF HP-UX systems provide two new subdirectories called hpux32 and hpux64 under /usr/lib
directory for IPF system and HP product libraries.
The diagram below shows the new directory structure:
The linker automatically finds the correct set of system libraries depending on whether the application
is compiled as a 32-bit or 64-bit application. Library providers are encouraged to supply both
32-bit and 64-bit versions of application libraries. Be sure to develop a strategy for library naming
conventions, directory structures, link-time options, and run-time environment variables.
Shared Library Extension (suffix)
IPF (32-bit and 64-bit) shared libraries are suffixed with .so while the PA-RISC shared libraries are
suffixed with .sl. The IPF linker supports shared libraries with both .so and .sl extension.
For example, /usr/lib/hpux32/libc.so is the IPF system 32-bit C library whereas
/usr/lib/libc.sl is the PA-RISC system 32-bit C library.
System Libraries - Locations and Library Name Extension87
Use the compiler -complete option or the linker -noshared option to create a statically-bound
program. The default is -dynamic.
Statically-bound programs are not supported on IPF. Most IPF (32-bit and 64-bit) system libraries,
including libc, are only available as shared libraries.
88Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
6 Creating and Using Libraries
Many libraries come with HP-UX. You can also create and use your own libraries on HP-UX. This
chapter discusses the following topics:
•General Information About Shared and Archive Libraries
“Overview of Shared and Archive Libraries” (page 89)◦
◦“What are Archive Libraries?” (page 90)
◦“What are Shared Libraries?” (page 91)
◦“Example Program Comparing Shared and Archive Libraries” (page 92)
◦“Shared Libraries with Debuggers, Profilers, and Static Analysis” (page 94)
•Creating Libraries on HP-UX
“Creating Archive Libraries” (page 94)◦
◦“Creating Shared Libraries” (page 98)
•Using Libraries on HP-UX
“Version Control with Shared Libraries” (page 110)◦
◦“Switching from Archive to Shared Libraries” (page 115)
◦“Summary of HP-UX Libraries” (page 117)
◦“Caution When Mixing Shared and Archive Libraries” (page 118)
•“Using Shared Libraries in Default Mode” (page 124)
“Internal Name Processing” (page 125)◦
◦“Dynamic Path Searching for Shared Libraries” (page 126)
◦“Shared Library Symbol Binding Semantics” (page 126)
◦“Mixed Mode Shared Libraries” (page 130)
◦“IPF Library Examples” (page 131)
Overview of Shared and Archive Libraries
HP-UX supports two kinds of libraries: archive and shared. A shared library is also called a dll
(dynamically linked library). Archive libraries are the more traditional of the two, but use of shared
libraries has increased dramatically, and is the preferred method. The following table summarizes
differences between archive and shared libraries.
Table 20 Differences between archive and shared libraries
creation
Suffix is .a.file name suffix
command
Shared (or dll)ArchiveComparing
Suffix is .sl or .<version> on PA systems and .so or
.so.<version> on Itanium-based systems, where version is the
version number of the library.
Combine object files with the ld commandCombine object files with the ar
Overview of Shared and Archive Libraries89
Table 20 Differences between archive and shared libraries (continued)
Shared (or dll)ArchiveComparing
address binding
a.out files
run time
Addresses of library subroutines
and data are resolved at link time.
Contains all library routines or
data (external references)
a.out file that does not use
complete executable.
Each program has its own copy of
archive library routines.
Addresses of library subroutines are bound at run time.
Addresses of data in a.out are bound at link time; addresses
of data in shared libraries are bound at run time.
Does not contain library routines; instead, contains a linkagetable that is filled in with the addresses of routines and shared
library data. An a.out that uses shared libraries is knownreferenced in the program. An
as an incomplete executable, and is almost always much
smaller than a complete executable.shared libraries is known as a
Shared library routines are shared among all processes that
use the library.
In Itanium-based systems, some of the system libraries are available both as a shared library and
as an archive library for 32-bit executables in the directory /usr/lib/hpux32/ and for 64-bit
executables in /usr/lib/hpux64/. Archive library file names end with .a whereas shared library
file names end with .so. For example, for 32-bit executables, the archive math library libm is
/usr/lib/hpux32/libm.a and the shared version is /usr/lib/hpux32/libm.so. For
64-bit executables, the archive math library libm is /usr/lib/hpux64/libm.a and the shared
version is /usr/lib/hpux64/libm.so If both shared and archived versions of a library exist,
ld uses the one that it finds first in the default library search path. If both versions exist in the same
directory, ld uses the shared version. For example, compiling the C program prog.c causes cc
to invoke the linker with a command like this:
•For 32-bit mode: ld prog.o -lc
•For 64-bit mode: ld prog.o -lc
The -lc option instructs the linker to search the C library, hpux32/libc or hpux64/libc, to
resolve unsatisfied references from prog.o. If a shared libc exists
(/usr/lib/hpux32/libc.so or /usr/lib/hpux64/libc.so), ld uses it instead of the
archive libc (/usr/lib/hpux32/libc.a or /usr/lib/hpux64/libc.a). You can,
however, override this behavior and select the archive version of a library with the -a option or
the -l: option. These are described in “Choosing Archive or Shared Libraries with -a” (page
36)and “Specifying Libraries with -l and -l:” (page 45) . In addition to the system libraries provided
on HP-UX, you can create your own archive and shared libraries. To create archive libraries,
combine object files with the ar command, as described in “Overview of Creating an Archive
Library” (page 95) . To create shared libraries, use ld to combine object files as described in
“Creating Shared Libraries” (page 98). For more information, see “Caution When Mixing Shared
and Archive Libraries” (page 118) .
What are Archive Libraries?
An archive library contains one or more object files, and is created with the ar command. When
linking an object file with an archive library, ld searches the library for global definitions that
match with external references in the object file. If a match is found, ld copies the object file
containing the global definition from the library into the a.out file. In short, any routines or data
a program needs from the library are copied into the resulting a.out file. Example For example,
suppose you write a C program that calls printf from the libc library. Figure 6 (page 91) shows
how the resulting a.out file looks if you linked the program with the archive version of libc.
90Creating and Using Libraries
Figure 6 Linking with an Archive Library
What are Shared Libraries?
Like an archive library, a shared library contains object code. However, ld treats shared libraries
quite differently from archive libraries. When linking an object file with a shared library, ld does
not copy object code from the library into the a.out file; instead, the linker simply notes in the
a.out file that the code calls a routine in the shared library. An a.out file that calls routines in
a shared library is known as an incomplete executable.
The Dynamic Loader
When an incomplete executable begins execution, the HP-UX dynamic loader looks at the a.out
file to see what libraries the a.out file needs during execution.
The kernel activates the dynamic loader for an a.out.The dynamic loader then loads and maps
any required shared libraries into the process's address space - known as attaching the libraries.
A program calls shared library routines indirectly through a linkage table that the dynamic loader
fills in with the addresses of the routines. By default, the dynamic loader places the addresses of
shared library routines in the linkage table as the routines are called - known as deferred binding.
Immediate binding is also possible - that is, binding all required symbols in the shared library at
program startup. In either case, any routines that are already loaded are shared.
Consequently, linking with shared libraries generally results in smaller a.out files than linking
with archive libraries. Therefore, a clear benefit of using shared libraries is that it can reduce disk
space and virtual memory requirements.
NOTE:In prior releases, data defined by a shared library was copied into the program file at
link time. All references to this data, both in the libraries and in the program file, referred to the
copy in the executable file. With the HP-UX 10.0 release, however, this data copying is eliminated.
Data is accessed in the shared library itself. The code in the executable file references the shared
library data indirectly through a linkage pointer, in the same way that a shared library references
the data.
Default Behavior When Searching for Libraries at Run Time
If the dynamic loader cannot find a shared library from the list by default, it generates a run-time
error and the program aborts. In PA-32 compatibility mode (with +compat), for example, suppose
that during development, a program is linked with the shared library liblocal.so in your current
working directory (say, /users/hyperturbo):
In PA-32 mode, the linker records the path name of liblocal.so in the a.out file as
/users/hyperturbo/liblocal.so. When shipping this application to users, you must ensure
that (1) they have a copy of liblocal.so on their system, and (2) it is in the same location as
What are Shared Libraries?91
it was when you linked the final application. Otherwise, when the users of your application run it,
the dynamic loader looks for /users/hyperturbo/liblocal.so, fail to find it, and the
program aborts.
In default mode, the linker records ./liblocal.so.
This is more of a concern with non-standard libraries-that is, libraries not found in
/usr/lib/hpux32 or /usr/lib/hpux64. There is little chance of the standard libraries not
being in these directories.
Caution on Using Dynamic Library Searching
If different versions of a library exist on your system, be aware that the dynamic loader may get
the wrong version of the library when dynamic library searching is enabled with SHLIB_PATH or
+b. For instance, you may want a program to use the PA1.1 libraries found in the
/usr/lib/pa1.1 directory; but through a combination of SHLIB_PATH settings and +b options,
the dynamic loader ends up loading versions found in /usr/lib instead. If this happens,
make sure that SHLIB_PATH and +b are set to avoid such conflicts.
Running setuid Programs
If SHLIB_PATH and LD_LIBRARY_PATH are set for setuid programs, the loader validates the
contents of the environment variables SHLIB_PATH and LD_LIBRARY_PATH against the contents
of the configuration file/etc/dld.sl.conf. The loader validates the contents only if:
1.The conf file is present
2.The conf file fulfils the following conditions:
•The superuser owns the conf file.
•Appropriate permissions are granted, that is, the conf file is writable only by the superuser.
•The conf file contains a list of absolute shared library search paths.
•Spaces are not present in the paths listed. The loader ignores everything on a line that
follows a space or # character. You can use the # character to comment out paths in the
conf file.
NOTE:The dld provides support for using $ORIGIN string in the embedded paths for setuid
programs.
If SHLIB_PATH / LD_LIBRARY_PATH contains any of the paths listed in the conf file, the loader
uses the paths in the order they are specified in the environment variables. If the contents of the
environment variables and the contents of the conf file do not overlap, the dynamic path lookup
is disabled and the search is restricted to the embedded path (RPATH). You can turn off this feature
by setting the environment variable _HP_DLDOPTS to -no_setuidpath. If you turn off this
feature, setuid programs do not carry out dynamic path searching.
NOTE:The configuration file /etc/dld.sl.conf must contain a list of shared library search
paths (delimited by either colon or newline characters). Any relative paths (paths not starting with
/) in the path list is ignored by the loader. To avoid redundant searches, ensure that a path appears
only once in the file and only once in the option SHLIB_PATH/LD_LIBRARY_PATH. For PA32,
this feature is enabled only if the /etc/dld.sl.conf file is present. The default behavior of
honoring these environment variables for setuid programs remains unchanged.
Example Program Comparing Shared and Archive Libraries
As an example, suppose two separate programs, prog1 and prog2, use shared libc routines
heavily. Suppose that the a.out portion of prog1 is 256Kb in size, while the a.out portion of prog.2
is 128Kb. Assume also that the shared libc is 512Kb in size. Figure 7 (page 93) shows how
physical memory might look when both processes run simultaneously. Notice that one copy of libc
92Creating and Using Libraries
is shared by both processes. The total memory requirement for these two processes running
simultaneously is 896Kb (256Kb + 128Kb + 512Kb).
Figure 7 Two Processes Sharing libc
Compare this with the memory requirements if prog1 and prog2 are linked with the archive version
of libc. As shown in Figure 8 (page 93), 1428Kb of memory is required (768Kb + 640Kb). The
numbers in this example are made up, but it is true in general that shared libraries reduce memory
requirements.
Figure 8 Two Processes with Their Own Copies of libc
Example Program Comparing Shared and Archive Libraries93
Shared Libraries with Debuggers, Profilers, and Static Analysis
Debugging of shared libraries is supported by the by the WDB Debugger. See the WDB
documentation at: http://www.hp.com/go/wdb
Profiling Shared Libraries with gprof(1)
The gprof tool produces an execution profile about an executable for application programs and
shared libraries. See gprof(1) for more information. Use the following steps to profile a shared
library:
•Set the environment variable LD_PROFILE to the shared library name.
•Link the application which links with the library to be profiled to take one of the following
actions:
◦Link with libc.sl.
◦Export all the symbols explicitly (with the ld +e option).
This is primarily for registration of the exit handler. You can only profile a single shared library.
You can profile either the application or a shared library. However, you cannot profile both the
application and the shared library together. To profile applications, continue to use the existing
gprof method, in which you compile with -G option, but do not set LD_PROFILE. For example,
to profile the shared library test.sl:
•Set the environment variable LD_PROFILE to specify your shared library.
$ LD_PROFILE=test.sl
$ export LD_PROFILE
•If a.out is linked to test.sl, execute a.out.
$ a.out
This step creates the file <shared_library>.profile (where shared_library is the name of the
shared library specified by the LD_PROFILE environment variable) at run time. This file
contains the profile information for the shared library. For this example, the file
test.sl.profile is created.
•To get the complete profile information about test.sl, run the gprof command:
$ gprof test.sl test.sl.profile
The following are the limitations for profiling shared library using gprof:
•Local, static, and hidden functions are not profiled.
•Shared libraries built with -B symbolic are not profiled.
•Any function calls made from library initializers are not collected.
Creating Archive Libraries
1.Compile one or more source files to create object files containing relocatable object code.
2.Combine these object files into a single archive library file with the ar command.
Following are the commands you can use to create an archive library called libunits.a:
$ cc -Aa -c length.c volume.c mass.c
$ ar r libunits.a length.o volume.o mass.o
These steps are described in detail in “Overview of Creating an Archive Library” (page 95). Other
topics relevant to archive libraries are:
•“Contents of an Archive File” (page 95)
•“Example of Creating an Archive Library” (page 96)
94Creating and Using Libraries
•“Replacing, Adding, and Deleting an Object Module” (page 97)
•“Summary of Keys to the ar(1) Command” (page 97)
•“Archive Library Location (IPF) ” (page 98)
Overview of Creating an Archive Library
To create an archive library:
1.Create one or more object files containing relocatable object code. Typically, each object file
contains one function, procedure, or data structure, but an object file can have multiple routines
and data.
2.Combine these object files into a single archive library file with the ar command. Invoke ar
with the r key.
("Keys" are like command line options, except that they do not require a preceding -.)
Figure 9 (page 95) summarizes the procedure for creating archive libraries from three C source
files (file1.c, file2.c, and file3.c). The process is identical for other languages, except that you use
a different compiler.
Figure 9 Creating an Archive Library
Contents of an Archive File
An archive library file consists of four main components:
1.A header string, "!<arch>\n", identifying the file as an archive file created by ar (\n
represents the newline character)
2.A symbol table, used by the linker and other commands to find the location, size, and other
information for each routine or data item contained in the library
3.An optional string table used by the linker to store file names that are greater than 15 bytes
long (only created if a long file name is encountered)
4.Object modules, one for each object file specified on the ar command line
To see what object modules a library contains, run ar with the t key, which displays a table of
contents. For example, to view the "table of contents" for libm.a:
$ ar t /usr/lib/hpux32/libm.a //Run ar with the t key.
Creating Archive Libraries95
acosh.o //Object modules are displayed.
erf.o
fabs.o
. . . .
This indicates that the library was built from object files named acosh.o, erf.o, fabs.o, and
so forth. In other words, module names are the same as the names of the object files from
which they were created.
Example of Creating an Archive Library
Suppose you are working on a program that does several conversions between English and Metric
units. The routines that do the conversions are contained in three C-language files. Following are
the three C-language files:
length.c - Routine to Convert Length Units
float in_to_cm(float in) /* convert inches to centimeters */
{
return (in * 2.54);
}
During development, each routine is stored in a separate file. To make the routines easily accessible
to other programmers, they must be stored in an archive library. To do this, first compile the source
files, either separately or together on the same command line:
$ cc -Aa -c length.c volume.c mass.c Compile them together.
length.c:
volume.c:
mass.c:
$ ls *.o List the .o files.
length.o mass.o volume.o
Then combine the .o files by running ar with the r key, followed by the library name (say libunits.a),
followed by the names of the object files to place in the library:
$ ar r libunits.a length.o volume.o mass.o
ar: creating libunits.a
To verify that ar created the library correctly, view its contents:
$ ar t libunits.a Use ar with the t key.
length.o
volume.o
mass.o All the .o modules are included; it worked.
Now suppose you have written a program, called convert.c, which calls several of the routines in
the libunits.a library. You can compile the main program and link it to libunits.a with the
following cc command:
$ cc -Aa convert.c libunits.a
96Creating and Using Libraries
Note that the whole library name was given, and the -l option was not specified. This is because
the library was in the current directory. If you move libunits.a to /usr/lib/hpux32 (IPF 32-bit
mode) or /usr/lib (PA32 mode) before compiling, the following command line works instead:
$ cc -Aa convert.c -lunits
Linking with archive libraries is covered in detail in “Determining How to Link Programs or Libraries
(Linker Tasks)” (page 27).
Replacing, Adding, and Deleting an Object Module
Occasionally you may want to replace an object module in a library, add an object module to a
library, or delete a module completely. For instance, suppose you add some new conversion
routines to length.c (defined in the previous section), and want to include the new routines in
the library libunits.a. You must then replace the length.o module in libunits.a.
Replacing or Adding an Object Module
To replace or add an object module, use the r key (the same key you use to create a library). For
example, to replace the length.o object module in libunits.a:
$ ar r libunits.a length.o
Deleting an Object Module
To delete an object module from a library, use the d key. For example, to delete volume.o from
libunits.a:
$ ar d libunits.a volume.o Delete volume.o.
$ ar t libunits.a List the contents.
length.o mass.o volume.o is gone.
Summary of Keys to the ar(1) Command
When used to create and manage archive libraries, the syntax of ar is:
ar [-] keys archive [modules] ...
IN the syntax, archive is the name of the archive library, modules is an optional list of object modules or
files. See ar(1) for the complete list of keys and options.
Useful ar Keys
Here are some useful ar keys and their modifiers:
Table 21 Useful ar Keys
Delete the modules from the archive.d
r
u
x
Replace or add the modules to the archive. If archive exists, ar replaces modules specified on
the command line. If archive does not exist, ar creates a new archive containing the modules.
Display a table of contents for the archive.t
Used with the r, this modifier tells ar to replace only those modules with creation dates later
than those in the archive.
Display verbose output.v
Extracts object modules from the library. Extracted modules are placed in .o files in the current
directory. Once an object module is extracted, you can use nm to view the symbols in the
module.
Descriptionkey
For example, when used with the v flag, the t flag creates a verbose table of contents - including
such information as module creation date and file size:
Creating Archive Libraries97
$ ar tv libunits.a
rw-rw-rw- 265/ 20 230 Feb 2 17:19 1990 length.o
rw-rw-rw- 265/ 20 228 Feb 2 16:25 1990 mass.o
rw-rw-rw- 265/ 20 230 Feb 2 16:24 1990 volume.o
The next example replaces length.o in libunits.a, only if length.o is more recent than
the one already contained in libunits.a:
$ ar ru libunits.a length.o
crt0.o
The crt0.o startup file is not needed for shared bound links because dld.so does some of the
startup duties previously done by crt0.o. However, you still need to include crt0.o on the link
line for all fully archive links (ld -noshared). In PA-32 mode, crt0.o must always be included
on the link line.
Users who link by letting the compilers such as cc invoke the linker do not have to include crt0.o
on the link line.
Archive Library Location (IPF)
After creating an archive library, you can save it in a location that is easily accessible to other
programmers who may want to use it. There are two main choices for places to put the library:
•in the 32-bit /usr/lib or 64-bit /user/lib/pa20_64 directory
•in the 32-bit /usr/local/lib or /usr/contrib/lib directory
Using /usr/lib and /usr/lib/pa20_64
Because the linker searches /usr/lib or /usr/lib/pa20_64 by default, you may put your
archive libraries in /usr/lib or /usr/lib/pa20_64 and thereby eliminate the task of entering
the entire library path name each time you compile or link.
The drawbacks of putting the libraries in /usr/lib or /usr/lib/pa20_64 are:
•You usually need super-user (system administrator) privileges to write to the directory.
•You may inadvertently overwrite an HP-UX system library that resides in the directory.
Check with your system administrator before attempting to use /usr/lib or
/usr/lib/pa20_64.
Using /usr/local/lib or /usr/contrib/lib
The /usr/local/lib and /usr/local/lib/pa20_64 library typically contain libraries
created locally - by programmers on the system; /usr/contrib/lib and
/usr/contrib/lib/pa20_64contain libraries supplied with HP-UX but not supported by HP.
Programmers can create their own libraries for both 32-bit and 64-bit code using the same library
name. Although ld does not automatically search these directories, they are still the best choice
for locating user-defined libraries because the directories are not write-protected. Therefore,
programmers can store the libraries in these directories without super-user privileges. Use
-L/usr/local/lib or -L/usr/contrib/lib for 32-bit libraries, or
-L/usr/local/lib/pa20_64 or -L/usr/contrib/lib/pa20_64 for 64-bit libraries to tell
the linker to search these directories.
Creating Shared Libraries
Two steps are required to create a shared library:
1.Compile one or more source files to create object files. In PA-32 mode, it is necessary to use
the +Z compiler option to create position-independent code.
2.“Creating the Shared Library with ld” (page 99) by linking with -b.
98Creating and Using Libraries
Following are the commands you can use to create a shared library called libunits.so:
In PA-32 mode, the first step in creating a shared library is to create object files containing
position-independent code (PIC). There are two ways to create PIC object files:
•Compile source files with the +z or +Z compiler option, described below.
•Write assembly language programs that use appropriate addressing modes, described in
“Writing and Generating Position-Independent Code” (page 185) .
In PA-32 mode, the +z and +Z options force the compiler to generate PIC object files. In PA-64
and IPF mode, the +Z option is the default.
Example Using +z
Suppose you have some C functions, stored in length.c, that convert between English and Metric
length units. To compile these routines and create PIC object files with the C compiler, you can
use this command:
$ cc -Aa -c +z length.c The +z option creates PIC.
You can then link it with other PIC object files to create a shared library, as discussed in “Creating
the Shared Library with ld” (page 99) .
Comparing +z and +Z
In PA-32 mode, the +z and +Z options are essentially the same. Normally, you compile with +z.
However, in some instances - when the number of referenced symbols per shared library exceeds
a predetermined limit - you must recompile with the +Z option instead. In this situation, the linker
displays an error message and tells you to recompile the library with +Z.
In PA-64 and IPF mode, +Z is the default and the compilers ignore the options and generate PIC
code.
Compiler Support for +z and +Z
In PA-32 mode, the C, C++, FORTRAN, and Pascal compilers support the +z and +Z options.
In PA-64 and IPF mode, +Z is the default for the C and C++ compilers.
Creating the Shared Library with ld
To create a shared library from one or more PIC object files, use the linker, ld, with the -b option.
By default, ld names the library a.out. You can change the name with the -o option.
For example, suppose you have three C source files containing routines to do length, volume, and
mass unit conversions. They are named length.c, volume.c, and mass.c, respectively. To
make a shared library from these source files, first compile all three files, then combine the resulting
.o files with ld. Following are the commands you can use to create a shared library named
libunits.so:
Once the library is created, ensure that it has read and execute permissions for all users who use
the library. For example, the following chmod command allows read/execute permission for all
users of the libunits.so library:
$ chmod +r+x libunits.so
This library can now be linked with other programs. For example, if you have a C program named
convert.c that calls routines from libunits.so, you can compile and link it with the cc
command:
$ cc -Aa convert.c libunits.so
In PA-32 mode, once the executable is created, the library must not be moved because the absolute
path name of the library is stored in the executable. (In PA-64 and IPF mode, ./libunit.so is
stored in the executable.) For details, see “Shared Library Location (IPF)” (page 102).
For details on linking shared libraries with your programs, see “Determining How to Link Programs
or Libraries (Linker Tasks)” (page 27).
Shared Library Dependencies
You can specify additional shared libraries on the ld command line when creating a shared
library. The created shared library is said to have a dependency on the specified libraries, and
these libraries are known as dependent libraries or supporting libraries. When you load a library
with dependencies, all its dependent libraries are loaded too. For example, suppose you create
a library named libdep.so using the command:
Thereafter, any programs that load libdep.so - either explicitly with dlopen or shl_load or
implicitly with the dynamic loader when the program begins execution - also automatically load
the dependent libraries libcurses.so and libcustom.so.
There are two additional issues that may be important to some shared library developers:
•When a shared library with dependencies is loaded, in what order are the dependent libraries
loaded?
•Where are all the dependent libraries placed in relation to other already loaded libraries?
That is, where are they placed in the process's shared library search list used by the dynamic
loader?
The Order in Which Libraries are Loaded (Load Graph)
When a shared library with dependencies is loaded, the dynamic loader builds a load graph to
determine the order in which the dependent libraries are loaded. For example, suppose you create
three libraries - libQ, libD, and libP - using the ld commands below. The order in which the
libraries are built is important because a library must exist before you can specify it as a dependent
library.