HP UX Linker and Libraries User Manual

HP-UX Linker and Libraries User's Guide

Version (For PA32 and PA64 Systems) B.11.72 Version (For Integrity Systems) B.12.57
HP Part Number: B2355-91150 Published: October 2012 Edition: 2
© Copyright 2011 Hewlett-Packard Development Company L.P.
Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license. The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein. UNIX is a registered trademark of The Open Group.
Itanium® is a trademark of Intel Corporation in the U.S. and other countries.

Contents

About This Document...................................................................................13
Intended Audience..................................................................................................................13
Document conventions and symbols..........................................................................................13
Related Information.................................................................................................................13
HP Encourages Your Comments................................................................................................14
Document Organization..........................................................................................................14
1 Compiling and Linking Programs on HP-UX..................................................16
Compiling Programs on HP-UX: An Example..............................................................................16
Overview..........................................................................................................................16
Looking Inside a Compiler...................................................................................................18
What is an Object File?.................................................................................................18
Local Definitions.......................................................................................................19
Global Definitions....................................................................................................19
External References...................................................................................................19
Compiler-Linker Interaction..................................................................................................19
Linking Programs on HP-UX......................................................................................................21
The crt0.o Startup File........................................................................................................21
The Program's Entry Point...............................................................................................22
The a.out File....................................................................................................................22
Magic Numbers (PA-RISC ONLY).........................................................................................22
File Permissions..................................................................................................................23
Linking with Libraries...............................................................................................................23
Library Naming Conventions...............................................................................................24
Default Libraries.................................................................................................................24
The Default Library Search Path.......................................................................................24
Link Order........................................................................................................................24
Running the Program...............................................................................................................25
Loading Programs: exec......................................................................................................25
Binding Routines to a Program.............................................................................................25
Deferred Binding is the Default............................................................................................25
Linker Thread-Safe Features......................................................................................................26
Shared library loading and unloading in multi-threaded applications.......................................26
2 Determining How to Link Programs or Libraries (Linker Tasks)..........................27
Using the Compiler to Link.......................................................................................................28
Changing the Default Library Search Path with -Wl, -L.............................................................28
Example Using -Wl, -L....................................................................................................28
Getting Verbose Output with -v............................................................................................29
Passing Linker Options from the Compiler Command with -Wl..................................................29
Example Using -Wl........................................................................................................29
Renaming the Output File with -o..........................................................................................29
Specifying Libraries with -l...................................................................................................29
Linking with the crt0.o Startup File in 32-bit mode (PA-RISC)................................................30
Suppressing the Link-Edit Phase with -c..................................................................................30
Using Linker Commands..........................................................................................................30
Linking with the crt0.o Startup File........................................................................................30
Changing the Default Library Search Path with -L, LPATH, and $ORIGIN....................................30
Overriding the Default Linker Search Path with LPATH.........................................................30
Augmenting the Default Linker Search Path with -L..............................................................31
Augmenting the Default Linker Search Path with +origin......................................................31
Using $ORIGIN.................................................................................................................31
Contents 3
Changing the Default Shared Library Binding with -B..............................................................32
Example Using -B immediate..........................................................................................32
Nonfatal Shared Library Binding with -B nonfatal..............................................................32
Restricted Shared Library Binding with -B restricted.............................................................32
Direct Shared Library Binding with -B direct......................................................................33
Shared Library Binding with -B group...............................................................................33
Lazydirect Shared Library Binding with -B lazydirect...........................................................33
Shared Library Binding with -B nodelete...........................................................................33
-B nodirect....................................................................................................................33
Improving Shared Library Performance with -B symbolic...........................................................34
Example Using -B symbolic.............................................................................................34
Comparing -B symbolic with -h and +e.............................................................................34
Case 1: Building a Shared Library with -B symbolic.......................................................34
Case 2: Building a Shared Library with -h or +e...........................................................35
Choosing Archive or Shared Libraries with -a.........................................................................36
Option Settings to -a......................................................................................................36
Example Using -a ....................................................................................................36
Linking Shared Libraries with -dynamic..................................................................................36
Linking Archived Libraries with -noshared..............................................................................37
Exporting Symbols with +e..................................................................................................37
Example Using +e.........................................................................................................37
When to use -h versus +e...............................................................................................37
Emitting debug information in a separate file.........................................................................38
Exporting Symbols with +ee................................................................................................38
Exporting Symbols from main with -E....................................................................................38
Hiding Symbols from Export with +hideallsymbols..................................................................39
Hiding Symbols with -h.......................................................................................................39
Example Using -h..........................................................................................................39
Tips on Using -h............................................................................................................39
Hiding and Exporting Symbols When Building a Shared Library.........................................40
Hiding Symbols when Combining .o Files with the -r Option...............................................40
Hiding and Exporting Symbols when Creating an a.out File................................................40
Not Recording Link Time Paths with +nodefaultrapth...............................................................41
Moving Libraries after Linking with +b..................................................................................41
Specifying a Path List with +b..........................................................................................41
Concatenating Search Paths Specified by Multiple +b path_list on PA64 and Integrity
Systems........................................................................................................................42
The Path List..................................................................................................................42
Moving Libraries After Linking with +s and SHLIB_PATH..........................................................43
Specifying a Path List with +s and SHLIB_PATH..................................................................43
For more information: ...............................................................................................43
Ignoring Dynamic Path Environment Variables with +noenvvar.................................................43
Controlling Archive Library Loading with +[no]forceload.........................................................44
Passing Linker Options in a file with -c..................................................................................44
Passing Linker Options with LDOPTS.....................................................................................44
Specifying Libraries with -l and -l:.........................................................................................45
Specifying Libraries (-l)...................................................................................................45
Using the -l: option........................................................................................................45
Example Using -l:..........................................................................................................45
Flagging Unsatisfied Symbols with +[no]allowunsats...............................................................45
Stripping Symbol Table Information from the Output File with -s and -x......................................46
Controlling Output from the Unwind Table with +strip unwind..................................................46
Using the IPF Linker with +compat or +std.............................................................................46
Using the Linker with +compat for Compatibility Mode.......................................................46
Using the Linker with +std for Standard Mode...................................................................47
4 Contents
Linking in PA-64 Mode with +std..........................................................................................48
Linking in PA-32 Mode with +compat...................................................................................48
Changing Mapfiles with -k and +nodefaultmap......................................................................48
Selecting Verbose Output with +vtype...................................................................................48
Turning on the linkage table protection with +protect..............................................................50
Creating read-only text segment in MPAS executable..............................................................50
Allocating Storage for Uninitialized Data with +nobss.............................................................50
Initializing Floating Point Environment with +FP .....................................................................50
Allocating Storage for Hidden Common Symbols with +alloc_hidden_commons.........................51
Turn Off Linker Warnings with -w.........................................................................................52
Preserving Compiler Generated Relocation Sections with -emit_relocs........................................52
3 Linker Tools for Itanium-Based Systems.........................................................53
Changing a Program's Attributes with chatr(1)............................................................................53
Viewing Symbols in an Object file with nm(1).............................................................................56
Viewing the Contents of an Object File with elfdump(1)................................................................58
Viewing Library Dependencies with ldd(1)..................................................................................60
Listing Dynamic Libraries with pldd(1)........................................................................................61
Printing a Stack Trace with pstack(1)..........................................................................................62
Viewing the Size of Object File Elements with size(1)....................................................................65
Reducing Storage Space with strip(1).........................................................................................65
Improving Program Start-up with fastbind(1)................................................................................66
Finding Object Library Ordering Relationships with lorder(1).........................................................67
Tracing Inter-Module Procedure Calls with ltrace(1)......................................................................67
4 Linker Tools for PA-RISC Systems.................................................................69
Changing a Program's Attributes with chatr(1)............................................................................69
Using chatr for 32-bit Program Attributes...............................................................................69
Using chatr for 64-bit Program Attributes...............................................................................70
Viewing Symbols in an Object file with nm(1).............................................................................71
Viewing the Contents of an Object File with elfdump(1)................................................................72
Viewing library dependencies with ldd(1)...................................................................................74
Viewing the Size of Object File Elements with size(1)....................................................................75
Reducing Storage Space with strip(1).........................................................................................76
Improving Program Start-up with fastbind(1)................................................................................76
Finding Object Library Ordering Relationships with lorder(1).........................................................77
5 Linker Toolset Differences Between PA-RISC and Itanium-Based Systems............79
Linker Toolset Compatibility with De Facto Industry Standards.......................................................79
ELF Object File Format .......................................................................................................79
PA-RISC Changes in Hardware Compatibility.............................................................................79
PA-RISC 2.0 Compatibility...................................................................................................80
PA-RISC Architectures and Their System Models......................................................................80
Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)........................................80
Run-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)........................................82
PA64 Mode Linker Options......................................................................................................82
Linker-Defined Symbols............................................................................................................82
Dynamic Path Searching for Shared Libraries..............................................................................83
Symbol Searching in Dependent Libraries..............................................................................86
System Libraries - Locations and Library Name Extension..............................................................87
System Library Location.......................................................................................................87
Shared Library Extension (suffix)...........................................................................................87
Statically-bound programs (archive-bound programs)..............................................................88
6 Creating and Using Libraries......................................................................89
Overview of Shared and Archive Libraries..................................................................................89
What are Archive Libraries?.....................................................................................................90
Contents 5
What are Shared Libraries?.....................................................................................................91
The Dynamic Loader ..........................................................................................................91
Default Behavior When Searching for Libraries at Run Time.....................................................91
Caution on Using Dynamic Library Searching........................................................................92
Running setuid Programs.....................................................................................................92
Example Program Comparing Shared and Archive Libraries.........................................................92
Shared Libraries with Debuggers, Profilers, and Static Analysis.....................................................94
Profiling Shared Libraries with gprof(1) .................................................................................94
Creating Archive Libraries........................................................................................................94
Overview of Creating an Archive Library...............................................................................95
Contents of an Archive File..................................................................................................95
Example of Creating an Archive Library................................................................................96
Replacing, Adding, and Deleting an Object Module..............................................................97
Replacing or Adding an Object Module...........................................................................97
Deleting an Object Module............................................................................................97
Summary of Keys to the ar(1) Command................................................................................97
Useful ar Keys...............................................................................................................97
crt0.o..........................................................................................................................98
Archive Library Location (IPF) ..............................................................................................98
Using /usr/lib and /usr/lib/pa20_64 ...........................................................................98
Using /usr/local/lib or /usr/contrib/lib..........................................................................98
Creating Shared Libraries........................................................................................................98
Creating Position-Independent Code (PIC).............................................................................99
Example Using +z.........................................................................................................99
Comparing +z and +Z...................................................................................................99
Compiler Support for +z and +Z.....................................................................................99
Creating the Shared Library with ld......................................................................................99
Shared Library Dependencies............................................................................................100
The Order in Which Libraries are Loaded (Load Graph)...................................................100
Placing Loaded Libraries in the Search List......................................................................101
Updating a Shared Library................................................................................................102
Incompatible Changes to a Shared Library.....................................................................102
Shared Library Location (IPF).............................................................................................102
Improving Shared Library Performance................................................................................102
Loading Shared Libraries with the LD_PRELOAD Environment Variable................................103
LD_PRELOAD Example.................................................................................................103
LD_PRELOAD Example (PA-RISC)...................................................................................104
64-bit Behavior......................................................................................................104
32-bit Behavior.......................................................................................................105
Loading Shared Libraries with the LD_PRELOAD_ONCE Environment Variable.....................106
Using Profile-Based Optimization on Shared Libraries.......................................................106
Exporting Only the Required Symbols............................................................................106
Placing Frequently-Called Routines Together....................................................................106
Making Shared Libraries Non-Writable..........................................................................107
Using the +ESlit/+Olit=all Option to cc..........................................................................107
+cond_rodata Command-Line Option............................................................................108
Using Filtered Shared Libraries (32-bit Mode Only)..........................................................108
Building Filtered Shared Libraries..............................................................................108
Building application programs linked to filtered shared libraries....................................109
Run time behavior of filtered shared libraries..............................................................109
Initializers..............................................................................................................109
Dynamic Path Lookup..............................................................................................110
Thread-Private Data (TLS).........................................................................................110
Maintaining filtered shared libraries..........................................................................110
Function Level Versioning..................................................................................................110
6 Contents
Version Control with Shared Libraries......................................................................................110
When to Use Shared Library Versioning..............................................................................110
Maintaining Old Versions of Library Modules......................................................................111
Library-Level Versioning.....................................................................................................111
How to Use Library-Level Versioning ..............................................................................111
Creating a New, Incompatible Version of the Library ......................................................112
Migrating an Existing Library to Use Library-Level Versioning.............................................112
The +h Option and Internal Names...............................................................................112
File System Links to Shared Libraries...................................................................................112
Using shl_load(3X) with Library-Level Versioning...................................................................113
Intra-Library Versioning (PA-RISC only).................................................................................113
The Version Number Compiler Directive.........................................................................113
Shared Library Dependencies and Version Control...........................................................114
Adding New Versions to a Shared Library......................................................................114
Specifying a Version Date............................................................................................115
Switching from Archive to Shared Libraries...............................................................................115
Relying on Undocumented Linker Behavior ..........................................................................115
Absolute Virtual Addresses................................................................................................116
Stack Usage....................................................................................................................116
Version Control................................................................................................................116
Debugger Limitations........................................................................................................116
Using the chroot Command with Shared Libraries.................................................................117
Profiling Limitations..........................................................................................................117
Summary of HP-UX Libraries...................................................................................................117
Caution When Mixing Shared and Archive Libraries.................................................................118
Example 1: Unsatisfied Symbols.........................................................................................118
Example 2: Using shl_load(3X)..........................................................................................120
Example 3: Hidden Definitions..........................................................................................122
Using Shared Libraries in Default Mode...................................................................................124
Internal Name Processing.................................................................................................125
Dynamic Path Searching for Shared Libraries.......................................................................126
Shared Library Symbol Binding Semantics...........................................................................126
Link-Time Symbol Resolution in Shared Libraries ..............................................................126
Resolution of Unsatisfied Shared Library References.........................................................127
Promotion of Uninitialized Global Data Items.............................................................128
Symbol Searching in Dependent Libraries..................................................................129
Mixed Mode Shared Libraries............................................................................................130
IPF Library Examples........................................................................................................131
Library Example: Creating an IPF Compatibility Mode Shared Library................................131
Library Example: Creating an IPF Standard Mode Shared Library......................................132
Library example: IPF Dynamic Path Searching.................................................................132
Library Example: IPF Compatibility Mode Link.................................................................133
Library Example: Using IPF Compatibility and Standard Shared Libraries............................133
Comparing Breadth-first and Depth-first Search in IPF/PA-64 Mode....................................133
Library Example: Using RPATH with Standard Mode Shared Library...................................134
Linking Libraries with +b pathlist....................................................................................134
Library Example: Linking to Libraries with +b path_list in IPF/PA-64 Mode..........................134
Library Example: Linking to Libraries with +b path_list in PA-32 Mode................................135
7 Shared Library Management Routines.......................................................136
Shared Library Management Routine Summaries.......................................................................136
The dlopen Routines Summary...........................................................................................136
The shl_load Routine Summary..........................................................................................137
Related Files and Commands.............................................................................................137
Shared Library Header Files...................................................................................................137
Contents 7
Using Shared Libraries with cc and ld Options.........................................................................138
Initializers for Shared Libraries................................................................................................138
Styles of Initializers ..........................................................................................................138
Init/Fini Style Initializers...............................................................................................138
HP-UX-10.X Style Initializers...........................................................................................139
Using Init/Fini Initializers..................................................................................................139
Init and Fini Usage Example.........................................................................................139
Ordering Within an Executable or Shared Library...........................................................141
Ordering Among Executables and Shared Libraries.........................................................142
Using HP-UX 10.X Style Initializers......................................................................................143
Declaring the Initializer with the +I Option......................................................................143
Order of Execution of Multiple Initializers.......................................................................143
Initializer Syntax..........................................................................................................144
Accessing Initializers' Addresses...............................................................................144
Example: An Initializer for Each Library..........................................................................144
Example: A Common Initializer for Multiple Libraries........................................................146
The dlopen Shared Library Management Routines.....................................................................148
The dlopen Routine .........................................................................................................148
Syntax ......................................................................................................................148
Return Values..............................................................................................................149
Description.................................................................................................................150
Using dlopen to load a shared library...........................................................................152
The dlsetlibpath Routine....................................................................................................153
Synopsis....................................................................................................................153
Description.................................................................................................................153
Using dlsetlibpath to set the dynamic search path.......................................................154
Multithread Usage.......................................................................................................155
Return Value...............................................................................................................155
Errors........................................................................................................................155
The dlerrno Routine..........................................................................................................155
Synopsis....................................................................................................................155
Description.................................................................................................................155
The dlgetfileinfo Routine....................................................................................................155
Synopsis....................................................................................................................155
Description.................................................................................................................155
Multithread Usage.......................................................................................................157
Return Value...............................................................................................................157
Errors........................................................................................................................157
The dlerror Routine...........................................................................................................157
Syntax.......................................................................................................................157
Description.................................................................................................................157
Using dlerror to get diagnostic information.....................................................................157
The dlsym Routine............................................................................................................157
Syntax.......................................................................................................................157
Return Values..............................................................................................................158
Description.................................................................................................................158
Usage.......................................................................................................................158
Using dlopen and dlsym to access either function or data objects......................................158
The dlget Routine.............................................................................................................159
Syntax.......................................................................................................................159
Return Values..............................................................................................................159
Description.................................................................................................................159
Using dlget to retrieve information about loaded modules.................................................160
The dlmodinfo Routine......................................................................................................160
Syntax ......................................................................................................................160
8 Contents
Return Values..............................................................................................................160
Description.................................................................................................................161
Using dlmodinfo to retrieve information about a load module............................................161
The dlgetname Routine.....................................................................................................161
Syntax.......................................................................................................................161
Return Values..............................................................................................................162
Description.................................................................................................................162
Using dlgetname to retrieve pathname...........................................................................162
The dlclose Routine..........................................................................................................162
Syntax.......................................................................................................................162
Return Values..............................................................................................................163
Description.................................................................................................................163
Using dlclose to unload a shared library........................................................................163
The dladdr Routine...........................................................................................................163
Syntax.......................................................................................................................163
Return Values..............................................................................................................164
Diagnostics................................................................................................................164
Description.................................................................................................................164
Using dladdr to get the symbolic information for an address.............................................165
The dlmodadd Routine......................................................................................................165
Syntax.......................................................................................................................165
Return Values..............................................................................................................165
Description.................................................................................................................166
The dlmodremove Routine.................................................................................................166
Syntax.......................................................................................................................166
Return Values..............................................................................................................166
Description.................................................................................................................166
The dlgetmodinfo Routine..................................................................................................166
Syntax.......................................................................................................................166
Return Values..............................................................................................................167
Description.................................................................................................................167
Using dlgetmodinfo.....................................................................................................167
The shl_load Shared Library Management Routines...................................................................168
The shl_load Routine........................................................................................................168
Syntax.......................................................................................................................168
Parameters.................................................................................................................168
Return Value...............................................................................................................169
Description.................................................................................................................169
shl_load Usage...........................................................................................................170
shl_load Example........................................................................................................170
BIND_NONFATAL Modifier.....................................................................................171
BIND_VERBOSE Modifier........................................................................................171
BIND_FIRST Modifier..............................................................................................171
DYNAMIC_PATH Modifier.......................................................................................171
BIND_NOSTART Modifier .......................................................................................171
BIND_RESTRICTED Modifier.....................................................................................171
BIND_TOGETHER Modifier......................................................................................172
BIND_BREADTH_FIRST Modifier...............................................................................172
The shl_findsym Routine....................................................................................................172
Syntax ......................................................................................................................172
Parameters ................................................................................................................173
Return Value...............................................................................................................173
Description.................................................................................................................173
shl_findsym Example....................................................................................................174
Load a Shared Library and Call its Routines and Access its Data...................................174
Contents 9
The shl_get and shl_get_r Routines.....................................................................................175
Syntax.......................................................................................................................175
Parameters.................................................................................................................175
Return Value...............................................................................................................176
Description.................................................................................................................176
Example ...................................................................................................................176
The shl_gethandle and shl_gethandle_r Routines..................................................................177
Syntax.......................................................................................................................177
Parameters.................................................................................................................177
Return Value...............................................................................................................177
Description.................................................................................................................177
Example....................................................................................................................177
The shl_definesym Routine.................................................................................................177
Syntax.......................................................................................................................178
Parameters ................................................................................................................178
Return Value...............................................................................................................178
Description.................................................................................................................178
The shl_getsymbols Routine...............................................................................................178
Syntax ......................................................................................................................178
Parameters ................................................................................................................179
Return Value...............................................................................................................179
The shl_symbol Structure...............................................................................................180
show_symbols - Display Shared Library Symbols..............................................................180
show_all - Use show_symbols to Show All Symbols .........................................................181
The shl_unload Routine.....................................................................................................182
Syntax ......................................................................................................................182
Parameters ................................................................................................................182
Return Value ..............................................................................................................182
Description ................................................................................................................182
Usage.......................................................................................................................182
The shl_unload Routine Returning ETXTBSY.....................................................................183
Dynamic Loader Compatibility Warnings.................................................................................183
Unsupported Shared Library Management Routines..............................................................183
Unsupported Shared Library Management Flags..................................................................183
8 Writing and Generating Position-Independent Code....................................185
What is a Relocatable Object Code?......................................................................................185
What is a Absolute Object Code?..........................................................................................185
What is a Position-Independent Code?....................................................................................186
Generating Position-Independent Code....................................................................................186
PIC Requirements for Compilers and Assembly Code............................................................187
Long Calls.......................................................................................................................188
Long Branches and Switch Tables.......................................................................................188
Assigned GOTO Statements .............................................................................................188
Literal References.............................................................................................................188
Global and Static Variable References................................................................................189
Procedure Labels..............................................................................................................189
9 Using Mapfiles.......................................................................................191
Controlling Mapfiles with the -k Option....................................................................................191
Changing Mapfiles with -k filename and +nodefaultmap............................................................191
Mapfile Example: Using -k mapfile and +nodefaultmap .......................................................191
Simple Mapfile.....................................................................................................................193
Default HP-UX 11.0 Release Mapfile.........................................................................................193
Defining Syntax for Mapfile Directives.....................................................................................195
Defining Mapfile Segment Declarations...................................................................................196
10 Contents
Segment Flags.................................................................................................................196
Mapfile Segment Declaration Examples..............................................................................197
Defining Mapfile Section Mapping Directives...........................................................................197
Internal Map Structure...........................................................................................................198
Placement of Segments in an Executable.............................................................................198
Mapping Input Sections to Segments..................................................................................198
Interaction between User-defined and Default Mapfile Directives.............................................200
Mapfile Option Error Messages..............................................................................................200
Fatal Errors.....................................................................................................................200
Warnings ......................................................................................................................201
10 Improving Your Application Performance..................................................202
Linker Optimizations..............................................................................................................202
Invoking Linker Optimizations from the Compile Line.............................................................202
Incompatibilities with other Options ...................................................................................203
Unused Procedure Elimination with +Oprocelim...................................................................203
Complete Executables..................................................................................................203
Incomplete Executables................................................................................................204
Shared Libraries..........................................................................................................204
Retain Unreferenced Symbols with +noprocelim_sym........................................................204
Relocatable Objects....................................................................................................204
Affects on Symbolic Debugging....................................................................................204
Profile-Based Optimization (PA-RISC)..................................................................................204
General Information about PBO....................................................................................204
Using PBO ................................................................................................................205
When to Use PBO.......................................................................................................205
How to Use PBO.........................................................................................................205
Instrumenting (+I/-I).....................................................................................................206
The Startup File icrt0.o............................................................................................207
The -I Linker Option.................................................................................................207
Code Generation from I-SOMs.................................................................................207
Building Portable Code with Linker Optimization.........................................................208
Profiling.....................................................................................................................208
Choosing Input Data...............................................................................................208
The flow.data File...................................................................................................208
Storing Profile Information for Multiple Programs.........................................................209
Sharing the flow.data File Among Multiple Processes..................................................209
Forking an Instrumented Application.........................................................................210
Optimizing Based on Profile Data (+P/-P).......................................................................210
The -P Linker Option................................................................................................210
Using The flow.data File..........................................................................................211
Specifying a Different flow.data File with +df..............................................................211
Specifying a Different flow.data with FLOW_DATA......................................................211
Interaction between FLOW_DATA and +df ................................................................211
Specifying a Different Program Name (+pgm)............................................................211
Selecting an Optimization Level with PBO.......................................................................212
Using PBO to Optimize Shared Libraries........................................................................212
Using PBO with ld -r....................................................................................................213
Restrictions and Limitations of PBO................................................................................214
Temporary Files......................................................................................................214
Source Code Changes and PBO..............................................................................214
Profile-Based Optimization (PBO) and High-Level Optimization (HLO)............................214
I-SOM File Restrictions.............................................................................................215
Compatibility with 9.0 PBO.....................................................................................216
Compatibility with 9.0 PBO..........................................................................................216
Contents 11
Options to Improve TLB Hit Rates............................................................................................217
Profile-Based Optimization (Itanium)........................................................................................217
Incremental Linking...............................................................................................................217
Using Incremental Linking Options......................................................................................219
Archive Library Processing.................................................................................................219
Shared Library Processing.................................................................................................219
Performance ...................................................................................................................219
Reusing Compiled Object Files (PA-RISC).................................................................................220
Improving Performance with the Global Symbol Table................................................................220
Improving Performance by Optimizing the Hash Table Size........................................................221
Improving Performance with Function Symbol Aliasing...............................................................222
Improving Shared Library Start-Up Time with fastbind................................................................222
Using fastbind.................................................................................................................222
Invoking the fastbind Tool..................................................................................................223
Invoking fastbind from the Linker........................................................................................223
How to Tell if fastbind Information is Current........................................................................223
Removing fastbind Information from a File...........................................................................224
Turning off fastbind at Run Time.........................................................................................224
Glossary..................................................................................................225
12 Contents

