The information contained in this document is subject to change without
notice.
Hewlett-Packard makes no warranty of any kind with regard to this
manual, including, but not limited to, the implied warranties of
merchantability and fitness for a particular purpose. Hewlett-Packard
shall not be liable for errors contained herein or direct, indirect, special,
incidental or consequential damages in connection with the furnishing,
performance, or use of this material.
rights are reserved. Reproduction, adaptation, or translation without
prior written permission is prohibited, except as allowed under the
copyright laws.
Corporate Offices:
Hewlett-Packard Co.
3000 Hanover St.
Palo Alto, CA 94304
Use, duplication or disclosure by the U.S. Government Department of
Defense is subject to restrictions as set forth in paragraph (b)(3)(ii) of the
Rights in Technical Data and Software clause in FAR 52.227-7013.
Rights for non-DOD U.S. Government Departments and Agencies are as
set forth in FAR 52.227-19(c)(1,2).
Use of this manual and flexible disc(s), compact disc(s), or tape
cartridge(s) supplied for this pack is restricted to this product only.
Additional copies of the programs may be made for security and back-up
purposes only. Resale of the programs in their present form or with
alterations, is expressly prohibited.
A copy of the specific warranty terms applicable to your Hewlett-Packard
product and replacement parts can be obtained from your local Sales and
Service Office.
Window System is a trademark of the Massachussetts Institute of
Technology.
MS-DOS and Microsoft are U.S. registered trademarks of Microsoft
Corporation.
OSF/Motif is a trademark of the Open Software Foundation, Inc. in the
U.S. and other countries. Certification for conformance with OSF/Motif
user environment pending.
• Chapter 1, “What's New in Recent Releases,” lists new features added
in recent releases.
• Chapter 2, “What Happens When You Compile and Link a Program,”
provides details on compiling and linking programs.
• Chapter 3, “Linker Tasks,” lists many ways you can specify how you
want your program linked.
• Chapter 4, “Linker Tools,” list the tools available in the linker toolset.
• Chapter 5, “Creating and Using Libraries,” discusses all aspects of
both archive and shared libraries.
• Chapter 6, “Shared Library Management Routines,” explains how to
explicitly load libraries at run time using shared library management
routines.
• Chapter 7, “Position-Independent Code,” describes how to write
position-independent assembly code.
• Chapter 8, “W a ys to Improve Performance, ” discusses several w a ys to
optimize your program.
• Appendix A, “Using Mapfiles,” describes mapfiles.
• Glossary contains definitions of important terms in this manual.
Printing History
New editions of this manual will incorporate all material updated since
the previous edition. The manual printing date and part number indicate
its current edition. The printing date changes when a new edition is
printed. The manual part number changes when extensive technical
changes are incorporated.
• November 1997, Edition 1, part number B2355-90655. This manual
supersedes HP-UX Linker and Libraries User’s Guide part number
B2355-90655. The main reason for this new edition is to document
new functionality for the HP-UX 11.00 release:
15
• Add the +ee linker option to export symbols.
• Add 64-bit linker toolset support for linker options.
• Add 64-bit mode linker tools and describe the enhancements to the
32-bit mode toolset.
• Describe 32-bit and 64-bit mode behavior differences.
• Add the dl* shared library management routines for 64-bit mode
support and describe enhancement to the shl_load routines for
shared libraries.
• Add init/fini style initializers for 64-bit mode support for shared
libraries.
• Add the BIND_BREADTH_FIRST flag to the shl_load routine to
control search path behavior.
• Add description of support for ELF object file format.
• April 1997, Edition 1, part number B2355-90654. This manual
supersedes Programming on HP-UX part number B2355-90652. The
main reason for this new edition is to document new functionality for
the HP-UX 10.30 release:
• Announce linker thread-safe features for ld, dld.sl, crt0.o,
and libdld.sl.
• Add the +pd size linker option to set the virtual memory page size
for program data.
• Add the +pi size linker option to set the virtual memory page size
for program instructions.
• Add the +k linker option (see ld(1)) to only create an executable if
no errors are found at link time.
• Add the chatr +k option to enable or disable kernel-assisted
branch prediction.
• Add the chatr +pd size and +pi size virtual memory page setting
options.
16
• July 1996, Edition 1, part number B2355-90653. This manual
supersedes Programming on HP-UX part number B2355-90652. The
main reason for this new edition is to document new functionality for
the HP-UX 10.20 release and to describe what's ahead in a future
release of the linker toolset:
• Add a -B symbolic option to help improve shared library
performance.
• Introduce the fastbind tool to improve the start up time of
programs that use shared libraries.
• Introduce the Linker and Libraries Online User Guide.
• Announce changes in PA-RISC hardw are compatibility—PA-RISC
1.1 systems, by default, generate PA-RISC 1.1 code; PA-RISC 2.0
systems generate 2.0 code.
• Describe compatibility warnings generated by the linker and
dynamic loader for HP 9000 architecture issues and linker toolset
features that may change in a future release.
• Describe what's changing in a future release of the linker toolset.
• Add the +Ostaticprediction option to use with profile-based
optimization.
• January 1995, Edition 1, part number B2355-90652. This manual
supersedes Programming on HP-UX part number B2355-90026. The
main reason for this new edition is to document new functionality for
the HP-UX 10.0 release:
• Update path names to reflect the new System V Release 4 file
system. Some of the changes are:
• Most files in /lib are now in /usr/lib.
• Most optional products are in /opt. For example, HP C is in
/opt/ansic, HP C is in /opt/CC, HP FORTRAN/9000 is in
/opt/fortran, and HP/DDE is in /opt/langtools/dde.
• Caution against mixing shared and archive libraries.
• Describe a new library-level versioning scheme for shared
libraries.
• Update the chapter on profile-based optimization.
• Describe changes in optimization levels 3 and 4.
17
• Describe thread-safe interfaces shl_get_r and
shl_gethandle_r.
• Add a new BIND_TOGETHER flag to the shl_load routine.
• Add a new chapter "Porting Applications to HP-UX."
18
What's New in Recent Releases
1What's New in Recent Releases
This section contains information about recent releases of the HP-UX
linker toolset:
For This Release
The HP-UX 11.00 linker toolset contains new features:
If you use the 32-bit mode linker toolset, see the following items:
• “PA-RISC Changes in Hardware Compatibility” updated in this
chapter.
• “Exporting Symbols with +ee” on page 81.
• “Changes in Future Releases” updated in this chapter.
If you use the 64-bit mode linker toolset, see the following items:
• “PA-RISC Changes in Hardware Compatibility” updated in this
chapter.
• “64-bit Mode Linker Toolset Compatibility with De Facto Industry
Standards” described in this chapter.
• “64-bit Mode ELF Object File Format” described in this chapter.
• “Dynamic Path Searching for Shared Libraries” on page 177
describes differences in the run time searching of shared libraries.
• “Shared Library Symbol Binding Semantics” on page 178 describes
differences in shared library binding semantics.
• New 64-bit mode linker options, symbols, and features, described
in“New Features for 64-bit Mode Linking” in this chapter.
• Unsupported 32-bit mode features, behavior, and linker options,
described in “64-bit Mode Link-time Differences” and“64-bit Mode
Run Time Differences” in this chapter.
• “64-bit Mode Initializers” on page 210 describes the init/fini support
for 64-bit mode shared libraries.
Chapter 119
What's New in Recent Releases
• “The dlopen Shared Library Management Routines” on page 240
describes the dl* family of shared library management routines for
64-bit mode.
• “BIND_BREADTH_FIRST Modifier” on page 222 describes the flag
added to the shl_load routine to modify search behavior.
• “Changes in Future Releases” updated in this chapter.
For Previous Releases
The following items were added in the HP-UX 10.30 release:
• “Linker Thread-Safe Features” on page 50.
• “Options to Improve TLB Hit Rates” on page 273.
• The +k linker option (see ld(1)) to remove an executable if the link
fails.
• The +k chatr option (see chatr(1)) to improve branch prediction on
PA-RISC 2.0.
The following items were added in the HP-UX 10.20 release:
• “Improving Shared Library Performance with -B symbolic” on page
60.
• “Improving Shared Library Start-Up Time with fastbind” on page
293.
• “Online Help for Linker and Libraries” described in this chapter.
• “PA-RISC Changes in Hardware Compatibility” described in this
chapter.
• “Linker Compatibility Warnings” on page 99.
• “Dynamic Loader Compatibility Warnings” on page 256.
• The +Ostaticprediction linker option described in the ld(1) man
page to use with profile-based optimization
20Chapter 1
What's New in Recent Releases
PA-RISC Changes in Hardware Compatibility
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 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.
NOTEThe +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 will
run on PA-RISC 2.0 systems. However, code generated for PA-RISC 2.0
systems will not run on P A-RISC 1.1 or 1.0. The linker issues a hardw are
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'll see a
message like:
$ a.out
ksh: ./a.out: Executable file incompatible with hardware
Chapter 121
What's New in Recent Releases
PA-RISC Changes in Hardware Compatibility
In this example, the +DAportable compiler option can be used to create
code compatible for 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 three versions of PA-RISC:
PA-RISC 1.0The original version of PA-RISC first introduced on
Series 800 servers. The following Series are included:
840, 825, 835/SE, 845/SE, 850, 855, 860, 865, 870/x00,
822, 832, 842, 852, 890, 808, 815, 635, 645.
PA-RISC 1.1The second version of PA-RISC first introduced on
Series 700 workstations. Newer Series 800 systems
also use this version of the architecture. The following
Series are included: 700, 705, 710, 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.
PA-RISC 2.0The newest version of PA-RISC. The following Series
• See your compiler online help or documentation for details 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.
22Chapter 1
What's New in Recent Releases
64-bit Mode Linker Toolset Compatibility with De Facto Industry Standards
64-bit Mode Linker Toolset
Compatibility with De Facto Industry
Standards
The 64-bit mode linker and dynamic loader provide linking and loading
behaviors found widely across the Unix industry, considered, with the
SVR4 standards, to define the de facto industry standards. The following
64-bit linker behavior is compliant with de facto industry standard:
• ELF object file format and libelf(3x) routines
• Dynamic path searching
• Library-level versioning
• dl* family of dynamic loading routines
• Breadth-first symbol searching
The HP-UX 11.00 release maintains certain behaviors to make
transition from 32-bit to 64-bit 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 32-bit
mode linker.
•ld +compat option for compatibility with 32-bit linking and loading
behavior.
Chapter 123
What's New in Recent Releases
64-bit Mode ELF Object File Format
64-bit Mode ELF Object File Format
Starting with HP-UX release 11.00, the 64-bit linker toolset supports the
ELF (executable and linking format) object file format. The 64-bit linker
toolset provides new tools to display and manipulate ELF files. The
libelf(3x) library routines provide access to ELF files. The command
elfdump(1) displays contents of an ELF file.
The following options instruct the compiler to generate 64-bit ELF object
code.
OptionCompiler
+DA2.0WC and aC++
+DD64C
See the HP-UX Software Transition Toolkit (STK) at
http://www.software.hp.com/STK/ for more information on the
structure of ELF object files.
24Chapter 1
What's New in Recent Releases
New Features for 64-bit Mode Linking
New Features for 64-bit Mode Linking
This section introduces new features of the 64-bit linker for HP-UX
release 11.00.
64-bit Mode Linker Options
The ld(1) command supports the following new options in 64-bit mode:
OptionAction
-dynamicForces 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 64-bit mode.
-nosharedForces the linker to create a fully bound
archive program.
-k filenameAllows you to control the mapping of input
section in the object file to segments in the
output file.
+[no]allowunsatsInstructs the linker how to report errors for
output files with unsatisfied symbols.
+compatInstruct the linker to use 32-bit mode
linking and dynamic loading behaviors.
+[no]forceloadEnables/disables forced loading of all the
object files from archive libraries.
+hideallsymbols
+nodefaultmapInstructs the linker not to load the default
Chapter 125
Hides all symbols from being exported.
mapfile. See the -k option.
a
a
a
What's New in Recent Releases
New Features for 64-bit Mode Linking
OptionAction
+noenvvarInstructs the dynamic loader not to look at
the LD_LIBRARY_PATH and SHLIB_PATH
environment variables at runtime.
a
+stdInstructs the linker to use SVR4 compatible
linking and loading behaviors. Default for
64-bit mode.
a
+stripunwindInstructs the linker not to output the
unwind table.
+vtype typeProduces verbose output about selected link
operations.
a
a. The linker accepts but ignores this option in 32-bit mode. It
creates an executable (a.out).
64-bit Mode Linker-defined Symbols
The 64-bit linker reserves the following symbol names:
SymbolDefinition
__SYSTEM_IDLargest architecture revision level used by
any compilation unit
_FPU_STATUS Initial value of FPU status register
_endAddress of first byte following the end of the
main program’s data segment; identifies the
beginning of the heap segment
__TLS_SIZESize of the Thread Local Storage segment
required by the program
__text_startBeginning of the text segment
_etextEnd of the text segment
__data_startBeginning of the data segment
26Chapter 1
What's New in Recent Releases
New Features for 64-bit Mode Linking
SymbolDefinition
_edataEnd of initialized data
__gpGlobal pointer value
__init_startBeginning of the .init section
__init_endEnd of the .init section
__fini_startBeginning of the .fini section
__fini_endEnd of the .fini section
__unwind_startBeginning of the unwind table
__unwind_endEnd of the unwind table
NOTEThe linker generates an error if a user application also defines these
symbols.
Chapter 127
What's New in Recent Releases
64-bit Mode Link-time Differences
64-bit Mode Link-time Differences
The 64-bit mode linker toolset does not support the following 32-bit mode
features.
Option or
Behavior
-A nameSpecifies incremental loading. 64-bit applications
must use shared libraries instead.
-C nDoes parameter type checking. This option is
unsupported.
-SGenerates an initial program loader header file.
This option is unsupported.
-TSave data and relocation information in temporary
files to reduce virtual memory requirements during
linking. This option is unsupported.
-q, -Q, -nGenerates an executable with file type
DEMAND_MAGIC, EXEC_MAGIC, and SHARE_MAGIC
respectively. These options have no effect and are
ignored in 64-bit mode.
-NCauses 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.
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.
Description
+cg pathnameSpecifies pathname for compiling I-SOMs to SOMs.
which have been removed due to dead procedure
elimination. Use the -v linker option instead.
Intra-library
versioning
Duplicate code
and data
symbols
All internal
and
undocumented
linker options
For more information, see the HP-UX Linker and Libraries Online UserGuide (ld +help).
Specified by using the HP_SHLIB_VERSION pragma
(C and aC++) or SHLIB_VERSION directive
(Fortran90).
In 32-bit mode, the linker lets you version your
library by object files. 64-bit applications must use
SVR4 library-level versioning instead.
Code and data cannot share the same namespace in
64-bit mode. You should rename the conflicting
symbols.
These options are unsupported.
Description
Chapter 129
What's New in Recent Releases
64-bit Mode Run Time Differences
64-bit Mode Run Time Differences
Applications compiled and linked in 64-bit mode use a run-time dynamic
loading model similar to other SVR4 systems. There are two main areas
where program startup changes in 64-bit mode:
• Dynamic path searching for shared libraries.
• Symbol searching in dependent libraries.
It is recommended that you use the standard SVR4 linking option
(+std), which is on by default when linking 64-bit applications. There
may be circumstances while you transition, that you need 32-bit
compatible linking behavior. The 64-bit linker provides the +compat
option to force the linker to use 32-bit linking and dynamic loading
behavior.
The following table summarizes the dynamic loader differences between
32-bit and 64-bit mode:
Linker and Loader
Functions
+s and +b path_list
ordering
32-bit Mode Behavior64-bit Mode Behavior
Ordering is significant.Ordering is insignificant by default.
Use +compat to enforce ordering.
30Chapter 1
What's New in Recent Releases
64-bit Mode Run Time Differences
Linker and Loader
Functions
Symbol searching in
dependent libraries
Run time path
environment variables
+b path_list and -L
directories interaction
For more information on transition issues , seeHP-UX 64-bit Porting and
Transition Guide.
-L directories recorded
as absolute paths in
executables.
LD_LIBRARY_PATH and
SHLIB_PATH are available.
Use +noenv or +compat to turn off
run-time path environment
variables.
-L directories are not recorded in
executables.
Add all directories specified in -L to
+b path_list.
Chapter 131
What's New in Recent Releases
Changes in Future Releases
Changes in Future Releases
The following changes are planned in future releases.
• Support of ELF 32 object file format
A future release will support the ELF 32 object file format.
• Future of ld +compat option
The +compat linker option and support of compatibility mode may
be discontinued in a future release.
• Support of shl_load shared library management routines
A future release may discontinue support of the shl_load family of
shared library management routines.
32Chapter 1
What's New in Recent Releases
Online Help for Linker and Libraries
Online Help for Linker and Libraries
The Linker and Libraries Online User Guide is available for HP 9000
Series 700 and 800 systems. The online help comes with HP C, HP C++,
HP aC++, HP Fortran, HP Pascal, and HP Micro Focus COBOL/UX.
Online help can be accessed from any X Window display device, or from
the charhelp(1) character-mode help browser.
Accessing Help with ld +help
To access the Linker and Libraries Online User Guide from the ld
command line:
ld +help
Accessing Help with the HP CDE Front Panel
To access the Linker and Libraries Online User Guide if your HP
compiler is installed on your system:
1. Click on the? icon on the HP CDE front panel.
2. The "Welcome to Help Manager" menu appears. Click on the HP
Linker icon.
Accessing Help with the dthelpview
Command
If your HP compiler is installed on another system or you are not
running HP CDE, enter the following command from the system where
your compiler is installed:
/usr/dt/bin/dthelpview -h linker
NOTETo make it easier to access, add the path /usr/dt/bin to your
.profile or .login file.
Accessing Help with the charhelp Command
To access the Linker and Libraries Online User Guide from a
character-mode terminal or terminal emulator:
Chapter 133
What's New in Recent Releases
Online Help for Linker and Libraries
/opt/langtools/bin/charhelp ld
See charhelp(1) for details.
34Chapter 1
What Happens When You Compile and Link a Program
2What Happens When You
Compile and Link a Program
This chapter describes the process of compiling and linking a program.
• “Compiling Programs on HP-UX: An Example” provides an overview
of compiling on HP-UX.
• “Looking “inside” a Compiler” describes the process of creating an
executable file in more detail.
• “Linking Programs on HP-UX” describes how ld creates an
executable file from one or more object files.
• “Linking with Libraries” describes conventions for using libraries
with ld.
• “Running the Program” describes the process of loading and binding
programs at run time.
• “Linker Thread-Safe Features”describes the thread-safe features.
Chapter 235
What Happens When You Compile and Link a Program
Compiling Programs on HP-UX: An Example
Compiling Programs on HP-UX:
An Example
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
Sum1to4: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:
$ f77 sumnum.fCompile and link sumnum.f.
...The compiler displays any messages here.
$ a.outRun 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:
Notice that cc displays the name of each source file it compiles . This way,
if errors occur, you know where they occur.
#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 */
36Chapter 2
What Happens When You Compile and Link a Program
sum += n; /* add n to sum */
return sum; /* return the value of sum */
}
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 contains a main program, and outputs an executable a.out file,
as shown in “High-Level View of the Compiler”.
Figure 2-1High-Level View of the Compiler
Compiling Programs on HP-UX: An Example
Chapter 237
What Happens When You Compile and Link a Program
Looking “inside” a 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?”.)
2. Then, the driver calls the HP-UX linker (ld) which builds an a.out
file from the object files. This is known as the link-edit phase of
compilation. (See Also “Compiler-Linker Interaction”.)
“Looking “inside” a Compiler” summarizes how a compiler driver works.
Figure 2-2Looking “inside” a Compiler
The C, C++, FORTRAN, and Pascal compilers provide the -v (verbose)
option to display the phases a compiler is performing. Compiling main.c
and func.c with the -v option produced this output on a Series 700
workstation (\ at the end of a line indicates the line is continued to the
next line):
$ 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 \\
This example shows that the cc driver calls the C preprocessor
(/opt/langtools/lbin/cpp.ansi) for each source file, then calls the
actual C compiler (/opt/ansic/lbin/ccom) to create the object files.
Finally, the driver calls the linker (/usr/ccs/bin/ld) on the object files
created by the compiler (main.o and func.o).
Chapter 239
What Happens When You Compile and Link a Program
What is an Object File?
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 or data definition can be either a localdefinition 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 up 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 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.
40Chapter 2
What Happens When You Compile and Link a Program
Compiler-Linker Interaction
Compiler-Linker Interaction
As described in “Looking “inside” a Compiler”, the compilers
automatically call ld 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 in 32-bit mode produces the output
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 32-bit 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.
In 64-bit mode, the startup functions are handled by the dynamic loader,
dld.sl. In most cases, the ld command line does not include crt0.o.
NOTEIf you are linking any C++ object files to create an executable or a shared
library, you must use the CC command to link. This ensures that
c++patch executes and chains together your nonlocal static constructors
and destructors. If you use ld, the library or executable may not work
correctly and you may not get any error messages. For more information
see the HP C++ Programmer's Guide.
Chapter 241
What Happens When You Compile and Link a Program
Linking Programs on HP-UX
Linking Programs on HP-UX
The HP-UX linker, ld, produces a single executable file from one or more
input object files and libraries. 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, a process 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”) main.o contains an external reference to sum_n, which has a
global definition in func.o. ld matches the external reference to the
global definition, allowing the main program code in a.out to access
sum_n (see Figure 2-3).
Figure 2-3Matching the External Reference to sum_n
If 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, ld cannot match the external reference to
sum_n and displays this output:
$ cc -Aa main.c
/usr/ccs/bin/ld: Unsatisfied symbols:
sum_n (code)
42Chapter 2
What Happens When You Compile and Link a Program
Linking Programs on HP-UX
The crt0.o Startup File
Notice in the example in “Compiler-Linker Interaction” that 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 entry point that 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 (dld.sl(5)) 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.
The 64-bit linker uses the startup file,
/opt/langtools/lib/pa_64/crt0.o, when:
• The linker is in compatibility mode (+compat).
• The linker is in default standard mode (+std) with the -noshared
option.
If the -p profiling option is specified on the 32-bit mode compile line, the
compilers link with mcrt0.o instead of crt0.o. If the -G profiling option is
specified, the compilers link with gcrt0.o. In 64-bit mode with the -p
option, the linker adds -lprof before the -lc option. With the -G
option, the linker adds -lgprof.
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
option.
For details on startup files, see crt0(3).
The Program's Entry Point
In 32-bit mode and in 64-bit statically-bound (-noshared) 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.
Chapter 243
What Happens When You Compile and Link a Program
Linking Programs on HP-UX
In 64-bit mode for dynamically bound executables, the entry point,
defined by the symbol $START$ in the dynamic loader (dld.sl).
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 code (text), data, and bss (uninitialized
data) segments reside in the file? For details on the format of this file , see
a.out(4).
Magic Numbers
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_MAGIC As 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 can improve process startup time since
the entire 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. The following shows which linker option to use to
specifically set the magic number.
44Chapter 2
What Happens When You Compile and Link a Program
Table 2-132-bit Mode Magic Number Linker Options
Linking Programs on HP-UX
To set the magic
number to:
Use this
option:
SHARE_MAGIC-n
DEMAND_MAGIC-q
EXEC_MAGIC-N
An executable file's magic number can also be changed using the chatr
command (see “Changing a Program's Attributes with chatr(1)” on page
104). 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 in the ELF
object file specifies how the file should be loaded.
File Permissions
If no linker errors occur, the linker gives the a.out file
read/write/execute permissions to all users (owner, group, and other). If
errors occurred, 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 other:
$ umask
022
$ ls -l a.out
-rwxr-xr-x1 michaelusers74440 Apr4 14:38 a.out
Chapter 245
What Happens When You Compile and Link a Program
Linking with Libraries
Linking with Libraries
In addition to matching external references to global definitions in object
files, 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.
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 or .sl if the
library is a shared library. suffix is a number, for
example .0, .1, and so forth, if library-level versioning
is being used.
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:
$ cc -Aa -v main.c func.c
...
/usr/ccs/bin/ld /opt/langtools/lib/crt0.o -u main main.o \
func.o -lc
cc: Entering Link editor.
Similarly, the Series 700/800 FORTRAN compiler automatically links
with the libcl (C interface), libisamstub (ISAM file I/O), and libc
libraries:
46Chapter 2
What Happens When You Compile and Link a Program
Linking with Libraries
$ f77 -v sumnum.f
...
/usr/ccs/bin/ld -x /opt/langtools/lib/crt0.o \
sumnum.o -lcl -lisamstub -lc
The Default Library Search Path
By default, ld searches for libraries in the directory /usr/lib. (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.) The default
order can be overridden with the LPATH environment variable or the -L
linker option. LPATH and -L are described in “Changing the Default
Library Search Path with -L and LPATH” on page 57.
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 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.
NOTEIf 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” on page 164.)
Chapter 247
What Happens When You Compile and Link a Program
Running the Program
Running the Program
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:
• Determine how to load the executable file by looking at its magic
number. (See Also “The a.out File”.)
• Determine where to begin execution of the program — that is, the
entry point — usually in crt0.o. (See Also “The crt0.o Startup
File”.)
• When the program uses shared libraries, the crt0.o startup code
invokes the dynamic loader (dld.sl), 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?” on page 126.)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 bss segment, 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.
48Chapter 2
What Happens When You Compile and Link a Program
Running the Program
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.
Chapter 249
What Happens When You Compile and Link a Program
Linker Thread-Safe Features
Linker Thread-Safe Features
Beginning with the HP-UX 10.30 release, the dynamic loader (dld.sl)
and its application interface library (libdld.sl) are thread-safe.
Also, beginning with the HP-UX 10.30 release, the linker toolset provides
thread local storage support in:
• ld — the link editor
• dld.sl — the shared library dynamic loader
• 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.
NOTEA program with thread local storage is only supported on systems
running HP-UX 10.30 or later versions of the operating system.
NOTEUse 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.
50Chapter 2
3Linker Tasks
You have a great deal of control over how the linker links your program
or library by using ld command-line options.
• Using the Compiler Command
• “Changing the Default Library Search Path with -Wl, -L”
• “Getting Verbose Output with -v”
• “Passing Linker Options from the Compiler Command with -Wl”
• “Renaming the Output File with -o”
• “Specifying Libraries with -l”
• “Suppressing the Link-Edit Phase with -c”
• Using the Linker Command
Linker Tasks
• “Linking with the 32-bit crt0.o Startup File”
• “Changing the Default Library Search Path with -L and LPATH”
• “Changing the Default Shared Library Binding with -B”
• “Choosing Archive or Shared Libraries with -a”
• “Dynamic Linking with -A and -R”
• “Exporting Symbols with +e”
• “Exporting Symbols from main with -E”
• “Getting Verbose Output with -v”
• “Hiding Symbols with -h”
• “Improving Shared Library Performance with -B symbolic”
• “Moving Libraries after Linking with +b”
• “Moving Libraries After Linking with +s and SHLIB_PATH”
• “Passing Linker Options from the Compiler Command with -Wl”
• “Passing Linker Options in a file with -c”
• “Passing Linker Options with LDOPTS”
Chapter 351
Linker Tasks
• “Specifying Libraries with -l and l:”
• “Stripping Symbol Table Information from the Output F ile with -s
and -x”
• Using the 64-bit mode linker command
• “Using the 64-bit Mode Linker with +compat or +std”
• “Linking Shared Libraries with -dynamic”
• “Linking Archived Libraries with -noshared”
• “Controlling Archive Library Loading with +[no]forceload”
• “Flagging Unsatisfied Symbols with +[no]allowunsats”
• “Hiding Symbols from export with +hideallsymbols”
• “Changing Mapfiles with -k and +nodefaultmap”
• “Changing Mapfiles with -k and +nodefaultmap”
• “Ignoring Dynamic Path Environment Variables with +noenvvar”
• “Linking in 64-bit Mode with +std”
• “Linking in 32-bit Mode Style with +compat”
• “Controlling Output from the Unwind Table with +stripwind”
• “Selecting Verbose Output with +vtype”
• “Linking with the 64-bit crt0.o Startup File”
• Linker Compatibility Warnings
52Chapter 3
Linker Tasks
Using the Compiler to Link
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
By default, the linker searches the directory /usr/lib and
/usr/ccs/lib for libraries specified with the -l compiler option. (If the
-p or -G compiler option is specified, then the linker also searches the
profiling library directory /usr/lib/libp.)
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
Chapter 353
Linker Tasks
Using the Compiler to Link
The LPATH environment variable provides another way to override the
default search path. For details, see “Changing the Default Library
Search Path with -L and LPATH”.
Getting Verbose Output with -v
The -v option makes a compiler display verbose information. This is
useful for seeing how the compiler calls ld. For example, using the -v
option with the Pascal compiler shows that it automatically links with
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 telling the linker to use an archive version of libmfrom the C command line is:
$ cc -Aa mathprog.c -Wl,-a,archive,-lm,-a,default
The command for telling the linker to use an archive version of libm is:
$ ld /opt/langtools/lib/crt0.o mathprog.o -a archive -lm \
-a default -lc
54Chapter 3
Linker Tasks
Using the Compiler to Link
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 theresulting file sum_num:
$ cc -Aa -o sum_num prog.cCompile using -o option.
$ sum_numRun 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 the default libraries.
For example, if a C program calls library routines in the curses library
(libcurses), you must specify -lcurses on the cc command line:
$ cc -Aa -v cursesprog.c -lcurses
...
/usr/ccs/bin/ld /opt/langtools/lib/crt0.o -u main \
cursesprog.o -lcurses -lc
cc: Entering Link editor.
Linking with the crt0.o Startup File in 32-bit mode
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 crt0(3) and “The crt0.o Startup File” on page 43.
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:
Chapter 355
Linker Tasks
Using the Compiler to Link
$ f77 -c func.fProduce .o for func.f.
$ ls func.o
func.oVerify that func.o was created.
$ f77 main.f func.oCompile main.f with func.o
$ a.outRun it to verify it worked.
56Chapter 3
Using Linker commands
Using Linker commands
This section describes linker commands for the 32-bit and 64-bit linker.
NOTEUnless otherwise noted, all examples show 32-bit behavior.
Linking with the 32-bit crt0.o Startup File
In 32-bit mode, you must always include crt0.o on the link line.
In 64-bit mode, you must include crt0.o on the link line for all fully
archive links (ld -noshared) and in compatibility mode (+compat). Y ou
do not need to include the crt0.o startup file on the ld command line
for shared bound links. In 64-bit mode, the dynamic loader, dld.sl, does
some of the startup duties previously done by crt0.o.
See “The crt0.o Startup File” on page 43, and the crt0(3) man page for
more information.
Linker Tasks
Changing the Default Library Search Path
with -L and LPATH
You can change or override the default linker search path by using the
LPATH environment variable or the -L 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 should contain a list of colon-separated directory path
names ld should search. For example, to include /usr/local/lib in
the search path after the default directories, set LPATH as follows:
$ LPATH=/usr/lib:/usr/local/libKorn and Bourne shell syntax.
$ export LPATH
Chapter 357
Linker Tasks
Using Linker commands
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:
If LPATH is set, then the -L option specifies the directories to search
before the directories specified in LPATH.
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 possibly 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, if you don't mind program startup taking a little longer.
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 could
use this ld command:
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:
Note that the -B nonfatal modifier does not work with deferred
binding because a symbol must have been 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 -B nonfatal 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.
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.
Chapter 359
Linker Tasks
Using Linker commands
• 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
will be 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
might run incorrectly. In such cases, -B restricted is useful, because
symbols bind the same way as they do with -B immediate, but actual
binding is still deferred.
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.
A benefit of -B symbolic is that it can help improve application
performance and the resulting shared library will be 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.
NOTEThe -B symbolic option applies only to function, but not variable,
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.sl, use -B symbolic as follows:
$ ld -B symbolic -b func1.o func2.o -o lib1.sl
60Chapter 3
Linker Tasks
Using Linker commands
NOTEThe +e option overrides the -B symbolic option. For example, 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 could not 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 symbolic.
2. Two main programs link to the shared library. main1 calls
convert_rtn() and main2 calls gal_to_liter().
$ cc -Aa main1.c libunits.sl -o main1
$ cc -Aa main1.c libunits.sl -o main2
Figure 3-1 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.
Chapter 361
Linker Tasks
Using Linker commands
Figure 3-1Symbols inside a Shared Library Visible with -B symbolic
main1
main () {
convert_rtn();
}
main2
main () {
gal_to_liter();
}
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 could hide the gal_to_liter symbol as shown:
In both cases, main2 will not be able to resolve its reference to
gal_to_liter() because only the convert_rtn() symbol is exported as
shown below:
main1
libunits.sl
main () {
convert_rtn ();
}
main2
main () {
gal_to_liter();
}
Unsatisfied symbol: gal_to_liter (at link-time)
convert_rtn() {
gal_to_liter();
}
gal_to_liter() { }
Only convert_rtn
symbol is
visible.
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 will run on a
system on which shared libraries may not be present. Since the program
could not 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” on page 164.
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:
Chapter 363
Linker Tasks
Using Linker commands
-a archiveSelect archive libraries. If the archive
library does not exist, ld generates
an error message and does not
generate the output file.
-a sharedSelect 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 cannot be 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 cannot be 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.
CAUTIONYou should avoid mixing shared libraries and archive libraries in the
same application. For more information see “Caution When Mixing
Shared and Archive Libraries” on page 164.
Example Using -a
The following command links with the archive versions of libcurses,
libm and libc:
$ ld /opt/langtools/lib/crt0.o prog.o -a archive -lcurses -lm -lc
64Chapter 3
Linker Tasks
Using Linker commands
Dynamic Linking with -A and -R
This section describes how to do dynamic linking — that is, how to add
an object module to a running program. Conceptually, it is very similar to
loading a shared library and accessing its symbols (routines and data).
In fact, if you require such functionality, you should probably use shared
library management routines (see Chapter 6, “Shared Library
Management Routines,” on page 195).
However, be aware that dynamic linking is incompatible with shared
libraries. That is, a running programcannot be linked to shared libraries
and also use ld -A to dynamically load object modules.
NOTEAnother reason to use shared library management routines instead of
dynamic linking is that dynamic linking may not be supported in a
future release. See “Linker Compatibility Warnings” and “Changes in
Future Releases” on page 32for additional future changes.
Topics in this section include:
• “Overview of Dynamic Linking” describes steps to load an object file
into a running program.
• “An Example Program” provides an example dynamic linking
scenario.
Overview of Dynamic Linking
The implementation details of dynamic linking vary across platforms. T o
load an object module into the address space of a running program, and
to be able to access its procedures and data, follow these steps on all
HP9000 computers:
1. Determine how much space is required to load the module.
2. Allocate the required memory and obtain its starting address.
3. Link the module from the running application.
4. Get information about the module's text, data, and bss segments from
the module's header.
5. Read the text and data into the allocated space.
6. Clear (fill with zeros) the bss segment.
7. Flush the text from the data cache before executing code from the
loaded module.
Chapter 365
Linker Tasks
Using Linker commands
8. Get the addresses of routines and data that are referenced in the
module.
Step 1: Determine how much space is required to load the
module.
module's text, data, and bss segments. You can make a liberal guess as to
how much memory is needed, and hope that you've guessed correctly. Or
you can be more precise by pre-linking the module and getting size
information from its header.
There must be enough contiguous memory to hold the
Step 2: Allocate the required memory and obtain its
starting address.
required memory. You must modify the starting address returned by
malloc to ensure that it starts on a memory page boundary (address
MOD 4096 == 0).
Typically, you use malloc(3C) to allocate the
Step 3: Link the module from the running application. Use
the following options when invoking the linker from the program:
-o mod_nameName of the output module that will be loaded by the
running program.
-A base_progTells the linker to prepare the output file for
incremental loading. Also causes the linker to include
symbol table information from base_prog in the output
file.
-R hex_addrSpecifies the hexadecimal address at which the module
will be loaded. This is the address calculated in Step 2.
-NCauses the data segment to be placed immediately
after the text segment.
-e entry_ptIf specified (it is optional), causes the symbol named
entry_pt to be the entry point into the module. The
location of the entry point is stored in the module's
header.
Step 4: Get information about the module's text, data, and
bss segments from the module's header.
structures stored at the start of the file: struct header (defined in
<filehdr.h>) and struct som_exec_auxhdr (defined in
<aouthdr.h>). The required information is stored in the second header,
so to get it, a program must seek past the first header before reading the
second one.
66Chapter 3
There are two header
Linker Tasks
Using Linker commands
The useful members of the som_exec_auxhdr structure are:
.exec_tsizeSize of text (code) segment.
.exec_tmemAddress at which to load the text (already adjusted for
offset specified by the -R linker option).
.exec_tfileOffset into file (location) where text segment starts.
.exec_dsizeSize of data segment.
.exec_dmemAddress at which to load the data (already adjusted).
.exec_dfileOffset into file (location) where data segment starts.
.exec_bsizeSize of bss segment. It is assumed to start immediately
after the data segment.
.exec_entryAddress of entry point (if one was specified by the -e
linker option).
Step 5: Read the text and data into the allocated space.
Once you know the location of the required segments in the file, you can
read them into the area allocated in Step 2.
The location of the text and data segments in the file is defined by the
.exec_tfile and .exec_dfile members of the som_exec_auxhdr
structure. The address at which to place the segments in the allocated
memory is defined by the .exec_tmem and .exec_dmem members. The
size of the segments to read in is defined by the .exec_tsize and
.exec_dsize members.
Step 6: Clear (zero out) the bss segment. The bss segment
starts immediately after the data segment. To zero out the bss, find the
end of the data segment and use memset (see memory(3C)) to zero out
the size of the bss.
The end of the data segment can be determined by adding the
.exec_dmem and .exec_dsize members of the som_exec_auxhdr
structure. The bss's size is defined by the .exec_bsize member.
Step 7: Flush the text from the data cache before executing
code from the loaded module.
allocated space, a program should flush the instruction and data caches.
Although this is really only necessary on systems that have instruction
and data caches, it is easiest just to do it on all systems for ease of
portability.
Chapter 367
Before executing code in the
Linker Tasks
Using Linker commands
Use an assembly language routine named flush_cache (see “The
flush_cache Function” in this chapter). You must assemble this routine
separately (with the as command) and link it with the main program.
Step 8: Get the addresses of routines and data that are
referenced in the module.
module's header will contain the address of the entry point. The entry
point's address is stored in the .exec_entry member of the
som_exec_auxhdr structure.
If the module contains multiple routines and data that must be accessed
from the main program, the main program can use the nlist(3C) function
to get their addresses.
Another approach that can be used is to have the entry point routine
return the addresses of required routines and data.
If the -e linker option was used, the
An Example Program
To illustrate dynamic linking concepts, this section presents an example
program, dynprog. This program loads an object module named
dynobj.o, which is created by dynamically linking two object files
file1.o and file2.o (see “file1.o and file2.o”).
The program allocates space for dynobj.o by calling a function named
alloc_load_space (see “The alloc_load_space Function” later in this
chapter). The program then calls a function named dyn_load to
dynamically link and load dynobj.o (see “The dyn_load Function” later
in this chapter). Both functions are defined in a file called dynload.c
(see “dynload.c”).
As a return value, dyn_load provides the address of the entry point in
dynobj.o — in this case, the function foo. To get the addresses of the
function bar and the variable counter, the program uses the nlist(3C)
function.
• “The Build Environment” shows the example makefile used to create
the dynprog program.
• “Source for dynprog” shows the C source code for the dynprog
program.
• “Output of dynprog” shows the run time output of the dynprog
program.
• “The flush_cache Function” provides example source code in assembly
language to flush text from the data cache.
68Chapter 3
Linker Tasks
Using Linker commands
The Build Environment. Before seeing the program's source code,
it may help to see how the program and the various object files were
built. The following shows the makefile used to generate the various
files.
# Create flush_cache.o:
flush_cache.o:
as flush_cache.s
This makefile assumes that the following files are found in the current
directory:
dynload.cThe file containing the alloc_load_space and
dyn_load functions.
dynprog.cThe main program that calls functions from
dynload.c and dynamically links and loads file1.o
and file2.o. Also contains the function glorp, which
is called by foo and bar.
file1.cContains the functions foo and bar.
file2.cContains the variable counter, which is incremented
by foo, bar, and main.
flush_cache.s
Assembly language source for function flush_cache,
which is called by the dyn_load function.
To create the executable programdynprog from this makefile, you would
simply run:
$ make dynprog file1.o file2.o
cc -Aa -D_POSIX_SOURCE -c dynprog.c
cc -Aa -D_POSIX_SOURCE -c dynload.c
cc -o dynprog dynprog.o dynload.o -Wl,-a,archive
cc -Aa -D_POSIX_SOURCE -c file1.c
cc -Aa -D_POSIX_SOURCE -c file2.c
as -o flush_cache flush_cache.s
Chapter 369
Linker Tasks
Using Linker commands
Note that the line CFLAGS =… causes any C files to be compiled in ANSI
mode (-Aa) and causes the compiler to search for routines that are
defined in the Posix standard (-D_POSIX_SOURCE).
For details on using make refer to make(1).
Source for dynprog. Here is the source file for the dynprog
const char * base_prog = “dynprog”; /* this executable’s name
*/
const char * obj_files = “file1.o file2.o”; /* .o files to combine
*/
const char * dest_file = “dynobj.o”; /* .o file to load
*/
const char * entry_pt = “foo”; /* define entry pt name
*/
void glorp (const char *); /* prototype for local
function */
void (* foo_ptr) (); /* pointer to entry point foo
*/
void (* bar_ptr) (); /* pointer to function bar
*/
int * counter_ptr; /* pointer to variable counter [file2.c]
*/
main()
{
unsigned int addr; /* address at which to load dynobj.o */
struct nlist nl[3]; /* nlist struct to retrieve addresse */
/*
STEP 1: Allocate space for module:
*/
addr = (unsigned int) alloc_load_space(base_prog,
obj_files, dest_file);
/*
STEP 2: Load the file at the address, and get address of entry
point:
*/
/*
* Now you can call the routines and modify the variables:
*/
glorp(“main”);
(*foo_ptr) ();
(*bar_ptr) ();
(*counter_ptr) ++;
printf(“counter = %d\n”, *counter_ptr);
}
void glorp(const char * from)
{
printf(“glorp called from %s\n”, from);
}
file1.o and file2.o . “Source for file1.c and file2.c” shows the source for
file1.o and file2.o. Notice that foo and bar call glorp in
dynprog.c. Also, both functions update the variable counter in
file2.o; however, foo updates counter through the pointer
(counter_ptr) defined in dynprog.c.
Source for file1.c and file2.c
/****************************************************************
* file1.c - Contains routines foo() and bar().
****************************************************************/
extern int * counter_ptr; /* defined in dynprog.c */
extern int counter; /* defined in file2.c */
extern void glorp(const char * from); /* defined in dynprog.c */
void foo()
{
Chapter 371
Linker Tasks
Using Linker commands
glorp(“foo”);
(*counter_ptr) ++; /* update counter indirectly with global
pointer */
}
The alloc_load_space Function . The alloc_load_space
function returns a pointer to space (allocated by malloc) into which
dynprog will load the object module dynobj.o. It syntax is:
void * alloc_load_space(const char * base_prog,
base_progThe name of the program that is calling the routine. In
other words, the name of the program that will
dynamically link and load dest_file.
72Chapter 3
const char * obj_files,
const char * dest_file)
Linker Tasks
Using Linker commands
obj_filesThe name of the object file or files that will be linked
together to create dest_file.
dest_fileThe name of the resulting object module that will by
dynamically linked and loaded by base_prog.
As described in Step 1 in “Overview of Dynamic Linking” at the start of
this section, you can either guess at how much space will be required to
load a module, or you can try to be more accurate. The advantage of the
former approach is that it is much easier and probably adequate in most
cases; the advantage of the latter is that it results in less memory
fragmentation and could be a better approach if you have multiple
modules to load throughout the course of program execution.
The alloc_load_space function allocates only the required amount of
space. T o determine how much memory is required,alloc_load_space
performs these steps:
1. Pre-link the specified obj_files to create base_prog.
2. Get text, data, and bss segment location and size information to
determine how much space to allocate.
3. Return a pointer to the space. (The address of the space is adjusted to
begin on a memory page boundary — that is, a 4096-byte boundary.)
“C Source for alloc_load_space Function” shows the source for this
function.
C Source for alloc_load_space Function
void * alloc_load_space(const char * base_prog,
const char * obj_files,
const char * dest_file)
{
char cmd_buf[256]; /* linker command line */
int ret_val; /* value returned by various lib calls */
size_t space; /* size of space to allocate for module */
size_t addr; /* address of allocated space */
size_t bss_size; /* size of bss (uninitialized data) */
FILE * destfp; /* file pointer for dest_file */
struct som_exec_auxhdr aux_hdr; /* file header */
unsigned int tdb_size; /* size of text, data, and bss combined */
/* -------------------------------------------------------------- * STEP 1: Pre-link the destination module so we can get its size:
*/
sprintf(cmd_buf, “/bin/ld -a archive -R80000 -A %s -N %s -o %s -lc”,
base_prog, obj_files, dest_file);
if (ret_val = system(cmd_buf)) {
Chapter 373
Linker Tasks
Using Linker commands
fprintf(stderr, “link failed: %s\n”, cmd_buf);
exit(ret_val);
}
/* -------------------------------------------------------------- * STEP 2: Get the size of the module’s text, data, and bss segments
* from the auxiliary header for dest_file; add them together to
* determine size:
*/
if ((destfp = fopen(dest_file, “r”)) == NULL) {
fprintf(stderr, “error opening %s\n”, dest_file);
exit(1);
}
/*
* Must seek past SOM “header” to get to the desired
* “som_exec_auxhdr”:
*/
if (fseek(destfp, sizeof(struct header), 0)) {
fprintf(stderr, “error seeking past header in %s\n”, dest_file);
exit(1);
}
if (fread(&aux_hdr, sizeof(aux_hdr), 1, destfp) <= 0) {
fprintf(stderr, “error reading som aux header from %s\n”, dest_file);
exit(1);
}
/* allow for page-alignment of data segment */
space = aux_hdr.exec_tsize + aux_hdr.exec_dsize
/* -------------------------------------------------------------- * STEP 3: Call malloc(3C) to allocate the required memory and get
* its address; then return a pointer to the space:
*/
addr = (size_t) malloc(space);
/*
* Make sure allocated area is on page-aligned address:
*/
if (addr % PAGE_SIZE != 0) addr += PAGE_SIZE - (addr % PAGE_SIZE);
return((void *) addr);
}
The dyn_load Function . The dyn_load function dynamically links
and loads an object module into the space allocated by the
alloc_load_space function. In addition, it returns the address of the
entry point in the loaded module. Its syntax is:
The base_prog, obj_files, and dest_file parameters are the same
parameters supplied to alloc_load_space. The addr parameter is the
address returned by alloc_load_space, and the entry_pt parameter
specifies a symbol name that you want to act as the entry point in the
module.
To dynamically link and load dest_file into base_prog, the dyn_load
function performs these steps:
1. Dynamically link base_prog with obj_files, producing dest_file. The
address at which dest_file will be loaded into memory is specified with
the -R addr option. The name of the entry point for the file is
specified with -e entry_pt.
2. Open dest_file and get its header information on the text, data, and
bss segments. Read this information into a som_exec_auxhdr
structure, which starts immediately after a header structure.
3. Read the text and data segments into the area allocated by
alloc_load_space. (The text and data segments are read
separately.)
4. Initialize (fill with zeros) the bss, which starts immediately after the
data segment.
5. Flush text from the data cache before execution, using the
flush_cache routine. (See “The flush_cache Function” later in this
chapter.)
6. Return a pointer to the entry point, specified by the -e option in Step
1.
C Source for dyn_load Function
void * dyn_load(const char * base_prog,
unsigned int addr,
const char * obj_files,
const char * dest_file,
const char * entry_pt)
{
char cmd_buf[256]; /* buffer holding linker command
*/
int ret_val; /* holds return value of library calls
*/
FILE * destfp; /* file pointer for destination file
*/
unsigned int bss_start; /* start address of bss in VM
*/
unsigned int bss_size; /* size of bss */
unsigned int entry_pt_addr; /* address of entry point
Chapter 375
Linker Tasks
Using Linker commands
*/
struct som_exec_auxhdr aux_hdr; /* som file auxiliary header
*/
unsigned int tdb_size; /* size of text, data, and bss
combined*/
/*
---------------------------------------------------------------- * STEP 1: Dynamically link the module to be loaded:
*/
sprintf(cmd_buf,
“/bin/ld -a archive -A %s -R %x -N %s -o %s -lc -e %s”,
base_prog, addr, obj_files, dest_file, entry_pt);
---------------------------------------------------------------- * STEP 2: Open dest_file. Read its auxiliary header for text,
data,
* and bss info:
*/
if ((destfp = fopen(dest_file, “r”)) == NULL)
{
fprintf(stderr, “error opening %s for loading\n”, dest_file);
exit(1);
}
/*
* Get auxiliary header information from “som_exec_auxhdr”
struct,
* which is after SOM header.
*/
if (fseek(destfp, sizeof(struct header), 0))
{
fprintf(stderr, “error seeking past header in %s\n”,
dest_file);
exit(1);
}
if (fread(&aux_hdr, sizeof(aux_hdr), 1, destfp) <= 0)
{
fprintf(stderr, “error reading som aux header from %s\n”,
dest_file);
exit(1);
}
/*
---------------------------------------------------------------- * STEP 3: Read the text and data segments into the buffer area:
*/
/*
* Read text and data separately. First load the text:
*/
76Chapter 3
Linker Tasks
Using Linker commands
if (fseek(destfp, aux_hdr.exec_tfile, 0))
{
fprintf(stderr, “error seeking start of text in %s\n”,
dest_file);
exit(1);
}
if ((fread(aux_hdr.exec_tmem, aux_hdr.exec_tsize, 1, destfp)) <=
0)
{
fprintf(stderr, “error reading text from %s\n”, dest_file);
exit(1);
}
/*
* Now load the data, if any:
*/
if (aux_hdr.exec_dsize) {
if (fseek(destfp, aux_hdr.exec_dfile, 0))
{
fprintf(stderr, “error seeking start of data in %s\n”,
dest_file);
exit(1);
}
if ((fread(aux_hdr.exec_dmem, aux_hdr.exec_dsize, 1,
destfp))<= 0)
{
fprintf(stderr, “error reading data from %s\n”, dest_file);
exit(1);
}
}
fclose(destfp); /* done reading from module file */
/*
* STEP 5: Flush the text from the data cache before execution:
*/
/*
* The flush_cache routine must know the exact size of the
* text, data, and bss, computed as follows:
* Size = (Data Addr - Text Addr) + Data Size + BSS Size
* where (Data Addr - Text Addr) = Text Size + alignment between
* Text and Data.
*/
tdb_size = (aux_hdr.exec_dmem - aux_hdr.exec_tmem) +
aux_hdr.exec_dsize + aux_hdr.exec_bsize;
flush_cache(addr, tdb_size);
Chapter 377
Linker Tasks
Using Linker commands
/*
---------------------------------------------------------------- * STEP 6: Return a pointer to the entry point specified by -e:
*/
The flush_cache Function . Since there is no existing routine to
flush text from the data cache before execution, you must create one.
Below is the assembly language source for such a function.
Assembly Language Source for flush_cache Function
; flush_cache.s
;
; Routine to flush and synchronize data and instruction caches
; for dynamic loading
;
; Copyright Hewlett-Packard Co. 1985,1991, 1995
;
; All HP VARs and HP customers have a non-exclusive royalty-free
; license to copy and use this flush_cashe() routine in source
; code and/or object code.
.code
; flush_cache(addr, len) - executes FDC and FIC instructions for
; every cache line in the text region given by starting addr and
; len. When done, it executes a SYNC instruction and then enough
; NOPs to assure the cache has been flushed.
;
; Assumption: Cache line size is at least 16 bytes. Seven NOPs
; is enough to assure cache has been flushed. This routine is
; called to flush the cache for just-loaded dynamically linked
; code which will be executed from SR5 (data) space.
; %arg0=GR26, %arg1=GR25, %arg2=GR24, %arg3=GR23, %sr0=SR0.
; loop1 flushes data cache. arg0 holds address. arg1 holds
offset.
; SR=0 means that SID of data area is used for fdc.
; loop2 flushes inst cache. arg2 holds address. arg3 holds
offset.
; SR=sr0 means that SID of data area is used for fic.
; fdc x(0,y) -> 0 means use SID of data area.
; fic x(%sr0,y) -> SR0 means use SR0 SID (which is set to data
area).
copy %arg1,%arg3 ; Copy offset from GR25 to GR23
fdc %arg1(0,%arg0) ; Flush data cache
@SID.address+offset
loop1
addib,>,n -16,%arg1,loop1 ; Decrement offset by cache line
size
fdc %arg1(0,%arg0) ; Flush data cache
@SID.address+offset
; flush first word at addr, to handle arbitrary cache line
boundary
fdc 0(0,%arg0)
sync
fic %arg3(%sr0,%arg2) ; Flush inst cache
@SID.address+offset
loop2
addib,>,n -16,%arg3,loop2 ; Decrement offset by cache line
size
fic %arg3(%sr0,%arg2) ; Flush inst cache
@SID.address+offset
; flush first word at addr, to handle arbitrary cache line
boundary
fic 0(%sr0,%arg2)
The +e option allow you to hide and export symbols. Exporting a
symbol makes the symbol a global definition, which can be accessed by
any other object modules or libraries. The +e option exports 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:
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:
$ ld -b -h check_sem_val sem.oOne -h option.
$ ld -b +e foo +e bar +e sem sem.oThree +e options.
In contrast, suppose you want to export only the check_sem_val
symbol. Either of the following commands would work:
$ ld -b -h foo -h bar -h sem sem.oThree -h options.
$ ld -b +e check_sem_val sem.oOne +e option.
When to use -h versus +e
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 should not combine -h and +e options on the same command line.
For instance, suppose you specify +e sem. This would export the symbol
sem and hide all other symbols. Any additional -h options would be
unnecessary. If both -h and +e are used on the same symbol, the -h
overrides the +e option.
The linker command line could get quite lengthy and difficult to read if
several such options were specified. And in fact, you could 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”. 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)
and when linking to create an a.out file. When combining .o files with
-r, you can still use only the -h option.
80Chapter 3
Linker Tasks
Using Linker commands
Exporting Symbols with +ee
Like the +e option, the +ee option allows you to export symbols. Unlike
the +e option, the option does not alter the visibility of any 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
By default, 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 doesnot
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 inChapter 6, “Shared Library Management
Routines,” on page 195). To make the linker export all symbols from a
program, invoke ld with the -E option.
The +e option allows you to be more selective about which symbols are
exported, resulting in better performance. For details on +e, see
“Exporting Symbols with +e”.
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 simply 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. Any 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:
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 do the following:
$ ld -b -h check_sem_val sem.o
Tips on Using -h
You should not combine -h and +e options on the same command line.
For instance, suppose you specify +e sem. This would export the symbol
sem and hide all other symbols. Any additional -h options would be
unnecessary. If both -h and +e are used on the same symbol, the -h
overrides the +e option.
The linker command line could get quite lengthy and difficult to read if
several such options were specified. And in fact, you could 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”. You can specify any number of -h or +e
options in this file.
Hiding and Exporting Symbols When Building a
Shared Library
When building a shared library, you might want to hide a symbol in the
library for several reasons:
• It can improve performance because the dynamic loader does not have
to bind hidden symbols. Since most symbols need not be exported
from a shared library, hiding selected symbols can have a significant
impact on performance.
• It 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 will be hidden from them.
82Chapter 3
Linker Tasks
Using Linker commands
• When linking with other libraries (to create an executable), it ensures
that the library will use 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 seldom 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 will be used by another shared library or the program, even
if these other files have definitions of the data symbols. Otherwise, your
shared library will use its own private copy of the global data, and
another library or the program file will not see any change.
One example of a data symbol that should almost always be exported
from a shared library is errno. errno is defined in every shared library
and program; if this definition is hidden, the value of errno will 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 a .o file are the same as the reasons listed
above for shared libraries. However, a performance improvement will
occur only if the resulting .o file is later linked into a shared library.
Hiding and Exporting Symbols When Creating an
a.out File
By default, 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.
Chapter 383
Linker Tasks
Using Linker commands
As mentioned previously in the section “Exporting Symbols from main
with -E”, 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 if a definition exists outside the program file. In such
cases, a shared library might update a global variable needed by the
program, but the program would never see the change because it would
be referencing its own copy.
One example of a data symbol that should almost always be exported
from a program is errno. errno is defined in every shared library and
program; if this definition is hidden, the value of errno will not be
shared outside of the program in which it is hidden.
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 won't 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)” on page 104).
84Chapter 3
Linker Tasks
Using Linker commands
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 would search for libfoo.sl, libm.sl, and libc.sl in
the current working directory (.), the directory /app/lib, and lastly in
the location in which the libraries were found at link time (::):
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:
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 basename of the library
path name stored in the executable. For instance, if a program is linked
with /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 (). 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
Chapter 385
Linker Tasks
Using Linker commands
the previous example were /apps/lib::xyz, the dynamic loader would
search for /apps/lib/libfoo.sl, /usr/local/lib/libfoo.sl,
then ./xyz/libfoo.sl.
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 will get the
library path list from the SHLIB_PATH environment variable at run time.
This is especially useful for application developers who don't know where
the libraries will 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” provides additional details about the path list to
SHLIB_PATH.
• “Moving Libraries after Linking with +b” provides another way to
move libraries.
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 could place them in a
file named eopts and force the linker to read options from the file as
follows:
$ ld -o libmods.sl -b -c eopts mod*.o
$ cat eoptsDisplay the file.
+e foo
+e bar
Note that the linker ignores lines in that option file that begin with a
pound sign (#). Y ou 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:
$ LDOPTS="-v -t"Korn and Bourne shell syntax.
$ export LDOPTS
Thereafter, the following commands would be equivalent:
$ ld /opt/langtools/lib/crt0.o -u main prog.o -lc
$ ld -v -t /opt/langtools/lib/crt0.o -u main prog.o -lc
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. F or example, if you write a C
program that calls POSIX math functions, you must link with libm.
Chapter 387
Linker Tasks
Using Linker commands
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 searchedbefore 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 basename of the library to link with.
For instance, -l:libm.a causes the linker to link with the archive
library /usr/lib/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” on page 164.)
For instance, suppose you use the LDOPTS environment variable (see
“Passing Linker Options with LDOPTS”) to set the -a option that you
want to use by default when linking. And depending on what
environment you are building an application for, you might set LDOPTS
to -a archive or -a shared. You can use -l: to ensure that the linker
will always link 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 would link with the archive libfoo.a in the directory
/usr/mylibs, the archive libm.a and libc.a:
$ ld /opt/langtools/lib/crt0.o -u main prog.o -L/usr/mylibs \
-l:libfoo.a -l:libc.a -l:libm.a
88Chapter 3
Linker Tasks
Using Linker commands
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. ld 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 affect
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 dramatically. Note, also,
that these options can also be used when generating shared libraries
without affecting shareability.
Chapter 389
Linker Tasks
Using 64-bit Mode Linker Options
Using 64-bit Mode Linker Options
This section introduces 64-bit-only linker options.
Using the 64-bit Mode Linker with +compat or
+std
In the HP-UX 11.0 release, the linker toolset supports extended features
for linking in 64-bit mode. Since compatibility with the previous linker
toolset is a high priority, the 64-bit linker uses much of the old behavior
in the new toolset. The 64-bit mode linker includes two options to allow
you to instruct the linker to link in one of two modes:
• Compatibility mode, with the +compat option, to create a link and
operation in 32-bit style. Because of some object file format
restrictions, the mode is not completely compatible with the style of
the 32-bit linker.
• Standard mode, with the +std option, set by default in 64-bit mode,
to create a link and load operation in 64-bit style. This mode uses the
new behaviors and features of the 64-bit linker.
Using the Linker with +compat for Compatibility
Mode
The +compat option instructs the linker to do a 32-bit-style link.
When you use the +compat option, the linker:
• Uses 32-bit style shared library internal name processing.
• Lists all dependent shared libraries in a DT_HP_NEEDED entry the
dynamic table using the 32 bit-style shared library naming
conventions. These dependent libraries are recorded as compatibility
mode libraries even if they are really created as standard mode
dependent libraries.
• If an error occurs during the link, the linker creates an a.out
without the executable permission bits set.
• Does not use embedded paths at link time to find dependent
libraries.
• Considers the order of ld +b and +s.
90Chapter 3
Linker Tasks
Using 64-bit Mode Linker Options
• +b 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.
• +s 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 32-bit style 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 the a.out was linked +std, 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. The dynamic
loader looks at whichever has second precedence next, 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 64-bit Linker with +std for Standard Mode
The +std option instructs the linker to do a standard mode 64-bit style
link. This is currently the default in 64-bit mode.
Chapter 391
Linker Tasks
Using 64-bit Mode Linker Options
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.
• ld +b and +s ordering is ignored. ld +s is on by default.
• If an error occurs during the link, the linker does not generate an
a.out file.
• 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/pa20_64:/usr/ccs/lib/pa20_64.
At runtime, the dynamic loader does a 64-bit-style 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.
92Chapter 3
Linker Tasks
Using 64-bit Mode Linker Options
• Looks at the environment variables first, followed by RPATH, and the
default directories by default when doing dynamic path searching for
standard-mode dependentshared libraries.
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
dynamically linked executable.
This option is on by default in standard mode.
In the following example, the linker only looks for shared libraries:
$ld main.o -dynamic -L. -lbar -lc
If you specified an archive library, the linker links it in, but the resulting
executable is still a dynamically linked executable. This is true even if
the linker finds no shared libraries at link time.
Linking Archived Libraries with -noshared
Use the -noshared option if you need to link with all archive libraries.
The linker outputs a statically bound executable.
NOTEYou cannot link in shared libraries if you specify this option.
In the following example, the linker only looks for
/usr/lib/pa20_64/libfoo.a and /usr/lib/pa20_64/libc.a:
ld crt0.o main.o -noshared -L. -lfoo -lc
If you specify a shared library with this option, the linker emits an error
message.
ld: The shared library “libbar.sl” cannot be processed in a static
link.
Fatal error.
Controlling Archive Library Loading with
+[no]forceload
Use the +[no]forceload option to control how the linker loads object
files from an archived library. +forceload instructs the linker to load
all object files from an archive library. +noforceload tells the linker to
Chapter 393
Linker Tasks
Using 64-bit Mode Linker Options
only load those modules from an archive library that is needed. The
mode you select, either by default or explicitly, remains on until you
change it.
+noforceload is the default on both 32-bit and 64-bit modes.
In the following example, main() references foo(), which is a module
in mylib.a. foo() doesn’t 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 in.
...
Selecting liba.a[foo.o] to forcibly load
Selecting liba.a[bar.o] to forcibly load
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 32-bit
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 32-bit mode).
For example, where main() references functions foo() and bar().
bar() resides in libbar.sl. foo() resides in libfoo.sl
ld main.o +allowunsats -L. -lbar -lc
ld: (warning) Unsatisfied symbol “foo”.
1 warning.
+allowunsats 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 emits an error message and an
unexecutable a.out only if linking with +compat set.
ld main.o -L. -lbar -lc
ld: Unsatisfied symbol “foo”.
1 error.
94Chapter 3
Linker Tasks
Using 64-bit Mode Linker Options
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(). Using
+hideallsymbols, the linker does not export these two routines in the
a.out.
ld main.o +hideallsymbols -L. -lfoo -lc
elfdump -t a.out
a.out:
...
.symtab
index Type Bind Other SectValueSizeName
1 FUNC LOCL 00xb 0x4000000000001104 0test
...
10FUNCLOCL00xb0x40000000000012000func
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.
NOTEIn 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
Appendix A, “Using Mapfiles,” on page 295.
Chapter 395
Linker Tasks
Using 64-bit Mode Linker Options
Ignoring Dynamic Path Environment
Variables with +noenvvar
Use the +noenvvar to instruct the dynamic loader not to look at the
environment variables relating to dynamic path searching at runtime. It
ignores LD_LIBRARY_PATH and SHLIB_PATH environment variables.
This option is on by default in with ld +compat. It is off by default with
ld +std.
For example, if libbar.sl has dependent library libfee.sl that is i
Use the +std option to instructs the linker to do a 64-bit mode link. This
is the default mode. For more information, see “Using the 64-bit Mode
Linker with +compat or +std”.
Linking in 32-bit Mode Style with +compat
Use the +compat option to instruct the linker to do a 32-bit mode style
link. For more information, see “Using the 64-bit Mode Linker with
+compat or +std”.
Controlling Output from the Unwind Table
with +stripwind
Use the +stripunwind option to suppress output of the unwind table.
Searching /usr/lib/pa20_64/libc.a:
Selecting /usr/lib/pa20_64/libc.a[printf.o] to
resolve printf
Selecting /usr/lib/pa20_64/libc.a[data.o] to
resolve __iob
...
sectionsDump information about each section added to the
output file.
ld main.o +vtype sections -L. -lfile1 -lfile2 -lc
main.o:
section .text PROG_BITS AX 116 8 added to text
segment
section .PARISC.unwind UNWIND 16 4 added to text
segment
section .data PROG_BITS AW 96 8 added to data
segment
symbolsDump 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.s:
printf is UNDEF GLOBAL FUNC
_DYNAMIC is DEFINED GLOBAL OBJECT
lib1_func is DEFINED GLOBAL FUNC
...
allDump all of the above. Same as -v.
Chapter 397
Linker Tasks
Using 64-bit Mode Linker Options
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 .text PROG_BITS AX 116 8 added to text
segment
section .PARISC.unwind UNWIND 16 4 added to text
segment
section .data PROG_BITS AW 96 8 added to data
segment
Loading ./libfile1.sl:
./libfile1.sl:
...
Linking with the 64-bit crt0.o Startup File
In 32-bit mode, you must always include crt0.o on the link line.
In 64-bit mode, you must include crt0.o on the link line for all fully
archive links (ld -noshared) and in compatibility mode (+compat). Y ou
do not need to include the crt0.o startup file on the ld command line
for shared bound links. In 64-bit mode, the dynamic loader, dld.sl, does
some of the startup duties previously done by crt0.o.
See “The crt0.o Startup File” on page 43, and crt0(3) manual page for
more information.
98Chapter 3
Linker Tasks
Linker Compatibility Warnings
Linker Compatibility Warnings
Beginning with the HP-UX 10.20 release, the linker generates
compatibility warnings. These warnings include HP 9000 architecture
issues, as well as linker features that may change over time.
Compatibility warnings can be turned off with the
+vnocompatwarnings linker option. Also, detailed warnings can be
turned on with the +vallcompatwarnings linker option. See the ld(1)
man page for a description of these options.
Link-time compatibility warnings include the following:
• Linking PA-RISC 2.0 object files on any system — PA-RISC 1.0
programs run on 1.1 and 2.0 systems. PA-RISC 2.0 programs do not
run on 1.1 or 1.0 systems. See Also “PA-RISC Changes in Hardware
Compatibility” on page 21.
• Dynamic linking with -A — If you do dynamic linking with -A, you
should migrate to using the shared library management routines
described in Chapter 6, “Shared Library Management Routines,” on
page 195. These routines are also described in the sh_load(3X) and
dl*(3X) man page.
The 64-bit mode linker does not support the -A option.
• Procedure call parameter and return type checking (which can be specified with -C) — The 32-bit linker checks the number and types of
parameters in procedure calls across object modules. In a future
release, you should expect HP compilers to perform cross-module type
checking, instead of the linker. This impacts HP Pascal and HP
Fortran programs.
The 64-bit mode linker does not support the -C option.
• Duplicate names found for code and data symbols — The 32-bit linker
can create a program that has a code and data symbol with the same
name. In the HP-UX 11.00 release, the 64-bit mode linker adopts a
single name space for all symbols. This means that code and data
symbols cannot share the same name. Renaming the conflicting
symbols solves this problem.
Chapter 399
Linker Tasks
Linker Compatibility Warnings
• Unsatisfied symbols found when linking to archive libraries — If you
specify the -v option with the +vallcompatwarnings option and
link to archive libraries, you may see new warnings. For an example,
see “Linking to Archive Libraries with Unsatisfied Symbols” in this
chapter.
• Versioning within a shared library — If you do versioning within a
shared library with the HP_SHLIB_VERSION (C and C++); or the
SHLIB_VERSION (Fortran and Pascal) compiler directive, you should
migrate to the industry standard and faster-performing library-level
versioning. See “Library-Level Versioning” on page 150 to learn how
to do library-level versioning. In the HP-UX 11.00 release, the 64-bit
mode linker does not support internal library versioning.
Linking to Archive Libraries with Unsatisfied
Symbols
If you link a program that contains a reference to an archive library, and
the archive library contains an undefined symbol, you may see the
following warning:
ld: (Warning) The file library.a(x.o) has not been fully
checked for unsatisfied symbols.This behavior may
change in future releases.
The 32-bit mode linker does not include an object from an archive library
simply because it contains a needed definition of an uninitialized global
data symbol. Instead, it changes the existing undefined symbol to an
uninitialized data symbol. This symbol has the same size as the
definition of the global variable in the library.
For example, given these source files:
archive.c
int foo;/* definition of uninitialized
void func()
{
unsat();
}
global data symbol*/
main.c
extern int foo; /* declaration of global data symbol */
main()
{
100Chapter 3
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.