JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Linker and Libraries Guide     Oracle Solaris 10 1/13 Information Library
search filter icon
search icon

Document Information

Preface

Part I Using the Link-Editor and Runtime Linker

1.  Introduction to the Oracle Solaris Link Editors

2.  Link-Editor

3.  Runtime Linker

4.  Shared Objects

Part II Quick Reference

5.  Link-Editor Quick Reference

Part III Advanced Topics

6.  Direct Bindings

Observing Symbol Bindings

Enabling Direct Binding

Using the -B direct Option

Using the -z direct Option

Using the DIRECT mapfile Keyword

Direct Bindings and Interposition

Localizing Symbol Instances

Removing Multiply Defined Symbols of the Same Name

Defining Explicit Interposition

Preventing a Symbol from being Directly Bound to

Using the -B nodirect Option

Using the NODIRECT mapfile Keyword

7.  Building Objects to Optimize System Performance

8.  Mapfiles

9.  Interfaces and Versioning

10.  Establishing Dependencies with Dynamic String Tokens

11.  Extensibility Mechanisms

Part IV ELF Application Binary Interface

12.  Object File Format

13.  Program Loading and Dynamic Linking

14.  Thread-Local Storage

Part V Appendices

A.  Linker and Libraries Updates and New Features

B.  System V Release 4 (Version 1) Mapfiles

Index

Observing Symbol Bindings

To understand the default symbol search model and compare this model with direct bindings, the following components are used to build a process.

$ cat main.c
extern int W(), X();

int main() { return (W() + X()); }

$ cat W.c
extern int b();

int a() { return (1); }
int W() { return (a() - b()); }

$ cat w.c
int b() { return (2); }

$ cat X.c
extern int b();

int a() { return (3); }
int X() { return (a() - b()); }

$ cat x.c
int b() { return (4); }

$ cc -o w.so.1 -G -Kpic w.c
$ cc -o W.so.1 -G -Kpic W.c -R. w.so.1
$ cc -o x.so.1 -G -Kpic x.c
$ cc -o X.so.1 -G -Kpic X.c -R. x.so.1
$ cc -o prog1 -R. main.c W.so.1 X.so.1

The components of the application are loaded in the following order.

$ ldd prog1
        W.so.1 =>        ./W.so.1
        X.so.1 =>        ./X.so.1
        w.so.1 =>        ./w.so.1
        x.so.1 =>        ./x.so.1

Both files W.so.1 and X.so.1 define a function that is named a(). Both files w.so.1 and x.so.1 define a function that is named b(). In addition, both files W.so.1 and X.so.1 reference the functions a() and b().

The runtime symbol search, using the default search model, together with the final binding, can be observed by setting the LD_DEBUG environment variable. From the runtime linkers diagnostics, the bindings to the functions a() and b() can be revealed.

$ LD_DEBUG=symbols,bindings prog1
.....
17375: symbol=a;  lookup in file=prog1  [ ELF ]
17375: symbol=a;  lookup in file=./W.so.1  [ ELF ]
17375: binding file=./W.so.1 to file=./W.so.1: symbol `a'
.....
17375: symbol=b;  lookup in file=prog1  [ ELF ]
17375: symbol=b;  lookup in file=./W.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./X.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./w.so.1  [ ELF ]
17375: binding file=./W.so.1 to file=./w.so.1: symbol `b'
.....
17375: symbol=a;  lookup in file=prog1  [ ELF ]
17375: symbol=a;  lookup in file=./W.so.1  [ ELF ]
17375: binding file=./X.so.1 to file=./W.so.1: symbol `a'
.....
17375: symbol=b;  lookup in file=prog1  [ ELF ]
17375: symbol=b;  lookup in file=./W.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./X.so.1  [ ELF ]
17375: symbol=b;  lookup in file=./w.so.1  [ ELF ]
17375: binding file=./X.so.1 to file=./w.so.1: symbol `b'

Each reference to one of the functions a() or b(), results in a search for the associated symbol starting with the application prog1. Each reference to a() binds to the first instance of the symbol which is discovered in W.so.1. Each reference to b() binds to the first instance of the symbol which is discovered in w.so.1. This example reveals how the function definitions in W.so.1 and w.so.1 interpose on the function definitions in X.so.1 and x.so.1. The existence of interposition is an important factor when considering the use of direct bindings. Interposition is covered in detail in the sections that follow.

This example is concise, and the associated diagnostics are easy to follow. However, most applications are far more complex, being constructed from many dynamic components. These components are frequently delivered asynchronously, having been built from separate source bases.

The analysis of the diagnostics from a complex process can be challenging. Another technique for analyzing the interface requirements of dynamic objects is to use the lari(1) utility. lari analyzes the binding information of a process together with the interface definitions provided by each object. This information allows lari to concisely convey interesting information about the symbol dependencies of a process. This information is very useful when analyzing interposition in conjunction with direct bindings.

By default, lari conveys information that is considered interesting. This information originates from multiple instances of a symbol definition. lari reveals the following information for prog1.

$ lari prog1
[2:2ES]: a(): ./W.so.1
[2:0]: a(): ./X.so.1
[2:2E]: b(): ./w.so.1
[2:0]: b(): ./x.so.1

In this example, the process established from prog1 contains two multiply defined symbols, a() and b(). The initial elements of the output diagnostics, those elements that are enclosed in the brackets, describe the associated symbols.

The first decimal value identifies the number of instances of the associated symbol. Two instances of a() and b() exist. The second decimal value identifies the number of bindings that have been resolved to this symbol. The symbol definition a() from W.so.1 reveals that two bindings have been established to this dependency. Similarly, the symbol definition b() from w.so.1 reveals that two bindings have been established to this dependency. The letters that follow the number of bindings, qualify the binding. The letter “E” indicates that a binding has been established from an external object. The letter “S” indicates that a binding has been established from the same object.

LD_DEBUG, lari, and the process examples built from these components, are used to further investigate direct binding scenarios in the sections that follow.