About This Document

This document discusses the most recent product information on HP-UX Linker and Libraries Version B.11.72 for HP 9000 systems and Version B.12.57 for Integrity systems that are running HP-UX 11i v1, HP-UX 11i v2, and HP-UX 11i v3.

Intended Audience

This document is intended for developers who want to compile, link, and build applications using the HP C/ANSI C Developer's Bundle on HP 9000 or HP Integrity systems.

Document conventions and symbols

Table 1 (page 13) lists the conventions and symbols used in this white paper.
Table 1 Document conventions
ElementConvention
Cross-reference links and email addressesMedium blue text:
Website addressesMedium blue, underlined text
(http://www.hp.com)
Bold font
Monospace font
Monospace, italic font
Monospace, bold font
Key names
Text typed into a GUI element, such as into a box
GUI elements that are clicked or selected, such as menu and list items,
buttons, and check boxes
Text emphasisItalic font
File and directory names
System output
Code
Text typed at the command line
Code variables
Command-line variables
Emphasis of file and directory names, system output, code, and text typed at the command line
CAUTION: Indicates that failure to follow directions can result in damage to equipment or data.
IMPORTANT: Provides clarifying information or specific instructions.
NOTE: Provides additional information.

Related Information

The following documents provide more information:
HP-UX Linker, Libraries, and Tools Versions B.11.72 and B.12.57 Release Notes
Improving program startup with fastbind: White paper
The HP-UX Linker web page is at:
http://www.hp.com/go/linker
Intended Audience 13

HP Encourages Your Comments

HP encourages your comments concerning this document. We are committed to providing documentation that meets your needs. Send any errors found, suggestions for improvement, or compliments to:
feedback@fc.hp.com
Include the document title, manufacturing part number, and any comment, error found, or suggestion for improvement you have concerning this document.

Document Organization

This guide is organized into the following chapters: This document is organized as follows:
“Compiling and Linking Programs on HP-UX” (page 16)
This chapter describes the process of compiling and linking programs on HP-UX. An example is used to illustrate the process. The sections here describe the process of creating an executable file and explain how ld creates an executable file from one or more object files. This chapter also describes the conventions for using libraries with ld, describes the process of loading and binding programs at run time, and explains the thread-safe features of linker. In addition, it explains the means by which you can control how the linker links your programs or libraries.
“Determining How to Link Programs or Libraries (Linker Tasks)” (page 27)
This chapter describes the tasks you can perform using the Compiler commands and Linker commands. The tasks help you determine how the linker must link your program or library.
“Linker Tools for Itanium-Based Systems” (page 53)
This chapter describes the linker toolset available for IA systems. The linker toolset provides several tools to help you find symbols, display and modify object files, and determine link order.
“Linker Tools for PA-RISC Systems” (page 69)
This chapter describes the linker toolset available for PA-RISC systems. The linker toolset provides several tools to help you find symbols, display and modify object files, and determine link order.
“Linker Toolset Differences Between PA-RISC and Itanium-Based Systems” (page 79)
This chapter describes some of the linker toolset differences between PA-RISC and Itanium-based systems. This chapter also describes linker options specific to PA64 mode, symbols reserved by linker, system library location, changes to the library name extension, and dynamic path searching for shared libraries.
“Creating and Using Libraries” (page 89)
This chapter provides an overview of shared and archived libraries, explains creating and using libraries on HP-UX, and describes how to use shared libraries for programs in IA.
“Shared Library Management Routines” (page 136)
This chapter explains shared library header files, initializers for shared libraries, and the various shared library management routines.
14
“Writing and Generating Position-Independent Code” (page 185)
This chapter is applicable to only PA-RISC 32-bit applications. The chapter explains relocatable object code, absolute object code, and position-independent code. The chapter also explains how to generate position-independent code.
“Using Mapfiles” (page 191)
This chapter explains how to use mapfiles. The mapfile option, which is an advanced feature of the linker toolset, is intended for use in system programming.
“Improving Your Application Performance” (page 202)
This chapter explains how you can use linker to improve the performance of your applications. This chapter discusses options to improve TLB hit rates, incremental linking, profile-based optimization, and other ways to improve application performance.
Glossary
The glossary provides definitions of terms listed alphabetically.
Document Organization 15

1 Compiling and Linking Programs on HP-UX

This chapter describes the process of compiling and linking a program.
DescriptionSection
Provides an overview of compiling on HP-UX.“Compiling Programs on HP-UX: An Example”
(page 16)
Describes how ld creates an executable file from one or more object.“Linking Programs on HP-UX” (page 21)
Describes conventions for using libraries with ld.“Linking with Libraries” (page 23)
Describes the process of loading and binding programs at run time.“Running the Program” (page 25)
Describes the thread-safe features.“Linker Thread-Safe Features” (page 26)

Compiling Programs on HP-UX: An Example

This chapter addresses the following:
“Overview” (page 16)
“Looking Inside a Compiler” (page 18)
“Compiler-Linker Interaction” (page 19)

Overview

To create an executable program, you compile a source file containing a main program. For example, to compile an ANSI C program named sumnum.c, shown below, use this command (-Aa says to compile in ANSI mode):
$ cc -Aa sumnum.c
The compiler displays status, warning, and error messages to standard error output (stderr). If no errors occur, the compiler creates an executable file named a.out in the current working directory. If your PATH environment variable includes the current working directory, you can run
a.out as follows:
$ a.out Enter a number: 4 Sum 1 to 4: 10
The process is essentially the same for all HP-UX compilers. For instance, to compile and run a similar FORTRAN program named sumnum.f:
$ f90 sumnum.f //Compile and link sumnum.f.
... //The compiler displays any messages here. $ a.out
//Run the program. ...
//Output from the program is displayed here.
Program source can also be divided among separate files. For example, sumnum.c could be divided into two files: main.c, containing the main program, and func.c, containing the function
sum_n. The command for compiling the two together is:
$ cc -Aa main.c func.c main.c: func.c:
16 Compiling and Linking Programs on HP-UX
Notice that cc displays the name of each source file it compiles. This way, if errors occur, you know where they occur. Also, the diagnostics mention the name of the source file.
#include <stdio.h> /* contains standard I/O defs */ int sum_n( int n )
/* sum numbers from n to 1 */ { int sum = 0;
/* running total; initially 0 */
for (; n >= 1; --n)
/* sum from n to 1 */
sum += n;
/* add n to sum */
return sum;
/* return the value of sum */ }
int main() /* begin main program
*/ { int n;
/* number to input from user */
printf("Enter a number: ");
/* prompt for number */
scanf("%d", &n);
/* read the number into n */
printf("Sum 1 to %d: %d\\n", n, sum_n(n)); /* display the sum */ }
Generally speaking, the compiler reads one or more source files, one of which optionally contains a main program, and outputs an executable named a.out by default unless a name is specified, as shown in Figure 1.
Compiling Programs on HP-UX: An Example 17
Figure 1 High-level View of the Compiler

Looking Inside a Compiler

On the surface, it appears as though an HP-UX compiler generates an a.out file by itself. Actually, an HP-UX compiler is a driver that calls other commands to create the a.out file. The driver performs different tasks (or phases) for different languages, but two phases are common to all languages:
1. For each source file, the driver calls the language compiler to create an object file. (See also
“What is an Object File?” (page 18))
2. The HP-UX linker (ld) links the specified object files to create either a reusable object file, also
called a shared library, or an executable, which is named a.out by default unless a name is specified. (See also “Compiler-Linker Interaction” (page 19).)
Figure 2 summarizes how a compiler driver works.
Figure 2 Looking Inside a Compiler
The C, aC++, and Fortran90 compilers provide the -v (verbose) option to display the phases a compiler is performing.
What is an Object File?
An object file is basically a file containing machine language instructions and data in a form that the linker can use to create an executable program. Each routine or data item defined in an object file has a corresponding symbol name by which it is referenced. A symbol generated for a routine
18 Compiling and Linking Programs on HP-UX
or data definition can be either a local definition or global definition. Any reference to a symbol outside the object file is known as an external reference.
To keep track of where all the symbols and external references occur, an object file has a symbol table. The linker uses the symbol tables of all input object files to match external references to global definitions.
Local Definitions
A local definition is a definition of a routine or data that is accessible only within the object file in which it is defined. Such a definition cannot be accessed from another object file. Local definitions are used primarily by debuggers, such as adb. More important for this discussion are the global definitions and external references.
Global Definitions
A global definition is a definition of a procedure, function, or data item that can be accessed by code in another object file. For example, the C compiler generates global definitions for all variable and function definitions that are not static. The FORTRAN compiler generates global definitions for subroutines and common blocks. In Pascal, global definitions are generated for external procedures, external variables, and global data areas for each module.
External References
An external reference is an attempt by code in one object file to access a global definition in another object file. A compiler cannot resolve external references because it works on only one source file at a time. Therefore, the compiler simply places external references in an object file's symbol table; the matching of external references to global definitions is left to the linker or loader.

Compiler-Linker Interaction

As described in “Looking Inside a Compiler” (page 18), the compilers automatically call the linker to create an executable file. To see how the compilers call ld, run the compiler with the -v (verbose) option.
For example, compiling a C program to produce an IPF 32-bit share-bound application, produces the output below:
$ cc -v main.c func.c -lm main.c: /opt/ansic/lbin/ecom -ia64abi all -architecture 32 -ext on -lang c \
-exception off -sysdir /usr/include - inline_power 1 -link_type dynamic \
-fpeval float - tls_dyn on -target_os 11.23 --sys_include /usr/include \
-D__hpux -D__unix -D__ia64=1 -D_BIG_ENDIAN=1 -D_ILP32 -D__HP_cc=60200 \
-D__STDC_EXT__ -D_HPUX_SOURCE -D_INCLUDE_LONGLONG -D_INLINE_ASM \
-D_BIND_LIBCALLS -D_Math_errhandling=MATH_ERREXCEPT -D_FLT_EVAL_METHOD=O \
-ucode hdriver=optlevel%1% -plusolistoption -O106const! -plusolistoption \
-O113moderate! -plusooption -Oq01,al,ag,cn,sz,ic,vo,Mf,Po,es,rs,Rf,Pr,sp,\ in,cl,om,vc,pi,fa,pe,rr,pa,pv,nf,cp,1x,Pg,ug,1u,lb,uj,dn,sg,pt,kt,em,np,ar,\ rp,dl,fs,bp,wp,pc,mp,1r,cx,cr,pi,so,Rc,fa,ft,fe,ap,st,lc,Bl,sr,ib,pl,sd,ll,\ rl,dl,Lt,ol,fl,lm,ts,rd,dp,If! main.c func.c: /opt/ansic/lbin/ecom -ia64abi all -architecture 32 -ext on -lang c \
-exception off -sysdir /usr/include - inline_power 1 -link_type dynamic \
-fpeval float - tls_dyn on -target_os 11.23 --sys_include /usr/include \
Compiling Programs on HP-UX: An Example 19
-D__hpux -D__unix -D__ia64=1 -D_BIG_ENDIAN=1 -D_ILP32 -D__HP_cc=60200 \
-D__STDC_EXT__ -D_HPUX_SOURCE -D_INCLUDE_LONGLONG -D_INLINE_ASM \
-D_BIND_LIBCALLS -D_Math_errhandling=MATH_ERREXCEPT -D_FLT_EVAL_METHOD=O \
-ucode hdriver=optlevel%1% -plusolistoption -O106const! -plusolistoption \
-O113moderate! -plusooption -Oq01,al,ag,cn,sz,ic,vo,Mf,Po,es,rs,Rf,Pr,sp,\ in,cl,om,vc,pi,fa,pe,rr,pa,pv,nf,cp,1x,Pg,ug,1u,lb,uj,dn,sg,pt,kt,em,np,ar,\ rp,dl,fs,bp,wp,pc,mp,1r,cx,cr,pi,so,Rc,fa,ft,fe,ap,st,lc,Bl,sr,ib,pl,sd,ll,\ rl,dl,Lt,ol,fl,lm,ts,rd,dp,If! func.c LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32 /usr/ccs/bin/ld -o a.out -u__exit -umain main.o func.o -lm -lc
removing /var/tmp/AAAa02486
This example shows that the cc driver calls the actual C compiler (/opt/ansic/lbin/ecom) for each source file. Then the driver calls the linker (/usr/ccs/bin/ld) on the object files created by the compiler (main.o and func.o).
The next-to-last line in the above example is the command line that the compiler used to invoke the linker, /usr/ccs/bin/ld. When building a share-bound executable, the startup functions are handled by the dynamic loader dld. By default, the dynamic loader is found in /usr/lib/hpux32. Thus, in most cases, the ld command does not include crtO.o. In the ld command line, ld combines the two object files created by the compiler (main.o and func.o). It also searches the libm (-lm) and libc (-lc) libraries.
On PA-RISC systems, the same compile command invokes the PA32 linker. The output is shown below.
$ cc -Aa -v main.c func.c -lm cc: CCOPTS is not set. main.c: /opt/langtools/lbin/cpp.ansi main.c /var/tmp/ctmAAAa10102 \
-D__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__hp9000x700 -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 PA32 mode linker, /usr/ccs/bin/ld. In this command, ld combines a startup file (crt0.o) and the two object files created by the compiler (main.o and func.o) Also, ld searches the libm and libc libraries.
For PA64 and IPF executables, the startup functions are handled by the dynamic loader. In most cases, the ld command line does not include crt0.o.
20 Compiling and Linking Programs on HP-UX

Linking Programs on HP-UX

“The crt0.o Startup File” (page 21)
“The a.out File” (page 22)
“Magic Numbers (PA-RISC ONLY)” (page 22)
“File Permissions” (page 23)
The HP-UX linker (ld) creates an executable file, shared library, or combines the object files to create another relocatable object file. In doing so, it matches external references to global definitions contained in other object files or libraries. It revises code and data to reflect new addresses. This process is known as relocation. If the input files contain debugger information, ld updates this information appropriately. The linker places the resulting executable code in a file named, by default, a.out.
In the C program example, (see “Compiling Programs on HP-UX: An Example” (page 16) ) main.o contains an external reference to sum_n, which has a global definition in func.o.
The linker (ld) matches the external reference to the global definition, allowing the main program code in a.out to access sum_n (see Figure 3 (page 21)).
Figure 3 Matching the External Reference to sum_n
If the linker (ld) cannot match an external reference to a global definition, it displays a message to standard error output. If, for instance, you compile main.c without func.c, the linker (ld) cannot match the external reference to sum_n and displays this output:
$ cc -Aa main.c ld: Unsatisfied symbol "func1" in file main.o 1 errors.

The crt0.o Startup File

Notice that in the PA32 example in “Compiler-Linker Interaction” (page 19) the first object file on the linker command line is /opt/langtools/lib/crt0.o, even though this file was not specified on the compiler command line. This file, known as a startup file, contains the program's entry point. The program's entry point is is the location at which the program starts running after HP-UX loads it into memory to begin execution. The startup code does such things as retrieving command line arguments into the program at run time, and activating the dynamic loader to load any required shared libraries. In the C language, it also calls the routine _start in libc which, in turn, calls the main program as a function.
Linking Programs on HP-UX 21
The linker uses four startup files:
32-bit PA is /opt/langtools/lib/crt0.o
64-bit PA is /opt/langtools/lib/pa_64/crt0.o
The linker uses this startup file when it is in compatibility mode (+compat) or it is in default standard mode (+std) with the -noshared option.
32-bit IPF is /opt/langtools/lib/hpux32/crt0.o
The linker uses this startup file when it is in default standard mode (+std) with the -noshared option.
64-bit IPF is /opt/langtools/lib/hpux64/crt0.o
The linker uses this startup file when it is in default standard mode (+std) with the -noshared option.
If the -p profiling option is specified on the compile line, the compilers link with -L
/usr/ccs/lib/libp -lprof. If the-G profiling option is specified, the compilers link with /usr/ccs/lib/lip -lgprof.
PA-RISC ONLY:
If the linker option -I is specified to create an executable file with profile-based optimization, in 32-bit mode icrt0.o is used, and in 64-bit mode the linker inserts /usr/ccs/lib/pa20_64/fdp_init.o. If the linker options -I and -b are specified to create a shared library with profile-based optimization, in 32-bit mode scrt0.o is used, and in 64-bit mode, the linker inserts /usr/ccs/lib/pa20_64/fdp_init-sl.o. In 64-bit mode, the linker uses the single 64-bit crt0.o to support these options.
For details on startup files, see crt0(3).
The Program's Entry Point
For archive-bound (using the -complete compiler option or the -noshared linker option) executables, the entry point is the location at which execution begins in the a.out file. The entry point is defined by the symbol $START$ in crt0.o. In share-bound executables, the entry point is defined by the symbol $START$ in the dynamic loader (dld.so).

The a.out File

The information contained in the resulting a.out file depends on which architecture the file was created on and what options were used to link the program. In any case, an executable a.out file contains information that HP-UX needs when loading and running the file. For example: Is it a shared executable? Does it reference shared libraries? Is it demand-loadable? Where do the text (code), data, and bss (uninitialized data) segments reside in the file? For details on the format of this file, see a.out(4).

Magic Numbers (PA-RISC ONLY)

In 32-bit mode, the linker records a magic number with each executable program that determines how the program should be loaded. There are three possible values for an executable file's magic number:
SHARE_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 improves process startup time since the entire
22 Compiling and Linking Programs on HP-UX
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. Table 2 (page
23) shows which linker option to use to specifically set the magic number.
Table 2 32-bit Mode Magic Number Linker Options
Use the optionTo set the magic number to
-nSHARE_MAGIC
-qDEMAND_MAGIC
-NEXEC_MAGIC
An executable file's magic number can also be changed using the chatr command (see “Changing
a Program's Attributes with chatr(1)” (page 53) ). However, chatr can only toggle between
SHARE_MAGIC and DEMAND_MAGIC; it cannot be used to change from or to EXEC_MAGIC. This is because the file format of SHARE_MAGIC and DEMAND_MAGIC is exactly the same, while EXEC_MAGIC files have a different format. For details on magic numbers, refer to magic(4).
In 64-bit mode, the linker sets the magic number to the predefined type for ELF object files (\177ELF). The value of the e_type field in the ELF object file header specifies how the file should be loaded.

File Permissions

If linker errors do not occur, the linker gives the a.out file read/write/execute permissions to all users (owner, group, and other). If errors occur, the linker gives read/write permissions to all users. Permissions are further modified if the umask is set (see umask(1)). For example, on a system with umask set to 022, a successful link produces an a.out file with read/write/execute permissions for the owner, and read/execute permissions for group and others:
$ umask 022 $ ls -l a.out
-rwxr-xr-x 1 michael users
74440 Apr
4 14:38 a.out

Linking with Libraries

“Library Naming Conventions” (page 24)
“Default Libraries” (page 24)
“Link Order” (page 24)
In addition to matching external references to global definitions in object files, the linker (ld) matches external references to global definitions in libraries. A library is a file containing object code for subroutines and data that can be used by other programs. For example, the standard C library, libc, contains object code for functions that can be used by C, C++, FORTRAN, and Pascal programs to do input, output, and other standard operations.
Linking with Libraries 23

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, .sl if the library is a PA-RISC shared library,
or .so if the library is a shared library. (The suffix can be .sl for an IPF shared library. This naming convention is not recommended, but it is supported for backwards compatibility with PA-32 and PA-64.)
Typically, library names are referred to without the suffix. For instance, the standard C library is referred to as libc.

Default Libraries

A compiler driver automatically specifies certain default libraries when it invokes ld. For example, cc automatically links in the standard library libc, as shown by the -lc option to ld in this example:
$ cc -Aa -v main.c func.c ... /usr/ccs/bin/ld -o a.out -u__exit -umain main.o func.o -lc cc: informational note 413: Entering Link editor.
Similarly, the Series 700/800 Fortran90 compiler automatically links with the libcl (C interface), libisamstub (ISAM file I/O), and libc libraries:
$ f90 -v sumnum.f ... /usr/ccs/bin/ld -x /opt/langtools/lib/crt0.o \ sumnum.o -lcl -lisamstub -lc
The Default Library Search Path
Following are the default search paths for the libraries:
On Itanium systems, ld searches for libraries in the directory /usr/lib/hpux32 for 32-bit
executables and /usr/lib/hpux64 for 64-bit executables.
On PA-RISC systems, ld searches for libraries in the directory /usr/lib/ for 32-bit
executables and /usr/lib/pa20_64/ for 64-bit executables.
If the -p or -G compiler profiling option is specified on the command line, the compiler directs the linker to also search:
/usr/lib/libp (for PA32)
/usr/lib/pa20__64/libp (for PA64)
/usr/lib/hpux32/libp (for IPF 32-bit)
/usr/lib/hpux64/libp (for IPF 64-bit)
The default order can be overridden with the LPATH environment variable, the -L linker option, specifies $ORIGIN in the library path, or the +origin option. These are described in Changing the“Changing the Default Library Search Path with -L, LPATH, and $ORIGIN” (page 30) .

Link Order

The linker searches libraries in the order in which they are specified on the command line - the link order. Link order is important in that a library containing an external reference to another library must precede the library containing the definition. This is why libc is typically the last
24 Compiling and Linking Programs on HP-UX
library specified on the linker command line: because the other libraries preceding it in the link order often contain references to libc routines and so must precede it.
NOTE: If multiple definitions of a symbol occur in the specified libraries, ld does not necessarily
choose the first definition. It depends on whether the program is linked with archive libraries, shared libraries, or a combination of both. Depending on link order to resolve such library definition conflicts is risky because it relies on undocumented linker behavior that may change in future releases. (See also “Caution When Mixing Shared and Archive Libraries” (page 118).)

Running the Program

“Loading Programs: exec” (page 25)
“Binding Routines to a Program” (page 25)
“Deferred Binding is the Default” (page 25)
An executable file is created after the program has been compiled and linked. The next step is to run or load the program.

Loading Programs: exec

When you run an executable file created by ld, the program is loaded into memory by the HP-UX program loader, exec. This routine is actually a system call and can be called by other programs to load a new program into the current process space. The exec function performs many tasks; some of the more important ones are:
Determining how to load the executable file by looking at its magic number. (See also“The
a.out File” (page 22).)
Determining where to begin execution of the program - that is, the entry point - For examples
in share-bound executables in dld.so, in archive-bound executables in crt0.o. (See also
“The crt0.o Startup File” (page 21).)
When the program uses shared libraries, the crt0.o startup code invokes the dynamic loader,
which in turn attaches any required shared libraries. If immediate binding was specified at link time, then the libraries are bound immediately. If deferred binding was specified, then libraries are bound as they are referenced. (See also “What are Shared Libraries?” (page
91).)
For details on exec, see the exec(2) page in the HP-UX Reference.

Binding Routines to a Program

Since shared library routines and data are not actually contained in the a.out file, the dynamic loader must attach the routines and data to the program at run time. Attaching a shared library entails mapping the shared library code and data into the process's address space, relocating any pointers in the shared library data that depend on actual virtual addresses, allocating the 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.

Deferred Binding is the Default

To accelerate program startup time, routines in a shared library are not bound until referenced. (Data items are always bound at program startup.) This deferred binding of shared library routines distributes the overhead of binding across the execution time of the program and is especially expedient for programs that contain many references that are not likely to be executed. In essence, deferred binding is similar to demand-loading.
Running the Program 25

Linker Thread-Safe Features

The dynamic loader (dld) and its application interface library (libdl) are thread-safe. Also, the linker toolset provides thread local storage support in:
ld - the link editor
crt0.o - the program startup file
Thread local storage (also called thread-specific data) is data specific to a thread. Each thread has its own copy of the data item.
NOTE: Use of the __thread keyword in a shared library prevents that shared library from being
dynamically loaded, that is, loaded by an explicit call to shl_load().
For More Information:
See your HP compiler documentation to learn how to create thread local storage data items
with the _thread compiler directive.
See Programming with Threads on HP-UX for information on threads.

Shared library loading and unloading in multi-threaded applications

The dynamic loader serializes all calls to dlopen, dlclose, shl_load, and shl_unload using a pthread mutex lock. A thread executing dlopen holds this lock, and another thread that wants to execute dlclose (for example), even on a different shared library, must wait for the dlopen in the first thread to release the lock after it is done.
Developers, who use these routines in multi-threaded applications (or shared libraries) and also use mutex locks for synchronizing threads should take note of this behavior to avoid deadlock situations. One example of such a situation is when a shared library initializer creates a new thread that calls dlopen - this would invariably lead to a deadlock in a multi-threaded application. A less trivial example could be as follows. Suppose thread A of an application calls dlopen to load a shared library, libA. Now this shared library has an initializer initA that wants to obtain a mutex lock M. But M is currently held by thread B of the application. Further, thread B wants to load another library, libB and then release the mutex lock M. Now thread B would call either dlopen or shl_load, either of which waits for the dld mutex lock to be released by the dlopen called by thread A. In turn, thread A waits for mutex lock M to be released before it can finish dlopen and release the dld mutex lock. This results in a deadlock.
26 Compiling and Linking Programs on HP-UX
2 Determining How to Link Programs or Libraries (Linker
Tasks)
You have a great deal of control over how the linker links your program or library by using ld command-line options. This chapter describes the tasks you can perform to determine how programs and libraries must link by using the Compiler commands and Linker commands.
“Using the Compiler to Link” (page 28)
“Changing the Default Library Search Path with -Wl, -L” (page 28)
“Getting Verbose Output with -v” (page 29)
“Passing Linker Options from the Compiler Command with -Wl” (page 29)
“Renaming the Output File with -o” (page 29)
“Specifying Libraries with -l” (page 29)
“Suppressing the Link-Edit Phase with -c” (page 30)
“Using Linker Commands” (page 30)
“Linking with the crt0.o Startup File” (page 30)
“Changing the Default Library Search Path with -L, LPATH, and $ORIGIN” (page 30)
“Using $ORIGIN” (page 31)
“Changing the Default Shared Library Binding with -B” (page 32)
“Improving Shared Library Performance with -B symbolic” (page 34)
“Choosing Archive or Shared Libraries with -a” (page 36)
“Linking Shared Libraries with -dynamic” (page 36)
“Linking Archived Libraries with -noshared” (page 37)
“Exporting Symbols with +e” (page 37)
“Exporting Symbols with +ee” (page 38)
“Exporting Symbols from main with -E” (page 38)
“Hiding Symbols from Export with +hideallsymbols” (page 39)
“Hiding Symbols with -h” (page 39)
“ Not Recording Link Time Paths with +nodefaultrapth” (page 41)
“Moving Libraries after Linking with +b” (page 41)
“Moving Libraries After Linking with +s and SHLIB_PATH” (page 43)
“Ignoring Dynamic Path Environment Variables with +noenvvar” (page 43)
“Controlling Archive Library Loading with +[no]forceload” (page 44)
“Passing Linker Options in a file with -c” (page 44)
“Passing Linker Options with LDOPTS” (page 44)
27
“Specifying Libraries with -l and -l:” (page 45)
“Flagging Unsatisfied Symbols with +[no]allowunsats” (page 45)
“Stripping Symbol Table Information from the Output File with -s and -x” (page 46)
“Controlling Output from the Unwind Table with +strip unwind” (page 46)
“Using the IPF Linker with +compat or +std” (page 46)
“Linking in PA-64 Mode with +std” (page 48)
“Linking in PA-32 Mode with +compat” (page 48)
“Changing Mapfiles with -k and +nodefaultmap” (page 48)
“Selecting Verbose Output with +vtype” (page 48)
“Turning on the linkage table protection with +protect” (page 50)
“Allocating Storage for Uninitialized Data with +nobss” (page 50)
“Initializing Floating Point Environment with +FP ” (page 50)
“Allocating Storage for Hidden Common Symbols with +alloc_hidden_commons” (page
51)
“Turn Off Linker Warnings with -w” (page 52)
“Preserving Compiler Generated Relocation Sections with -emit_relocs” (page 52)

Using the Compiler to Link

In many cases, you use your compiler command to compile and link programs. Your compiler uses options that directly affect the linker.

Changing the Default Library Search Path with -Wl, -L

The -L libpath option to ld augments the default search path; that is, it causes ld to search the specified libpath before the default places. The C compiler (cc), the C++ compiler (CC), the POSIX FORTRAN compiler (fort77), and the HP Fortran 90 compiler (f90) recognize the -L option and pass it directly to ld. However, the HP FORTRAN compiler (f77) and Pascal compiler (pc) do not recognize -L; it must be passed to ld with the -Wl option.
Example Using -Wl, -L
For example, to make the f77 compiler search /usr/local/lib to find a locally developed library named liblocal, use this command line:
$ f77 prog.f -Wl,-L,/usr/local/lib -llocal
(The f77 compiler searches /opt/fortran/lib and /usr/lib as default directories.) To make the f90 compiler search /usr/local/lib to find a locally developed library named
liblocal, use this command line:
$ f90 prog.f90 -L/usr/local/lib -llocal
(The f90 compiler searches /opt/fortran90/lib and /usr/lib as default directories.) For the C compiler, use this command line:
$ cc -Aa prog.c -L /usr/local/lib -llocal
The LPATH environment variable provides another way to override the default search path. For details, see “Changing the Default Library Search Path with -L, LPATH, and $ORIGIN” (page 30)
28 Determining How to Link Programs or Libraries (Linker Tasks)

Getting Verbose Output with -v

The -v option makes a compiler display the verbose information. This is useful for viewing how the compiler calls ld. For example, using the -v option with the C compiler shows that it automatically links with libc.
$ cc -v himom.c /opt/ansic/lbin/ecom -ia64abi all -architecture 32 -ext on -lang c \
-exception off -sysdir /usr/include -inline_power 1 -link_type dynamic \
-fpeval float -tls_dyn on -target_os 11.23 -- sys_include /usr/include \
-D__hpux -D__unix -D__ia64=1 -D_BIG_ENDIAN=1 -D_ILP32 -D__HP_cc=60200 \
-D__STDC_EXT__ -D_HPUX_SOURCE -D_INCLUDE_LONGLONG -D_INLINE_ASM \
-D_BIND_LIBCALLS -D_Math_errhandling=MATH_ERREXCEPT -D_FLT_EVAL_METHOD=0 \
-ucode hdriver=optlevel%1% -plusolistoption -O106const! -plusolistoption \
-O113moderate! -plusooption -Oq01,al,ag,cn,sz,ic,vo,Mf,Po,es,rs,Rf,Pr,sp,\ in,cl,om,vc,pi,fa,pe,rr,pa,pv,nf,cp,1x,Pg,ug,1u,lb,uj,dn,sg,pt,kt,em,np,\ ar,rp,dl,fs,bp,wp,pc,mp,lr,cx,cr,pi,so,Rc,fa,ft,fe,ap,st,lc,Bl,sr,ib,pl,\ sd,ll,rl,dl,Lt,ol,fl,lm,ts,rd,dp,If! himom.c LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32 /usr/ccs/bin/ld -o a.out -u__exit -umain himom.o -lc removing /var/tmp/AAAa17931 removing himom.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 instructing 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 instructing the linker to use an archive version of libm is:
$ $ ld /opt/langtools/lib/crt0.o mathprog.o -a archive -lm
-a default -lc

Renaming the Output File with -o

The -o name option causes ld to name the output file name instead of a.out. For example, to compile a C program prog.c and name the resulting file sum_num:
$ cc -Aa -o sum_num prog.c //Compile using -o option. $ sum_num //Run the program. Enter a number to sum: 5 The sum of 1 to 5: 15

Specifying Libraries with -l

Sometimes programs call routines not contained in the default libraries. In such cases you must explicitly specify the necessary libraries on the compile line with the -l option. The compilers pass
-l options directly to the linker before any default libraries, such as libc. For example, if a C program calls library routines in the curses library (libcurses), you must
specify -lcurses on the cc command line: .
Using the Compiler to Link 29
$ cc -Aa -v cursesprog.c -lcurses ... /usr/ccs/bin/ld /opt/langtools/lib/crt0.o cursesprog.o -lcurses \
-u main -lc cc: informational note 413: Entering Link editor.
Linking with the crt0.o Startup File in 32-bit mode (PA-RISC)
Notice also, in the above example, that the compiler linked cursesprog.o with the file /opt/langtools/lib/crt0.o. This file contains object code that performs tasks which must be executed when a program starts running - for example, retrieving any arguments specified on the command line when the program is invoked. For details on this file, see “The crt0.o Startup
File” (page 21)

Suppressing the Link-Edit Phase with -c

The -c compiler option suppresses the link-edit phase. That is, the compiler generates only the .o files and not the a.out file. This is useful when compiling source files that contain only subprograms and data. These may be linked later with other object files, or placed in an archive or shared library. The resulting object files can then be specified on the compiler command line, just like source files. For example:
$ f90 -c func.f //Produce .o for func.f. $ ls func.o func.o $ f90 main.f func.o //Compile main.f with func.o $ a.out //Run it to verify it worked.

Using Linker Commands

This section describes linker commands for the 32-bit and 64-bit linker
NOTE: Unless otherwise noted, all examples show 32-bit behavior.

Linking with the crt0.o Startup File

In default mode, you need not include crt0.o on the link line. However, you must include crt0.o on the link line for all fully archive links (ld -noshared) and in compatibility mode (+compat). You need not include the crt0.o startup file on the ld command line for shared bound links. The dynamic loader does some of the startup duties previously done by crt0.o.
See “The crt0.o Startup File” (page 21), and crt0(3) manpage for more information.

Changing the Default Library Search Path with -L, LPATH, and $ORIGIN

You can change or override the default linker search path by using the LPATH environment variable, the -L linker option, or the +origin linker option.
Overriding the Default Linker Search Path with LPATH
The LPATH environment variable allows you to specify which directories ld should search. If LPATH is not set, ld searches the default directory /usr/lib. If LPATH is set, ld searches only the directories specified in LPATH; the default directories are not searched unless they are specified in LPATH.
If set, LPATH must contain a list of colon-separated directory path names that ld must search. For example, to include /usr/local/lib in the search path after the default directories, set LPATH as follows:
30 Determining How to Link Programs or Libraries (Linker Tasks)
Augmenting the Default Linker Search Path with -L
The -L option to ld also allows you to add additional directories to the search path. If -L libpath is specified, ld searches the libpath directory before the default places.
For example, suppose you have a locally developed version of libc, which resides in the directory /usr/local/lib. To make ld find this version of libc before the default libc, use the -L option as follows:
$ ld prog.o -L /usr/local/lib -lc
If LPATH is set, then the -L option specifies the directories to search before the directories specified in LPATH.
Augmenting the Default Linker Search Path with +origin
The +origin option to ld instructs the linker to search for the library in the directory from which the object module originated.
The +origin option only applies to the shared library specified directly afterwards, for example, libc.so or -lc.
At runtime, if the dynamic loader cannot find the library listed in the path specified by $ORIGIN, it attempts to search paths according to the search path algorithm described above.
The syntax is as follows:
$ ld main.o +origin -lc
or
$ ld main.o +origin /usr/lib/hpux32/libc.so

Using $ORIGIN

You can use the $ORIGIN string in LD_LIBRARY_PATH, SHLIB_PATH, RUNPATH (the embedded path or RPATH), or in the path of a shared library in the shared library list. If the DF_ORIGIN flag is set, the loader determines the path of the current load module when the load module is first loaded. If the DF_ORIGIN flag is not set, the loader determines the path of the current load module when the loader first encounters $ORIGIN, whether it is in LD_LIBRARY_PATH, SHLIB_PATH, RUNPATH, or the shared library name in the shared library list.
To add $ORIGIN to the environment variables LD_LIBRARY_PATH or SHLIB_PATH, place $ORIGIN in the value of these environment variables. To add $ORIGIN to the RUNPATH, use the linker options +b or -L. To add $ORIGIN to the path of a shared library in the shared library list, use the linker option +origin.
+origin -lx
or
+origin shared_library_name
(You can use only the +origin option before the -l option or the name of a shared library.) The option causes the linker to add $ORIGIN before the shared library name in the shared library list and set the DF_ORIGIN flag for the output module. At runtime, the dynamic loader determines the directory of the parent module (object module, shared library, or executable) and replaces $ORIGIN for that directory name. For example,
$ ld main.o +origin libx.so -L -lc
Using Linker Commands 31
NOTE: You can use $ORIGIN in SHLIB_PATH/LD_LIBRARY_PATH only for programs on PA32
systems. While the +origin option is available, the recommended way to specify $origin is in the
embedded path with the +b option. For example,
$ ld main.o -lc +b $ORIGIN
If you use +b,\$ORIGIN; the $ORIGIN only affects libraries that are subject to dynamic path lookup; that is, the library shared_library_name is specified with -l or with no embedded / character. If you use +origin shared_library_name, the library is located using $ORIGIN, which is recorded in the full library name.

Changing the Default Shared Library Binding with -B

You might want to force immediate binding - that is, force all routines and data to be bound at startup time. With immediate binding, the overhead of binding occurs only at program startup, rather than across the program's execution. One useful characteristic of immediate binding is that it causes any possible unresolved symbols to be detected at startup time, rather than during program execution. Another use of immediate binding is to get better interactive performance, but in this case the program startup may take a little longer.
$ ld -B immediate prog.o -lc
Example Using -B immediate
To force immediate binding, link an application with the -B immediate linker option. For example, to force immediate binding of all symbols in the main program and in all shared libraries linked with it, you can use this ld command:
$ ld -B immediate prog.o -lc
Nonfatal Shared Library Binding with -B nonfatal
The linker also supports nonfatal binding, which is useful with the -B immediate option. Like immediate binding, nonfatal immediate binding causes all required symbols to be bound at program startup. The main difference from immediate binding is that program execution continues even if the dynamic loader cannot resolve symbols. Compare this with immediate binding, where unresolved symbols cause the program to abort.
To use nonfatal binding, specify the -B nonfatal option along with the -B immediate option on the linker command line. The order of the options is not important, nor is the placement of the options on the line. For example, the following ld command uses nonfatal immediate binding:
$ ld prog.o -B nonfatal -B immediate -lc
Note that the -B nonfatal modifier does not work with deferred binding because a symbol must be bound by the time a program actually references or calls it. A program attempting to call or access a nonexistent symbol is a fatal error.
Restricted Shared Library Binding with -B restricted
The linker also supports restricted binding, which is useful with the -B deferred and -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.
32 Determining How to Link Programs or Libraries (Linker Tasks)
When is -B restricted most useful? Consider a program that creates duplicate symbol definitions by either of these methods:
The program uses shl_load with the BIND_FIRST flag to load a library that contains symbol
definitions that are already defined in a library that was loaded at program startup.
The program calls shl_definesym to define a symbol that is already defined in a library
that was loaded at program startup.
If such a program is linked with -B immediate, references to symbols are bound at program startup, regardless of whether duplicate symbols are created later by shl_load or shl_definesym.
But what happens when, to take advantage of the performance benefits of deferred binding, the same program is linked with -B deferred? If a duplicate, more visible symbol definition is created prior to referencing the symbol, it binds to the more visible definition, and the program may run incorrectly. In such cases, -B restricted is useful, because symbols bind the same way as they do with -B immediate, but the actual binding is still deferred.
Direct Shared Library Binding with -B direct
The linker also supports direct binding, which creates a direct link between symbol references and shared libraries by recording the name of the resolved shared library during symbol resolution. This information is used during runtime to quickly resolve symbols without searching through all currently-loaded libraries.
The -B direct option implicitly turns on symbolic binding and disables dependent shared library processing.
Direct binding can be disabled during runtime by setting the LD_NODIRECTBIND environment variable.
Shared Library Binding with -B group
Group binding marks the shared library so that it behaves as if loaded with RTLD_GROUP flag to dlopen(). This does not affect the dependent shared libraries.
NOTE: You can use the libraries built with the -B group option only with the dld.sl in version
B.11.37 or later.
Lazydirect Shared Library Binding with -B lazydirect
Lazydirect binding only records direct bind information to shared libraries that are marked for lazy loading. See +[no]lazyload.
Shared Library Binding with -B nodelete
Nodelete binding marks the shared library so that an explicit unload using dlclose or shl_load returns success silently without detaching the shared library from the process. Subsequently, the shared library handle is valid only for shl_findsym. It stays invalid for dlsym, dlclose, and shl_unload until the next explicit load using shl_load or dlopen.
NOTE: You can use the libraries built with the -B nodelete option only with the dld.sl in
version B.11.37 or later.
-B nodirect
Nodirect binding precludes direct binding. Only a "direct hint" is recorded for references to libraries marked for lazy loading. This is the default behavior.
Using Linker Commands 33

Improving Shared Library Performance with -B symbolic

The linker supports the -B symbolic option which optimizes call paths between procedures when building shared libraries. It does this by building direct internal call paths inside a shared library. In linker terms, import and export stubs are bypassed for calls within the library.
The benefit of using -B symbolic option is that it helps improve application performance and the resulting shared library is slightly smaller. The -B symbolic option is useful for applications that make a lot of calls between procedures inside a shared library, and when these same procedures are called by programs outside of the shared library.
NOTE: The -B symbolic option applies only to function references in a shared library.
Example Using -B symbolic
For example, to optimize the call path between procedures when building a shared library called
lib1.s, use -B symbolic as follows:
$ ld -B symbolic -b func1.o func2.o -o lib1.s
NOTE: The +e option overrides the -B symbolic option. For example, when you use +e
symbol, only symbol is exported and all other symbols are hidden. Similarly, if you use +ee symbol, only symbol is exported, but other symbols exported by default remain visible.
Since all internal calls inside the shared library are resolved inside the shared library, user-supplied modules with the same name are not seen by routines inside the library. For example, you cannot replace internal libc.sl malloc() calls with your own version of malloc() if libc.sl was linked with -B symbolic.
Comparing -B symbolic with -h and +e
Similar to the -h (hide symbol) and +e (export symbol) linker options, -B symbolic optimizes call paths in a shared library. However, unlike -h and +e, all functions in a shared library linked with -B symbolic are also visible outside of the shared library.
Case 1: Building a Shared Library with -B symbolic
Suppose you have two functions to place in a shared library. The convert_rtn() calls gal_to_liter().
1. Build the shared library with -b. Optimize the call path inside the shared library with -B
symbolic.
$ ld -B symbolic -b convert.o volume.o -o libunits.sl
2. Two main programs link to the shared library. The main1 calls convert_rtn() and main2
calls gal_to_liter().
$ cc -Aa main1.c libunits.sl -o main1 $ cc -Aa main2.c libunits.sl -o main2
Figure 4 (page 35) shows that a direct call path is established between convert_rtn() and
gal_to_liter() inside the shared library. Both symbols are visible to outside callers.
34 Determining How to Link Programs or Libraries (Linker Tasks)
Figure 4 Symbols Inside a Shared Library Visible with -B symbolic
Case 2: Building a Shared Library with -h or +e
The -h (hide symbol) and +e (export symbol) options can also optimize the call path in a shared library for symbols that are explicitly hidden. However, only the exported symbols are visible outside of the shared library.
For example, you can hide the gal_to_liter symbol, as shown:
$ 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
In both cases, main2 cannot to resolve its reference to gal_to_liter() because only the convert_rtn() symbol is exported, as shown below in Figure 5 (page 35).
Figure 5 Symbol Hidden in a Shared Library
Using Linker Commands 35

Choosing Archive or Shared Libraries with -a

If both an archive and shared version of a particular library reside in the same directory, ld links with the shared version. Occasionally, you might want to override this behavior.
As an example, suppose you write an application that runs on a system on which shared libraries may not be present. Since the program cannot run without the shared library, it would be best to link with the archive library resulting in executable code that contains the required library routines. See also“Caution When Mixing Shared and Archive Libraries” (page 118)
Option Settings to -a
The -a option tells the linker what kind of library to link with. It applies to all libraries (-l
options) until the end of the command line or until the next -a option. Its syntax is:
-a {archive | shared | default | archive_shared | shared_archive}
The different option settings are:
-a archive Select archive libraries. If the archive library does not exist, ld generates an error message and does not generate the output file.
-a ar-a shared chive 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 is not 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 is not found in either version, ld generates an error message and does not generate the output file.
The -a shared and -a archive options specify only one type of library to use. An error results if that type is not found. The other three options specify a preferred type of library and an alternate type of library if the preferred type is not found.
CAUTION: You must avoid mixing shared libraries and archive libraries in the same application.
For more information, see “Caution When Mixing Shared and Archive Libraries” (page 118)
Example Using -a
The following command links with the archive versions of libcurses, libm, and libc:
$ ld /opt/langtools/lib/hpux32/crt0.o prog.o -a archive -lcurses -lm -lc

Linking Shared Libraries with -dynamic

Use the -dynamic option to instruct the linker to look for shared libraries first and then archive libraries. The linker outputs a share-bound executable.
This option is on by default. For example:
$ ld main.o -dynamic -L. -lbar -lc
is the same as:
$ ld main.o -L. -lbar -lc
If you specified an archive library, the linker links it in, but the resulting executable is still a share-bound executable. This is true even if the linker finds no shared libraries at link time.
36 Determining How to Link Programs or Libraries (Linker Tasks)

Linking Archived Libraries with -noshared

Use the -noshared option if you need to link with all archive libraries. The linker outputs an archive-bound executable.
NOTE: You cannot link in shared libraries if you specify this option.
In the following example, the linker only looks for:
/usr/lib/hpux32/libfoo.a and /user/lib/hpux32/libc.a:
$ ld /usr/ccs/hpux32/crt0.o main.o -noshared -L. -lfoo -lc
If you specify a shared library libbar.so with this option, the linker displays the error message:
ld: The shared library "libbar.so" cannot be processed in a static link. Fatal error.

Exporting Symbols with +e

The +e option allows you to hide and export symbols. Exporting a symbol makes the symbol a global definition, which can be accessed by other object modules or libraries. The +e option exports the symbol and hides from export all other global symbols not specified with +e. In essence,
-h and +e provide two different ways to do the same thing. The syntax of the +e option is:
+e symbol
Example Using +e
Suppose you want to build a shared library from an object file that contains the following symbol definitions as displayed by the nm command:
$ nm -p sem.o 0000000000 U $global$ 1073741824 d $THIS_DATA$ 1073741864 b $THIS_BSS$ 0000000004 cS sem_val 0000000000 T check_sem_val 0000000036 T foo 0000000000 U printf 0000000088 T bar 0000000140 T sem
In this example, check_sem_val, foo, bar, and sem are all global definitions. To create a shared library where check_sem_val is a hidden, local definition, you could use either of the following commands:
$ ld -b -h check_sem_val sem.o -o libsem.so //One -h option. $ ld -b +e foo +e bar +e sem sem.o -o libsem.so //Three +e options.
In contrast, suppose you want to export only the check_sem_val symbol. Either of the following commands work:
$ ld -b -h foo -h bar -h sem sem.o -o libsem.so //Three -h options. $ ld -b +e check_sem_val sem.o -o libsem.so //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 must not run -h and +e options on the same command line. For instance, suppose you specify +e sem. This exports the symbol sem and hides all other symbols. Any additional -h options becomes unnecessary. If both -h and +e are used on the same symbol, the -h overrides the +e option.
Using Linker Commands 37
The linker command line gets lengthy and difficult to read if several such options are specified. In fact, you exceed the maximum HP-UX command line length if you specify too many options. To get around this, use ld linker option files, described under “Passing Linker Options in a file with
-c” (page 44) . You can specify any number of -h or +e options in this file.
You can use -h or +e options when building a shared library (with -b), combining .o files ( with
-r), and when linking to create an a.out file.

Emitting debug information in a separate file

Valid for executable and shared library links with +noobjdebug option. Instructs the linker to dump all debug information in a separate file specified in filename and not include them in the executable. The HP debugger (WDB 6.2 and later) supports the separate debug information file during debugging. This option is useful to create an executable without debug information and retain the debug information for later use. It also helps to reduce the size of the executable.
Use the +dbgfile option to create a separate debug information file. This option takes a filename as an argument.
The following example shows the result of creating a separate debug information file using the +dbgfile option.
Example 1 Create a separate debug information file using +dbgfile option
$cc -g example.c -Wl,+dbgfile,a.out.dbg -o a.out $elfdump -S -h a.out.dbg | grep '\.debug' 31 PBIT 00000000 0000051a 000003fb .debug_macinfo 32 PBIT 00000000 00000915 000000c7 .debug_abbrev 33 PBIT 00000000 000009dc 00000405 .debug_info 34 PBIT 00000000 00000de1 000000df .debug_line 35 PBIT 00000000 00000ec0 00000032 .debug_actual 36 PBIT 00000000 00000ef2 00000030 .debug_procs_abbrev 37 PBIT 00000000 00000f22 0000005b .debug_procs_info
In this example, the name of the separate debug information file is a.out.dbg and it is provided as the argument to the linker option +dbgfile. This creates a file by name a.out.dbg which contains all the debug information.
Linker gives out information about the debug file in the executable, and the debugger automatically picks up the debug information file. As seen through the elfdump output, all the .debug_ sections are in a.out.dbg file.
This feature is available only on Integrity systems.

Exporting Symbols with +ee

Like the +e option, the +ee option allows you to export symbols. However, this option, the option does not alter the visibility of other symbols in the file. It exports the specified symbol, and does not hide any of the symbols exported by default.

Exporting Symbols from main with -E

In PA-32 mode, the linker exports from a program only those symbols that were imported by a shared library. For example, if a shared executable's libraries do not reference the program's main routine, the linker does not include the main symbol in the a.out file's export list. Normally, this is a problem only when a program calls shared library management routines (described in “Shared
Library Management Routines” (page 136)). To make the linker export all symbols from a program,
invokeld with the -E option. In IPF/PA-64 mode, the behavior is specified by -E is the default behavior. The +e option allows
you to be more selective about which symbols are exported, resulting in better performance. For more information on +e, see “Exporting Symbols with +e” (page 37).
38 Determining How to Link Programs or Libraries (Linker Tasks)

