Kenwood HP 9000 User Manual

HP-UX Linker and Libraries User's Guide
HP 9000 Computers
B2355-90655
November 1997
© Copyright 1997 Hewlett-Packard Company. All rights reserved.
Legal Notices
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.
Copyright © 1997 Hewlett-Packard Company. This document contains information which is protected by copyright. All
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.
© Copyright 1980, 1984, 1986 AT&T Technologies, Inc. UNIX and System V are registered trademarks of AT&T in the USA and other countries.
2
UNIX is a registered trademark in the United States and other countries, licensed exclusively through X/Open Company Limited.
© Copyright 1979, 1980, 1983, 1985-1990 Regents of the University of California. This software is based in part on the Fourth Berkeley Software Distribution under license from the Regents of the University of California.
Copyright © The Regents of the University of Colorado, a body corporate 1979
This document has been reproduced and modified with the permission of the Regents of the University of Colorado, a body corporate.
PostScript is a trademark of Adobe Systems, Inc. Intel is a registered trademark and Intel 80386 is a trademark of Intel
Corporation. Ethernet is a trademark of Xerox Corporation. © Copyright 1985-1986, 1988 Massachussetts Institute of Technology. X
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.
3
4
Contents
Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Printing History. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .15
1. What's New in Recent Releases
PA-RISC Changes in Hardware Compatibility . . . . . . . . . . . . . . . . . . . .21
PA-RISC 2.0 Compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21
PA-RISC Architectures and Their System Models. . . . . . . . . . . . . . . .22
64-bit Mode Linker Toolset Compatibility with De Facto Industry
Standards. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .23
64-bit Mode ELF Object File Format . . . . . . . . . . . . . . . . . . . . . . . . . . . .24
New Features for 64-bit Mode Linking. . . . . . . . . . . . . . . . . . . . . . . . . . .25
64-bit Mode Linker Options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25
64-bit Mode Linker-defined Symbols. . . . . . . . . . . . . . . . . . . . . . . . . . .26
64-bit Mode Link-time Differences. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28
64-bit Mode Run Time Differences. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
Changes in Future Releases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .32
Online Help for Linker and Libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Accessing Help with ld +help. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Accessing Help with the HP CDE Front Panel. . . . . . . . . . . . . . . . . . .33
Accessing Help with the dthelpview Command . . . . . . . . . . . . . . . . . .33
Accessing Help with the charhelp Command. . . . . . . . . . . . . . . . . . . .33
2. What Happens When You Compile and Link a Program
Compiling Programs on HP-UX:
An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36
Looking “inside” a Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38
What is an Object File? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
Local Definitions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .40
5
Contents
Global Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
External References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Compiler-Linker Interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Linking Programs on HP-UX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
The crt0.o Startup File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
The a.out File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
File Permissions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Linking with Libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Library Naming Conventions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Default Libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
The Default Library Search Path. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Link Order. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Running the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Loading Programs: exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Binding Routines to a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Deferred Binding is the Default. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Linker Thread-Safe Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3. Linker Tasks
Using the Compiler to Link. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Changing the Default Library Search Path with -Wl, -L . . . . . . . . . . 53
Getting Verbose Output with -v. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Passing Linker Options from the Compiler Command with -Wl . . . . 54
Renaming the Output File with -o. . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Specifying Libraries with -l . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Suppressing the Link-Edit Phase with -c . . . . . . . . . . . . . . . . . . . . . . 55
Using Linker commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Linking with the 32-bit crt0.o Startup File. . . . . . . . . . . . . . . . . . . . . 57
Changing the Default Library Search Path with -L and LPATH. . . . 57
6
Contents
Changing the Default Shared Library Binding with -B. . . . . . . . . . . .58
Improving Shared Library Performance with -B symbolic . . . . . . . . .60
Choosing Archive or Shared Libraries with -a . . . . . . . . . . . . . . . . . . .63
Dynamic Linking with -A and -R. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .65
Exporting Symbols with +e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .79
Exporting Symbols with +ee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81
Exporting Symbols from main with -E . . . . . . . . . . . . . . . . . . . . . . . . .81
Hiding Symbols with -h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .81
Moving Libraries after Linking with +b . . . . . . . . . . . . . . . . . . . . . . . .84
Moving Libraries After Linking with +s and SHLIB_PATH . . . . . . . .86
Passing Linker Options in a file with -c . . . . . . . . . . . . . . . . . . . . . . . .86
Passing Linker Options with LDOPTS. . . . . . . . . . . . . . . . . . . . . . . . .87
Specifying Libraries with -l and l:. . . . . . . . . . . . . . . . . . . . . . . . . . . . .87
Stripping Symbol Table Information from the Output File with -s and
-x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .89
Using 64-bit Mode Linker Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .90
Using the 64-bit Mode Linker with +compat or +std. . . . . . . . . . . . . .90
Linking Shared Libraries with -dynamic . . . . . . . . . . . . . . . . . . . . . . .93
Linking Archived Libraries with -noshared . . . . . . . . . . . . . . . . . . . . .93
Controlling Archive Library Loading with +[no]forceload. . . . . . . . . .93
Flagging Unsatisfied Symbols with +[no]allowunsats. . . . . . . . . . . . .94
Hiding Symbols from export with +hideallsymbols . . . . . . . . . . . . . . .95
Changing Mapfiles with -k and +nodefaultmap. . . . . . . . . . . . . . . . . .95
Ignoring Dynamic Path Environment Variables with +noenvvar . . . .96
Linking in 64-bit Mode with +std . . . . . . . . . . . . . . . . . . . . . . . . . . . . .96
Linking in 32-bit Mode Style with +compat . . . . . . . . . . . . . . . . . . . . .96
Controlling Output from the Unwind Table with +stripwind . . . . . . .96
Selecting Verbose Output with +vtype . . . . . . . . . . . . . . . . . . . . . . . . .97
Linking with the 64-bit crt0.o Startup File . . . . . . . . . . . . . . . . . . . . .98
Linker Compatibility Warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .99
Linking to Archive Libraries with Unsatisfied Symbols . . . . . . . . . .100
7
Contents
4. Linker Tools
Changing a Program's Attributes with chatr(1). . . . . . . . . . . . . . . . . . 104
Using chatr for 32-bit Program Attributes . . . . . . . . . . . . . . . . . . . . 104
Using chatr for 64-bit Program Attributes . . . . . . . . . . . . . . . . . . . . 105
Viewing Symbols in an Object file with nm(1) . . . . . . . . . . . . . . . . . . . 107
Viewing the Contents of an Object File with elfdump(1). . . . . . . . . . . 111
Viewing library dependencies with ldd(1). . . . . . . . . . . . . . . . . . . . . . . 113
Viewing the Size of Object File Elements with size(1). . . . . . . . . . . . . 115
Reducing Storage Space with strip(1). . . . . . . . . . . . . . . . . . . . . . . . . . 116
Improving Program Start-up with fastbind(1) . . . . . . . . . . . . . . . . . . . 118
Finding Object Library Ordering Relationships with lorder(1). . . . . . 120
5. Creating and Using Libraries
Overview of Shared and Archive Libraries. . . . . . . . . . . . . . . . . . . . . . 122
What are Archive Libraries? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Example. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
What are Shared Libraries? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
The Dynamic Loader dld.sl. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Default Behavior When Searching for Libraries at Run Time. . . . . 127
Caution on Using Dynamic Library Searching. . . . . . . . . . . . . . . . . 127
Example Program Comparing Shared and Archive Libraries. . . . . . . 128
Shared Libraries with Debuggers, Profilers, and Static Analysis. . . . 130
Creating Archive Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Overview of Creating an Archive Library . . . . . . . . . . . . . . . . . . . . . 131
Contents of an Archive File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Example of Creating an Archive Library. . . . . . . . . . . . . . . . . . . . . . 133
Replacing, Adding, and Deleting an Object Module . . . . . . . . . . . . . 134
8
Contents
Summary of Keys to the ar(1) Command . . . . . . . . . . . . . . . . . . . . . .135
crt0.o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
Archive Library Location. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .136
Creating Shared Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .138
Creating Position-Independent Code (PIC). . . . . . . . . . . . . . . . . . . . .138
Creating the Shared Library with ld. . . . . . . . . . . . . . . . . . . . . . . . . .139
Shared Library Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .140
Updating a Shared Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Shared Library Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Improving Shared Library Performance. . . . . . . . . . . . . . . . . . . . . . .145
Version Control with Shared Libraries . . . . . . . . . . . . . . . . . . . . . . . . .149
When to Use Shared Library Versioning . . . . . . . . . . . . . . . . . . . . . .149
Maintaining Old Versions of Library Modules . . . . . . . . . . . . . . . . . .150
Library-Level Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .150
Intra-Library Versioning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .154
Switching from Archive to Shared Libraries . . . . . . . . . . . . . . . . . . . . .158
Library Path Names. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158
Relying on Undocumented Linker Behavior. . . . . . . . . . . . . . . . . . . .158
Absolute Virtual Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .159
Stack Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160
Version Control. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .160
Debugger Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
Using the chroot Command with Shared Libraries . . . . . . . . . . . . . .161
Profiling Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
Summary of HP-UX Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .162
Caution When Mixing Shared and Archive Libraries. . . . . . . . . . . . . .164
Example 1: Unsatisfied Symbols. . . . . . . . . . . . . . . . . . . . . . . . . . . . .164
Example 2: Using shl_load(3X) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .167
Example 3: Hidden Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
Summary of Mixing Shared and Archive Libraries . . . . . . . . . . . . . .175
9
Contents
Using Shared Libraries in 64-bit mode. . . . . . . . . . . . . . . . . . . . . . . . . 176
Internal Name Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Dynamic Path Searching for Shared Libraries. . . . . . . . . . . . . . . . . 177
Shared Library Symbol Binding Semantics . . . . . . . . . . . . . . . . . . . 178
Mixed Mode Shared Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
64-bit Mode Library Examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
6. Shared Library Management Routines
Shared Library Management Routine Summaries . . . . . . . . . . . . . . . 196
The shl_load Routine Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
The dlopen Routines Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
Related Files and Commands. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
Shared Library Header Files. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
Using Shared Libraries with cc and ld Options . . . . . . . . . . . . . . . . . . 200
Initializers for Shared Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Styles of Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
32-bit Mode Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
64-bit Mode Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
The shl_load Shared Library Management Routines . . . . . . . . . . . . . 215
The shl_load and cxxshl_load Routines. . . . . . . . . . . . . . . . . . . . . . . 215
The shl_findsym Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
The shl_get and shl_get_r Routines. . . . . . . . . . . . . . . . . . . . . . . . . . 226
The shl_gethandle and shl_gethandle_r Routines . . . . . . . . . . . . . . 230
The shl_definesym Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
The shl_getsymbols Routine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
The shl_unload and cxxshl_unload Routines . . . . . . . . . . . . . . . . . . 238
The dlopen Shared Library Management Routines. . . . . . . . . . . . . . . 240
The dlopen Routine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
The dlerror Routine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
10
Contents
The dlsym Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .245
The dlget Routine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .248
The dlmodinfo Routine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .249
The dlgetname Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .252
The dlclose Routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .253
Dynamic Loader Compatibility Warnings . . . . . . . . . . . . . . . . . . . . . . .256
Unsupported Shared Library Management Routines . . . . . . . . . . . .256
Unsupported Shared Library Management Flags . . . . . . . . . . . . . . .256
7. Position-Independent Code
What Is Relocatable Object Code? . . . . . . . . . . . . . . . . . . . . . . . . . . . . .260
What is Absolute Object Code?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .261
What Is Position-Independent Code? . . . . . . . . . . . . . . . . . . . . . . . . . . .262
Generating Position-Independent Code . . . . . . . . . . . . . . . . . . . . . . . . .263
For More Information: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .264
PIC Requirements for Compilers and Assembly Code. . . . . . . . . . . .264
Long Calls. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .265
Long Branches and Switch Tables. . . . . . . . . . . . . . . . . . . . . . . . . . . .265
Assigned GOTO Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .266
Literal References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .266
Global and Static Variable References . . . . . . . . . . . . . . . . . . . . . . . .267
Procedure Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .267
8. Ways to Improve Performance
Linker Optimizations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .270
Invoking Linker Optimizations from the Compile Line. . . . . . . . . . .270
Incompatibilities with other Options . . . . . . . . . . . . . . . . . . . . . . . . .271
Unused Procedure Elimination with +Oprocelim. . . . . . . . . . . . . . . .271
Options to Improve TLB Hit Rates. . . . . . . . . . . . . . . . . . . . . . . . . . . . .273
11
Contents
Profile-Based Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
General Information about PBO . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
Using PBO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
When to Use PBO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
How to Use PBO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Instrumenting (+I/-I). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Profiling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Optimizing Based on Profile Data (+P/-P). . . . . . . . . . . . . . . . . . . . . 283
Selecting an Optimization Level with PBO. . . . . . . . . . . . . . . . . . . . 285
Using PBO to Optimize Shared Libraries . . . . . . . . . . . . . . . . . . . . . 286
Using PBO with ld -r . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
Restrictions and Limitations of PBO. . . . . . . . . . . . . . . . . . . . . . . . . 288
Compatibility with 9.0 PBO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
Improving Shared Library Start-Up Time with fastbind . . . . . . . . . . 293
Using fastbind. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Invoking the fastbind Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Invoking fastbind from the Linker. . . . . . . . . . . . . . . . . . . . . . . . . . . 294
How to Tell if fastbind Information is Current. . . . . . . . . . . . . . . . . 294
Removing fastbind Information from a File . . . . . . . . . . . . . . . . . . . 294
Turning off fastbind at Run Time . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
For More Information: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
A. Using Mapfiles
Controlling Mapfiles with the -k Option. . . . . . . . . . . . . . . . . . . . . . . . 296
Mapfile Example: Using -k filename (without +nodefaultmap Option)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Changing Mapfiles with -k filename and +nodefaultmap . . . . . . . . . . 298
Mapfile Example: Using -k mapfile and +nodefaultmap . . . 298
Simple Mapfile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Default HP-UX Release 11.0 Mapfile . . . . . . . . . . . . . . . . . . . . . . . . . . 301
12
Contents
Defining Syntax for Mapfile Directives . . . . . . . . . . . . . . . . . . . . . . . . .303
Defining Mapfile Segment Declarations. . . . . . . . . . . . . . . . . . . . . . . . .304
Segment Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .304
Mapfile Segment Declaration Examples. . . . . . . . . . . . . . . . . . . . . . .306
Defining Mapfile Section Mapping Directives . . . . . . . . . . . . . . . . . . . .307
Internal Map Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .309
Placement of Segments in an Executable. . . . . . . . . . . . . . . . . . . . . .309
Mapping Input Sections to Segments . . . . . . . . . . . . . . . . . . . . . . . . .309
Interaction between User-defined and Default Mapfile Directives. .312
Mapfile Option Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .313
Fatal Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .313
Warnings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .313
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
13
Contents
14
Preface
This Guide covers the following topics:
• 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 64-bit mode dynamic path searching mechanisms.
• Add 64-bit mode symbol binding semantics.
• 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
1 What'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 1 19
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
20 Chapter 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.
NOTE The +DA1.0 option will be obsolete in a future release. You can achieve
better performance on PA-RISC 1.1 and 2.0 systems by not using this option.
PA-RISC 2.0 Compatibility
The instruction set on PA-RISC 2.0 is a superset of the instruction set on PA-RISC 1.1. As a result, code generated for PA-RISC 1.1 systems 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 1 21
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.0 The 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.1 The 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.0 The newest version of PA-RISC. The following Series
are included: C160, C180, C180XP, C200, C240, J280, J282, J2240, Dx70, Dx80, Kx50, Kx60, Kx70, T600, V2200.
For More Information
• See your compiler online help or documentation for 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.
22 Chapter 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 1 23
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.
Option Compiler
+DA2.0W C and aC++ +DD64 C
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.
24 Chapter 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:
Option Action
-dynamic Forces the linker to create a shared executable. The linker looks for shared libraries first and then archived libraries. This option is on by default when you compile in 64-bit mode.
-noshared Forces the linker to create a fully bound archive program.
-k filename Allows you to control the mapping of input section in the object file to segments in the output file.
+[no]allowunsats Instructs the linker how to report errors for
output files with unsatisfied symbols.
+compat Instruct the linker to use 32-bit mode
linking and dynamic loading behaviors.
+[no]forceload Enables/disables forced loading of all the
object files from archive libraries.
+hideallsymbols +nodefaultmap Instructs the linker not to load the default
Chapter 1 25
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
Option Action
+noenvvar Instructs the dynamic loader not to look at
the LD_LIBRARY_PATH and SHLIB_PATH environment variables at runtime.
a
+std Instructs the linker to use SVR4 compatible
linking and loading behaviors. Default for 64-bit mode.
a
+stripunwind Instructs the linker not to output the
unwind table.
+vtype type Produces 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:
Symbol Definition
__SYSTEM_ID Largest architecture revision level used by
any compilation unit
_FPU_STATUS Initial value of FPU status register _end Address of first byte following the end of the
main program’s data segment; identifies the beginning of the heap segment
__TLS_SIZE Size of the Thread Local Storage segment
required by the program
__text_start Beginning of the text segment _etext End of the text segment __data_start Beginning of the data segment
26 Chapter 1
What's New in Recent Releases
New Features for 64-bit Mode Linking
Symbol Definition
_edata End of initialized data __gp Global pointer value __init_start Beginning of the .init section __init_end End of the .init section __fini_start Beginning of the .fini section __fini_end End of the .fini section __unwind_start Beginning of the unwind table __unwind_end End of the unwind table
NOTE The linker generates an error if a user application also defines these
symbols.
Chapter 1 27
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 name Specifies incremental loading. 64-bit applications must use shared libraries instead.
-C n Does parameter type checking. This option is unsupported.
-S Generates an initial program loader header file. This option is unsupported.
-T Save data and relocation information in temporary files to reduce virtual memory requirements during linking. This option is unsupported.
-q, -Q, -n Generates 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.
-N Causes the data segment to be placed immediately after the text segment. This option is accepted but ignored in 64-bit mode. If this option is used because your application data segment is large, then the option is no longer needed in 64-bit mode. 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 pathname Specifies pathname for compiling I-SOMs to SOMs.
This option is unsupported.
28 Chapter 1
What's New in Recent Releases
64-bit Mode Link-time Differences
Option or
Behavior
+dpv Displays verbose messages regarding procedures
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 User Guide (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 1 29
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 Behavior 64-bit Mode Behavior
Ordering is significant. Ordering is insignificant by default.
Use +compat to enforce ordering.
30 Chapter 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.
32-bit Mode Behavior 64-bit Mode Behavior
Depth-first search order. Breadth-first search order.
Use +compat to enforce depth first ordering.
No run time environment variables by default.
If +s is specified, then SHLIB_PATH is available.
-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 1 31
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.
32 Chapter 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
NOTE To 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 1 33
What's New in Recent Releases
Online Help for Linker and Libraries
/opt/langtools/bin/charhelp ld
See charhelp(1) for details.
34 Chapter 1
What Happens When You Compile and Link a Program
2 What 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 2 35
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.f Compile and link sumnum.f.
... The compiler displays any messages here.
$ a.out Run the program.
... Output from the program is displayed here.
Program source can also be divided among separate files. For example, sumnum.c could be divided into two files: main.c, containing the main program, and func.c, containing the function sum_n. The command for compiling the two together is:
$ cc -Aa main.c func.c main.c: func.c:
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 */
36 Chapter 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-1 High-Level View of the Compiler
Compiling Programs on HP-UX: An Example
Chapter 2 37
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-2 Looking “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 \\
-D__hp9000s700 -D__hp9000s800 -D__hppa -D__hpux \\
-D__unix -D_PA_RISC1_1
cc: Entering Preprocessor. /opt/ansic/lbin/ccom /var/tmp/ctmAAAa10102 main.o -O0 -Aa \\ func.c: /opt/langtools/lbin/cpp.ansi func.c /var/tmp/ctmAAAa10102 \\
-D__hp9000s700 -D__hp9000s800 -D__hppa -D__hpux \\
38 Chapter 2
What Happens When You Compile and Link a Program
Looking “inside” a Compiler
-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.
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 2 39
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 local definition or global definition. Any reference to a symbol outside the object file is known as an external reference.
To keep track of where all the symbols and external references occur, an object file has a symbol table. The linker uses the symbol tables of all input object files to match 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.
40 Chapter 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__hp9000s700 -D__hp9000s800 -D__hppa -D__hpux \\
-D__unix -D_PA_RISC1_1 cc: Entering Preprocessor. /opt/ansic/lbin/ccom /var/tmp/ctmAAAa10102 main.o -O0 -Aa func.c: /opt/langtools/lbin/cpp.ansi func.c /var/tmp/ctmAAAa10102 \\
-D__hp9000s700 -D__hp9000s800 -D__hppa -D__hpux \\
-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.
NOTE If 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 2 41
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-3 Matching 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)
42 Chapter 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 2 43
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_MAGIC The 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_MAGIC Neither 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.
44 Chapter 2
What Happens When You Compile and Link a Program
Table 2-1 32-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-x 1 michael users 74440 Apr 4 14:38 a.out
Chapter 2 45
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 name is a string of one or more characters that identifies the
library.
suffix is .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:
46 Chapter 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.
NOTE If multiple definitions of a symbol occur in the specified libraries, ld does
not necessarily choose the first definition. It depends on whether the program is linked with archive libraries, shared libraries, or a combination of both. Depending on link order to resolve such library definition conflicts is risky because it relies on undocumented linker behavior that may change in future releases. (See Also “Caution When Mixing Shared and Archive Libraries” on page 164.)
Chapter 2 47
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.
48 Chapter 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 2 49
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.
NOTE A program with thread local storage is only supported on systems
running HP-UX 10.30 or later versions of the operating system.
NOTE Use of the __thread keyword in a shared library prevents that shared
library from being dynamically loaded, that is, loaded by an explicit call to shl_load().
For More Information:
• See your HP compiler documentation to learn how to create thread
local storage data items with the _thread compiler directive.
• See Programming with Threads on HP-UX for information on
threads.
50 Chapter 2
3 Linker 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 3 51
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
52 Chapter 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 3 53
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
libcl, libm, and libc.
$ pc -v prog.p /opt/pascal/lbin/pascomp prog.p prog.o -O0 LPATH = /usr/lib/pa1.1:/usr/lib:/opt/langtools/lib /usr/ccs/bin/ld /opt/langtools/lib/crt0.o -z prog.o -lcl -lm -lc unlink prog.o
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 libm from 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
54 Chapter 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 the resulting file sum_num:
$ cc -Aa -o sum_num prog.c Compile using -o option. $ sum_num Run the program. Enter a number to sum: 5 The sum of 1 to 5: 15
Specifying Libraries with -l
Sometimes programs call routines not contained in the default libraries. In such cases you must explicitly specify the necessary libraries on the compile line with the -l option. The compilers pass -l options directly to the linker before 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 3 55
Linker Tasks
Using the Compiler to Link
$ f77 -c func.f Produce .o for func.f. $ ls func.o func.o Verify that func.o was created. $ f77 main.f func.o Compile main.f with func.o $ a.out Run it to verify it worked.
56 Chapter 3
Using Linker commands
Using Linker commands
This section describes linker commands for the 32-bit and 64-bit linker.
NOTE Unless otherwise noted, all examples show 32-bit behavior.
Linking with the 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/lib Korn and Bourne shell syntax. $ export LPATH
Chapter 3 57
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:
$ ld /opt/langtools/lib/crt0.o prog.o -L /usr/local/lib -lc
Multiple -L options can be specified. For example, to search /usr/contrib/lib and /usr/local/lib before the default places:
$ ld /opt/langtools/lib/crt0.o prog.o -L /usr/contrib/lib \
-L /usr/local/lib -lc
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:
$ ld -B immediate /opt/langtools/lib/crt0.o prog.o -lc -lm
58 Chapter 3
Linker Tasks
Using Linker commands
Nonfatal Shared Library Binding with -B nonfatal
The linker also supports nonfatal binding, which is useful with the -B immediate option. Like immediate binding, nonfatal immediate binding
causes all required symbols to be bound at program startup. The main difference from immediate binding is that program execution continues even if the dynamic loader cannot resolve symbols. Compare this with immediate binding, where unresolved symbols cause the program to abort.
To use nonfatal binding, specify the -B nonfatal option along with the
-B immediate option on the linker command line. The order of the options is not important, nor is the placement of the options on the line. For example, the following ld command uses nonfatal immediate binding:
$ ld /opt/langtools/lib/crt0.o prog.o -B nonfatal \
-B immediate -lm -lc
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 3 59
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.
NOTE The -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
60 Chapter 3
Linker Tasks
Using Linker commands
NOTE The +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.
$ ld -B symbolic -b convert.o volume.o -o libunits.sl
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 3 61
Linker Tasks
Using Linker commands
Figure 3-1 Symbols 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:
$ ld -b convert.o -h gal_to_liter volume.o -o libunits.sl
or export the convert_rtn symbol:
$ ld -b +e convert_rtn convert.o volume.o -o libunits.sl
libunits.sl
convert_rtn() {
gal_to_liter();
}
gal_to_liter() { }
Direct call path Both convert_rtn and
gal_to_liter symbols are visible.
62 Chapter 3
Linker Tasks
Using Linker commands
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 3 63
Linker Tasks
Using Linker commands
-a archive Select archive libraries. If the archive library does not exist, ld generates an error message and does not generate the output file.
-a shared Select shared libraries. If the shared library does not exist, ld generates an error message and does not generate the output file.
-a default This is the same as -a shared_archive.
-a archive_shared Select 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_archive Select 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.
CAUTION You 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
64 Chapter 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.
NOTE Another 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 3 65
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_name Name of the output module that will be loaded by the
running program.
-A base_prog Tells 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_addr Specifies the hexadecimal address at which the module
will be loaded. This is the address calculated in Step 2.
-N Causes the data segment to be placed immediately
after the text segment.
-e entry_pt If 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.
66 Chapter 3
There are two header
Linker Tasks
Using Linker commands
The useful members of the som_exec_auxhdr structure are: .exec_tsize Size of text (code) segment. .exec_tmem Address at which to load the text (already adjusted for
offset specified by the -R linker option). .exec_tfile Offset into file (location) where text segment starts. .exec_dsize Size of data segment. .exec_dmem Address at which to load the data (already adjusted). .exec_dfile Offset into file (location) where data segment starts. .exec_bsize Size of bss segment. It is assumed to start immediately
after the data segment. .exec_entry Address 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 3 67
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.
68 Chapter 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.
Makefile Used to Create Dynamic Link Files
CFLAGS = -Aa -D_POSIX_SOURCE dynprog: dynprog.o dynload.o flush_cache.o # Compile line: cc -o dynprog dynprog.o dynload.o flush_cache.o -Wl,-a,archive
file1.o: file1.c dynprog.c file2.o: file2.c
# 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.c The file containing the alloc_load_space and
dyn_load functions.
dynprog.c The 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.c Contains the functions foo and bar. file2.c Contains 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 3 69
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
program.
dynprog.c — Example Dynamic Link and Load Program
#include <stdio.h> #include <nlist.h>
extern void * alloc_load_space(const char * base_prog, const char * obj_files, const char * dest_file);
extern void * dyn_load(const char * base_prog, unsigned int addr, const char * obj_files, const char * dest_file, const char * entry_pt);
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: */
70 Chapter 3
Linker Tasks
Using Linker commands
foo_ptr = (void (*)()) dyn_load(base_prog, addr, obj_files, dest_file, entry_pt);
/* STEP 3: Get the addresses of all desired routines using nlist(3C): */
nl[0].n_name = “bar”; nl[1].n_name = “counter”; nl[2].n_name = NULL; if (nlist(dest_file, nl)) { fprintf(stderr, “error obtaining namelist for %s\n”, dest_file); exit(1); } /* * Assign the addresses to meaningful variable names: */ bar_ptr = (void (*)()) nl[0].n_value; counter_ptr = (int *) nl[1].n_value;
/* * 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 3 71
Linker Tasks
Using Linker commands
glorp(“foo”); (*counter_ptr) ++; /* update counter indirectly with global pointer */ }
void bar() { glorp(“bar”); counter ++; /* update counter directly */ }
/**************************************************************** * file2.c - Global counter variable referenced by dynprog.c * and file1.c.
****************************************************************/ int counter = 0;
Output of dynprog . Now that you see how the main program and
the module it loads are organized, here is the output produced when
dynprog runs:
glorp called from main glorp called from foo glorp called from bar counter = 3
dynload.c . The dynload.c file contains the definitions of the
functions alloc_load_space and dyn_load. “Include Directives for dynload.c” shows the #include directives must appear at the start of this file.
Include Directives for dynload.c
#include <stdio.h> #include <stdlib.h> #include <nlist.h> # include <filehdr.h> # include <aouthdr.h> # define PAGE_SIZE 4096 /* memory page size */
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_prog The 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.
72 Chapter 3
const char * obj_files, const char * dest_file)
Linker Tasks
Using Linker commands
obj_files The name of the object file or files that will be linked
together to create dest_file.
dest_file The 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 3 73
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
+ aux_hdr.exec_bsize + 2 * PAGE_SIZE; fclose(destfp); /* done reading from module file */
/* --------------------------------------------------------------­ * 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:
void * dyn_load(const char * base_prog,
74 Chapter 3
unsigned int addr, const char * obj_files, const char * dest_file, const char * entry_pt)
Linker Tasks
Using Linker commands
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 3 75
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);
if (ret_val = system(cmd_buf)) { fprintf(stderr, “link command failed: %s\n”, cmd_buf); exit(ret_val); }
/*
----------------------------------------------------------------­ * 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: */
76 Chapter 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 4: Zero out the bss (uninitialized data segment): */
bss_start = aux_hdr.exec_dmem + aux_hdr.exec_dsize; bss_size = aux_hdr.exec_bsize;
memset(bss_start, 0, bss_size); /*
-----------------------------------------------------------------
* 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 3 77
Linker Tasks
Using Linker commands
/*
----------------------------------------------------------------­ * STEP 6: Return a pointer to the entry point specified by -e: */
entry_pt_addr = (unsigned int) aux_hdr.exec_entry; return ((void *) entry_pt_addr); }
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).
.proc .callinfo .export flush_cache,entry flush_cache .enter ldsid (0,%arg0),%r1 ; Extract SID (SR5) from address mtsp %r1,%sr0 ; SID -> SR0 ldo -1(%arg1),%arg1 ; offset = length -1 copy %arg0,%arg2 ; Copy address from GR26 to GR24
78 Chapter 3
Linker Tasks
Using Linker commands
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)
sync nop nop nop nop nop nop nop .leave .procend .end
Exporting Symbols with +e
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:
Chapter 3 79
Linker Tasks
Using Linker commands
$ nm -p sem.o 0000000000 U $global$ 1073741824 d $THIS_DATA$ 1073741864 b $THIS_BSS$ 0000000004 cS sem_val 0000000000 T check_sem_val 0000000036 T foo 0000000000 U printf 0000000088 T bar 0000000140 T sem
In this example, check_sem_val, foo, bar, and sem are all global definitions. To create a shared library where check_sem_val is a hidden, local definition, you could use either of the following commands:
$ ld -b -h check_sem_val sem.o One -h option. $ ld -b +e foo +e bar +e sem sem.o Three +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.o Three -h options. $ ld -b +e check_sem_val sem.o One +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.
80 Chapter 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:
Chapter 3 81
Linker Tasks
Using Linker commands
$ nm -p sem.o 0000000000 U $global$ 1073741824 d $THIS_DATA$ 1073741864 b $THIS_BSS$ 0000000004 cS sem_val 0000000000 T check_sem_val 0000000036 T foo 0000000000 U printf 0000000088 T bar 0000000140 T sem
In this example, check_sem_val, foo, bar, and sem are all global definitions. To create a shared library where check_sem_val is a hidden, local definition, you could 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.
82 Chapter 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 3 83
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:
$ ld /usr/ccs/lib/crt0.o prog.o +e main +e foo -lm -lc -ldld
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).
84 Chapter 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 (::):
$ ld /opt/langtools/lib/crt0.o +b .:/app/lib:: prog.o -lfoo \
-lm -lc
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:
$ LPATH=/tmp ; export LPATH $ ld /opt/langtools/lib/crt0.o +b : -L/app/lib prog.o -lfoo \
-lm -lc
The Path List
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 3 85
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 eopts Display the file. +e foo +e bar
86 Chapter 3
Linker Tasks
Using Linker commands
+e reverse_tree +e preorder_traversal +e shift_reduce_parse
. . .
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 3 87
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
88 Chapter 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:
-s Strips 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.
-x Strips 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 3 89
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.
90 Chapter 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 3 91
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.
92 Chapter 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.
NOTE You 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 3 93
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.
ld crt0.o main.o +vtype libraries mylib.a -lc
... Selecting liba.a[foo.o] to resolve foo
ld crt0.o main.o +forceload mylib.a -lc +vtype libraries
... 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.
94 Chapter 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.
NOTE In most cases, the linker produces a correct executable without the use of
the mapfile option. The mapfile option is an advanced feature of the linker toolset intended for systems programming use, not application programming use. When using the mapfile option, you can create executable files that do not execute.
For more information on mapfiles and examples using these options, see Appendix A, “Using Mapfiles,” on page 295.
Chapter 3 95
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
./ at link time, but is moved to /tmp by runtime:
ld main.o -L. -lbar -lc export LD_LIBRARY_PATH=/tmp mv libbar.sl /tmp a.out called bar() called fee() mv /tmp/libbar.sl ./ ld main.o +noenvvar -L. -lbar -lc mv libbar.sl /tmp a.out dld.sl: Unable to find library “libbar.sl”
Linking in 64-bit Mode with +std
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.
ld -b foo.o -o libfoo.sl +stripunwind elfdump -U libfoo.sl
libfoo.sl:
96 Chapter 3
Linker Tasks
Using 64-bit Mode Linker Options
Selecting Verbose Output with +vtype
Use the +vtype option to get verbose output about specified elements of the link operation. The following values specify the type:
Parameter Description
files Dump information about each object file loaded.
ld main.o +vtype files -L. -lfile1 -lfile2 -lc
Loading main.o: Loading ./libfile1.sl: Loading ./libfile2.sl: Loading /usr/lib/pa20_64/libc.2: Loading /usr/lib/pa20_64/libdl.1:
libraries Dump information about libraries searched.
ld main.o +vtype libraries -L. -lfile1 -lfile2 -lc
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 ...
sections Dump 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
symbols Dump information about global symbols
referenced/defined from/in the input files.
ld main.o +vtype symbols -L. -lfile1 -lfile2 -lc
main.o: main is DEFINED GLOBAL FUNC printf is UNDEF GLOBAL FUNC lib1_func is UNDEF GLOBAL FUNC lib2_func is UNDEF GLOBAL FUNC ./libfile1.s: printf is UNDEF GLOBAL FUNC _DYNAMIC is DEFINED GLOBAL OBJECT lib1_func is DEFINED GLOBAL FUNC ...
all Dump all of the above. Same as -v.
Chapter 3 97
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.
98 Chapter 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 3 99
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() {
100 Chapter 3
Loading...