search    
HP-UX Linker and Libraries User's Guide
Hewlett-Packard
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

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 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:

PA-RISC 1.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.

PA-RISC 1.1

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.

PA-RISC 2.0

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):

Option Description

-A name

Specifies incremental loading. IPF applications must use shared libraries instead.

-C n

Does parameter type checking. This option is unsupported.

-S

Generates an initial program loader header file. This option is unsupported.

-T

Save data and relocation information in temporary files to reduce virtual memory requirements during linking. This option is unsupported.

-q, -Q, -n

Generates an executable with file type DEMAND_MAGIC, EXEC_MAGIC, and SHARE_MAGIC respectively. These options have no effect and are ignored in IPF (32 bit and 64 bit) and PA-64.

-N

Causes the data segment to be placed immediately after the text segment. This option is accepted but ignored in 64-bit mode. If this option is used because your application data segment is large, then the option is no longer needed in 64-bit mode. 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.

+cg pathname

Specifies pathname for compiling I-SOMs to SOMs. This option is unsupported.

+objdebug mode 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.
+nosrcpos 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)

Behavior Description
Share library suffix 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. 

Intra-library versioning

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.

Duplicate code and data symbols

Code and data cannot share the same namespace in IPF mode. You must rename the conflicting symbols.

All internal and undocumented linker options

These options are unsupported.

Toolset Description
odump

The odump tool that displays information about a SOM object file is not supported. 

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:

  • Dynamic path searching for shared libraries.

  • Symbol searching in dependent libraries.

IHP recommends that you use the standard SVR4 linking option (+std), which is on by default when linking IPF (32-bit and 64-bit) and PA-64 applications. There can be circumstances, while you transition, you need PA-32-compatible linking behavior. The IPF and PA-64 linkers provides the mode +compat option to force the linker to use PA-32 linking and dynamic loading behavior.

The following table summarizes the dynamic loader differences between PA-32 and IPF/PA-64 bit modes (IPF (64-bit and 32-bit) and PA-64):

Linker and Loader Functions PA-32 Mode Behavior IPF (32-bit and 64-bit) and PA-64 Mode Behavior

+s and +b path_list ordering

Ordering is significant.

Ordering is insignificant by default. Use +compat to enforce ordering.

Symbol searching in dependent libraries

Depth-first search order.

Breadth-first search order. Use +compat to enforce depth first ordering.

Run time path environment variables

No run time environment variables by default. If +s is specified, then SHLIB_PATH is available.

LD_LIBRARY_PATH and SHLIB_PATH are enabled by default. Use +noenvvar or +compat to turn off run-time path environment variables.

+b path_list and -L directories interaction

-L directories recorded as absolute paths in executables.

-L directories are not recorded in executables. Add all directories specified in -L to +b path_list.

PA64 Mode Linker Options

This section describes the PA64 mode linker options.

Option Action
-dynamic

Forces the linker to create a shared executable. The linker looks for shared libraries first and then archived libraries. This option is on by default when you compile in PA64 mode.

-noshared

Forces the linker to create a fully bound archive program.

-k filename

Allows you to control the mapping of input section in the object file to segments in the output file.

+[no]allowunsats

Instructs the linker how to report errors for output files with unsatisfied symbols.

+compat

Instructs the linker to use 32-bit mode linking and dynamic loading behaviors.

+[no]forceload

Enables/disables forced loading of all the object files from archive libraries. The linker accepts but ignores this option in 32-bit mode. It creates an executable (a.out).

+hideallsymbols

Hides all symbols from being exported.

+nodefaultmap

Instructs the linker not to load the default mapfile. See the -k option.

+noenvvar

Instructs the dynamic loader not to look at the LD_LIBRARY_PATH and SHLIB_PATH environment variables at runtime.

+std

Instructs the linker to use SVR4 compatible linking and loading behaviors. Default for PA64 mode.

+stripunwind

Instructs the linker not to output the unwind table.

+vtype type

Produces verbose output about selected link operations.

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.

Symbol Definition
__SYSTEM_ID

Largest architecture revision level used by any compilation unit

_FPU_STATUS

Initial value of FPU status register.

_end

Address of first byte following the end of the main program's data segment; identifies the beginning of the heap segment.

__TLS_SIZE

Size of the Thread Local Storage segment required by the program. This symbol is not reserved in PA32 (SOM).

__text_start

Beginning of the text segment.

_etext

End of the text segment.

__data_start

Beginning of the data segment.

_edata

End of initialized data.

__gp

Global pointer value. This symbol is not reserved in PA32 (SOM).

__init_start

Beginning of the .init section.

__init_end

End of the .init section.

__fini_start

Beginning of the .fini section.

__fini_end

End of the .fini section.

__unwind_start

Beginning of the unwind table. This symbol is not reserved in PA32 (SOM).

__unwind_end

End of the unwind table. This symbol is not reserved in PA32 (SOM).

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:

    1. dynamic path (if set using dlsetlibpath())

    2. LD_LIBRARY_PATH (if set)

    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)

Examples

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.

      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. SHLIB_PATH (if set) 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.

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.


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.