Hiding Symbols from Export with +hideallsymbols

Use the +hideallsymbols option to hide all symbols to prevent the linker from exporting them in a shared link. In the following example, main() exports func() and test(). If you use
+hideallsymbols, the linker cannot export the following routines in the a.out.
$ ld main.o +hideallsymbols -L. -lfoo -lc
$ elfdump -t a.out
a.out:
... .symtab
index Type Bind Other Sect Value Size Name 1 FUNC LOCL 0 0xb 0x4000000000001104 0 test ... 10 FUNC LOCL 0 0xb 0x4000000000001200 0 func

Hiding Symbols with -h

The -h option allows you to hide symbols. Hiding a symbol makes the symbol a local definition, accessible only from the object module or library in which it is defined. Use -h if you want to hide a few symbols
You can use -h option when building a shared library (with -b) and when linking to create an a.out file. When combining .o files with -r, you can use the -h option.
The syntax of the -h option is: -h symbol The -h option hides symbol. Other global symbols remain exported unless hidden with -h.
Example Using -h
Suppose you want to build a shared library from an object file that contains the following symbol definitions as displayed by the nm command:
$ nm -p sem.o 0000000000 U $global$ 1073741824 d $THIS_DATA$ 1073741864 b $THIS_BSS$ 0000000004 cS sem_val 0000000000 T check_sem_val 0000000036 T foo 0000000000 U printf 0000000088 T bar 0000000140 T sem
In this example, check_sem_val, foo, bar, and sem are all global definitions. To create a shared library where check_sem_val is a hidden, local definition, you can do the following:
$ ld -b -h check_sem_val sem.o
Tips on Using -h
You must not run -h and +e options on the same command line. For instance, suppose you specify +e sem. This exports the symbol sem and hides all other symbols. Additional -h options becomes unnecessary. If both -h and +e are used on the same symbol, the -h overrides the +e option.
The linker command line gets lengthy and difficult to read if several such options are specified. In fact, you exceed the maximum HP-UX command line length if you specify too many options. To get around this, use ld linker option files, described under “Passing Linker Options in a file with
-c” (page 44) . You can specify any number of -h or +e options in this file.
Using Linker Commands 39
Hiding and Exporting Symbols When Building a Shared Library
When building a shared library, you may want to hide a symbol in the library for the following reasons:
When building a shared library, you may want to hide a symbol in the library for the following
reasons:
Hiding a symbol ensures that the definition can only be accessed by other routines in the same
library. When linking with other object modules or libraries, the definition is hidden from them.
When linking with other libraries (to create an executable), hiding a symbol ensures that the
library uses the local definition of a routine rather than a definition that occurs earlier in the link order.
Exporting a symbol is necessary if the symbol must be accessible outside the shared library. But remember that, by default, most symbols are global definitions anyway, so it is not necessary to explicitly export symbols. In C, all functions and global variables that are not explicitly declared as static have global definitions, while static functions and variables have local definitions. In FORTRAN, global definitions are generated for all subroutines, functions, and initialized common blocks.
When using +e, be sure to export any data symbols defined in the shared library that is used by another shared library or the program, even if these other files have definitions of the data symbols. Otherwise, your shared library uses its own private copy of the global data, and another library or the program file cannot see any change.
One example of a data symbol that must be exported from a shared library is errno. The errno data symbol is defined in every shared library and program; if this definition is hidden, the value of errno is not be shared outside of the library.
Hiding Symbols when Combining .o Files with the -r Option
The -r option combines multiple .o files, creating a single .o file. The reasons for hiding symbols in an .o file are the same as the reasons listed above for shared libraries. However, a performance improvement occurs only if the resulting .o file is later linked into a shared library.
Hiding and Exporting Symbols when Creating an a.out File
In PA-32 mode, the linker exports all of a program's global definitions that are imported by shared libraries specified on the linker command line. For example, given the following linker command, all global symbols in crt0.o and prog.o that are referenced by libm or libc are automatically exported:
$ ld /usr/ccs/lib/crt0.o prog.o -lm -lc
With libraries that are explicitly loaded with shl_load, this behavior may not always be sufficient because the linker does not search explicitly loaded libraries (they aren't even present on the command line). You can work around this using the -E or +e linker option.
As mentioned previously in the section “Exporting Symbols from main with -E” (page 38) , the -E option forces the export of all symbols from the program, regardless of whether they are referenced by shared libraries on the linker command line. The +e option allows you to be more selective in what symbols are exported. You can use +e to limit the exported symbols to only those symbols you want to be visible.
For example, the following ld command exports the symbols main and foo. The symbol main is referenced by libc. The symbol foo is referenced at run time by an explicitly loaded library not specified at link time:
$ 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
40 Determining How to Link Programs or Libraries (Linker Tasks)
if a definition exists outside the program file. In such cases, a shared library may update a global variable needed by the program, but the program would never see the change because it is referencing its own copy.
One example of a data symbol that should almost always be exported from a program is errno. The errno data symbol is defined in every shared library and program; if this definition is hidden, the value of errno is not shared outside of the program in which it is hidden.
In IPF/PA-64 mode, the behavior specified by -E is the default behavior.

Not Recording Link Time Paths with +nodefaultrapth

By default, the linker records the link time paths of dependent shared libraries in the resultant executables and shared libraries. In 32-bit mode, link time paths are recorded as a part of the library name in the shared library list. In 64-bit mode, link time paths are recorded as embedded path (unless embedded path is defined explicitly using +b option).
The linker can be told not to record any link time paths by specifying the +nodefaultrpath option at link time. This option applies only to libraries specified with -l on the linker command line (for example, -lfoo). Link time paths will still be recorded for libraries whose full path name is specified (for example, /usr/contrib/lib/libfoo.sl) on the link line.
By default (i.e., if no other paths are specified) the 32 bit dld.sl searches for libraries in the current directory and the 64 bit dld.sl searches in the /lib/pa20_64 and /usr/lib/pa20_64 directories. So if +nodefaultrpath is specified at link time and the application needs libraries that are not present in above paths, care must be taken to provide the paths of these libraries using either SHLIB_PATH, LD_LIBRARY_PATH or embedded path.

Moving Libraries after Linking with +b

A library can be moved even after an application has been linked with it. This is done by providing the executable with a list of directories to search at run time for any required libraries. One way you can store a directory path list in the program is by using the +b path_list linker option.
Note that dynamic path list search works only for libraries specified with -l on the linker command line (for example, -lfoo). It does not work for libraries whose full path name is specified (for example, /usr/contrib/lib/libfoo.sl). However, it can be enabled for such libraries with the -l option to the chatr command (see “Changing a Program's Attributes with chatr(1)” (page
53) ).
Specifying a Path List with +b
The syntax of the +b option is:
+b path_list
where path_list is the list of directories you want the dynamic loader to search at run time. For example, the following linker command causes the path .:/app/lib to be stored in the executable. At run time, the dynamic loader searches for libfoo, libm, and libc in the current working directory (.), and then in the directory /app/lib
$ 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
On PA32 systems, if multiple +b options appear on the link line, the output file records the +b option that is specified first.
Using Linker Commands 41
On PA32 systems, double colon (::) refers to the location in which the libraries were found at link time. For example, the following linker command instructs the dynamic loader to search for libfoo, libm, and libc first in the current working directory (.), then in the directory /app/lib, and lastly in the location in which the libraries were found at link time (::).
$ ld /opt/langtools/lib/crt0.o +b .:/app/lib:: prog.o -lfoo -lm -lc
NOTE: The double colon (::) feature is available only for PA32 systems.
Concatenating Search Paths Specified by Multiple +b path_list on PA64 and Integrity Systems
On PA64 systems and Itanium-based systems, the +[no]concatrpath option enables or disables the concatenation of search paths specified by multiple +b path_list at link time.
If +noconcatrpath option is specified, only the path that is specified by the last +b path_list option on the command line is recorded. The default is + noconcatrpath
. The following example illustrates the use of +[no]concatrpath option with +b:
$ cat output/lib1.c #include <stdio.h> void lib1() { printf("lib1 in output\n"); } $ cc -b output/lib1.c -o output/lib1.sl
$ cat input/lib1.c #include <stdio.h> void lib1() { printf("lib1 in input\n"); } $ cc -b input/lib1.c -o input/lib1.sl
$ cat main.c #include <stdio.h> void lib1(); int main() { lib1(); return 0; } $ cc -c main.c
If +concatrpath is specified, the linker record all the +b pathlist entries, as follows:
$ ld main.o -lc +b output +b input +concatrpath -L input -l1 $ a.out lib1 in output
If +noconcatrpath is specified (or if +[no]concatrpath options are not specified), the linker records only the last +b pathlist entry, as follows:
$ ld main.o -lc +b output +b input -L input -l1 $ a.out lib1 in input
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 base name of the library path name stored in the executable. For instance, if a program is linked with
42 Determining How to Link Programs or Libraries (Linker Tasks)
/usr/local/lib/libfoo.sl, and the directory path list contains /apps/lib:xyz, the dynamic loader searches for /apps/lib/libfoo.sl, then ./xyz/libfoo.sl.
The full library path name stored in the executable is referred to as the default library path. To cause the dynamic loader to search for the library in the default location, use a null directory path ().
NOTE: The use of null directory path () is PA32 specific.
When the loader comes to a null directory path, it uses the default shared library path stored in the executable. For instance, if the directory path list in the previous example was
/apps/lib::xyz, the dynamic loader searches for /apps/lib/libfoo.sl, /usr/local/lib/libfoo.sl, then ./xyz/libfoo.s.
If the dynamic loader cannot find a required library in any of the directories specified in the path list, it searches for the library in the default location () recorded by the linker.

Moving Libraries After Linking with +s and SHLIB_PATH

A library can be moved even after an application has been linked with it. Linking the program with +s, enables the program to use the path list defined by the SHLIB_PATH environment variable at run time.
Specifying a Path List with +s and SHLIB_PATH
When a program is linked with +s, the dynamic loader gets the library path list from the SHLIB_PATH environment variable at run time. This is especially useful for application developers who do not know where the libraries reside at run time. In such cases, they can have the user or an install script set SHLIB_PATH to the correct value.
For more information:
“The Path List” (page 42)
provides additional details about the path list to SHLIB_PATH.
“Moving Libraries after Linking with +b” (page 41)
provides another way to move libraries.

Ignoring Dynamic Path Environment Variables with +noenvvar

Use the +noenvvar option to instruct the dynamic loader not to look at the environment variables relating to dynamic path searching at runtime. It ignores LD_LIBRARY_PATH, SHLIB_PATH, and $ORIGIN environment variables. This option is on by default in PA32 mode and in programs linked with ld +compat. It is off by default with ld +std.
For example, if libbar.so has dependent library libfee.so that is found in ./ at link time, but is moved to /tmp by runtime:
$ ld main.o -L. -lbar -lc $ export LD_LIBRARY_PATH=/tmp $ mv libbar.so /tmp $ a.out called bar() called fee() $ mv /tmp/libbar.so ./ $ ld main.o +noenvvar -L. -lbar -lc $ mv libbar.so /tmp $ a.out dld.so: Unable to find library "libbar.so"
Using Linker Commands 43

Controlling Archive Library Loading with +[no]forceload

Use the +[no]forceload option to control how the linker loads object files from an archived library. The +forceload instructs the linker to load all object files from an archive library. The +noforceload option instructs the linker to only load those modules from an archive library that is needed. The mode you select, either by default or explicitly, remains active until you change it.
The +noforceload option is the default. In the following example, main() references foo(), which is a module in mylib.a. The function foo() does not reference any other module in
mylib.a and libc.a. If mylib.a contains foo.o and bar.o, then only foo.o is linked.
$ ld /opt/langtools/lib/hpux32/crt0.o main.o +vtype libraries mylib.a -lc
... Selecting mylib.a[foo.o] to resolve foo
$ ld /opt/langtools/lib/hpux32/crt0.o main.o +forceload mylib.a -lc +vtype libraries ... Selecting mylib.a[foo.o] to forcibly load Selecting mylib.a[bar.o] to forcibly load

Passing Linker Options in a file with -c

The -c file option causes the linker to read command line options from the specified file. This is useful if you have many -h or +e options to include on the ld command line, or if you have to link with numerous object files. For example, suppose you have over a hundred +e options that you need when building a shared library. You can place them in a file named eopts and force the linker to read options from the file as follows:
$ ld -o libmods.sl -b -c eopts mod*.o $ cat eopts Display the file. +e foo +e bar +e reverse_tree +e preorder_traversal +e shift_reduce_parse . . .
NOTE: The linker ignores lines in that option file that begin with a pound sign (#). You can use
such lines as comment lines or to temporarily disable certain linker options in the file. For instance, the following linker option file for an application contains a disabled -O option:
# Exporting only the "compress" symbol resulted # in better run-time performance: +e compress # When the program is debugged, remove the pound sign # from the following optimization option: # -O

Passing Linker Options with LDOPTS

If you use certain linker options all the time, you may find it useful to specify them in the LDOPTS environment variable. The linker inserts the value of this variable before all other arguments on the linker command line. For instance, if you always want the linker to display verbose information (-v) and a trace of each input file (-t), set LDOPTS as follows:
$ LDOPTS="-v -t" Korn and Bourne shell syntax. $ export LDOPTS
Thereafter, the following commands would be equivalent:
$ ld -u main prog.o -lc $ ld -v -t -u main prog.o -lc
44 Determining How to Link Programs or Libraries (Linker Tasks)

Specifying Libraries with -l and -l:

To direct the linker to search a particular library, use the -lname option. For example, to specify libc, use -lc; to specify libm, use -lm; to specify libXm, use -lXm.
Specifying Libraries (-l)
When writing programs that call routines not found in the default libraries linked at compile time, you must specify the libraries on the compiler command line with the -lx option. For example, if you write a C program that calls POSIX math functions, you must link with libm.
The x argument corresponds to the identifying portion of the library path name - the part following lib and preceding the suffix .a or .sl. For example, for the libm.sl or libm.a library, x is the letter m:
$ cc -Aa mathprog.c -lm
The linker searches libraries in the order in which they are specified on the command line (that is, the link order). In addition, libraries specified with -l are searched before the libraries that the compiler links by default.
Using the -l: option
The -l: option works just like the -l option with one major difference: -l: allows you to specify the full base name of the library to link with. For instance, -l:libm.a causes the linker to link with the archive library /opt/langtools/lib/hpux32/libm.a, regardless of whether -a shared was specified previously on the linker command line.
The advantage of using this option is that it allows you to specify an archive or shared library explicitly without having to change the state of the -a option. (See also “Caution When Mixing
Shared and Archive Libraries” (page 118) .)
For instance, suppose you use the LDOPTS environment variable (see “Passing Linker Options with
LDOPTS” (page 44) ) to set the -a option that you want to use by default when linking. Depending
on what environment you are building an application for, you may set LDOPTS to -a archive or -a shared. You can use -l: to ensure that the linker always links with a particular library regardless of the setting of the -a option in the LDOPTS variable.
Example Using -l:
For example, even if LDOPTS were set to -a shared, the following command links with the archive libfoo.a in the directory /usr/mylibs, the archive libm.a and libc.a:
$ ld /opt/langtools/lib/hpux32/crt0.o -u main prog.o -L/usr/mylibs \
-l:libfoo.a -l:libc.a -l:libm.a

Flagging Unsatisfied Symbols with +[no]allowunsats

Use the +allowunsats option to instruct the linker to not flag unsatisfied symbols at link time. This is the default for relocatable (-r) and shared library builds (-b), and is the default behavior in PA-32 mode.
Use the +noallowunsat option to instruct the linker to flag as an error any unsatisfied symbol in the resulting output file. The linker still creates a.out, but the file does not have any execute permission bits set. This is the default for program files (same behavior as in PA-32 mode).
For example, where main() references functions foo() and bar(). The bar() resides in
libbar and foo() resides in libfoo
$ ld main.o +allowunsats -L. -lbar -lc
ld: (warning) Unsatisfied symbol "foo". 1 warning.
Using Linker Commands 45
The +allowunsats option still causes the linker to emit a warning message and output a.out. If you do not specify the option and the linker finds an unsatisfied symbol, the linker displays an error message and a non-executable a.out.
$ ld main.o -L. -lbar -lc
ld: Unsatisfied symbol "foo". 1 error.

Stripping Symbol Table Information from the Output File with -s and -x

The a.out file created by the linker contains symbol table, relocation, and (if debug options were specified) information used by the debugger. Such information can be used by other commands that work on a.out files, but is not actually necessary to make the file run. The ld command provides two command line options for removing such information and, thus, reducing the size of executables:
-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 effect on commands that work with executables. However, using this option may still make the file unusable by a symbolic debugger. These options can reduce the size of executables drastically. Note, also, that these options can also be used when generating shared libraries without affecting shareability.

Controlling Output from the Unwind Table with +strip unwind

Use the +stripunwind option to suppress output of the unwind table.
$ ld -b foo.o -o libfoo.sl +stripunwind $ elfdump -U libfoo.sl
libfoo.sl:

Using the IPF Linker with +compat or +std

In the HP-UX 11.0 release, the linker toolset supports extended features for linking in PA-64 mode. Since compatibility with the previous linker toolset is a high priority, on Itanium-based system the linker uses much of the old behavior in the new toolset. The Itanium-based system linker includes two options to allow you to instruct the linker to link in one of the following modes:
Compatibility mode, with the +compat option, to create a link and operation in PA-32 mode.
Because of some object file format restrictions, the mode is not completely compatible with the style of the PA-32 linker.
Standard mode, with the +std option, set by default in the linker on Itanium-based system,
to create a link and load operation in PA-64 mode. This mode uses the new behaviors and features of the PA-64 linker.
Using the Linker with +compat for Compatibility Mode
The +compat option instructs the linker to do a PA-32 link. When you use the +compat option, the linker:
Uses PA-32 shared library internal name processing.
Lists all dependent shared libraries in a DT_HP_NEEDED entry the dynamic table using the
PA-32 shared library naming conventions. These dependent libraries are recorded as
46 Determining How to Link Programs or Libraries (Linker Tasks)
compatibility-mode libraries even if they are really created as standard mode dependent libraries.
Does not use embedded paths at link time to find dependent libraries.
Considers the order of ld, +b and +s.
The +b option first means dld looks at the RPATH first when searching for dependent
shared libraries. To get the default RPATH, you must specify ld +b. This instructs the linker to construct a default RPATH consisting of the -L directories and LPATH.
The +s option first means the dynamic loader looks at the SHLIB_PATH environment
variable first when searching for dependent shared libraries. You must specify ld +s to force the dynamic loader to use SHLIB_PATH to search for shared libraries at runtime.
At runtime, the dynamic loader does a PA-32 load for all compatibility-mode dependent shared libraries. The dynamic loader:
Does dynamic path searching for compatibility-mode dependent shared libraries that have
the dynamic path selected (set in the DT_HP_NEEDED entry if the shared library was specified with -l).
Uses SHLIB_PATH only if you specify ld +s (or chatr+s) for compatibility-mode shared
libraries.
Allows RPATH inheritance from ancestors to children when searching for dependent
compatibility-mode shared libraries specified with ld -l. This is only allowed in an a.out that was linked with +compat. If a.out was linked in standard mode with +std option, no library (even a compatibility mode shared library) uses embedded RPATH inheritance.
Allows dynamic path searching on shared libraries loaded by shl_load routines, if the
DYNAMIC_FLAG is passed to shl_load().
Does a depth-first search of all compatibility-mode dependent libraries.
Looks at RPATH or SHLIB_PATH first, depending on the ld +b/+s ordering for all ld -l
dependent shared libraries. Next, the dynamic loader looks at whichever has second precedence, and then looks for the shared library as specified in the dynamic load entry.
Looks for the dynamic table entry as if the dynamic path bit is not set.
Using the Linker with +std for Standard Mode
The +std option instructs the linker to do a standard mode PA-64 link. This is currently the default. This default may change in future releases. When you use +std, the linker:
Assumes -dynamic was passed to ld. The linker looks for shared libraries first. The output
executable is a shared executable.
All dependent shared libraries are output in the dynamic table in a DT_NEEDED entry. These
dependent shared libraries are recorded as standard mode shared libraries.
The ld +b and +s ordering is ignored. The ld +s option is on by default.
Uses de facto standard internal name processing for dependent shared libraries.
Uses embedded RPATHs at link time to find dependent shared libraries.
If you do not specify ld +b, the linker uses a default RPATH consisting of the -L directories,
LPATH, and the default directories /usr/lib/hpux32:/opt/langtools/lib/hpux32 for 32-bit applications and /usr/lib/hpux64:/opt/langtools/lib/hpux64 for 64-bit applications.
Using Linker Commands 47
At runtime, the dynamic loader does a PA-64 load for all standard mode dependent shared libraries. The dynamic loader:
Does dynamic path searching only for standard-mode shared libraries in the DT_NEEDED
entry of the dynamic table which do not contain a path. For those standard-mode dynamic libraries that contain paths, dld looks for the library as specified.
Looks for the shared library as specified in the DT_NEEDED dynamic table entry if it contains
a path.
Looks at LD_LIBRARY_PATH and SHLIB_PATH environment variables at runtime by default
when doing dynamic path searching for standard-mode shared libraries.
Does not allow RPATH inheritance from ancestors to children (only allowed from parent to
child).
Does a breadth-first search for all standard-mode dependent shared libraries.
Looks at the environment variables first, followed by RPATH, and the default directories by
default when doing dynamic path searching for standard-mode dependent shared libraries.

Linking in PA-64 Mode with +std

Use the +std option to instructs the linker to do a PA-64 link. This is the default mode. For more information, see “Using the IPF Linker with +compat or +std” (page 46).

Linking in PA-32 Mode with +compat

Use the +compat option to instruct the linker to do a PA-32 link. For more information, see “Using
the IPF Linker with +compat or +std” (page 46).

Changing Mapfiles with -k and +nodefaultmap

The linker automatically maps sections from input object files onto output segments in executable files. These options to the ld command allow you to change the linker's default mapping.
Use the -k filename option to provide a memory map. The linker uses the file specified by filename as the output file memory map. The +nodefaultmap
option used with -k option prevents the linker from concatenating the default memory map to the map provided by filename. If you specify +nodefaultmap, the linker does not append the default mapfile to your mapfile. If you do not specify +nodefaultmap with -k, the linker appends the output file to the default mapfile.
NOTE: In most cases, the linker produces a correct executable without the use of the mapfile
option. The mapfile option is an advanced feature of the linker toolset intended for systems programming use, not application programming use. When using the mapfile option, you can create executable files that do not execute.
For more information on mapfiles and examples using these options, see “Using Mapfiles” (page
191).

Selecting Verbose Output with +vtype

Use the +vtype option to get verbose output about specified elements of the link operation. The following values specify the typeTable 3 (page 48):
Table 3 values specify the type
DescriptionParameter
files
48 Determining How to Link Programs or Libraries (Linker Tasks)
Dump information about each object file loaded.
$ ld main.o +vtype files -L. -lfile1 -lfile2 -lc Loading main.o:
Table 3 values specify the type (continued)
DescriptionParameter
Loading ./libfile1.so: Loading ./libfile2.so: Loading /usr/lib/hpux32/libc.so: Loading /usr/lib/hpux32/libdl.so.1:
libraries
sections
symbols
Dump information about libraries searched.
$ ld main.o +vtype libraries -L. -lfile1 -lfile2 -lc Searching /usr/lib/hpux32/libc.a: Selecting /usr/lib/hpux32/libc.a
Dump information about each input section added to the output file.
$ ld main.o +vtype sections -L. -lfile1 -lfile2 -lc main.o: section .note NOTE 240 4 added to note segment section .note NOTE 48 4 added to note segment section .IA_64.unwind_info PROGBITS A 28 4 added to text segment section .text PROGBITS AX 112 16 added to text segment section .IA_64.unwind UNWIND A 12 4 added to text segment section .rodata PROGBITS A 9 8 added to text segment section .HP.opt_annot PROGBITS A 25 8 added to text segment
Dump information about global symbols referenced/defined from/in the input files.
$ ld main.o +vtype symbols -L. -lfile1 -lfile2 -lc main.o: main is DEFINED GLOBAL FUNC printf is UNDEF GLOBAL FUNC lib1_func is UNDEF GLOBAL FUNC lib2_func is UNDEF GLOBAL FUNC ./libfile1.so: printf is UNDEF GLOBAL FUNC _DYNAMIC is DEFINED GLOBAL OBJECT lib1_func is DEFINED GLOBAL FUNC ...
all
Dump all of the above. Same as -v.
$ ld main.o +vtype all -L. -lfile1 -lfile2 -lc Loading main.o: main.o: main is DEFINED GLOBAL FUNC printf is UNDEF GLOBAL FUNC lib1_func is UNDEF GLOBAL FUNC lib2_func is UNDEF GLOBAL FUNC main.o: section .note NOTE 240 4 added to note segment section .note NOTE 48 4 added to note segment section .IA_64.unwind_info PROGBITS A 28 4 added to text segment section .text PROGBITS AX 112 16 added to text segment section .IA_64.unwind UNWIND A 12 4 added to text segment section .rodata PROGBITS A 9 8 added to text segment section .HP.opt_annot PROGBITS A 25 8 added to text segment Loading ./libfile1.so: ./libfile1.so: ...
Using Linker Commands 49
Table 3 values specify the type (continued)
DescriptionParameter
procelim
procelim
Dump information about the sections that have been rejected by the +Oprocelim option.
$ ld main.o +Oprocelim +vtype procelim -L. -lfile1 -lfile2 Deleting 236 bytes in section file.note Eliminated 0K of dead code and data, 0 global, 0 local and 0 hidden symbols

Turning on the linkage table protection with +protect

You can use the +protect option to turn on the linkage table protection mode. When you turn on this option, the linker aligns the linkage table within page boundaries so that no other data resides in the same page. During runtime, the pages containing the linkage table is marked READ_ONLY.
The +protect option turns on immediate binding. For more information about immediate binding, see “Changing the Default Shared Library Binding with -B” (page 32).
The following options are not compatible with the +protect option:
+mergeseg
+filter
+lazyload

Creating read-only text segment in MPAS executable

By default, text segment in MPAS executable would be mapped private to the process. With the +mpas_rotext option, it is possible to build MPAS executable to support read-only text segment that is mapped shared. By setting the kernel tunable 'mpas_readonly_text' to value 1, the MPAS executable built with +mpas_rotext option runs with read-only text segment. This also helps to improve memory usage because the text segment is shared.
NOTE: The kernel patch PHKL_41355 must be installed to make use of this feature.

Allocating Storage for Uninitialized Data with +nobss

When the loader loads a shared library, the loader must ensure that the data segment and bss are mapped adjacent to each other in memory. This may involve repeated calls to mmap() and munmap(). When shared libraries are frequently loaded and unloaded, application performance may be affected.
You can use the new +nobss linker option to include the bss data of the shared library in its data segment. When you build programs with the +nobss option, the number of mmap and munmap calls at load time are minimal. However, the use of +nobss option increases the disk size of the shared library. HP recommends the use of +nobss option only when the frequent loading and unloading of shared libraries affect the application performance.

Initializing Floating Point Environment with +FP

You can use the +FP option to specify how the run time environment for floating point operations must be initialized at program startup and used at link time.
The following table describes the Table 4 (page 51).
50 Determining How to Link Programs or Libraries (Linker Tasks)
Table 4
flags
that are supported
Use the flagTo
VEnable trap on invalid floating-point operations.
vDisable trap on invalid floating-point operations.
ZEnable trap on divide by zero.
zDisable trap on divide by zero.
OEnable trap on floating-point overflow.
oDisable trap on floating-point overflow.
UEnable trap on floating-point underflow.
uDisable trap on floating-point underflow.
IEnable trap on floating-point operations that produce inexact results.
iDisable trap on floating-point operations that produce inexact results.
DEnable sudden underflow (flush to zero) of denormalized values.
dDisable sudden underflow (flush to zero) of denormalized values.
All trapping behaviors are disabled by default. In addition to the flags, you can specify values for the rounding mode. The following values are
available:
RN
Round to nearest. This is the default value.
RU
Round upward toward +infinity.
RD
Round downward toward -infinity
RZ
Round toward zero, that is, truncate.
For more information on the +FP option, see the HP-UX Floating Point Guide.

Allocating Storage for Hidden Common Symbols with +alloc_hidden_commons

You can use the +alloc_hidden_commons option in combination with the -r option to force the allocation of storage for hidden common symbols. The -r option is used to produce a relocatable object file that can be used in subsequent link commands. By default, storage is not allocated for common symbols when linking with -r. The -d option can be use with -r to force the allocation of storage for all common symbols. The +alloc_hidden_commons option provides finer control by allocating storage for hidden common symbols. If -d and +alloc_hidden_commons are both specified in the same link command, the -d option will take precedence.
The +alloc_hidden_commons option provides a safer alternative to -d, because it only allocates storages for common symbols that are not visible in subsequent links. This prevents any problems that might result from allocating storage for non-hidden commons, and provides consistent handling of hidden commons and hidden data.
Using Linker Commands 51

Turn Off Linker Warnings with -w

In some build processes you might want to improve parsing of build output by ignoring linker warnings. You can turn off linker warnings with the -w option.

Preserving Compiler Generated Relocation Sections with -emit_relocs

The -emit_relocs option enables the linker to preserve compiler-generated relocation sections in the output binary. The input relocation information is stored in the executable, or the shared library. This information provides the necessary support for third-party programming tools to perform post-link instrumentation.
The following example illustrates that the compiler generated relocation sections (such as
.rela.text, and .rela.IA64_64.unwind) are copied to the output binary with
-emit_relocs:
$ cc -c main.c $ ld -emit_relocs main.o -lc $ elfdump -h -S a.out | grep rela 7 RELA 04000740 00000740 0000000c .rela.plt 30 RELA 00000000 00010304 00000024 .rela.IA_64.unwind 31 RELA 00000000 00010328 0000000c .rela.IA_64.unwind_info 32 RELA 00000000 00010334 00000024 .rela.text 34 RELA 00000000 00010398 0000000c .rela.debug_line 36 RELA 00000000 000103d8 0000000c .rela.debug_actual 39 RELA 00000000 00010470 0000003c .rela.debug_procs_info
The following example illustrates that only the linker genereated relocation sections are copied to the output binary if -emit_relocs is not used:
$ ld main.o -lc $ elfdump -h -S a.out | grep rela 7 RELA 040006ec 000006ec 0000000c .rela.plt
The compiler generated relocation sections are not copied to the output binary if -emit_relocs is not used.
52 Determining How to Link Programs or Libraries (Linker Tasks)

3 Linker Tools for Itanium-Based Systems

This chapter describes the linker toolset for Itanium-based system. This toolset provides several tools to help you find symbols, display and modify object files, and determine link order. These tools are specific to ELF (executable and linking format) object file type. The following lists Table 5 (page
53).
Table 5 Linker toolset for Itanium-Based systems
DescriptionTool
chatr
nm
elfdump
ldd
pldd
pstack
size
strip
fastbind
lorder
Displays or modifies the internal attributes of an object file. See “Changing a Program's Attributes
with chatr(1)” (page 53)
Displays the symbol table of an object file. See “Viewing Symbols in an Object file with nm(1)”
(page 56)
Displays the contents of an ELF object file. See “Viewing the Contents of an Object File with
elfdump(1)” (page 58)
Lists dynamic dependencies of executable files and shared libraries. “Viewing Library Dependencies
with ldd(1)” (page 60)
Lists the dynamic libraries linked into each process, including shared objects explicitly attached using dlopen/shl_load.See “Listing Dynamic Libraries with pldd(1)” (page 61)
Prints a stack trace (hex+symbolic) for each lwp in each process and core file. See “Printing a
Stack Trace with pstack(1)” (page 62)Example 2 “Using the nm command”
Prints sizes of object file elements. See “ Viewing the Size of Object File Elements with size(1)”
(page 65)
Strips symbol and debugging information from an object file, executable, or archive library. See
“Reducing Storage Space with strip(1)” (page 65)
Improves start-up time of programs that use shared libraries. See“Improving Program Start-up with
fastbind(1)” (page 66)
Finds ordering relationship for an object library. See “Finding Object Library Ordering Relationships
with lorder(1)” (page 77)
ltrace
Traces inter-module procedure calls. See “Tracing Inter-Module Procedure Calls with ltrace(1)”
(page 67)

Changing a Program's Attributes with chatr(1)

The chatr command (see chatr(1)) allows you to change various program attributes that were determined at link time. When run without any options, chatr displays the attributes of the specified file. The following summarizes the options you can use to change various attributes:
The chatr command supports two different command syntaxes. One is provided for the easy manipulation of simple files. Use it to modify files that have only a single text segment and data segment. The second command syntax allows you to specify selected segments to modify.
The following sections list the additional IPF/PA-64 mode options for the chatr command. See the chatr(1) manpage for more information about formats.
The following summarizes the options you can use to change various attributes:
Table 6 options to change various attributes
path lists are provided (see +s and +b).
Use the optionTo do this
-l libnameIndicate that the specified shared library is subject to run-time path lookup if directory
-sPerform operations silently.
Changing a Program's Attributes with chatr(1) 53
Table 6 options to change various attributes (continued)
complement of the -Z option.)
default, share_magic, exec_magic, shmem_magic, and mpas. The default value is currently equivalent to share_magic. In order to set the mode to any value other than the default, the binary must be built with the -N compiler option to ensure that the text and data segments are contiguous.
be used to locate shared libraries needed by the program. The two flag values, enable and disable, respectively enable and disable use of the embedded path list. However, you cannot use disable on an ELF file, and a warning message is issued. If +b enable and +s enable are both specified, the order in which they appear determines which search path is used first. See the +s option.
it is denoted by the +c flag for the segment listing in the chatr output.
by the +c flag for the segment listing in the chatr output.
Use the optionTo do this
-zEnable run-time dereferencing of null pointers to produce a SIGSEGV signal. (This is the
-B immediateUse immediate binding for all libraries loaded at program start-up.
-B deferredUse deferred binding for all libraries loaded at program start-up.
-ZDisable run-time dereferencing of null pointers. (This is the complement of the -z option.)
+as modeControl the address space model to be used by the kernel. Possible values for mode are
+b flagControl whether the embedded path list stored when the program (if any) was built can
+c flagFormat 2 only: Enable or disable the code bit for a specified segment. If this is enabled,
+cd flagEnable or disable the code bit for the file's data segment(s). If this is enabled, it is denoted
by the +c flag for the segment listing.
debugger and set breakpoints in its dependent shared libraries. For shared libraries, this flag makes the text segment mapped private and writable.
(such as the stack or heap).
disable. See the "Restricting Execute Permission on Stacks" section of the chatr(1) manpage for additional information related to security issues.
symbol import/export entries. The two flag values, enable and disable, respectively enable and disable use of the global symbol table hash mechanism. The default is disable.
value can vary between 1 and MAXINT. The default value is 1103. Use this option with +gst enable. This option works on files linked with the +gst option.
on ccNUMA (Coherent Non-Uniform Memory Architecture) systems. The flag value may be either enable or disable. When enabled, the data segment uses interleaved memory. When disabled (the default), the data segment uses cell local memory. This behavior is inherited across a fork() but not an exec. For more information on ccNUMA, see pstat_getlocality(2).
on and off, respectively.
+ci flagEnable or disable the code bit for the file's text segments(s). If this is enabled, it is denoted
+dbg flagEnable or disable the ability to run a program, and, after it is running, attach to it with a
+dz flagFormat 2 only: Enable or disable lazy swap allocation for dynamically allocated segments
+es flagControl the ability of user code to execute from stack with the flag values, enable and
+gst flagControl whether the global symbol table hash mechanism is used to look up values of
+gstsize sizeRequest a particular hash array size using the global symbol table hash mechanism. The
+id flagControls the preference of physical memory for the data segment. This is important only
+k flagRequest kernel assisted branch prediction. The flags, enable and disable, turn this request
default library path stored in the executable.
enabled, it is denoted by the +m flag for the segment listing in the chatr output.
54 Linker Tools for Itanium-Based Systems
+l libnameDo not subject a library to path list lookup, even if path lists are provided. That is, use
+m flagFormat 2 only: Enable or disable the modification bit for a specified segment. If this is
Table 6 options to change various attributes (continued)
is denoted by the +m flag for the segment listing in the chatr output.
Use the optionTo do this
+md flagEnable or disable the modification bit for the file's data segment(s). If this is enabled, it
Enable or disable the automatic preloading of librtc.so runtime library for the specified executable to support runtime memory leak checking. The +mem_check option also directs the loader to map all shared library text into the private address space of the process.
segments of shared libraries loaded at program start-up are merged into a single block. Data segments for each dynamically loaded library are merged with the data segments of its dependent libraries. Merging of these segments increases run-time performance by allowing the kernel to use larger size page table entries.
denoted by the +m flag for the segment listing in the chatr output.
absolute path of the load module directory. Enabling the flag instructs the dynamic loader to calculate the absolute path of the parent module (object module, shared library, or executable) when it is first loaded. The loader then uses this path for all occurrences of $ORIGIN. If there are no occurrences of $ORIGIN, you should disable the DF_ORIGIN flag, to avoid calculating the absolute path. By default, if $ORIGIN is not present, the DF_ORIGIN flag is disabled.
16K, 64K, 256K, 1M, 4M, 16M, 64M, 256M, 1G, 4G, D, and L are supported. A size of D results in using the default page size. A size of L results in using the largest page size available. The actual page size may vary if the requested size cannot be fulfilled.
See the +pd option for additional information.
+mem_check <enable|disable>
+mergeseg flagEnable or disable the shared library segment merging features. When enabled, all data
+mi flagEnable or disable the modification bit for the file's text segment(s). If this is enabled, it is
+o flagEnable or disable the DF_ORIGIN flag to control use of $ORIGIN in calculating the
+p sizeFormat 2 only: Set the page size for a specified segment.
+pd sizeRequest a particular virtual memory page size that must be used for data. Sizes of 4K,
+pi sizeRequest a particular virtual memory page size that should be used for text (instructions).
disable this request. If this request is enabled, it is denoted by the +r flag for the segment listing in the chatr output.
SHLIB_PATH environment variables can be used to locate shared libraries needed by the program. The two flag values, enable and disable, respectively enable and disable use of the environment variable. If both +s and +b are used, their relative order on the command line indicates which path list is searched first. See the +b option.
modifications.
segment (using Format 2). The flags enable and disable, this request. Cannot be used with non-data segments.
enabled, the dynamic loader (see dld.so(5)) automatically invokes caliper upon program execution to collect profile information.
Disable linkage table protection. Once you disable, you cannot use +protect to enable linkage table protection. You have to relink the executable to turn on the linkage table protection.
+r flagRequest static branch prediction when executing this program. The flags enable and
+s flagControl whether the directory path list specified with the LD_LIBRARY_PATH and
+sa addressFormat 2 only: Specify a segment using an address for a set of attribute modifications.
+sallFormat 2 only: Use all segments in the file for a set of attribute modifications.
+si indexFormat 2 only: Specify a segment using a segment index number for a set of attribute
+z flagEnable or disable lazy swap on all data segments (using Format 1) or on a specific
+I flagEnable or disable dynamic instrumentation by /opt/langtools/bin/caliper. If
+protect disable flag
Changing a Program's Attributes with chatr(1) 55

Viewing Symbols in an Object file with nm(1)

The nm(1) command displays the symbol table of each specified object. The file can be a relocatable object file or an executable object file, or an archive of relocatable or executable object files.
The nm command provides three general output formats: the default (neither -p nor -P specified),
-p, and -P. See the nm(1) man page for a detailed description of the output formats.
-r.
format or the -p format. Equivalent to -td.
weak symbols. Only takes effect with -p and/or -P.
Use the optionTo do this
-APrefix each output line with the name of the object file or archive file. Equivalent to
-CDemangle C++ names before printing them.
-dDisplay the value and size of a symbol in decimal. This is the default for the default
-eDisplay only external and static symbols. This option is ignored (see -f).
-fDisplay full output. This option is in force by default.
-gDisplay only external (global) symbol information.
-hDo not display the output header data.
-lDistinguish between weak and global symbols by appending * to the key letter of
the default. To turn off this option, use -N.
Display information in a blank-separated output format. Each symbol name is preceded by its value (blanks if undefined) and one of the letters. Lower case letters indicate local values. Upper case letters indicate global values.
absolute
a, A
bss symbol
b, B
common symbol
c, C
data symbol
d, D
milli symbol
m, M
no type
n, N
section region
r, R
-nSort symbols by name, in ascending collation order before they are printed. This is
-NDisplay symbols in the order in which they appear in the symbol table.
-oDisplay the value and size of a symbol in octal. Equivalent to -t o.
-p
text symbol
t, T
undefined symbol
u, U
manpage for format information. Note that -p is not compatible with -P.
56 Linker Tools for Itanium-Based Systems
-PDisplay information in a portable output format to standard output. See the nm(1)
-A.
d
Display the value and size of a symbol in decimal. This is the default for the default format or the -p format. Equivalent to -d.
o
Display the value and size of a symbol in octal. Equivalent to
-o.
x
Display the value and size of a symbol in hexadecimal. This is the default for the -P format. Equivalent to -x.
format. Equivalent to -t x.
-rPrefix each output line with the name of the object file or archive file. Equivalent to
-sPrint the section index instead of the section name (ELF only).
-t formatDisplay each numeric value in the specified format. The format can be one of:
-uDisplay undefined symbols only.
-UPrint the usage menu.
-vSort symbols by value before they are printed.
-VDisplay the executing version of the nm command on standard error.
-xDisplays the value and size of a symbol in hexadecimal. this is the default for the -P
Viewing Symbols in an Object file with nm(1) 57
Example 2 Using the nm command
Display which object files have undefined references for the symbol leap:
nm -rup *.o | grep leap
Display which object files have a definition for the text symbol leap:
nm -rP *.o | awk '{ if ($3 == "T" && $2 == "leap" ) { print $0 } }'
To view the symbols defined in an object file, use the nm command. The following 32-bit mode
example shows output from running nm -p on the func.o and main.o object files.
$ nm -p func.o
0000000000 u 0000000000 r .HP.opt_annot 0000000000 r .IA_64.unwind_info 0000000000 r .text 0000000000 a func.c 0000000000 T sum_n //Global definitions of sum_n. $ nm -p main.o 0000000000 U $global$ //Other symbols created from compiling. 0000000000 u 0000000000 r .HP.opt_annot 0000000000 r .IA_64.unwind_info 0000000000 r .data 0000000000 r .sdata 0000000000 r .text 0000000000 a main.c 0000000000 T main //Global definition of main. 0000000000 U printf 0000000000 U scanf 0000000000 U sum_n

Viewing the Contents of an Object File with elfdump(1)

The elfdump(1) command displays information contained in ELF format object files, archives, and shared libraries. Use the following options to select the information you want to display:
option has the same effect as elfdump -dc-dl.
used to generate the file as well as the link time.
and microloader). Only shared bound executables have this string. To change the setting, use the ld+interp command.
Use the optionTo view this
-aArchive headers from an archive library.
-cString table(s).
-dThe .note section which contains the compilation unit dictionary and linker footprint. This
-dcThe compilation unit dictionary of the .note section.
-dcThe linker footprint of the .note section. The linker footprint has information on the linker
-fFile header.
-gGlobal symbols from an archive.
-hSection headers.
+interpThe run-time interpreter path name for a.out (usually the location of the dynamic loader
the +objdebug option. The object dictionary entry contains the name of the object file that contributed to a particular section, the relative offset within the section, size of the object file's contribution, and attributes of the entry.
58 Linker Tools for Itanium-Based Systems
-jThe object dictionary for one or more executable files, if the source file was compiled with
-kThe CTTI section headers according to the directory member relationship.
ld+ild command).
the ld +ild command).
the ld +ild command).
option. This option is useful in verifying the data stored in the symbol table.
Use the optionTo view this
-LThe .dynamic section in shared libraries and dynamically linked program files.
+linkmapThe .linkmap section, which is only created when the incremental linker is used (with the
+linkmap_bssThe .linkmap_bss section, which is only created when the incremental linker is used (with
+linkmap_fileThe .linkmap_file section, which is only created when the incremental linker is used (with
-oOptional headers (program headers).
-rRelocations.
+objdebugSections beginning with .objdebug_ as a string table.
-sSection contents.
-tSymbol table entries.
-txDumps the value of st_shndx in symbol table, in addition to information dump from -t
-tvPrints versioned symbols.
-uUsage message.
-UUnwind table.
-VVersion number for elfdump.
The elfdump command provides the following additional options to modify your selections:
Causes elfdump toModifiesOption
-c, -r, -s, -t-C
-h, -s-D num
-h, -s+D num2
-r-D num
-r+D num2
all-H
-h, -r, -s-n name
-t-n name
Demangle C++ symbol names before displaying them.
With -H, ignored.
With -n name, display the symbol whose unmangled name matches
name, and prints its symbol name as a demangled name.
Display the section whose index is num.
Display the sections in the range 1 to num2.
With -D, display the sections in the range num to num2.
Display the relocation whose index is num.
Display only the relocations which apply to the section(s) in the range.
Select output format in hexadecimal, octal, or decimal.
Display information about the section specified by name.
Display information about the symbol entry specified by name.
all-p
-k-q
-c, -t+s name
-h,-o-S
-t-T num
Suppress title printing.
Suppress printing CTTI section headers.
Display the section specified by name.
Display headers in short format.
Display the symbol whose index is num.
Viewing the Contents of an Object File with elfdump(1) 59
Causes elfdump toModifiesOption
-t+T num2
-k-v
Display the symbols in the range 0 to num2.
With-T, display the symbols in the range num to num2.
Verify the CTTI section headers before printing.

Viewing Library Dependencies with ldd(1)

The ldd(1) command lists the dynamic dependencies of executable files or shared libraries. The ldd command displays verbose information about dynamic dependencies and symbol references:
Executable
All shared libraries loaded as a result of executing the file.
Shared library
All shared libraries loaded as a result of loading the library.
The ldd command uses the same algorithm as the dynamic loader (/usr/lib/hpux32/dld.so and /usr/lib/hpux64/dld.so) to locate the shared libraries.
The ldd command does not list shared libraries explicitly loaded using dlopen(3C) or shl_load(3X). The ldd command prints the record of shared library path names to stdout. It prints a list of symbol resolution problems to stderr
Table 7 Symbol resolution problems to stderr
Use the optionTo do this
-dCheck reference to data symbols.
-rCheck reference to data and code symbols.
-sDisplays the search path used to locate the shared libraries.
-vDisplay all dependency relationships
-y, <symbol>Find names of module which refers and defines the symbol
.
60 Linker Tools for Itanium-Based Systems
Example 3 Using the ldd command
By default, ldd prints simple dynamic path information, including the dependencies recorded
in the executable (or the shared library) followed by the physical location where the dynamic loader finds these libraries.
$ ldd a.out
./libx.so => ./libx.so libc.so.1 => /usr/lib/hpux32/libc.so.1 libdl.so.1 => /usr/lib/hpux32/libdl.so.1
The -v option causes ldd to print the dependency relationships along with the dynamic path
information.
$ ldd -v a.out
find library=./libx.so; required by a.out ./libx.so => ./libx.so find library=libc.so.1; required by a.out libc.so.1 => /usr/lib/hpux32/libc.so.1 find library=libdl.so.1; required by usr/lib/hpux32/libc.so.1 libdl.so.1 => /usr/lib/hpux32/libdl.so.1
The -r option to causes it to analyze all symbol references and print information about
unsatisfied code and data symbols.
$ldd -r a.out
./libx.sl => ./libx.sl libc.so.1 => /usr/lib/hpux32/libc.so.1 libdl.1 => /usr/lib/hpux32/libdl.so.1 symbol not found: val1 (./libx.so) symbol not found: count (./libx.so) symbol not found: func1 (./libx.so) symbol not found: func2 (./libx.so)
The -y, <symbol> option can be used to point out the module from which the specified
symbol is being resolved. It can also be used to point out modules that refer to the specified symbol.
$ ldd -y,bar a.out
libx.so => ./libx.so libc.so.1 => /usr/lib/hpux32/libc.so.1 libdl.so.1 => /usr/lib/hpux32/libdl.so.1 bar (data) : needed by a.out; found in ./libx.so bar (data) : needed by ./libx.so; found in ./libx.so
$ ldd -y,foo a.out
libx.so => ./libx.so libc.so.1 => /usr/lib/hpux32/libc.so.1 libdl.so.1 => /usr/lib/hpux32/libdl.so.1 foo (code) : needed by a.out; found in ./libx.so foo (code) : needed by ./libx.so; found in ./libx.so

Listing Dynamic Libraries with pldd(1)

Given a process ID (PID) or a corefile, the pldd command prints a list of shared libraries loaded including those loaded explicitly with dlopen() and shl_load(). The pldd command works by attaching to the process to read its memory. Mismatch between executable and corefile may result in unpredictable behavior. The pldd command searches for the executable file in the current
Listing Dynamic Libraries with pldd(1) 61
directory and $PATH. The executable path can be specified along with the pid/corepath, separated by a colon (:) character. Use the -h option to print the usage menu.
The following exit values are returned:
0: Successful operation
non-zero: An error has occurred.
Use the following options to view information for your specified files.
Use the optionTo
-hPrint the usage menu
-lPrint the start and end addresses of text and data segment mappings for the shared libraries
The –l option can be used to print the start and end address of text and data segment mappings of each shared library used by the process.
Example 4 Executing ‘pldd –t XXXXX’ gives the following information
27739: ./thread32
Text start Text end Data start Data end Name
0x04000000 0x04000f50 0x40010000 0x40010098 ./thread32
0xc0018000 0xc00bb2d0 0x7efec000 0x7eff0a58 /usr/lib/hpux32/dld.so
0xc00bc000 0xc01c8970 0x7efe0000 0x7efe2e28 /usr/lib/hpux32/libpthread.so.1
0xc01cc000 0xc04a4ce0 0x7efcc000 0x7efdfaa8 /usr/lib/hpux32/libc.so.1
0xc04a8000 0xc04abf90 0x7efc4000 0x7efc4150 /usr/lib/hpux32/libdl.so.1

Printing a Stack Trace with pstack(1)

Given the PID of a running process or the full path to a corefile, the pstack command prints the stack trace for each lwp thread in the process. To obtain symbol information, pstack searches load modules (executable/shared libraries) in the current directory, $PATH, $LD_LIBRARY_PATH, and $SHLIB_PATH. The executable path can be specified along with the PID/core-file-path, separated by a colon (:) character. If a load module is not found, symbol information for frames in that module is not displayed.
The pstack command works by attaching to the running process and reading its registers, memory, and stack. Mismatch between executable and corefile may result in unpredictable behavior.
The following exit values are returned:
0:Successful operation
non-zero: An error has occurred.
Use the following options to view information for your specified files:
Table 8 Options to view information specified files
Print stack upto a specified level
62 Linker Tools for Itanium-Based Systems
Use the optionTo view this
-hPrint the usage menu
-level (with level parameter)
-t (with thread id)Print stack of only one thread using suspending execution of other threads
The -level n option can be used to print n levels of procedure calls. Without this option, pstack normally prints the complete procedure stack. With this option, pstack can be restricted to print 'n' levels in the procedure stack. With this option, pstack can be restricted to print only n levels of procedure calls in the procedure stack.
The following example shows the result of running pstack for a process id 3975.
Example 5 Calling pstack with a process id
-------------------------------- lwpid : 4549 -------------------------------
0: 60000000c0454230 : _read_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
1: 60000000c0469840 : _read() + 0x80 (/usr/lib/hpux32/libc.so.1)
2: 60000000c04304a0 : __filbuf() + 0x1a0 (/usr/lib/hpux32/libc.so.1)
3: 00000000040009e0 : (unknown) () (unknown)
4: 60000000c0048c90 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)
The following example shows the usage id -level option is used to print 3 levels of procedures stack for a process id 3975.
Example 6 Calling pstack with -level option
-------------------------------- lwpid : 4549 -------------------------------
0: 60000000c0454230 : _read_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
1: 60000000c0469840 : _read() + 0x80 (/usr/lib/hpux32/libc.so.1)
2: 60000000c04304a0 : __filbuf() + 0x1a0 (/usr/lib/hpux32/libc.so.1)
On HP-UX 11i v3 Integrity systems, the -t <thread id> can be used to print stack trace of the target thread alone. Only the execution of the target thread is suspended while other threads continue to execute. The following example shows the usage if -t <thread id> option is used to print the default output for a sample threaded process.
Printing a Stack Trace with pstack(1) 63
Example 7 Printing the default output for a sample threaded process
-------------------------------- lwpid : 119942 -------------------------------
0: 60000000c042fb70 : __pause_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
1: 60000000c0444de0 : pause() + 0xc0 (/usr/lib/hpux32/libc.so.1)
2: 0000000004000e80 : main() + 0x270 (./thread32)
3: 60000000c0030c90 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)
-------------------------------- lwpid : 119943 -------------------------------
0: 60000000c042fb70 : __pause_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
1: 60000000c0444de0 : pause() + 0xc0 (/usr/lib/hpux32/libc.so.1)
2: 0000000004000b80 : thread_func1() + 0x50 (./thread32)
3: 60000000c00f69a0 : __pthread_bound_body() + 0x190 (/usr/lib/hpux32/libpthread.so.1)
-------------------------------- lwpid : 119944 -------------------------------
0: 60000000c042fb70 : __pause_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
1: 60000000c0444de0 : pause() + 0xc0 (/usr/lib/hpux32/libc.so.1)
2: 0000000004000bf0 : thread_func2() + 0x50 (./thread32)
3: 60000000c00f69a0 : __pthread_bound_body() + 0x190 (/usr/lib/hpux32/libpthread.so.1)
Using the –t option to specify the thread, you can get the information specific to a thread without stopping the other threads as shown below.
Example 8 Printing the output for a sample threaded process with the -t option
-------------------------------- lwpid : 119942 -------------------------------
0: 60000000c042fb70 : __pause_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
1: 60000000c0444de0 : pause() + 0xc0 (/usr/lib/hpux32/libc.so.1)
2: 0000000004000e80 : main() + 0x270 (./thread32)
3: 60000000c0030c90 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)
A special argument -1 enables you to trace the calling process without entering the PID of the process. Hence, you can skip the process of finding the PID by using this argument on a calling process.
The example below shows the usage of special argument -1 that can be used to run pstack on the calling process. In this case, the calling process is the shell itself.
64 Linker Tools for Itanium-Based Systems
Example 9 Calling pstack with special argument -1
3774: /usr/bin/bash
-------------------------------- lwpid : 4520 -------------------------------
0: 00000000040c47c1 : make_child() + 0x311 (/usr/bin/bash)
1: 000000000420bd60 : push_scope() + 0x3b0 (/usr/bin/bash)
2: 0000000004208e40 : coproc_closeall() + 0xfa0 (/usr/bin/bash)
3: 00000000040ba440 : execute_command_internal() + 0xf70 (/usr/bin/bash)
4: 000000000416c420 : execute_command() + 0x160 (/usr/bin/bash)
5: 00000000042206f0 : reader_loop() + 0x670 (/usr/bin/bash)
6: 00000000040776b0 : main() + 0xc60 (/usr/bin/bash)
7: 60000000c0048c90 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)

Viewing the Size of Object File Elements with size(1)

The size(1) command produces section size information for each section in your specified object files. It displays the size of the text, data, and bss (uninitialized data) sections with the total size of the object file. If you specify an archive file, the information for all archive members is displayed. Use the following options to view information for your specified files:
with its name, size, and virtual address.

Reducing Storage Space with strip(1)

Use the optionTo view this
-dSizes in decimal (default).
-fSize of each allocatable section.
-FSize and permission bits of each loadable segment.
-nSizes of nonloadable segments or nonallocatable sections.
-oSizes in octal.
-UDisplay the usage message.
-VVersion information about the size command.
-vVerbose list of the subspaces in the object files. Each subspace is listed on a separate line
-xSizes in hexadecimal.
The strip(1) command removes the symbol table and line number information from object files, including archives. Thereafter, no symbolic debugging access is available for that file. The purpose of this command is to reduce file storage overhead consumed by the object file. Use this command on production modules that have been debugged and tested. The effect is nearly identical to using the -s option of ld. You can control the amount of information stripped from the symbol table by using the following options:
Viewing the Size of Object File Elements with size(1) 65
Table 9 Options to control the amount of information stripped
Use the optionTo
-lStrip line number information only; do not strip any symbol table information.
-rSame as the -x option. Obsolete.
-uStrip the unwind information and annotations.
-UPrint the usage message.
-VPrint the version of the strip command to stderr.
-xStrip the debug information and line number table.
NOTE: The -l and -x options are synonymous because the symbol table contains only static
and external symbols. Either option strips only symbolic debugging information and unloadable data.
If there are any relocation entries in the object file and any symbol table information is to be stripped, strip issues a message and terminates without stripping the specified file unless the -r option is used. If you execute strip on an archive file (see ar(4)), it removes the archive symbol table. The archive symbol table must be restored by executing ar with its s operator (see ar(1)) before the ld command (see ld (1)) can use the archive. The strip command issues appropriate warning messages when this situation occurs.

Improving Program Start-up with fastbind(1)

The fastbind(1) command prepares an incomplete executable for faster program start-up. It can improve the start-up time of programs that use shared libraries (incomplete executables) by storing information about needed shared library symbols in the executable file. The fastbind command performs analysis on the symbols used to bind an executable and all of its dependent shared libraries, and stores this information in the executable file. The next time the executable is run, the dynamic loader (/usr/lib/hpux32/dld.so for 32-bit or /usr/lib/hpux64/dld.so for 64-bit) detects that this information is available, and uses it to bind the executable instead of using the standard search method for binding the symbols. The fastbind command writes the fastbind information in the executable file. Hence, you must have write permission on the executable file. If the executable file being analyzed is being run as another process or the file is locked against modifications by the kernel, the fastbind command fails. If the shared libraries that an executable is dependent on are modified after the fastbind information is created, the dynamic loader silently reverts to standard search method for binding the symbols. The fastbind information can be re-created by running the fastbind command on the executable again. The fastbind command automatically erases the old fastbind information and generates the new one.
was in before you ran fastbind on it.
Use the optionTo do this
-nRemove the fastbind information from the executable, returning it to the same state it as
information, it generates an error message and does not modify the executable file. However, when you invoke fastbind with the -u option, fastbind allows unresolved symbols.
The PA-32-bit mode fastbind command does not work with EXEC_MAGIC executables. The fastbind command effectively enforces the binding modes bind-restricted and bind-immediate. For example, consider an executable linked bind-deferred, which calls a function foo() defined in an implicitly loaded library. Before the actual call is made, if it explicitly loads a shared library (using shl_load(3X) with BIND_FIRST) having a definition for foo() when foo() is finally
66 Linker Tools for Itanium-Based Systems
-uNormally, if fastbind detects any unsatisfied symbols while building the fastbind
called, it is resolved from the explicitly-loaded library. But after running fastbind, the symbol foo() is resolved from the implicitly-loaded library. For more information about fastbind and how to improve program start-up time, see “Improving Shared Library Start-Up Time with fastbind” (page
222) .
Example 10 Example
To run fastbind on the executable file a.out:
$fastbind a.out
To later remove the fastbind information from the executable file a.out
$fastbind -n a.out

Finding Object Library Ordering Relationships with lorder(1)

The lorder command finds the ordering relation for an object library. You can specify one or more object or archive library files (see ar(1)) on the command line or read those files from standard input. The standard output is a list of pairs of object file names, meaning that the first file of the pair refers to external identifiers defined in the second. You can process the output with tsort to find an ordering of a library suitable for one-pass access by ld (see tsort(1) and ld(1)). The linker ld is capable of multiple passes over an archive in the archive format and does not require that you use lorder when building an archive. Using the lorder command may, however, allow for a slightly more efficient access of the archive during the link-edit process. The symbol table maintained by ar allows ld to randomly access symbols and files in the archive, making the use of lorder unnecessary when building archive libraries (see ar(1)). The lorder command overlooks object files whose names do not end with .o, even when contained in library archives, and attributes their global symbols and references to some other file.
Example 11 Examples
Build a new library from existing .o files:
$ar cr library `lorder *.o | tsort`
When creating libraries with so many objects that the shell cannot properly handle the *.o
expansion, the following technique may prove useful:
$ls |grep '.o$'|lorder|tsort|xargs ar cq library

Tracing Inter-Module Procedure Calls with ltrace(1)

The ltrace(1) command traces inter-module procedure calls. ltrace can be invoked as follows:
$ /usr/ccs/bin/ltrace [ltrace options] executable [-a <arguments to the executable>]
On executing the above command, a log is generated in the file logfile.txt in the current working directory. In case the log file already exists, it is appended with the output of the current ltrace invocation. For each call made in the application, the following line is added into the logfile:
lwp # <address>:<library>:<procedure>(<arguments>)
NOTE: The arguments are printed in the logfile only if a debug version of a library is being
traced. To re-direct the output of the logfile.txt to an alternate file mylogfile, use the following command:
$/usr/ccs/bin/ltrace -f mylogfile ./a.out
In case of multiple invocations through the same command line, such as:
$ /usr/ccs/bin/ltrace ./a.out ./b.out
Finding Object Library Ordering Relationships with lorder(1) 67
The output from each of the execution is appended to the log file. To generate a log when a program $ ./a.out arg1 arg2 arg3 .. argn is executed, use the following
command syntax:
$/usr/ccs/bin/ltrace ./a.out -a "arg1 arg2 arg3 .. argn"
For example:
$/usr/ccs/bin/ltrace /usr/bin/ls -a "-ltr"
The above-mentioned command has the effect of tracing all inter-module procedure calls when /usr/bin/ls -ltr command is executed.
NOTE: ltrace does not need the debug version of the library libc as it already includes
prototype information for some of the most commonly used libc procedures. For the remaining libc procedures, only the execution is reported.
68 Linker Tools for Itanium-Based Systems

4 Linker Tools for PA-RISC Systems

This chapter describes the linker toolset, which provides several tools to help you find symbols, display and modify object files, and determine link order. Some of these tools are specific to a particular object file type. Others are available in both 32-bit and 64-bit mode. The following table lists the linker toolset.
DescriptionModeTool
32-bit/64-bitchatr
32-bit/64-bitnm
64-bitelfdump
32-bit/64-bitldd
32-bit/64-bitsize
32-bit/64-bitstrip
32-bit/64-bitfastbind
32-bit/64-bitlorder
Displays or modifies the internal attributes of an object file. See “Changing a
Program's Attributes with chatr(1)” (page 69) .
Displays the symbol table of an object file. See “Viewing Symbols in an Object
file with nm(1)” (page 71) .
Displays the contents of an ELF object file. See “Viewing the Contents of an Object
File with elfdump(1)” (page 72)
Lists dynamic dependencies of executable files and shared libraries. “Viewing
library dependencies with ldd(1)” (page 74).
Prints sizes of object file elements. See “Viewing the Size of Object File Elements
with size(1)” (page 75)
Strips symbol and debugging information from an object file, executable, or archive library. See “Reducing Storage Space with strip(1)” (page 76)
Improves startup time of programs that use shared libraries. See. “Improving
Program Start-up with fastbind(1)” (page 76)
Finds ordering relationship for an object library. See “Finding Object Library
Ordering Relationships with lorder(1)” (page 77)
Displays the contents of a SOM object file. See the odump(1).32-bitodump

Changing a Program's Attributes with chatr(1)

The chatr command (seechatr(1)) allows you to change various program attributes that were determined at link time. When run without any options, chatr displays the attributes of the specified file.

Using chatr for 32-bit Program Attributes

The following table summarizes the options you can use to change various attributes:
32-bit mode only: Set the file's magic number to SHARE_MAGIC.
32-bit mode only: Set the file's magic number to DEMAND_MAGIC.
32-bit mode only: Change the file's magic number from EXEC_MAGIC to SHMEM_MAGIC.
32-bit mode only: Change the file's magic number from SHMEM_MAGIC to EXEC_MAGIC.
Use immediate binding for all libraries loaded at program startup.
Use deferred binding for all libraries loaded at program startup.
Use nonfatal binding. Must be specified with -B immediate or -B deferred.
Use restricted binding. Must be specified with -B immediate or -B deferred.
Use the optionTo
-n
-q
-M
-N
-B immediate
-B deferred
-B nonfatal
-B restricted
Changing a Program's Attributes with chatr(1) 69
Enable run-time use of the path list specified with the +b option at link time.
Use the optionTo
+b enable
If +b enable and +s enable are both specified, the order in which they appear determines which search path is used first.
Disable run-time use of the path list specified with the +b option at link time.
Enable the use of the SHLIB_PATH environment variable to perform run-time path list lookup of shared libraries.
Disable the use of the SHLIB_PATH environment variable to perform run-time path list lookup of shared libraries.
32-bit mode only: Use default library path stored in the executable even if path lists are provided. That is, prevent a library from looking up a path list.
32-bit mode only: Subject a library to path list lookup if directory path lists are provided. Useful for libraries that were specified with a full path name at link time.
Set the virtual memory page size for data segments.
Set the virtual memory page size for instructions.
Assist branch prediction on PA-RISC 2.0 systems. Programs must be linked with +Ostaticprediction.
Request static branch prediction.
Disable linkage table protection. Once you disable, you cannot use +protect to enable linkage table protection. You have to relink the executable to turn on the linkage table protection.
Enable or disable the automatic preloading of librtc.sl runtime library for the specified executable to support runtime memory leak checking. The +mem_check option also directs the loader to map all shared library text into the private address space of the process.
+b disable
+s enable
+s disable
+l libname
-l libname
+pd size
+pi size
+k
+r
+protect disable
+mem_check <enable|disable>

Using chatr for 64-bit Program Attributes

In 64-bit mode, chatr supports two different command syntaxes. One is compatible with the 32-bit command. Use it to modify files that have only a single text segment and data segment. The second command syntax allows you specify selected segments to modify. The following sections list the additional 64-bit mode options for the chatr command.
Table 10 For the 32-bit compatible syntax
the complement of the -Z option.)
Use the optionTo
+mdSet the modification bit for the file's data segment(s).
+miSet the modification bit for the file's text segment(s).
+cdSet the code bit for the file's data segment(s).
+ciSet the code bit for the file's text segment(s).
+zEnable lazy swap on all data segments. Do not use with non-data segments.
-zEnable run-time dereferencing of null pointers to produce a SIGSEGV signal. (This is
70 Linker Tools for PA-RISC Systems
Table 11 For the 64-bit only syntax
the stack or heap).
use with non-data segments.
the complement of the -Z option.)

Viewing Symbols in an Object file with nm(1)

The nm command displays the symbol table of each specified object. The file can be a relocatable object file or an executable object file, or an archive of relocatable or executable object files. The nm command provides three general output formats: the default (neither -p nor -P specified), -p, and -P. See the nm(1) man page for a detailed description of the output formats.
Use the optionTo
+cSet the code bit for a specified segment.
+dzEnables or disables lazy swap allocation for dynamically allocated segments (such as
+mSet the modification bit for a specified segment.
+pSet the page size for a specified segment.
+siIdentify a segment using a segment index number.
+saIdentify a segment using an address.
+sallUse all segments in the file for a set of attribute modifications.
+zEnable lazy swap on a specific segment (using the second command syntax). Do not
-zEnable run-time dereferencing of null pointers to produce a SIGSEGV signal. (This is
or the -p format. Equivalent to -t d.
symbols. Only takes effect with -p and/or -P.
To turn off this option, use -N.
its value (blanks if undefined) and one of the letters. A absolute B bss symbol C common symbol D data symbol R section region S tstorage symbol (32-bit mode SOM files only) If the symbol is local (nonexternal), the type letter is in lowercase. If the symbol is a secondary definition, the type letter is followed by the letter S. Note that -p is not compatible with -P. T text symbol U undefined
Use the optionTo
-APrefix each output line with the name of the object file or archive file. Equivalent to -r.
-C64-bit mode ELF files only: Demangle C++ names before printing them.
-dDisplay the value and size of a symbol in decimal. This is the default for the default format
-eDisplay only external and static symbols. This option is ignored (see -f).
-fDisplay full output. This option is in force by default.
-gDisplay only external (global) symbol information.
-hDo not display the output header data.
-lDistinguish between weak and global symbols by appending * to the key letter of weak
-nSort symbols by name, in ascending collation order, before they are printed. This is the default.
-NDisplay symbols in the order in which they appear in the symbol table.
-oDisplay the value and size of a symbol in octal. Equivalent to -t o.
-pDisplay information in a blank-separated output format. Each symbol name is preceded by
compatible with -P.
-PDisplay information in a portable output format to standard output. Note that -p is not
-q32-bit mode SOM files only: Silence some warning messages.
Viewing Symbols in an Object file with nm(1) 71
value and size of a symbol in decimal. This is the default for the default format or the -p format. Equivalent to -d. o Display the value and size of a symbol in octal. Equivalent to -o. x Display the value and size of a symbol in hexadecimal. This is the default for the -P format. Equivalent to -x.
and place an asterisk as the last character in the displayed name to mark it as truncated. If
-A or -r is also specified, the file prefix is truncated first. By default, nm prints the entire name of the symbols listed. Because object files can have symbol names with an arbitrary number of characters, a name that is longer than the width of the column set aside for names overflows its column, forcing every column after the name to be misaligned.
Equivalent to -t x.
Example 12 Viewing Symbols in an Object file with nm(1)
Use the optionTo
-rPrefix each output line with the name of the object file or archive file. Equivalent to -A.
-t formatDisplay each numeric value in the specified format. The format can be one of: d Display the
-T32-bit mode SOM files only: Truncate every name that would otherwise overflow its column
-uDisplay undefined symbols only.
-UPrint the usage menu.
-vSort symbols by value before they are printed.
-VDisplay the executing version of the nm command on standard error.
-xDisplays the value and size of a symbol in hexadecimal. This is the default for the -P format.
Display which object files have undefined references for the symbol "leap":
$ nm -rup *.o | grep leap
Display which object files have a definition for the text symbol "leap":
$ nm -rP *.o | awk '{ if ($3 == "T" && $2 == "leap" ) { print $1 } }'
To view the symbols defined in an object file, use the nm command. The following 32-bit mode
example shows output from running nm -p on the func.o and main.o object files.
$ nm -p func.o
1073741824 d $THIS_DATA$ 1073741824 d $THIS_SHORTDATA$ 1073741824 b $THIS_BSS$ 1073741824 d $THIS_SHORTBSS$ 0000000000 T sum_n //Global definitions of sum_n. $ nm -p main.o 0000000000 U $global$ //Other symbols created from compiling. 1073741824 d $THIS_DATA$ 1073741872 d $THIS_SHORTDATA$ 1073741872 b $THIS_BSS$ 1073741872 d $THIS_SHORTBSS$ 0000000000 T main //Global definition of main. 0000000000 U printf 0000000000 U scanf 0000000000 U sum_n
The first column shows the address of each symbol or reference. The last column shows the symbol name. The second column denotes the symbol's type: T indicates a global definition. U indicates an external reference. d indicates a local definition of data. b indicates a local definition of uninitialized data (bss). Thus, a global definition of sum_n is found in func.o. An external reference to sum_n is found in main.o. External references to the C printf and scanf routines are found in main.o. For details on the use of nm, see nm(1).

Viewing the Contents of an Object File with elfdump(1)

NOTE: The elfdump command works on 64-bit executables or shared libraries.
72 Linker Tools for PA-RISC Systems
The elfdump command displays information contained in ELF format object files, archives, and shared libraries. Use the following options to select the information you want to display:
Use the optionTo view
-tSymbol table entries.
-aArchive headers from an archive library.
-cString table(s).
-fFile header.
-gGlobal symbols from an archive.
-hSection headers.
-LThe .dynamic section in shared libraries and dynamically linked program files.
-oOptional headers (program headers).
-rRelocations
-sSection contents.
-UUnwind table.
-tvVersioned symbols.
The elfdump command provides the following additional options to modify your selections:
Causes elfdump toModifiesOption
Select output format in hexadecimal, octal, or decimal.all-H
Suppress title printing.all-p
Display headers in short format.-h,-o-S
Demangle C++ symbol names before displaying them.-c, -r, -s, -t-C
With -H, ignored.
With -n name, display the symbol whose unmangled name matches
name, and prints its symbol name as a demangled name.
Display the section whose index is num.-h, -s-D num
-h, -s+D num2
Display the sections in the range 1 to num2.
With -D, display the sections in the range num to num2.
Display the relocation whose index is num.-r-D num
Display only the relocations which apply to the section(s) in the range.-r+D num2
Display the section specified by name.-c, -t+s name
Display information about the section specified by name.-h, -r, -s-n name
Display information about the symbol entry specified by name.-t-n name
Display the symbol whose index is num.-t-T num
-t+T num2
Display the symbols in the range 0 to num2.
With-T, display the symbols in the range num to num2.
Viewing the Contents of an Object File with elfdump(1) 73

Viewing library dependencies with ldd(1)

The ldd command lists the dynamic dependencies of executable files or shared libraries. The ldd command displays verbose information about dynamic dependencies and symbol references: Executable All shared libraries that are loaded as a result of executing the file. Shared library All shared libraries that are loaded as a result of loading the library. The ldd command uses the same algorithm as the dynamic loader (/usr/lib/dld.sl and /usr/lib/pa20_64/dld.sl) to locate the shared libraries. The ldd command does not list shared libraries explicitly loaded using dlopen(3C) or shl_load(3X). The ldd command prints the record of shared library path names to stdout. It prints the optional list of symbol resolution problems to stderr.
Table 12 optional list of symbol resolution problems to stderr
libraries and report unsats. By default the smartbind mechanism in dld.sl only binds libraries whose symbols are explicitly referenced.
Use the optionTo do this
-b32-bit mode only: Used in conjunction with -d and/or -r, force dld.sl to bind all dependent
-dCheck reference to data symbols.
-rCheck reference to data and code symbols.
-sDisplay the search path used to locate the shared libraries.
-vDisplay all dependency relationships.
-y, <symbol>Find names of module which refers and defines the symbol.
74 Linker Tools for PA-RISC Systems
Example 13 Viewing library dependencies with ldd(1)
By default, ldd prints simple dynamic path information, including the dependencies recorded
in the executable (or the shared library) followed by the physical location where the dynamic loader finds these libraries.
$ ldd a.out
./libx.sl => ./libx.sl libc.2 => /lib/pa20_64/libc.2 libdl.1 => /lib/pa20_64/libdl.1
The -v option causes ldd to print the dependency relationships along with the dynamic path
information.
$ ldd -v a.out
find library=./libx.sl; required by a.out ./libx.sl => ./libx.sl find library=libc.2; required by a.out libc.2 => /lib/pa20_64/libc.2 find library=libdl.1; required by /lib/pa20_64/libc.2 libdl.1 => /lib/pa20_64/libdl.1
The -r option to causes it to analyze all symbol references and print information about
unsatisfied code and data symbols.
$ ldd -r a.out
./libx.sl => ./libx.sl libc.2 => /lib/pa20_64/libc.2 libdl.1 => /lib/pa20_64/libdl.1 symbol not found: val1 (./libx.sl) symbol not found: count (./libx.sl) symbol not found: func1 (./libx.sl) symbol not found: func2 (./libx.sl)
The -y, <symbol> option can be used to point out the module from which the specified
symbol is being resolved. It can also be used to point out modules that refer to the specified symbol.
$ ldd -y,bar a.out
libx.so => ./libx.so libc.so.1 => /usr/lib/hpux32/libc.so.1 libdl.so.1 => /usr/lib/hpux32/libdl.so.1 bar (data) : needed by a.out; found in ./libx.so bar (data) : needed by ./libx.so; found in ./libx.so
$ ldd -y,foo a.out
libx.so => ./libx.so libc.so.1 => /usr/lib/hpux32/libc.so.1 libdl.so.1 => /usr/lib/hpux32/libdl.so.1 foo (code) : needed by a.out; found in ./libx.so foo (code) : needed by ./libx.so; found in ./libx.so

Viewing the Size of Object File Elements with size(1)

The size command produces section size information for each section in your specified object files. It displays the size of the text, data and bss (uninitialized data) sections with the total size of
Viewing the Size of Object File Elements with size(1) 75
the object file. If you specify an archive file, the information for all archive members is displayed. Use the following options to display information for your specified files:
with its size, physical address, and virtual address.

Reducing Storage Space with strip(1)

The strip command removes the symbol table and line number information from object files, including archives. Thereafter, no symbolic debugging access is available for that file. The purpose of this command is to reduce file storage overhead consumed by the object file. Use this command on production modules that have been debugged and tested. The effect is nearly identical to using the -s option of ld. You can control the amount of information stripped from the symbol table by using the following options:
Use the optionTo display
-dSizes in decimal (default).
-oSizes in octal.
-xSizes in hexadecimal.
-VVersion information about the size command.
-vVerbose list of the subspaces in the object files. Each subspace is listed on a separate line
-f64-bit mode only: Size of each allocatable section.
-F64-bit mode only: Size and permission bits of each loadable segment=.
-n64-bit mode only: Sizes of non loadable segments or non allocatable sections.
-UPrint the usage menu
Use the optionTo
-lStrip line number information only; do not strip any symbol table information.
-xDo not strip static or external symbol information.
-r32-bit mode only: Reset the relocation indexes into the symbol table. This option allows strip
to be run on relocatable files, in which case the effect is also to strip only symbolic debugging information and unloadable data.
-VPrint the version of the strip command to stderr.
NOTE: The -l and -x options are synonymous because the symbol table contains only static
and external symbols. Either option strips only symbolic debugging information and unloadable data.
If there are any relocation entries in the object file and any symbol table information is to be stripped, strip issues a message and terminates without stripping the specified file unless the -r option is used.
If you execute strip on an archive file (see ar(4)), it removes the archive symbol table. The archive symbol table must be restored by executing ar with its s operator (see ar(1)) before the ld command (see ld (1)) can use the archive. strip issues appropriate warning messages when this situation occurs.

Improving Program Start-up with fastbind(1)

The fastbind(1) command prepares an incomplete executable for faster program start-up. It can improve the start-up time of programs that use shared libraries (incomplete executables) by storing information about needed shared library symbols in the executable file.
76 Linker Tools for PA-RISC Systems
The fastbind command performs analysis on the symbols used to bind an executable and all of its dependent shared libraries, and stores this information in the executable file. The next time the executable is run, the dynamic loader (/usr/lib/dld.sl for 32-bit mode or /usr/lib/pa20_64/dld.sl for 64-bit mode) detects that this information is available, and uses it to bind the executable instead of using the standard search method for binding the symbols.
Because fastbind writes the fastbind information in the executable file, you must have write permission on the executable file. If the executable file being analyzed is being run as another process or the file is locked against modifications by the kernel, the fastbind command fails.
If the shared libraries that an executable is dependent on are modified after the fastbind information is created, the dynamic loader silently reverts to standard search method for binding the symbols. The fastbind information can be re-created by running fastbind on the executable again. The fastbind command automatically erases the old fastbind information and generate the new one.
Use the optionTo
-nRemove the fastbind information from the executable, returning it to the same state it as was in
before you ran fastbind on it.
-uNormally, if fastbind detects any unsatisfied symbols while building the fastbind information, it generates an error message and does not modify the executable file. When you invoke fastbind with the -u option however, it allows unresolved symbols.
The 32-bit mode fastbind command does not work with EXEC_MAGIC executables. The fastbind command effectively enforces the binding modes bind-restricted and bind-immediate.
For example, consider an executable linked bind-deferred, which calls a function foo() defined in an implicitly loaded library. Before the actual call is made, if it explicitly loads a shared library (using shl_load(3X) with BIND_FIRST) having a definition for foo() when foo() is finally called, it is resolved from the explicitly-loaded library. But after running fastbind, the symbol foo() is resolved from the implicitly-loaded library.
For more information about fastbind and performance, see “Improving Shared Library Start-Up
Time with fastbind” (page 222) .
Example 14 Improving Program Start-up with fastbind(1)
To run fastbind on the executable file a.out:
$ fastbind a.out
To remove the fastbind information from the executable file a.out:
$ fastbind -n a.out

Finding Object Library Ordering Relationships with lorder(1)

The lorder command finds the ordering relation for an object library. You can specify one or more object or archive library files (see ar(1)) on the command line or read those files from standard input. The standard output is a list of pairs of object file names, meaning that the first file of the pair refers to external identifiers defined in the second.
You can process the output with tsort to find an ordering of a library suitable for one-pass access by ld (see tsort(1) and ld(1)). The linker ld is capable of multiple passes over an archive in the archive format and does not require that you use lorder when building an archive. Using the lorder command may, however, allow for a slightly more efficient access of the archive during the link-edit process.
The symbol table maintained by ar allows ld to randomly access symbols and files in the archive, making the use of lorder unnecessary when building archive libraries (see ar(1)).
Finding Object Library Ordering Relationships with lorder(1) 77
The lorder command overlooks object files whose names do not end with .o, even when contained in library archives, and attributes their global symbols and references to some other file.
Example 15 Finding Object Library Ordering Relationships with lorder(1)
Build a new library from existing .o files:
$ ar cr library `lorder *.o | tsort`
When creating libraries with so many objects that the shell cannot properly handle the *.o
expansion, the following method may prove useful:
$ ls |grep '.o$'|lorder|tsort|xargs ar cq library
78 Linker Tools for PA-RISC Systems
5 Linker Toolset Differences Between PA-RISC and
Itanium-Based Systems
This chapter describes some of the linker toolset differences between PA-RISC and Itanium-based systems. This chapter discusses the following topics:
“Linker Toolset Compatibility with De Facto Industry Standards” (page 79)
“PA-RISC Changes in Hardware Compatibility” (page 79)
“Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)” (page 80)
“Run-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)” (page 82)
“PA64 Mode Linker Options” (page 82)
“Linker-Defined Symbols” (page 82)
“Dynamic Path Searching for Shared Libraries” (page 83)
“System Libraries - Locations and Library Name Extension” (page 87)

Linker Toolset Compatibility with De Facto Industry Standards

The HP-UX linker and dynamic loader provide linking and loading behaviors found widely across the Unix industry (SVR4 (System V Release 4) standards). The following linker behaviors are compliant with de facto industry standard:
ELF object file format and libelf(3E) routines
Dynamic path searching
Library-level versioning
The dl* family of dynamic loading routines
Breadth-first symbol searching
The HP-UX 11i v1.5 release maintains the following compatibility behaviors to make transition from PA-32 to IPF mode easier:
Creation of default run-time path environment variable (RPATH) if no ld +b is seen on the link
line, to improve transition from the PA-32 linker.
Theld +compat option for compatibility with PA-32 linking and loading behavior.

ELF Object File Format

Starting with the HP-UX 11.0 release, the linker toolset supports the ELF (executable and linking format) object file format. The linker toolset provides new tools to display and manipulate ELF files. The libelf(3E) library routines provide access to ELF files. The command elfdump(1) displays contents of an ELF file. For more information about the structure of ELF object files, see the HP-UX Software Transition Kit (STK) available at:
http://devrsrc1.external.hp.com/STK/index.html

PA-RISC Changes in Hardware Compatibility

The HP-UX 10.20 release introduced HP 9000 systems based on the PA-RISC 2.0 architecture. Also, beginning with that release, HP compilers by default generate executable code for the PA-RISC architecture of the machine on which you are compiling. In previous releases, the compilers generated PA-RISC 1.0 code on all HP 9000 Series 800 servers and PA-RISC 1.1 code on Series 700 workstations. HP compilers now, by default, generate PA-RISC 1.1 code on 1.1 systems and
2.0 code on 2.0 systems. Using the +DAportable compiler option provides compatibility of code between PA-RISC 1.1 and 2.0 systems. Note that the HP-UX 10.10 release is the last supported
Linker Toolset Compatibility with De Facto Industry Standards 79
release for PA-RISC 1.0 systems, so code generated by the HP-UX 10.20 release of HP compilers is not supported on PA-RISC 1.0 systems.
NOTE: The +DA1.0 option will be obsolete in a future release. You can achieve better
performance on PA-RISC 1.1 and 2.0 systems by not using this option.

PA-RISC 2.0 Compatibility

The instruction set on PA-RISC 2.0 is a superset of the instruction set on PA-RISC 1.1. As a result, code generated for PA-RISC 1.1 systems run on PA-RISC 2.0 systems. However, code generated for PA-RISC 2.0 systems does not run on PA-RISC 1.1 or 1.0. If you have enabled the +vcompatwarnings, the linker displays the following hardware compatibility warning whenever it links in any PA-RISC 2.0 object files:
/usr/ccs/bin/ld: (Warning) At least one PA 2.0 object file (sum.o) was detected. The linked output may not run on PA 1.x system.
If you try to run a PA-RISC 2.0 program on a 1.1 system, you see a message like:
$ a.out ksh: ./a.out: Executable file incompatible with hardware
In this example, the +DAportable compiler option can be used to create code compatible with PA-RISC 1.1 and 2.0 systems.

PA-RISC Architectures and Their System Models

The HP 9000 PA-RISC (Precision Architecture Reduced Instruction Set Computing) Series 700/800 family of workstations and servers has evolved from the following versions of PA-RISC architecture:
Table 13 Versions of PA-RISC architecture
PA-RISC 1.0
PA-RISC 1.1
PA-RISC 2.0
The original version of PA-RISC was first introduced on Series 800 servers. The following Series were included: 840, 825, 835/SE, 845/SE, 850, 855, 860, 865, 870/x00, 822, 832, 842, 852, 890, 808, 815, 635, 645.
The second version of PA-RISC was first introduced on Series 700 workstations. Newer Series 800 systems also use this version of the architecture. The following Series were included: 700, 705, 710, 712, 715, 720, 725, 730, 735, 750, 755, B132L, B160L, B132L+, B180L, C100, C110, J200, J210, J210XC, 742i, 742rt, 743i, 743rt, 745i, 747i, 748i, 8x7, D (except Dx70, Dx80), E, F, G, H, I, K (except Kx50, Kx60, Kx70), T500, T520.
This is the latest version of PA-RISC. The following Series are included: B2600/C3000, C160, C180, C180XP, C200, C240, J280, J282, J2240, Dx70, Dx80, Kx50, Kx60, Kx70, T600, V2200.
For More Information
See your compiler online help or documentation for more information on the +DA option.
See the file /opt/langtools/lib/sched.models for a complete list of model numbers
and their architectures. Use the command model to determine the model number of your system.

Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)

This section summarizes the significant PA32 (System Object Module (SOM) file) features, behavior, and options that linker does not support in PA64 mode and Itanium-based 32-bit and 64-bit mode (Executable and Linking Format (ELF) file format). The following table summarizes the differences in option, behavior, and toolset between PA-32 and IPF/PA-64 bit modes (IPF (64-bit and 32-bit) and PA-64):
80 Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
Table 14 Differences in options between PA-32 and IPF/PA-64 bit modes
DescriptionOption
Specifies incremental loading. IPF applications must use shared libraries instead.-A name
Does parameter type checking. This option is unsupported.-C n
Generates an initial program loader header file. This option is unsupported.-S
-T
-q, -Q, -n
-N
+objdebug mode
+nosrcpos
Save data and relocation information in temporary files to reduce virtual memory requirements during linking. This option is unsupported.
Generates an executable with file type DEMAND_MAGIC, EXEC_MAGIC, and SHARE_MAGIC respectively. These options have no effect and are ignored in IPF (32 bit and 64 bit) and PA-64.
Causes the data segment to be placed immediately after the text segment. This option is accepted but ignored in 64-bit mode. If this option is used because your application data segment is large, then the option is no longer needed in 64-bit mode. It can be used in 32-bit and IPF applications. If this option is used because your program is used in an embedded system or other specialized application, consider using mapfile support with the -k option.
Specifies pathname for compiling I-SOMs to SOMs. This option is unsupported.+cgpathname
In IPF (32-bit and 64-bit), the compiler option +objdebug is the default. When used with
-g, the +objdebugoption leaves debug information in the object files instead of copying it to the executable file at link time, resulting in shorter link times and smaller executables. The +noobjdebug option can be used to override the +objdebug option and copy all debug information to the executable file.
In IPF (32-bit and 64-bit), the +srcpos option is the default. The +srcpos option causes the compiler to generate part of the debug information even when the -g compiler option is not specified. The +srcpos option also causes part of the debug information to be always copied over to the executable file resulting in larger executables. The +srcpos option enables users to profile programs using tools like CXperf and HP Caliper, or compiler options like +I and +P, even in the absence of -g compilation. The linker option +nosrcpos can be used to override the +srcpos option and strip the associated debug information during link time. The +nosrcpos option can also be used with -g+objdebug to fully enforce the +objdebug mode (i.e., leaving the debug information in the object files).
Table 15 Differences in behavior between PA-32 and IPF/PA-64 bit modes
DescriptionBehavior
Share library suffix
Intra-library versioning
Duplicate code and data symbols
In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix.
Specified by using the HP_SHLIB_VERSION pragma (C and aC++) or SHLIB_VERSION directive (Fortran90). In PA-32 mode, the linker lets you version your library by object files. IPF or PA-64 applications must use SVR4 library-level versioning instead.
Code and data cannot share the same namespace in IPF mode. You must rename the conflicting symbols.
These options are unsupported.All internal and undocumented linker options
Table 16 Differences in Toolset between PA-32 and IPF/PA-64 bit modes
DescriptionToolset
The odump tool that displays information about a SOM object file is not supported.odump
Link-time Differences Between SOM (PA32) and ELF (PA64 and Itanium) 81

Run-time Differences Between SOM (PA32) and ELF (PA64 and Itanium)

IPF applications (32-bit and 64-bit) and PA-64 applications use a run-time dynamic loading model similar to other SVR4 systems. Following are two main areas where the IPF/PA-64 program startup differs from PA 32-bit mode:
Table 17 Main areas where the IPF/PA-64 program startup differs from PA 32-bit mode
libraries
Run time path environment variables
+bpath_list and -Ldirectories interaction

PA64 Mode Linker Options

This section describes the PA64 mode linker options.
Table 18 PA64 mode linker options
ActionOption
-dynamic
Forces the linker to create a shared executable. The linker looks for shared libraries first and then archived libraries. This option is on by default when you compile in PA64 mode.
PA-32 Mode BehaviorLinker and Loader Functions
Ordering is significant.+s and +bpath_list ordering
Depth-first search order.Symbol searching in dependent
No run time environment variables by default. If +s is specified, then
SHLIB_PATH is available.
-Ldirectories recorded as absolute
paths in executables.
IPF (32-bit and 64-bit) and PA-64 Mode
Behavior
Ordering is insignificant by default. Use +compat to enforce ordering.
Breadth-first search order. Use +compat to enforce depth first ordering.
LD_LIBRARY_PATH and SHLIB_PATH are enabled by default. Use +noenvvar or +compat to turn off run-time path environment variables.
-Ldirectories are not recorded in executables. Add all directories specified in
-L to +b path_list.
Forces the linker to create a fully bound archive program.-noshared
-k filename
+[no]allowunsats
+hideallsymbols
+nodefaultmap
+noenvvar
+std
Allows you to control the mapping of input section in the object file to segments in the output file.
Enables/disables forced loading of all the object files from archive libraries. The linker accepts but ignores this option in 32-bit mode. It creates an executable (a.out).
Hides all symbols from being exported.+compat
Instructs the linker not to load the default mapfile. See the -k option.+[no]forceload
Instructs the dynamic loader not to look at the LD_LIBRARY_PATH and SHLIB_PATH environment variables at runtime.
Instructs the dynamic loader not to look at the LD_LIBRARY_PATH and SHLIB_PATH environment variables at runtime.
Instructs the linker to use SVR4 compatible linking and loading behaviors. Default for PA64 mode.
Instructs the linker to use SVR4 compatible linking and loading behaviors. Default for PA64 mode.
Instructs the linker not to output the unwind table.+stripunwind
Produces verbose output about selected link operations.+vtype type

Linker-Defined Symbols

This section describes the symbol names that linker reserves in PA64 mode (ELF). If an application uses any of these symbols, linker displays an error message.
82 Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
Table 19 Symbol names
Largest architecture revision level used by any compilation unit__SYSTEM_ID
Initial value of FPU status register._FPU_STATUS
DefinitionSymbol
_end
__TLS_SIZE
Address of first byte following the end of the main program's data segment; identifies the beginning of the heap segment.
Size of the Thread Local Storage segment required by the program. This symbol is not reserved in PA32 (SOM).
Beginning of the text segment.__text_start
End of the text segment._etext
Beginning of the data segment.__data_start
End of initialized data._edata
Global pointer value. This symbol is not reserved in PA32 (SOM).__gp
Beginning of the .init section.__init_start
End of the .init section.__init_end
Beginning of the .fini section.__fini_start
End of the .fini section.__fini_end
Beginning of the unwind table. This symbol is not reserved in PA32 (SOM).__unwind_start
End of the unwind table. This symbol is not reserved in PA32 (SOM).__unwind_end

Dynamic Path Searching for Shared Libraries

Dynamic path searching is the process that enables you to specify the location of shared libraries at run time. In PA-32 mode, you can enable run-time dynamic path searching of shared libraries in the following ways:
By linking the program with +s, enabling the program to use the path list defined by the
SHLIB_PATH environment variable at run time.
By storing a directory path list in the program with the linker option +b path_list.
If +s or +b path_list is enabled, all shared libraries specified with the -l library or -l:library linker options are subject to a dynamic path lookup at run time.
In IPF, the dynamic path searching behavior has changed (same as PA-64 mode):
The +s dynamic path searching option is enabled by default. It is not enabled by default in
PA-32 mode.
The LD_LIBRARY_PATH environment variable is available in addition to the SHLIB_PATH
environment variable.
An embedded run-time path list called RUNPATH may be stored in the executable. If +b
path_list is specified at link time, these directories are added to RUNPATH. If +b path_list is not specified, the linker creates a default RUNPATH consisting of:
1. directories in the -L option (if specified), followed by
2. directories in the LPATH environment variable (if specified).
By default, the linker ignores the ordering of the +b path_list and +s options.
At run time, the dynamic loader searches directory paths in the following order:
dynamic path (if set using dlsetlibpath())1.
2. LD_LIBRARY_PATH (if set)
Dynamic Path Searching for Shared Libraries 83
3. SHLIB_PATH (if set)
4. RUNPATH
5. the default location /usr/lib/hpux32 for 32-bit programs and /usr/lib/hpux64
for 64-bit programs.
6. current working directory (dlopen and dlopene only)
84 Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
Example 16 Specifying library paths in PA-32 mode and IPF/PA-64 mode
The following are examples of specifying library paths in PA-32 mode and IPF/PA-64 mode (IPF (32-bit and 64-bit) and PA-64):
Linking to libraries by fully qualifying paths. The library does not contain SONAME specified
by the linker +h option when building the shared library: In this example, the program is linked with /opt/myapp/mylib.sl:
$ cc main.o /opt/myapp/mylib.sl
Perform 32-bit link.
$ cc +DD64 main.o /opt/myapp/mylib.sl
Perform 64-bit link.
At run-time, in both 32-bit and 64-bit mode, the dynamic loader only looks in /opt/myapp to find mylib.sl.
Linking to libraries using -l library or -l:library options:
In this example, the +s option is not explicitly enabled at link time. Both 32-bit and 64-bit versions of a shared library called libfoo.sl exist in the default location.
PA-32 and IPF 32-bit mode example:
$ cc main.o -lfoo -o main
Perform 32-bit link. With the +DD32 default, when linked in PA-32 mode, main aborts at run time if
libfoo.sl is moved from /usr/lib. This is because the absolute path name of the
shared library /usr/lib/libfoo.sl is stored in the executable. When linked in IPF 32-bit mode, main does not abort at run time if libfoo.sl is moved
from /usr/lib/hpux32 as long as LD_LIBRARY_PATH or SHLIB_PATH is set and point to libfoo.sl.
PA-64 and IPF 64-bit mode example:
$ cc +DD64 main.o -lfoo -o main
Perform 64-bit link.
When linked in IPF or PA-64 mode, main does not abort at run time if libfoo.sl is moved, as long as LD_LIBRARY_PATH or SHLIB_PATH is set and point to libfoo.sl.
Linking to libraries using -L and +b path_list:
The -L option is used by the linker to locate libraries at link time. The +b option is used to embed a library path list in the executable for use at run time.
PA-32, IPF 32-bit mode example:
$ cc main.o -L. -Wl,+b/var/tmp -lme
Link the program.
$ mv libme.sl /var/tmp/libme.sl
Move libme.sl.
$ a.out
Run the program.
Dynamic Path Searching for Shared Libraries 85
In PA-32 mode, the dynamic loader searches paths to resolve external references in the following order:
1. /var/tmp to find libme.sl found
2. /var/tmp to find libc.sl not found
3. /usr/lib/libc.sl found
In IPF 32-bit mode, the dynamic loader searches paths to resolve external references in the following order:
1. LD_LIBRARY_PATH (if set) to find libme.sl not found
2. SHLIB_PATH (if set) to find libme.sl not found
3. /var/tmp to find libc.sl not found
4. LD_LIBRARY_PATH (if set) to find libc.so not found
5. SHLIB_PATH (if set) to find libc.so not found
6. /var/tmp to find libc.so not found
7. /usr/lib/hpux32/libc.so found
PA-64, IPF 64-bit mode example:
$ cc +DD64 main.o -L. -Wl,+b/var/tmp -lme
Link the program.
$ mv libme.sl /var/tmp/libme.sl
Move libme.sl.
$ a.out
Run the program.
The dynamic loader searching order is the same in PA-64 and IPF (32-bit and 64-bit). The dynamic loader searches paths to resolve external references in the following order:
1. LD_LIBRARY_PATH (if set) to find libme.sl not found
2. SHLIB_PATH (if set) to find libme.sl not found
3. /var/tmp to find libme.sl found
4. LD_LIBRARY_PATH (if set) to find libc.so/libc.sl not found
5. /var/tmp to find libc.so/libc.sl not found
6. /var/tmp to find libc.so/libc.sl not found
7. /usr/lib/pa20_64/libc.sl (PA-64) or /usr/lib/hpux64/libc.so (IPF 64-bit) found

Symbol Searching in Dependent Libraries

In IPF (32-bit and 64-bit) and PA-64 mode, the dynamic loader searches shared libraries using a breadth-first search order. Breadth-first symbol searching is used on all SVR4 platforms.
86 Linker Toolset Differences Between PA-RISC and Itanium-Based Systems
In PA-32 mode, the dynamic loader searches shared libraries using a depth-first search order. The diagram below illustrates a sample program with shared libraries and compares the two search methods:
a.out | |-----------------| | | lib1 lib2 | lib3
Breadth-first search list: a.out -> lib1 -> lib2 -> lib3 Depth-first search list: a.out -> lib1 -> lib3 -> lib2 The commands to build the libraries and the executable in "Search Order of Dependent Libraries"
are shown:
$ ld -b lib2.o -o lib2.s $ ld -b lib3.o -o lib3.s $ d -b lib1.o -L. -l3 -o lib1.s $ cc main.o -Wl,-L. -l1 -l2 -o main
In PA-32 mode, if a procedure called same_name() is defined in both lib3 and lib2, main calls the procedure defined in lib3. In PA-64 and IPF (32-bit and 64-bit), main calls the procedure in lib2.

System Libraries - Locations and Library Name Extension

This section describes the system library locations and changes to the library name extension.

System Library Location

IPF HP-UX systems provide two new subdirectories called hpux32 and hpux64 under /usr/lib directory for IPF system and HP product libraries.
The diagram below shows the new directory structure:
/(root) | |-------------------------------------| | | opt usr | | application lib | | lib |----------|---------| | | | |----|-----| hpux32 hpux64 hpux32 hpux64
The linker automatically finds the correct set of system libraries depending on whether the application is compiled as a 32-bit or 64-bit application. Library providers are encouraged to supply both 32-bit and 64-bit versions of application libraries. Be sure to develop a strategy for library naming conventions, directory structures, link-time options, and run-time environment variables.

Shared Library Extension (suffix)

IPF (32-bit and 64-bit) shared libraries are suffixed with .so while the PA-RISC shared libraries are suffixed with .sl. The IPF linker supports shared libraries with both .so and .sl extension.
For example, /usr/lib/hpux32/libc.so is the IPF system 32-bit C library whereas /usr/lib/libc.sl is the PA-RISC system 32-bit C library.
System Libraries - Locations and Library Name Extension 87

Statically-bound programs (archive-bound programs)

Use the compiler -complete option or the linker -noshared option to create a statically-bound program. The default is -dynamic.
Statically-bound programs are not supported on IPF. Most IPF (32-bit and 64-bit) system libraries, including libc, are only available as shared libraries.
88 Linker Toolset Differences Between PA-RISC and Itanium-Based Systems

6 Creating and Using Libraries

Many libraries come with HP-UX. You can also create and use your own libraries on HP-UX. This chapter discusses the following topics:
General Information About Shared and Archive Libraries
“Overview of Shared and Archive Libraries” (page 89)
“What are Archive Libraries?” (page 90)
“What are Shared Libraries?” (page 91)
“Example Program Comparing Shared and Archive Libraries” (page 92)
“Shared Libraries with Debuggers, Profilers, and Static Analysis” (page 94)
Creating Libraries on HP-UX
“Creating Archive Libraries” (page 94)
“Creating Shared Libraries” (page 98)
Using Libraries on HP-UX
“Version Control with Shared Libraries” (page 110)
“Switching from Archive to Shared Libraries” (page 115)
“Summary of HP-UX Libraries” (page 117)
“Caution When Mixing Shared and Archive Libraries” (page 118)
“Using Shared Libraries in Default Mode” (page 124)
“Internal Name Processing” (page 125)
“Dynamic Path Searching for Shared Libraries” (page 126)
“Shared Library Symbol Binding Semantics” (page 126)
“Mixed Mode Shared Libraries” (page 130)
“IPF Library Examples” (page 131)

Overview of Shared and Archive Libraries

HP-UX supports two kinds of libraries: archive and shared. A shared library is also called a dll (dynamically linked library). Archive libraries are the more traditional of the two, but use of shared libraries has increased dramatically, and is the preferred method. The following table summarizes differences between archive and shared libraries.
Table 20 Differences between archive and shared libraries
creation
Suffix is .a.file name suffix
command
Shared (or dll)ArchiveComparing
Suffix is .sl or .<version> on PA systems and .so or .so.<version> on Itanium-based systems, where version is the version number of the library.
Combine object files with the ld commandCombine object files with the ar
Overview of Shared and Archive Libraries 89
Table 20 Differences between archive and shared libraries (continued)
Shared (or dll)ArchiveComparing
address binding
a.out files
run time
Addresses of library subroutines and data are resolved at link time.
Contains all library routines or data (external references)
a.out file that does not use
complete executable.
Each program has its own copy of archive library routines.
Addresses of library subroutines are bound at run time. Addresses of data in a.out are bound at link time; addresses of data in shared libraries are bound at run time.
Does not contain library routines; instead, contains a linkage table that is filled in with the addresses of routines and shared library data. An a.out that uses shared libraries is knownreferenced in the program. An as an incomplete executable, and is almost always much smaller than a complete executable.shared libraries is known as a
Shared library routines are shared among all processes that use the library.
In Itanium-based systems, some of the system libraries are available both as a shared library and as an archive library for 32-bit executables in the directory /usr/lib/hpux32/ and for 64-bit executables in /usr/lib/hpux64/. Archive library file names end with .a whereas shared library file names end with .so. For example, for 32-bit executables, the archive math library libm is /usr/lib/hpux32/libm.a and the shared version is /usr/lib/hpux32/libm.so. For 64-bit executables, the archive math library libm is /usr/lib/hpux64/libm.a and the shared version is /usr/lib/hpux64/libm.so If both shared and archived versions of a library exist, ld uses the one that it finds first in the default library search path. If both versions exist in the same directory, ld uses the shared version. For example, compiling the C program prog.c causes cc to invoke the linker with a command like this:
For 32-bit mode: ld prog.o -lc
For 64-bit mode: ld prog.o -lc
The -lc option instructs the linker to search the C library, hpux32/libc or hpux64/libc, to resolve unsatisfied references from prog.o. If a shared libc exists (/usr/lib/hpux32/libc.so or /usr/lib/hpux64/libc.so), ld uses it instead of the archive libc (/usr/lib/hpux32/libc.a or /usr/lib/hpux64/libc.a). You can, however, override this behavior and select the archive version of a library with the -a option or the -l: option. These are described in “Choosing Archive or Shared Libraries with -a” (page
36)and “Specifying Libraries with -l and -l:” (page 45) . In addition to the system libraries provided
on HP-UX, you can create your own archive and shared libraries. To create archive libraries, combine object files with the ar command, as described in “Overview of Creating an Archive
Library” (page 95) . To create shared libraries, use ld to combine object files as described in “Creating Shared Libraries” (page 98). For more information, see “Caution When Mixing Shared and Archive Libraries” (page 118) .

What are Archive Libraries?

An archive library contains one or more object files, and is created with the ar command. When linking an object file with an archive library, ld searches the library for global definitions that match with external references in the object file. If a match is found, ld copies the object file containing the global definition from the library into the a.out file. In short, any routines or data a program needs from the library are copied into the resulting a.out file. Example For example, suppose you write a C program that calls printf from the libc library. Figure 6 (page 91) shows how the resulting a.out file looks if you linked the program with the archive version of libc.
90 Creating and Using Libraries
Figure 6 Linking with an Archive Library

What are Shared Libraries?

Like an archive library, a shared library contains object code. However, ld treats shared libraries quite differently from archive libraries. When linking an object file with a shared library, ld does not copy object code from the library into the a.out file; instead, the linker simply notes in the a.out file that the code calls a routine in the shared library. An a.out file that calls routines in a shared library is known as an incomplete executable.

The Dynamic Loader

When an incomplete executable begins execution, the HP-UX dynamic loader looks at the a.out file to see what libraries the a.out file needs during execution.
The kernel activates the dynamic loader for an a.out.The dynamic loader then loads and maps any required shared libraries into the process's address space - known as attaching the libraries. A program calls shared library routines indirectly through a linkage table that the dynamic loader fills in with the addresses of the routines. By default, the dynamic loader places the addresses of shared library routines in the linkage table as the routines are called - known as deferred binding. Immediate binding is also possible - that is, binding all required symbols in the shared library at program startup. In either case, any routines that are already loaded are shared.
Consequently, linking with shared libraries generally results in smaller a.out files than linking with archive libraries. Therefore, a clear benefit of using shared libraries is that it can reduce disk space and virtual memory requirements.
NOTE: In prior releases, data defined by a shared library was copied into the program file at
link time. All references to this data, both in the libraries and in the program file, referred to the copy in the executable file. With the HP-UX 10.0 release, however, this data copying is eliminated. Data is accessed in the shared library itself. The code in the executable file references the shared library data indirectly through a linkage pointer, in the same way that a shared library references the data.

Default Behavior When Searching for Libraries at Run Time

If the dynamic loader cannot find a shared library from the list by default, it generates a run-time error and the program aborts. In PA-32 compatibility mode (with +compat), for example, suppose that during development, a program is linked with the shared library liblocal.so in your current working directory (say, /users/hyperturbo):
$ ld /usr/lib/hpux32/crt0.o prog.o -lc liblocal.so
In PA-32 mode, the linker records the path name of liblocal.so in the a.out file as /users/hyperturbo/liblocal.so. When shipping this application to users, you must ensure
that (1) they have a copy of liblocal.so on their system, and (2) it is in the same location as
What are Shared Libraries? 91
it was when you linked the final application. Otherwise, when the users of your application run it, the dynamic loader looks for /users/hyperturbo/liblocal.so, fail to find it, and the program aborts.
In default mode, the linker records ./liblocal.so. This is more of a concern with non-standard libraries-that is, libraries not found in
/usr/lib/hpux32 or /usr/lib/hpux64. There is little chance of the standard libraries not being in these directories.

Caution on Using Dynamic Library Searching

If different versions of a library exist on your system, be aware that the dynamic loader may get the wrong version of the library when dynamic library searching is enabled with SHLIB_PATH or
+b. For instance, you may want a program to use the PA1.1 libraries found in the /usr/lib/pa1.1 directory; but through a combination of SHLIB_PATH settings and +b options,
the dynamic loader ends up loading versions found in /usr/lib instead. If this happens, make sure that SHLIB_PATH and +b are set to avoid such conflicts.

Running setuid Programs

If SHLIB_PATH and LD_LIBRARY_PATH are set for setuid programs, the loader validates the contents of the environment variables SHLIB_PATH and LD_LIBRARY_PATH against the contents of the configuration file/etc/dld.sl.conf. The loader validates the contents only if:
1. The conf file is present
2. The conf file fulfils the following conditions:
The superuser owns the conf file.
Appropriate permissions are granted, that is, the conf file is writable only by the superuser.
The conf file contains a list of absolute shared library search paths.
Spaces are not present in the paths listed. The loader ignores everything on a line that
follows a space or # character. You can use the # character to comment out paths in the conf file.
NOTE: The dld provides support for using $ORIGIN string in the embedded paths for setuid
programs.
If SHLIB_PATH / LD_LIBRARY_PATH contains any of the paths listed in the conf file, the loader uses the paths in the order they are specified in the environment variables. If the contents of the environment variables and the contents of the conf file do not overlap, the dynamic path lookup is disabled and the search is restricted to the embedded path (RPATH). You can turn off this feature by setting the environment variable _HP_DLDOPTS to -no_setuidpath. If you turn off this feature, setuid programs do not carry out dynamic path searching.
NOTE: The configuration file /etc/dld.sl.conf must contain a list of shared library search
paths (delimited by either colon or newline characters). Any relative paths (paths not starting with /) in the path list is ignored by the loader. To avoid redundant searches, ensure that a path appears only once in the file and only once in the option SHLIB_PATH/LD_LIBRARY_PATH. For PA32, this feature is enabled only if the /etc/dld.sl.conf file is present. The default behavior of honoring these environment variables for setuid programs remains unchanged.

Example Program Comparing Shared and Archive Libraries

As an example, suppose two separate programs, prog1 and prog2, use shared libc routines heavily. Suppose that the a.out portion of prog1 is 256Kb in size, while the a.out portion of prog.2 is 128Kb. Assume also that the shared libc is 512Kb in size. Figure 7 (page 93) shows how physical memory might look when both processes run simultaneously. Notice that one copy of libc
92 Creating and Using Libraries
is shared by both processes. The total memory requirement for these two processes running simultaneously is 896Kb (256Kb + 128Kb + 512Kb).
Figure 7 Two Processes Sharing libc
Compare this with the memory requirements if prog1 and prog2 are linked with the archive version of libc. As shown in Figure 8 (page 93), 1428Kb of memory is required (768Kb + 640Kb). The numbers in this example are made up, but it is true in general that shared libraries reduce memory requirements.
Figure 8 Two Processes with Their Own Copies of libc
Example Program Comparing Shared and Archive Libraries 93

Shared Libraries with Debuggers, Profilers, and Static Analysis

Debugging of shared libraries is supported by the by the WDB Debugger. See the WDB documentation at: http://www.hp.com/go/wdb

Profiling Shared Libraries with gprof(1)

The gprof tool produces an execution profile about an executable for application programs and shared libraries. See gprof(1) for more information. Use the following steps to profile a shared library:
Set the environment variable LD_PROFILE to the shared library name.
Link the application which links with the library to be profiled to take one of the following
actions:
Link with libc.sl.
Export all the symbols explicitly (with the ld +e option).
This is primarily for registration of the exit handler. You can only profile a single shared library. You can profile either the application or a shared library. However, you cannot profile both the application and the shared library together. To profile applications, continue to use the existing gprof method, in which you compile with -G option, but do not set LD_PROFILE. For example, to profile the shared library test.sl:
Set the environment variable LD_PROFILE to specify your shared library.
$ LD_PROFILE=test.sl $ export LD_PROFILE
If a.out is linked to test.sl, execute a.out.
$ a.out
This step creates the file <shared_library>.profile (where shared_library is the name of the shared library specified by the LD_PROFILE environment variable) at run time. This file contains the profile information for the shared library. For this example, the file test.sl.profile is created.
To get the complete profile information about test.sl, run the gprof command:
$ gprof test.sl test.sl.profile
The following are the limitations for profiling shared library using gprof:
Local, static, and hidden functions are not profiled.
Shared libraries built with -B symbolic are not profiled.
Any function calls made from library initializers are not collected.

Creating Archive Libraries

1. Compile one or more source files to create object files containing relocatable object code.
2. Combine these object files into a single archive library file with the ar command.
Following are the commands you can use to create an archive library called libunits.a:
$ cc -Aa -c length.c volume.c mass.c $ ar r libunits.a length.o volume.o mass.o
These steps are described in detail in “Overview of Creating an Archive Library” (page 95). Other topics relevant to archive libraries are:
“Contents of an Archive File” (page 95)
“Example of Creating an Archive Library” (page 96)
94 Creating and Using Libraries
“Replacing, Adding, and Deleting an Object Module” (page 97)
“Summary of Keys to the ar(1) Command” (page 97)
“Archive Library Location (IPF) ” (page 98)

Overview of Creating an Archive Library

To create an archive library:
1. Create one or more object files containing relocatable object code. Typically, each object file
contains one function, procedure, or data structure, but an object file can have multiple routines and data.
2. Combine these object files into a single archive library file with the ar command. Invoke ar
with the r key.
("Keys" are like command line options, except that they do not require a preceding -.)
Figure 9 (page 95) summarizes the procedure for creating archive libraries from three C source
files (file1.c, file2.c, and file3.c). The process is identical for other languages, except that you use a different compiler.
Figure 9 Creating an Archive Library

Contents of an Archive File

An archive library file consists of four main components:
1. A header string, "!<arch>\n", identifying the file as an archive file created by ar (\n
represents the newline character)
2. A symbol table, used by the linker and other commands to find the location, size, and other
information for each routine or data item contained in the library
3. An optional string table used by the linker to store file names that are greater than 15 bytes
long (only created if a long file name is encountered)
4. Object modules, one for each object file specified on the ar command line
To see what object modules a library contains, run ar with the t key, which displays a table of contents. For example, to view the "table of contents" for libm.a:
$ ar t /usr/lib/hpux32/libm.a //Run ar with the t key.
Creating Archive Libraries 95
acosh.o //Object modules are displayed.
erf.o fabs.o
. . . .
This indicates that the library was built from object files named acosh.o, erf.o, fabs.o, and so forth. In other words, module names are the same as the names of the object files from which they were created.

Example of Creating an Archive Library

Suppose you are working on a program that does several conversions between English and Metric units. The routines that do the conversions are contained in three C-language files. Following are the three C-language files:
length.c - Routine to Convert Length Units
float in_to_cm(float in) /* convert inches to centimeters */ { return (in * 2.54); }
volume.c - Routine to Convert Volume Units
float gal_to_l(float gal) /* convert gallons to liters */ { return (gal * 3.79); }
mass.c - Routine to Convert Mass Units
float oz_to_g(float oz) /* convert ounces to grams */ { return (oz * 28.35); }
During development, each routine is stored in a separate file. To make the routines easily accessible to other programmers, they must be stored in an archive library. To do this, first compile the source files, either separately or together on the same command line:
$ cc -Aa -c length.c volume.c mass.c Compile them together. length.c: volume.c: mass.c: $ ls *.o List the .o files. length.o mass.o volume.o
Then combine the .o files by running ar with the r key, followed by the library name (say libunits.a), followed by the names of the object files to place in the library:
$ ar r libunits.a length.o volume.o mass.o ar: creating libunits.a
To verify that ar created the library correctly, view its contents:
$ ar t libunits.a Use ar with the t key. length.o volume.o mass.o All the .o modules are included; it worked.
Now suppose you have written a program, called convert.c, which calls several of the routines in the libunits.a library. You can compile the main program and link it to libunits.a with the following cc command:
$ cc -Aa convert.c libunits.a
96 Creating and Using Libraries
Note that the whole library name was given, and the -l option was not specified. This is because the library was in the current directory. If you move libunits.a to /usr/lib/hpux32 (IPF 32-bit mode) or /usr/lib (PA32 mode) before compiling, the following command line works instead:
$ cc -Aa convert.c -lunits
Linking with archive libraries is covered in detail in “Determining How to Link Programs or Libraries
(Linker Tasks)” (page 27).

Replacing, Adding, and Deleting an Object Module

Occasionally you may want to replace an object module in a library, add an object module to a library, or delete a module completely. For instance, suppose you add some new conversion routines to length.c (defined in the previous section), and want to include the new routines in the library libunits.a. You must then replace the length.o module in libunits.a.
Replacing or Adding an Object Module
To replace or add an object module, use the r key (the same key you use to create a library). For example, to replace the length.o object module in libunits.a:
$ ar r libunits.a length.o
Deleting an Object Module
To delete an object module from a library, use the d key. For example, to delete volume.o from libunits.a:
$ ar d libunits.a volume.o Delete volume.o. $ ar t libunits.a List the contents. length.o mass.o volume.o is gone.

Summary of Keys to the ar(1) Command

When used to create and manage archive libraries, the syntax of ar is:
ar [-] keys archive [modules] ...
IN the syntax, archive is the name of the archive library, modules is an optional list of object modules or files. See ar(1) for the complete list of keys and options.
Useful ar Keys
Here are some useful ar keys and their modifiers:
Table 21 Useful ar Keys
Delete the modules from the archive.d
r
u
x
Replace or add the modules to the archive. If archive exists, ar replaces modules specified on the command line. If archive does not exist, ar creates a new archive containing the modules.
Display a table of contents for the archive.t
Used with the r, this modifier tells ar to replace only those modules with creation dates later than those in the archive.
Display verbose output.v
Extracts object modules from the library. Extracted modules are placed in .o files in the current directory. Once an object module is extracted, you can use nm to view the symbols in the module.
Descriptionkey
For example, when used with the v flag, the t flag creates a verbose table of contents - including such information as module creation date and file size:
Creating Archive Libraries 97
$ ar tv libunits.a rw-rw-rw- 265/ 20 230 Feb 2 17:19 1990 length.o rw-rw-rw- 265/ 20 228 Feb 2 16:25 1990 mass.o rw-rw-rw- 265/ 20 230 Feb 2 16:24 1990 volume.o
The next example replaces length.o in libunits.a, only if length.o is more recent than the one already contained in libunits.a:
$ ar ru libunits.a length.o
crt0.o
The crt0.o startup file is not needed for shared bound links because dld.so does some of the startup duties previously done by crt0.o. However, you still need to include crt0.o on the link line for all fully archive links (ld -noshared). In PA-32 mode, crt0.o must always be included on the link line.
Users who link by letting the compilers such as cc invoke the linker do not have to include crt0.o on the link line.

Archive Library Location (IPF)

After creating an archive library, you can save it in a location that is easily accessible to other programmers who may want to use it. There are two main choices for places to put the library:
in the 32-bit /usr/lib or 64-bit /user/lib/pa20_64 directory
in the 32-bit /usr/local/lib or /usr/contrib/lib directory
Using /usr/lib and /usr/lib/pa20_64
Because the linker searches /usr/lib or /usr/lib/pa20_64 by default, you may put your archive libraries in /usr/lib or /usr/lib/pa20_64 and thereby eliminate the task of entering the entire library path name each time you compile or link.
The drawbacks of putting the libraries in /usr/lib or /usr/lib/pa20_64 are:
You usually need super-user (system administrator) privileges to write to the directory.
You may inadvertently overwrite an HP-UX system library that resides in the directory.
Check with your system administrator before attempting to use /usr/lib or /usr/lib/pa20_64.
Using /usr/local/lib or /usr/contrib/lib
The /usr/local/lib and /usr/local/lib/pa20_64 library typically contain libraries created locally - by programmers on the system; /usr/contrib/lib and /usr/contrib/lib/pa20_64contain libraries supplied with HP-UX but not supported by HP. Programmers can create their own libraries for both 32-bit and 64-bit code using the same library name. Although ld does not automatically search these directories, they are still the best choice for locating user-defined libraries because the directories are not write-protected. Therefore, programmers can store the libraries in these directories without super-user privileges. Use
-L/usr/local/lib or -L/usr/contrib/lib for 32-bit libraries, or
-L/usr/local/lib/pa20_64 or -L/usr/contrib/lib/pa20_64 for 64-bit libraries to tell
the linker to search these directories.

Creating Shared Libraries

Two steps are required to create a shared library:
1. Compile one or more source files to create object files. In PA-32 mode, it is necessary to use
the +Z compiler option to create position-independent code.
2. “Creating the Shared Library with ld” (page 99) by linking with -b.
98 Creating and Using Libraries
Following are the commands you can use to create a shared library called libunits.so:
$ cc -Aa -c +z length.c volume.c mass.c $ ld -b -o libunits.so length.o volume.o mass.o
Other topics relevant to shared libraries are:
“Shared Library Dependencies” (page 100)
“Updating a Shared Library” (page 102)
“Shared Library Location (IPF)” (page 102)
“Improving Shared Library Performance” (page 102)
“Function Level Versioning” (page 110)

Creating Position-Independent Code (PIC)

In PA-32 mode, the first step in creating a shared library is to create object files containing position-independent code (PIC). There are two ways to create PIC object files:
Compile source files with the +z or +Z compiler option, described below.
Write assembly language programs that use appropriate addressing modes, described in
“Writing and Generating Position-Independent Code” (page 185) .
In PA-32 mode, the +z and +Z options force the compiler to generate PIC object files. In PA-64 and IPF mode, the +Z option is the default.
Example Using +z
Suppose you have some C functions, stored in length.c, that convert between English and Metric length units. To compile these routines and create PIC object files with the C compiler, you can use this command:
$ cc -Aa -c +z length.c The +z option creates PIC.
You can then link it with other PIC object files to create a shared library, as discussed in “Creating
the Shared Library with ld” (page 99) .
Comparing +z and +Z
In PA-32 mode, the +z and +Z options are essentially the same. Normally, you compile with +z. However, in some instances - when the number of referenced symbols per shared library exceeds a predetermined limit - you must recompile with the +Z option instead. In this situation, the linker displays an error message and tells you to recompile the library with +Z.
In PA-64 and IPF mode, +Z is the default and the compilers ignore the options and generate PIC code.
Compiler Support for +z and +Z
In PA-32 mode, the C, C++, FORTRAN, and Pascal compilers support the +z and +Z options. In PA-64 and IPF mode, +Z is the default for the C and C++ compilers.

Creating the Shared Library with ld

To create a shared library from one or more PIC object files, use the linker, ld, with the -b option. By default, ld names the library a.out. You can change the name with the -o option.
For example, suppose you have three C source files containing routines to do length, volume, and mass unit conversions. They are named length.c, volume.c, and mass.c, respectively. To make a shared library from these source files, first compile all three files, then combine the resulting
.o files with ld. Following are the commands you can use to create a shared library named libunits.so:
Creating Shared Libraries 99
$ cc -Aa -c +z length.c volume.c mass.c length.c: volume.c: mass.c: $ ld -b -o libunits.so length.o volume.o mass.o
Once the library is created, ensure that it has read and execute permissions for all users who use the library. For example, the following chmod command allows read/execute permission for all users of the libunits.so library:
$ chmod +r+x libunits.so
This library can now be linked with other programs. For example, if you have a C program named convert.c that calls routines from libunits.so, you can compile and link it with the cc command:
$ cc -Aa convert.c libunits.so
In PA-32 mode, once the executable is created, the library must not be moved because the absolute path name of the library is stored in the executable. (In PA-64 and IPF mode, ./libunit.so is stored in the executable.) For details, see “Shared Library Location (IPF)” (page 102).
For details on linking shared libraries with your programs, see “Determining How to Link Programs
or Libraries (Linker Tasks)” (page 27).

Shared Library Dependencies

You can specify additional shared libraries on the ld command line when creating a shared library. The created shared library is said to have a dependency on the specified libraries, and these libraries are known as dependent libraries or supporting libraries. When you load a library with dependencies, all its dependent libraries are loaded too. For example, suppose you create a library named libdep.so using the command:
$ ld -b -o libdep.so mod1.o mod2.o -lcurses -lcustom
Thereafter, any programs that load libdep.so - either explicitly with dlopen or shl_load or implicitly with the dynamic loader when the program begins execution - also automatically load the dependent libraries libcurses.so and libcustom.so.
There are two additional issues that may be important to some shared library developers:
When a shared library with dependencies is loaded, in what order are the dependent libraries
loaded?
Where are all the dependent libraries placed in relation to other already loaded libraries?
That is, where are they placed in the process's shared library search list used by the dynamic loader?
The Order in Which Libraries are Loaded (Load Graph)
When a shared library with dependencies is loaded, the dynamic loader builds a load graph to determine the order in which the dependent libraries are loaded. For example, suppose you create three libraries - libQ, libD, and libP - using the ld commands below. The order in which the libraries are built is important because a library must exist before you can specify it as a dependent library.
$ ld -b -o libQ.so modq.o -lB $ ld -b -o libD.so modd.o -lQ -lB $ ld -b -o libP.so modp.o -lA -lD -lQ
The dependency lists for these three libraries are:
libQ depends on libB
libD depends on libQ and libB
libP depends on libA, libD, and libQ
100 Creating and Using Libraries
Loading...