Resend: Add a new chapter on the dynamic linker

Message ID 20171012215658.8524-1-woodard@redhat.com
State New, archived
Headers

Commit Message

Ben Woodard Oct. 12, 2017, 9:56 p.m. UTC
  Add a new chapter covering dynamic linking to the glibc manual. Remove
    previous placeholder documents.

    Can we restart the review process on this with the intent of this
    getting merged. It has been through review once and all concerns
    were addressed however this patch was never merged.
    
---
 ChangeLog           |    4 +
 manual/Makefile     |    2 +-
 manual/dynamic.texi | 1191 +++++++++++++++++++++++++++++++++++++++++++++++++++
 manual/libdl.texi   |   10 -
 manual/signal.texi  |    2 +-
 5 files changed, 1197 insertions(+), 12 deletions(-)
 create mode 100644 manual/dynamic.texi
 delete mode 100644 manual/libdl.texi
  

Comments

Joseph Myers Oct. 12, 2017, 10:54 p.m. UTC | #1
On Thu, 12 Oct 2017, Ben Woodard wrote:

>     Add a new chapter covering dynamic linking to the glibc manual. Remove
>     previous placeholder documents.
> 
>     Can we restart the review process on this with the intent of this
>     getting merged. It has been through review once and all concerns
>     were addressed however this patch was never merged.

The following are just a few observations of things I noticed from looking 
at this document (each should be considered globally as the issue may 
appear many times but just be noted once).  This is *not* a general review 
of the patch.  I agree that dynamic linking should be documented in the 
glibc manual, and think the general outline of this document is 
reasonable.

A high-level design principle of dynamic linking is that things that work 
with static linking should also work with dynamic linking.  This has 
implications for the main program being able to reference functions and 
variables in a shared library without it being known at compile time 
whether those will come from a shared library or elsewhere in the main 
executable.  The less obvious consequences (e.g. regarding how the static 
linker handles references to variables with aliases) are off-topic for 
this manual, but maybe it makes sense to talk explicitly about how it's 
not known when the executable is compiled whether symbols will come from a 
shared library.  (Especially as this is different from some non-ELF models 
that may require e.g. dllimport markers.)

> +On every operating system currently supported by @theglibc{}, the
> +operating system provides a facility for run time dynamic

Adjective "run-time" (when referring to the time at which the program is 
run, as opposed to the C runtime library; see GCC's codingconventions.html 
for different variants of "run time", "run-time" and "runtime" and when 
each is correct).  Likewise elsewhere (and for other such adjectives).

> +linking. This facility is implemented by @theglibc{}'s dynamic linker.
> +This benefits the operating system by allowing the resident RAM used
> +by libraries to be shared between processes. Runtime dynamic linking

General observation, two spaces after "." in Texinfo source.

> +Because run time linking is so intimately involved with the lauching

"launching".  Running a spell check in this document would be a good idea.

> +The same run time dynamic linking capability which allows applications
> +to be loaded along with their libraries at initial execution time has
> +also been made available to application programmers through a group of
> +run time dynamic linker function explained below. This facility is

"functions".

> +The run time dynamic linker also provides several mechanisms which
> +allow the system administrator or user to modify its operation when
> +running an application. Many of the tools to modify glibc's run time

"@theglibc{}'s".

> +outside of a particular compilation unit. If you link object files
> +then the linker is able to find the location of referenced symbols or
> +functions in other compilation unit's object files, insert them into

"units'", as you're referring to the object files of multiple compilation 
units.

> +Libraries are a special kind object file which include the partially

"kind of object file".

> +linked aggregation of many compilation unit's object files. You can

"units'".

> +to run the executable. The shared libraries needed by am executable or

"an executable".

> +a library are stored in dynamic section of the ELF header. The list of

"the dynamic section".

> +The full set libraries needed by an executable or a library and all of

"set of libraries".

> +implementing the the @code{la_objsearch()} function.

GNU style does not use () when referring to a function.

> +@findex la_objsearch
> +
> +If a library listed as NEEDED includes a slash in its name, then it is
> +assumed to be either an absolute or relative pathname as is often the
> +case when a library is specified on the command line. When a pathname
> +is found as the target of the NEEDED section it is resolved as such.

The GNU Coding Standards say to use "file name", not "pathname".

> +@vindex LD_LIBRARY_PATH
> +@cindex RPATH
> +@cindex DT_RPATH
> +Sometimes a library's location will be explicitly referenced using a
> +deprecated feature called a RPATH. Specifying the location of a

"an RPATH".

> +library using RPATHs is not recommended for a variety of reasons
> +including the fact that it its extremely high precedence makes it

"it its" -> "its".

> +Very occasionally RPATH and RUNPATH may include some macros that will
> +be expanded before objects search is performed in the directories
> +specified. Users are encouraged to look at the linux ld.so man page
> +for more details.

"Linux" should only be used strictly to refer to the kernel.  This is 
nothing to do with the kernel.  I don't think referring to GNU/Linux is 
really right here either; $ORIGIN at least ought to be documented in this 
manual rather than relying on some third-party documentation.

> +@pindex ldconfig
> +@cindex ld.so.conf
> +@command{ldconfig} will cache the location of the libraries in the trusted
> +library directories (@file{/lib} and @file{/usr/lib} and also
> +@file{/lib64} and @file{/usr/lib64} on 64bit systems). The operating

There are more library directory variants for different ports of glibc - 
some have lib32 or libx32 (and AArch64 ILP32, not yet included in glibc, 
has libilp32).

> +@node Finding a Symbol
> +@subsection Finding a Symbol
> +When two objects are linked dynamically, the location of symbols which
> +are referenced in one object file which exist an an other object file

"in another".

> +cannot be resolved until run time. This is because the location within
> +a process's address space where a library will be loaded is
> +intentionally slightly non-deterministic to make hacking more
> +difficult and because different applications can load the same object

Although the GNU Coding Standards don't specifically say that "hacking" 
should not be used to refer to breaking into computers, I think we can 
take it as obvious, especially given the usage of "hacker" therein.

> +@node Binding a Variable
> +@subsection Binding a Variable
> +Binding a variable is the process of patching the location of a symbol
> +in the processes current address space into the code which refers to
> +it. There might be hundreds if not thousands of uses of a particular
> +variabletherefore patching in the location into every one of those

"variable therefore".

> +flags that this region is both wriable and dynamically allocated. At

"writable".

This section seems to be missing any discussion of the case of the main 
(non-PIC) program accessing a variable in a shared library (and how the 
copy of the variable in the program ends up as the main copy in that 
case).

> +The way this is accomplished is through another section of read-only
> +executable code called the Procedure Linkage Table, or PLT. The
> +executing code calls a tiny bit of stub code in the PLT. This stub
> +code jumps to the location of an associated entry in the GOT. This is

It jumps to a location *pointed to* by a GOT entry.  It does not jump into 
the GOT (which is writable and should not be executable).

> +After a function is bound, the entry in the GOT pointed to by the PLT
> +stub code will contain the address of the function in the process's
> +address space. Before the function is bound, usually at the time when
> +the object is loaded, the dynamic later inserts value in the GOT that

"dynamic linker inserts a value".

> +it is loaded before the dynamic linker object @code{ld_linux} is

The dynamic linker object has lots of different names on different 
systems.

> +@node la_objsearch
> +@subsection la_objsearch
> +@deftypefun char *la_objsearch(const char *@var{name}, uintptr_t *@var{cookie}, unsigned int @var{flag})
> +@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
> +@findex la_objsearch
> +
> +Within a run time linker audit library @code{la_obsearch()} is

la_objsearch or la_obsearch?  (And avoiding (), as elsewhere.)

> +@var{LA_SER_ORIG} This is the original name either found in the ELF
> +dynamic header or the parameter passed in by dlopen(3).

@code{dlopen}, don't use man-page section references.

> +@var{LA_SER_CONFIG} This is the name found in

@var is for metasyntactic variables, not for any literal source code 
string.

> +expected. This will only happen if ldconfig has never been run or if

@command{ldconfig}.

> +@findex dlclose
> +When the libraries are loaded as part of the standard process startup,
> +they are not closed when a process exits therefore this function is
> +not called except as a result of @code{dlclose()}

Missing trailing ".".
  
Joseph Myers Oct. 13, 2017, 12:29 a.m. UTC | #2
Also: the documentation of RPATH and RUNPATH seems to be missing what I 
think of as the key difference: a RUNPATH is only used to locate objects 
listed as NEEDED in the same executable or shared library that has the 
RUNPATH, whereas the RPATH of the executable (and those of intermediate 
shared libraries) gets used to search for indirect shared library 
dependencies.

(This is also why I'm dubious of deprecation of RPATH.  If you want to use 
libraries from a non-default sysroot, you can link an executable with 
-Wl,-dynamic-linker,/sysroot/path-to-ld.so 
-Wl,-rpath,/sysroot/lib:/sysroot/usr/lib (or similar), and all required 
libraries, whether direct or indirect dependencies, will be loaded from 
the sysroot if present there.  This only works with RPATH semantics, not 
RUNPATH semantics.)
  
Florian Weimer Oct. 13, 2017, 8:32 p.m. UTC | #3
* Ben Woodard:

> +@node Dynamic Linking, Program Basics, Signal Handling, Top
> +@c %MENU% Loading libraries, finding functions, and other symbols
> +@chapter Dynamic Linker
> +
> +On every operating system currently supported by @theglibc{}, the
> +operating system provides a facility for run time dynamic
> +linking. This facility is implemented by @theglibc{}'s dynamic linker.

Two spaces after the end of a sentence (this applies throughout).

Dynamic linking support in glibc is in fact optional, and can be
disabled at build time.

I think it makes to mention here that glibc strives to implement the
ELF specification for dynamic linking.

> +Because run time linking is so intimately involved with the lauching
> +of almost every program, it exists at the interface between the
> +operating system kernel and the system libraries. Thus configuration
> +and administration of the run time dynamic linker is operating system
> +specific. Individuals who are interested in this topic are encouraged
> +to look at the operating system documentation.
> +@c which is often found in
> +@c the @cite{ld.so(8)} and the @cite{ldconfig(8)} man pages.
> +@c pindex ld.so
> +@c pindex ldconfig

The above is a bit weird.  I'm not sure what the intent of this
paragraph is.  Do you want to say that there are manual pages for
ld.so and ldconfig (provided by glibc) which live outside of the glibc
project and provide additional information?

> +The run time dynamic linker also provides several mechanisms which
> +allow the system administrator or user to modify its operation when
> +running an application. Many of the tools to modify glibc's run time

“to modify the operation of @theglibc{} run time linker”

> +linker's operation are environmental variables. However, if more
> +sophisticated manipulation of the process of run time linking and
> +symbol resolution is needed, the dynamic has a kind of plugin
> +called an audit library.

“The dynamic linker offers a plugin facility called the audit
subsystem.”

> +@node Concepts of Dynamic Linking
> +@section Concepts of Dynamic linking

Should probably be “Concepts of Static and Dynamic Linking”.

I think you could explain here that linking has to parts: symbol
binding and relocation, and that there are three and half different
ELF object types—ET_REL, ET_DYN, ET_EXEC and PIE ET_EXEC (currently
ET_DYN as well).

> +When you compile a file and are left with an object file that is
> +called a compilation unit. At the time that it is compiled, the
> +compiler can see all the variables and functions that are within the
> +file and it can fill in references to those function and
> +variables. Many times there are functions or variables that exist
> +outside of a particular compilation unit. If you link object files
> +then the linker is able to find the location of referenced symbols or
> +functions in other compilation unit's object files, insert them into
> +the resulting executable, and bind the references to them.
> +
> +Libraries are a special kind object file which include the partially
> +linked aggregation of many compilation unit's object files. You can
> +link with a library one of two ways. Linking with a library statically
> +is the old original way of linking. This is no different than linking
> +with any other object file. Linking statically is not recommended in
> +almost all cases. The second way of linking is dynamically linking
> +with the library.

Can you reword it so that it's clear that there two different types of
libraries?

> In this case, the linker makes sure that all the
> +functions and symbols referred to by your program can be found in the
> +libraries that you are linking with but instead of copying the
> +function or variable over into the resulting executable, it stores a
> +reference to the library in the executable's header and replaces the
> +references to the function with calls to stub functions that will make
> +sure that the needed library is loaded into memory and then will
> +ultimately call the required function. Variables that exist in
> +libraries are handled similarly through a level of indirection.

That's not actually true in all cases.  It depends on the binding and
relocation type (see the noplt function attribute and copy relocations
for variables).

I think it's reasonable to gloss over the implementation details at
this stage.

> +@menu
> +* Finding a Library:: The process of resolving the location of a library
> +* Finding a Symbol:: The process of resolving symbols within libraries
> +* Binding a Variable:: How the GOT is used to bind a variable in a library
> +* Binding a Function:: How the PLT is used to bind functions from libraries
> +* Linkage Tables:: Using non-global linking to avoid potential symbol conflicts
> +@end menu

(line too long)

Maybe this should start with the kernel loading the program
interpreter and the main executable, for completeness.  Something like
this.

@node Loading The Program Interpreter

When the kernel replaces the current process image with a new
executable during the @code{execve} call, it parses the ELF program
header of the executable and performs the file mappings
(readable/writable/executable) indicated there.

@smallexample
$ readelf -l /bin/ls

Elf file type is DYN (Shared object file)
Entry point 0x5430
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x00000000000001f8 0x00000000000001f8  R E    0x8
  INTERP         0x0000000000000238 0x0000000000000238 0x0000000000000238
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x000000000001e184 0x000000000001e184  R E    0x200000
  LOAD           0x000000000001e388 0x000000000021e388 0x000000000021e388
                 0x0000000000001260 0x0000000000002440  RW     0x200000
  DYNAMIC        0x000000000001edb8 0x000000000021edb8 0x000000000021edb8
                 0x00000000000001f0 0x00000000000001f0  RW     0x8
  NOTE           0x0000000000000254 0x0000000000000254 0x0000000000000254
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_EH_FRAME   0x000000000001ab74 0x000000000001ab74 0x000000000001ab74
                 0x000000000000082c 0x000000000000082c  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x000000000001e388 0x000000000021e388 0x000000000021e388
                 0x0000000000000c78 0x0000000000000c78  R      0x1
@end smallexample

The kernel also extracts the program interpreter path (see
@code{INTERP} in the example), and loads it as well.  It then transfer
control to the program interpreter (in userspace).  The program
interpreter first relocates itself (during a bootstrapping step) and
then proceeds to load the shared objects needed by the main executable
(and their dependencies), and finally relocates all the objects and
the main program.

Unlike many other operating systems, dynamic linking, as implemented
by @theglibc{}, is a process which completely resides within
userspace.  The kernel is only used for initial bootstrapping.


> +
> +@node Finding a Library
> +@subsection Finding a Library
> +@cindex Finding a Library, Dynamic Linking
> +Binaries that are not linked statically require the dynamic linker to
> +load the libraries into the process's address space before beginning
> +to run the executable. The shared libraries needed by am executable or
> +a library are stored in dynamic section of the ELF header. The list of
> +the libraries needed can be quickly enumerated with the
> +@command{readelf} command.
> +@pindex readelf
> +
> +@cindex NEEDED, dynamic linking
> +@cindex DT_NEEDED
> +@example
> +$ readelf -d /usr/bin/ls | grep NEEDED

Please use /bin/ls, the portable path.

> +@pindex ldd
> +To make the association between between the library listed as needed
> +in the ELF dynamic section and where they are located as shown by the
> +@command{ldd} command, the run time linker has to look in several
> +places. This process is known as object search. A library can audit or
> +interpose itself into this process of locating a library by
> +implementing the the @code{la_objsearch()} function.
> +@findex la_objsearch

The audit interface should be covered in a separate section, IMHO.

> +If a library listed as NEEDED includes a slash in its name, then it is
> +assumed to be either an absolute or relative pathname as is often the
> +case when a library is specified on the command line. When a pathname
> +is found as the target of the NEEDED section it is resolved as such.

I think this needs some polishing, and I'm not actually sure how the
dynamic linker behaves.  Will any slash in DT_NEEDED inhibit searches
along the library path?

> +the system. Thus extensive use of @env{LD_LIBRARY_PATH} could have
> +substantial negative performance implications.

NB: Only affects load time, not run time.

> +@cindex RUNPATH
> +@cindex DT_RUNPATH
> +After processing @env{LD_LIBRARY_PATH}, an ELF directive similar to RPATH
> +called RUNPATH is searched. This ELF directive is what libtool and
> +other compile time linkers insert when linking with libraries in
> +unusual directories specified on the link command line. Any RUNPATHs
> +found in an ELF executable or library can be listed by printing the
> +dynamic section of the ELF header.

Some distros strip DT_RUNPATH or patch libtool not to add it.

> +Very occasionally RPATH and RUNPATH may include some macros that will
> +be expanded before objects search is performed in the directories
> +specified. Users are encouraged to look at the linux ld.so man page
> +for more details.

That's actualy quite widely used because OpenJDK relies on it.

> +@node Finding a Symbol
> +@subsection Finding a Symbol
> +When two objects are linked dynamically, the location of symbols which
> +are referenced in one object file which exist an an other object file
> +cannot be resolved until run time. This is because the location within
> +a process's address space where a library will be loaded is
> +intentionally slightly non-deterministic to make hacking more
> +difficult and because different applications can load the same object
> +file in different locations.

The relative locations are currently totally predictable, so this is
misleading.  The main point is that implementations can change and
shared objects can change sizes (or the length of functions), which
makes these offsets non-constant over time and require computation of
these offsets at run time.

> This is why libraries must be compiled as
> +position independent code.

Technically, this is a non sequitur.  Position-independent code
changes the relocation types used within an object, it does not
necessarily affect symbol binding directly.

>                             These unresolved symbols are known as
> +relocations. You can use the @command{readelf} command to list the
> +relocations needing to be satisfied within an object file.

You could refer back to the discussion of relocations vs symbol
binding earlier (or expand on the distinction here).

Not all relocations have associated symbols.  Undefined symbols will
be used by at least one relocation (I think, but perhaps there is a
counterexample).  Defined symbols may not have any associated
relocations at all.

> +The dynamic linker's job is to find the required symbol in the shared
> +libraries. The symbols available within an object file can be
> +enumerated with the @command{readelf --dyn-sym} command.

@samp{readelf --dyn-sym -W}, I think.

> +All of the relocations needed by the executable and all its libraries
> +will be satisfied by the objects loaded. For example two of the
> +symbols needed by the @command{ls} can be found in the
> +@file{/usr/lib64/libc.so.6} library.
> +
> +@example
> +$ readelf --relocs /usr/bin/ls | egrep stdout\|opendir
> +00000061af90  000f00000006 R_X86_64_GLOB_DAT 0000000000000000 stdout + 0
> +00000061b0e0  001e00000007 R_X86_64_JUMP_SLO 0000000000000000 opendir + 0
> +$ readelf --dyn-syms /usr/lib64/libc.so.6 | egrep " stdout| opendir"
> +  1036: 00000000003b88e8     8 OBJECT  GLOBAL DEFAULT   32 stdout@@GLIBC_2.2.5

stdout is a bit of a bad example because the executable has a
definition of the object as well, and there is a copy relocation for
it.

> +  1270: 00000000000c0350    13 FUNC    WEAK   DEFAULT   12 opendir@@GLIBC_2.2.5
> +@end example
> +
> +After the symbol is found in the object file, the reference to the
> +symbol must be patched so that the code can referring to it can make
> +use of it. This is known as binding a symbol.
> +
> +@node Binding a Variable
> +@subsection Binding a Variable
> +Binding a variable is the process of patching the location of a symbol
> +in the processes current address space into the code which refers to
> +it. There might be hundreds if not thousands of uses of a particular
> +variabletherefore patching in the location into every one of those
           ^ missing “, ”

> +uses would increase the amount of time spent in the dynamic linker
> +before main was started. Also patching the actual destination memory

“before the @code{main} function was started.”

> +address into the code of the object that refers to it would change the
> +in memory version of that object so that it could no longer be shared
> +with all the other processes using that object. The solution to these

Technically, glibc does in fact support text relocations.

> +two problems is to have indirect references to the external variables
> +and to place tables of these indirect references in a region of memory
> +not shared by users of that object. This indirection can be easily
> +seen when looking at the assembly code for a simple function. In this
> +case x86_64 is used but a similar mechanism is used for most
> +architectures.

Actually, x86-64 is way simpler than most architectures.

> +@example
> +$ cat test.c
> +extern int foo;
> +
> +int function(void) @{
> +    return foo;
> +@}
> +$ gcc -shared -fPIC -g -o libtest.so test.c
> +$ gdb libtest.so -q -ex "disassemble function" -ex quit
> +Reading symbols from libtest.so...done.
> +Dump of assembler code for function function:
> +   0x00000000000006d0 <+0>:	push   %rbp
> +   0x00000000000006d1 <+1>:	mov    %rsp,%rbp
> +   0x00000000000006d4 <+4>:	mov    0x200905(%rip),%rax        # 0x200fe0
> +   0x00000000000006db <+11>:	mov    (%rax),%eax
> +   0x00000000000006dd <+13>:	pop    %rbp
> +   0x00000000000006de <+14>:	retq
> +End of assembler dump.
> +$ readelf --relocs libtest.so | egrep dyn\|Type\|foo
> +Relocation section '.rela.dyn' at offset 0x470 contains 9 entries:
> +  Offset          Info           Type           Sym. Value    Sym. Name + Addend
> +000000200fe0  000400000006 R_X86_64_GLOB_DAT 0000000000000000 foo + 0
> +$ readelf --sections libtest.so | egrep -A1 Nr\|20\]\|Key\|order
> +  [Nr] Name              Type             Address           Offset
> +       Size              EntSize          Flags  Link  Info  Align
> +--
> +  [20] .got              PROGBITS         0000000000200fd0  00000fd0
> +       0000000000000030  0000000000000008  WA       0     0     8
> +--
> +Key to Flags:
> +  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
> +  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
> +  O (extra OS processing required) o (OS specific), p (processor specific)
> +@end example
> +
> +The address of the variable foo is located at the address 0x200905
> +past the current instruction pointer. GDB nicely computes this for you
> +to be 0x200fe0. This matches the address of the location in the
> +relocation section. When you find that address in the list of sections
> +within the ELF file you find that it is in a section called the
> +``GOT'' which stands for the global offset table. We can see from the
> +flags that this region is both wriable and dynamically allocated. At
                                  ^ “writable”
                                  
> +run time it is allocated and then then the dynamic linker inserts the
> +location of foo into 0x200fe0. This is the process known as binding a
> +symbol.

“writes the location of @code{foo} to the address 0x200fe0”

Arguably, this is relocation. 8-)  Binding the symbol is the lookups to
find the DSO that defines it and figuring out what kind of location
operation has to be used.

> +
> +@node Binding a Function
> +@subsection Binding a Function
> +
> +@cindex procedure linkage table
> +@cindex PLT
> +Binding a function is very similar to binding a variable except there
> +are a couple of other features and requirements that add a little bit
> +of additional complexity. Some of the additional complexity is due to
> +the need to make function calls between position independent code
> +which needs to be in read only memory. A couple of other important
> +features are lazy binding and the ability to audit function calls
> +between objects.

Note that many distributions have essentially removed the ability to
audit system libraries, so that tools like latrace stop working:

  https://bugzilla.redhat.com/show_bug.cgi?id=1483591

> +Like variable relocations, the requirement to have references in read
> +only memory so executable sections can be shared necessitates the use
> +of indirection. A simple approach would be to put the address to the
> +function in the GOT. However, another layer of indirection is needed
> +to support lazy binding of functions.
> +
> +The way this is accomplished is through another section of read-only
> +executable code called the Procedure Linkage Table, or PLT. The
> +executing code calls a tiny bit of stub code in the PLT. This stub
> +code jumps to the location of an associated entry in the GOT. This is
> +not a call, this is a jump and so returning the function's return
> +value and call stack is not disturbed.

There is considerable variance how PLT-like constructs are
implemented, and modern distributions do not have PLTs anymore in most
binaries on x86-64.

I am not sure if it makes sense to explain lazy binding in such detail
because it is increasingly of historical interest only.

> +After a function is bound, the entry in the GOT pointed to by the PLT
> +stub code will contain the address of the function in the process's
> +address space. Before the function is bound, usually at the time when
> +the object is loaded, the dynamic later inserts value in the GOT that
                                           ^ “stores”

Inserting implies shifting the other values around.

> +@node Linkage Tables
> +@subsection Linkage Tables
> +@findex dlopen
> +@findex dlmopen
> +Linkage tables are lists of the objects that the dynamic linker has
> +loaded into the process's address space. They are defined in
> +@file{<link.h>} and made up of the @code{link_map} structure. The
> +executable, the libraries that it needs to run, and any object files
> +that it opens with @code{dlopen} will be linked together in a doubly
> +linked list in a base link map. However, a process which opens objects
> +using @code{dlmopen} will have other link maps as well.

Isn't there a struct link_map object for each loaded object, not just
for each namespace?

I'm not sure if it is advisable to discuss these internals in such
detail.  These exports look more or less accidental or historical to
me.  Access is not thread safe, so different interfaces should be used
in general (such as dladdr, dlinfo, or __dl_iterate_phdr).

> +These @code{link_map} structures should be considered read only and
> +should not be modified. In addition to the the @code{l_next} and
> +@code{l_prev} pointers connecting the list, each @code{link_map}
> +structure has the @code{l_name} which is the name of the object
> +represented by this structure. In most cases, this value is filled in,
> +however the name of the executable object being run is not set because
> +it is loaded before the dynamic linker object @code{ld_linux} is
> +loaded.

“not set”?  Do you mean it is set as the empty string?

I think this is just the convention used to identify the main
executable.

> +@node Dynamic Linker API Functions
> +@section Dynamic Linker API Functions
> +@cindex Dynamic Linker API Functions
> +@Theglibc in conjunction with the underlying operating system provides
> +several functions which can be called from applications to load
> +linkable objects, most frequently libraries and plugins, and find the
> +addresses of symbols within them so that they can subsequently be
> +called through a function pointer. These functions are well documented
> +in their associated man pages.

See above.  Maybe we can somehow bridge the licensing gap and include
that text here for completeness.

> +These functions are all defined in @file{<dlfcn.h>} and exist in the
> +@file{libdl} library.

“Objects using these functions need to link with @code{-ldl}.”  (The
name of the dynamic linker library is implementation-defined.)

> +@section Audit Interface
> +@cindex rtld-audit
> +@cindex Audit, dynamic linking
> +
> +The dynamic linker provides an interface to monitor and intercept its
> +functioning. Since this interface was modeled after the Solaris's
> +audit interface, a good reference to it's operation is the Oracle
> +@cite{Solaris Linker and Libraries Guide}.
> +@c The linux man page for
> +@c rtld-audit(7) has a brief summary of the interface.
> +
> +@vindex LD_AUDIT
> +To run a program with an audit library, set the @env{LD_AUDIT}
> +environment variable to a colon separated list of shared libraries

(shared objects)

> +which implement any subset of the functions listed above containing

Listed below?

> +@code{la_version()} which is required to be present in all audit libraries.
> +@findex la_version
> +
> +The current implementation of the run time linker audit interface
> +currently includes the following functions.

Drop one current.

> +
> +@menu
> +* la_version:: Negotiate the version of the audit interface.
> +* la_objsearch:: Called when searching for a library.
> +* la_activity::  Called the link map is updated.
> +* la_objopen:: Called when an object file is opened.
> +* la_objclose:: Called just before the object file is unloaded.
> +* la_preinit:: Called after libraries are loaded but before main is called.
> +* la_symbind:: Called when a symbol is bound.
> +* la_pltenter:: Called when entering the PLT.
> +* la_pltexit:: Called when exiting the PLT.
> +@end menu
> +
> +@node la_version
> +@subsection la_version
> +@deftypefun unsigned int la_version(unsigned int @var{version})
> +@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
> +@findex la_version
> +
> +This is the only function guaranteed to be implemented by the every
> +version of the audit interface. It is also the only function required
> +to be defined in every audit library.
> +
> +The parameter passed in, is the highest version of the audit interface
> +that the run time linker implements. An audit library should check
> +this version to make sure that the run time linker implements a
> +version of the audit interface that is compatible and sufficient for
> +its needs. The audit library should return the version of the
> +interface that it intends to use to use. While this is likely to be

s/ to use_to use/to use/

> +the same as the version passed in as a parameter, it can also be an
> +older version. This allows an older audit library to still work with a
> +newer version of the audit interface. Currently, the run time linker
> +supports all previous versions of the audit interface and it is
> +expected that it will continue to provide backward compatibility with
> +these older versions of the interface for the foreseeable future. It
> +is unlikely that this guarantee of backward compatibility will be
> +broken during the lifetime of the ELF, Executable and Linkable File,
> +file format, but if the run time linker cannot support the version of
> +the audit interface returned by the auditing library's la_version()
> +function then that audit library will be ignored. One example where
> +this might be the case is if an audit library was compiled against a
> +newer version of glibc which implemented a newer version of the

@theglibc{}

> +interface and it required those new capabilities to run properly. The
> +audit library can also choose to return zero and the run time linker
> +will then ignore that audit library.
> +
> +The current version of the audit interface implemented by the run time
> +linker is defined as LAV_CURRENT in @file{link.h}. Thus a suggested

@code{LAV_CURRENT}.

> +implementation of @code{la_version()} without the capability to run against
> +version one of the audit interface would be:

GNU style does not use () after function names, so pleae use
@code{la_version} throughout.

> +Within a run time linker audit library @code{la_obsearch()} is
> +invoked each time the run time dynamic linker is going to search for
> +an object. This function may be called multiple times during the
> +process of resolving the location of a library. Initially, the run
> +time linker passes in the name of the object found from DT_NEEDED

@code{DT_NEEDED}.  All constants need similar markup.

Sorry, have to stop here for now.
  
Ben Woodard Oct. 13, 2017, 10:08 p.m. UTC | #4
On Thu, Oct 12, 2017 at 3:54 PM, Joseph Myers <joseph@codesourcery.com>
wrote:

> On Thu, 12 Oct 2017, Ben Woodard wrote:
>
> >     Add a new chapter covering dynamic linking to the glibc manual.
> Remove
> >     previous placeholder documents.
> >
> >     Can we restart the review process on this with the intent of this
> >     getting merged. It has been through review once and all concerns
> >     were addressed however this patch was never merged.
>
> The following are just a few observations of things I noticed from looking
> at this document (each should be considered globally as the issue may
> appear many times but just be noted once).  This is *not* a general review
> of the patch.  I agree that dynamic linking should be documented in the
> glibc manual, and think the general outline of this document is
> reasonable.
>
> A high-level design principle of dynamic linking is that things that work
> with static linking should also work with dynamic linking.  This has
> implications for the main program being able to reference functions and
> variables in a shared library without it being known at compile time
> whether those will come from a shared library or elsewhere in the main
> executable.  The less obvious consequences (e.g. regarding how the static
> linker handles references to variables with aliases) are off-topic for
> this manual, but maybe it makes sense to talk explicitly about how it's
> not known when the executable is compiled whether symbols will come from a
> shared library.  (Especially as this is different from some non-ELF models
> that may require e.g. dllimport markers.)
>
> > +On every operating system currently supported by @theglibc{}, the
> > +operating system provides a facility for run time dynamic
>
> Adjective "run-time" (when referring to the time at which the program is
> run, as opposed to the C runtime library; see GCC's codingconventions.html
> for different variants of "run time", "run-time" and "runtime" and when
> each is correct).  Likewise elsewhere (and for other such adjectives).
>

I fixed all of those.

>
> > +linking. This facility is implemented by @theglibc{}'s dynamic linker.
> > +This benefits the operating system by allowing the resident RAM used
> > +by libraries to be shared between processes. Runtime dynamic linking
>
> General observation, two spaces after "." in Texinfo source.
>

Fixed.

>
> > +Because run time linking is so intimately involved with the lauching
>
> "launching".  Running a spell check in this document would be a good idea.
>
> > +The same run time dynamic linking capability which allows applications
> > +to be loaded along with their libraries at initial execution time has
> > +also been made available to application programmers through a group of
> > +run time dynamic linker function explained below. This facility is
>
> "functions".
>

It is a hard document to spell check due to the formatting and code
examples. I think I found 4 misspellings.

>
> > +The run time dynamic linker also provides several mechanisms which
> > +allow the system administrator or user to modify its operation when
> > +running an application. Many of the tools to modify glibc's run time
>
> "@theglibc{}'s".
>

Fixed. I missed that one.

>
> > +outside of a particular compilation unit. If you link object files
> > +then the linker is able to find the location of referenced symbols or
> > +functions in other compilation unit's object files, insert them into
>
> "units'", as you're referring to the object files of multiple compilation
> units.
>

I don't think that you are correct about this. I intended it to be a
possessive not a plural.


> > +Libraries are a special kind object file which include the partially
>
> "kind of object file".
>
> > +linked aggregation of many compilation unit's object files. You can
>
> "units'".
>

See above. Possessive.


>
> > +to run the executable. The shared libraries needed by am executable or
>
> "an executable".
>

I disagree with this change. It breaks the agreement between the subject
and the object

"...load the libraries into the process's address space before beginning
to run the executable." The fact that you are talking about "the process's
address space" and so it must be "the executable".

>
> > +a library are stored in dynamic section of the ELF header. The list of
>
> "the dynamic section".
>

fixed

>
> > +The full set libraries needed by an executable or a library and all of
>
> "set of libraries".
>
> > +implementing the the @code{la_objsearch()} function.
>
> GNU style does not use () when referring to a function.
>
> > +@findex la_objsearch
> > +
> > +If a library listed as NEEDED includes a slash in its name, then it is
> > +assumed to be either an absolute or relative pathname as is often the
> > +case when a library is specified on the command line. When a pathname
> > +is found as the target of the NEEDED section it is resolved as such.
>
> The GNU Coding Standards say to use "file name", not "pathname".
>

fixed

>
> > +@vindex LD_LIBRARY_PATH
> > +@cindex RPATH
> > +@cindex DT_RPATH
> > +Sometimes a library's location will be explicitly referenced using a
> > +deprecated feature called a RPATH. Specifying the location of a
>
> "an RPATH".
>

Second opinion anybody? I think it should be a RPATH because it is "RPATH"
not "ARPATH" even though it sounds like there is a vowel in there. Maybe I
think too visually but "an RPATH" sounds wrong to me.


>
> > +library using RPATHs is not recommended for a variety of reasons
> > +including the fact that it its extremely high precedence makes it
>
> "it its" -> "its".
>

fixed

>
> > +Very occasionally RPATH and RUNPATH may include some macros that will
> > +be expanded before objects search is performed in the directories
> > +specified. Users are encouraged to look at the linux ld.so man page
> > +for more details.
>
> "Linux" should only be used strictly to refer to the kernel.  This is
> nothing to do with the kernel.  I don't think referring to GNU/Linux is
> really right here either; $ORIGIN at least ought to be documented in this
> manual rather than relying on some third-party documentation.
>

This is a vexingly tricky one.  I think that this needs some discussion.
I have no problem turning that into GNU/LInux there. However it might be
better if I just drop Linux in that paragraph and say:

Very occasionally RPATH and RUNPATH may include some macros that will
be expanded before objects search is performed in the directories
specified. Users are encouraged to look at the ld.so man page for your
operating system for more details.

I'm not sure what macros exist for different OSs that make use of glibc and
how much I can say here that applies to everything. Are you saying $ORIGIN
is universal? Are there more things are and need documenting?

I kind of understand what you mean about not referring to 3rd party sources
but this is one of those things where you do need to point users at the OS
specific documentation.


> > +@pindex ldconfig
> > +@cindex ld.so.conf
> > +@command{ldconfig} will cache the location of the libraries in the
> trusted
> > +library directories (@file{/lib} and @file{/usr/lib} and also
> > +@file{/lib64} and @file{/usr/lib64} on 64bit systems). The operating
>
> There are more library directory variants for different ports of glibc -
> some have lib32 or libx32 (and AArch64 ILP32, not yet included in glibc,
> has libilp32).
>
>
Noted  I tried to clear this up without turning it into a list.


> > +@node Finding a Symbol
> > +@subsection Finding a Symbol
> > +When two objects are linked dynamically, the location of symbols which
> > +are referenced in one object file which exist an an other object file
>
> "in another".
>

Fixed the duplicated "an" but grammatically in this case "an other" is the
correct usage here rather than "another". I just looked it up because 10th
grade English class was a long time ago.


>
> > +cannot be resolved until run time. This is because the location within
> > +a process's address space where a library will be loaded is
> > +intentionally slightly non-deterministic to make hacking more
> > +difficult and because different applications can load the same object
>
> Although the GNU Coding Standards don't specifically say that "hacking"
> should not be used to refer to breaking into computers, I think we can
> take it as obvious, especially given the usage of "hacker" therein.
>

Changed it to "exploiting code". I think that we lost that argument WRT to
common usage though.

>
> > +@node Binding a Variable
> > +@subsection Binding a Variable
> > +Binding a variable is the process of patching the location of a symbol
> > +in the processes current address space into the code which refers to
> > +it. There might be hundreds if not thousands of uses of a particular
> > +variabletherefore patching in the location into every one of those
>
> "variable therefore".
>

fixed


>
> > +flags that this region is both wriable and dynamically allocated. At
>
> "writable".
>

fixed

>
> This section seems to be missing any discussion of the case of the main
> (non-PIC) program accessing a variable in a shared library (and how the
> copy of the variable in the program ends up as the main copy in that
> case).
>

Right copy relocations need to be covered.


> > +The way this is accomplished is through another section of read-only
> > +executable code called the Procedure Linkage Table, or PLT. The
> > +executing code calls a tiny bit of stub code in the PLT. This stub
> > +code jumps to the location of an associated entry in the GOT. This is
>
> It jumps to a location *pointed to* by a GOT entry.  It does not jump into
> the GOT (which is writable and should not be executable).
>
> > +After a function is bound, the entry in the GOT pointed to by the PLT
> > +stub code will contain the address of the function in the process's
> > +address space. Before the function is bound, usually at the time when
> > +the object is loaded, the dynamic later inserts value in the GOT that
>
> "dynamic linker inserts a value".
>

fixed

>
> > +it is loaded before the dynamic linker object @code{ld_linux} is
>
> The dynamic linker object has lots of different names on different
> systems.
>
>
I changed it to ld.so in this one location.
I will think about how and where to note that its name varies  from OS to
OS. I don't think doing it right here is the right place.

> +@node la_objsearch
> > +@subsection la_objsearch
> > +@deftypefun char *la_objsearch(const char *@var{name}, uintptr_t
> *@var{cookie}, unsigned int @var{flag})
> > +@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
> > +@findex la_objsearch
> > +
> > +Within a run time linker audit library @code{la_obsearch()} is
>
> la_objsearch or la_obsearch?  (And avoiding (), as elsewhere.)
>

fixed


>
> > +@var{LA_SER_ORIG} This is the original name either found in the ELF
> > +dynamic header or the parameter passed in by dlopen(3).
>
> @code{dlopen}, don't use man-page section references.
>
> > +@var{LA_SER_CONFIG} This is the name found in
>
> @var is for metasyntactic variables, not for any literal source code
> string.
>

Fixed.


>
> > +expected. This will only happen if ldconfig has never been run or if
>
> @command{ldconfig}.
>
>
fixed


> > +@findex dlclose
> > +When the libraries are loaded as part of the standard process startup,
> > +they are not closed when a process exits therefore this function is
> > +not called except as a result of @code{dlclose()}
>
> Missing trailing ".".
>

fixed


>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>
  
Joseph Myers Oct. 13, 2017, 10:39 p.m. UTC | #5
On Fri, 13 Oct 2017, Ben Woodard wrote:

> > > +outside of a particular compilation unit. If you link object files
> > > +then the linker is able to find the location of referenced symbols or
> > > +functions in other compilation unit's object files, insert them into
> >
> > "units'", as you're referring to the object files of multiple compilation
> > units.
> >
> 
> I don't think that you are correct about this. I intended it to be a
> possessive not a plural.

I was reading it as a possessive of a plural that ends with s (so needing 
the apostrophe after the s, not before).  If it were the possessive of a 
singular compilation unit, I'd expect e.g. "another" in place of "other".

> > > +Libraries are a special kind object file which include the partially
> >
> > "kind of object file".
> >
> > > +linked aggregation of many compilation unit's object files. You can
> >
> > "units'".
> >
> 
> See above. Possessive.

Again, possessive of plural (here it seems clear it's possessive of a 
plural not a singular compilation unit, given the "many").

> > > +to run the executable. The shared libraries needed by am executable or
> >
> > "an executable".
> >
> 
> I disagree with this change. It breaks the agreement between the subject
> and the object

I'm correcting the "am executable".

> I'm not sure what macros exist for different OSs that make use of glibc and
> how much I can say here that applies to everything. Are you saying $ORIGIN
> is universal? Are there more things are and need documenting?

$ORIGIN is nothing to do with the operating system.  It's implemented in 
OS-independent code in glibc, not in OS-specific code (though OS-specific 
glibc code should still be documented in the glibc manual) and not in the 
kernel.  Likewise $PLATFORM and $LIB.  (The setting of dl_platform values 
is generally architecture-specific not OS-specific.)
  
Ben Woodard Oct. 13, 2017, 11:01 p.m. UTC | #6
On Fri, Oct 13, 2017 at 3:39 PM, Joseph Myers <joseph@codesourcery.com>
wrote:

> On Fri, 13 Oct 2017, Ben Woodard wrote:
>
> > > > +outside of a particular compilation unit. If you link object files
> > > > +then the linker is able to find the location of referenced symbols
> or
> > > > +functions in other compilation unit's object files, insert them into
> > >
> > > "units'", as you're referring to the object files of multiple
> compilation
> > > units.
> > >
> >
> > I don't think that you are correct about this. I intended it to be a
> > possessive not a plural.
>
> I was reading it as a possessive of a plural that ends with s (so needing
> the apostrophe after the s, not before).  If it were the possessive of a
> singular compilation unit, I'd expect e.g. "another" in place of "other".
>
>
I literally had to diagram out the sentence to make sense of this one. In
this case, I am referring to one location and so "another" is more
appropriate to agree with "object file"  rather than "object files".

> > > +Libraries are a special kind object file which include the partially
> > >
> > > "kind of object file".
> > >
> > > > +linked aggregation of many compilation unit's object files. You can
> > >
> > > "units'".
> > >
> >
> > See above. Possessive.
>
> Again, possessive of plural (here it seems clear it's possessive of a
> plural not a singular compilation unit, given the "many").
>
> This one is a possessive of a plural.
Fixed.


> > > > +to run the executable. The shared libraries needed by am executable
> or
> > >
> > > "an executable".
> > >
> >
> > I disagree with this change. It breaks the agreement between the subject
> > and the object
>
> I'm correcting the "am executable".
>

fixed

>
> > I'm not sure what macros exist for different OSs that make use of glibc
> and
> > how much I can say here that applies to everything. Are you saying
> $ORIGIN
> > is universal? Are there more things are and need documenting?
>
> $ORIGIN is nothing to do with the operating system.  It's implemented in
> OS-independent code in glibc, not in OS-specific code (though OS-specific
> glibc code should still be documented in the glibc manual) and not in the
> kernel.  Likewise $PLATFORM and $LIB.  (The setting of dl_platform values
> is generally architecture-specific not OS-specific.)
>

TODO. along with copy relocations

>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>
  
Pedro Alves Oct. 16, 2017, 11:54 a.m. UTC | #7
On 10/14/2017 12:01 AM, Ben Woodard wrote:
> 
> 
> On Fri, Oct 13, 2017 at 3:39 PM, Joseph Myers <joseph@codesourcery.com
> <mailto:joseph@codesourcery.com>> wrote:
> 
>     On Fri, 13 Oct 2017, Ben Woodard wrote:
> 
>     > > > +outside of a particular compilation unit. If you link object files
>     > > > +then the linker is able to find the location of referenced symbols or
>     > > > +functions in other compilation unit's object files, insert them into
>     > >
>     > > "units'", as you're referring to the object files of multiple compilation
>     > > units.
>     > >
>     >
>     > I don't think that you are correct about this. I intended it to be a
>     > possessive not a plural.
> 
>     I was reading it as a possessive of a plural that ends with s (so
>     needing
>     the apostrophe after the s, not before).  If it were the possessive of a
>     singular compilation unit, I'd expect e.g. "another" in place of
>     "other".
> 
> 
> I literally had to diagram out the sentence to make sense of this one.
> In this case, I am referring to one location and so "another" is more
> appropriate to agree with "object file"  rather than "object files".

(since you asked for a second opinion, and I was reading this,
here's mine.)

I think rephrasing to avoid possessive may clarify.
E.g., using "of" instead, and taking the corrected singular form
using "another" as you seem to be suggesting was intended:

 If you link object files then the linker is able to find the 
 location of referenced symbols or functions in the object files
 of another compilation unit.

However, the above doesn't seem to make much sense to me.
What does "object files of another compilation unit" mean?

Plural would seem a bit better:

 If you link object files then the linker is able to find the 
 location of referenced symbols or functions in the object files
 of other compilation units.

but then neither possessive relationship really makes sense to
me, in light of the sentence just before, where "compilation unit"
is defined as _the_ "object file":

 "When you compile a file and are left with an object file that is
  called a compilation unit."

(I assume you meant "you are" instead of "and are".)

Thanks,
Pedro Alves
  

Patch

diff --git a/ChangeLog b/ChangeLog
index e8f8382a5c..ce74b76d33 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6109,6 +6109,10 @@ 
 	* socket/opensock.c (__opensock): Likewise.
 	* sysdeps/unix/sysv/linux/opensock.c (__opensock): Likewise.
 
+2017-08-16 Ben Woodard <woodard@redhat.com>
+	* manual/Makefile (chapters): Add dynamic chapter.
+	* manual/dynamic.texi: New file
+
 2017-08-16  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #21944]
diff --git a/manual/Makefile b/manual/Makefile
index 3b4c7c934a..3f6b486978 100644
--- a/manual/Makefile
+++ b/manual/Makefile
@@ -39,7 +39,7 @@  chapters = $(addsuffix .texi, \
 		       pipe socket terminal syslog math arith time	\
 		       resource setjmp signal startup process ipc job	\
 		       nss users sysinfo conf crypt debug threads	\
-		       probes tunables)
+		       probes dynamic tunables)
 appendices = lang.texi header.texi install.texi maint.texi platform.texi \
 	     contrib.texi
 licenses = freemanuals.texi lgpl-2.1.texi fdl-1.3.texi
diff --git a/manual/dynamic.texi b/manual/dynamic.texi
new file mode 100644
index 0000000000..6207225c5e
--- /dev/null
+++ b/manual/dynamic.texi
@@ -0,0 +1,1191 @@ 
+@node Dynamic Linking, Program Basics, Signal Handling, Top
+@c %MENU% Loading libraries, finding functions, and other symbols
+@chapter Dynamic Linker
+
+On every operating system currently supported by @theglibc{}, the
+operating system provides a facility for run time dynamic
+linking. This facility is implemented by @theglibc{}'s dynamic linker.
+This benefits the operating system by allowing the resident RAM used
+by libraries to be shared between processes. Runtime dynamic linking
+also enhances the security and maintainability of the operating
+system. As long as the ABI, application binary interface, is
+maintained through proper library versioning, a new version of a
+library can be installed on a system to fix bugs or resolve a security
+issue without the need to recompile all the applications which make
+use of that library.
+
+Because run time linking is so intimately involved with the lauching
+of almost every program, it exists at the interface between the
+operating system kernel and the system libraries. Thus configuration
+and administration of the run time dynamic linker is operating system
+specific. Individuals who are interested in this topic are encouraged
+to look at the operating system documentation.
+@c which is often found in
+@c the @cite{ld.so(8)} and the @cite{ldconfig(8)} man pages.
+@c pindex ld.so
+@c pindex ldconfig
+
+The same run time dynamic linking capability which allows applications
+to be loaded along with their libraries at initial execution time has
+also been made available to application programmers through a group of
+run time dynamic linker function explained below. This facility is
+often used for plugins to add optional or extended features to an
+application without introducing library dependencies.
+
+The run time dynamic linker also provides several mechanisms which
+allow the system administrator or user to modify its operation when
+running an application. Many of the tools to modify glibc's run time
+linker's operation are environmental variables. However, if more
+sophisticated manipulation of the process of run time linking and
+symbol resolution is needed, the dynamic has a kind of plugin
+called an audit library.
+
+@menu
+* Concepts of Dynamic Linking:: Introduction to dynamic linking.
+* Environmental Variables:: Variables that can be used affect the operation
+                            of dynamic linker.
+* Dynamic Linker API Functions:: Functions to load libraries, find functions
+                                 and other symbols.
+* Audit Interface:: Monitor or intercede in the operation of the dynamic linker
+@end menu
+
+@node Concepts of Dynamic Linking
+@section Concepts of Dynamic linking
+
+When you compile a file and are left with an object file that is
+called a compilation unit. At the time that it is compiled, the
+compiler can see all the variables and functions that are within the
+file and it can fill in references to those function and
+variables. Many times there are functions or variables that exist
+outside of a particular compilation unit. If you link object files
+then the linker is able to find the location of referenced symbols or
+functions in other compilation unit's object files, insert them into
+the resulting executable, and bind the references to them.
+
+Libraries are a special kind object file which include the partially
+linked aggregation of many compilation unit's object files. You can
+link with a library one of two ways. Linking with a library statically
+is the old original way of linking. This is no different than linking
+with any other object file. Linking statically is not recommended in
+almost all cases. The second way of linking is dynamically linking
+with the library. In this case, the linker makes sure that all the
+functions and symbols referred to by your program can be found in the
+libraries that you are linking with but instead of copying the
+function or variable over into the resulting executable, it stores a
+reference to the library in the executable's header and replaces the
+references to the function with calls to stub functions that will make
+sure that the needed library is loaded into memory and then will
+ultimately call the required function. Variables that exist in
+libraries are handled similarly through a level of indirection.
+
+@menu
+* Finding a Library:: The process of resolving the location of a library
+* Finding a Symbol:: The process of resolving symbols within libraries
+* Binding a Variable:: How the GOT is used to bind a variable in a library
+* Binding a Function:: How the PLT is used to bind functions from libraries
+* Linkage Tables:: Using non-global linking to avoid potential symbol conflicts
+@end menu
+
+@node Finding a Library
+@subsection Finding a Library
+@cindex Finding a Library, Dynamic Linking
+Binaries that are not linked statically require the dynamic linker to
+load the libraries into the process's address space before beginning
+to run the executable. The shared libraries needed by am executable or
+a library are stored in dynamic section of the ELF header. The list of
+the libraries needed can be quickly enumerated with the
+@command{readelf} command.
+@pindex readelf
+
+@cindex NEEDED, dynamic linking
+@cindex DT_NEEDED
+@example
+$ readelf -d /usr/bin/ls | grep NEEDED
+0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
+0x0000000000000001 (NEEDED) Shared library: [libcap.so.2]
+0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
+0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+$ readelf -d /lib64/libselinux.so.1 | grep NEEDED
+0x0000000000000001 (NEEDED) Shared library: [libpcre.so.1]
+0x0000000000000001 (NEEDED) Shared library: [liblzma.so.5]
+0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
+0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
+0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
+@end example
+
+The full set libraries needed by an executable or a library and all of
+its dependencies and where they are currently being found can be
+enumerated with the @command{ldd} command.
+@pindex ldd
+
+@example
+$ ldd /usr/bin/ls
+linux-vdso.so.1 => (0x00007fff3e5e9000)
+libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f0e913ce000)
+libcap.so.2 => /lib64/libcap.so.2 (0x00007f0e911c9000)
+libacl.so.1 => /lib64/libacl.so.1 (0x00007f0e90fbf000)
+libc.so.6 => /lib64/libc.so.6 (0x00007f0e90c02000)
+libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f0e90995000)
+liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f0e9076f000)
+libdl.so.2 => /lib64/libdl.so.2 (0x00007f0e9056b000)
+/lib64/ld-linux-x86-64.so.2 (0x00007f0e9160b000)
+libattr.so.1 => /lib64/libattr.so.1 (0x00007f0e90366000)
+libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0e90149000)
+@end example
+
+@pindex ldd
+To make the association between between the library listed as needed
+in the ELF dynamic section and where they are located as shown by the
+@command{ldd} command, the run time linker has to look in several
+places. This process is known as object search. A library can audit or
+interpose itself into this process of locating a library by
+implementing the the @code{la_objsearch()} function.
+@findex la_objsearch
+
+If a library listed as NEEDED includes a slash in its name, then it is
+assumed to be either an absolute or relative pathname as is often the
+case when a library is specified on the command line. When a pathname
+is found as the target of the NEEDED section it is resolved as such.
+
+@vindex LD_LIBRARY_PATH
+@cindex RPATH
+@cindex DT_RPATH
+Sometimes a library's location will be explicitly referenced using a
+deprecated feature called a RPATH. Specifying the location of a
+library using RPATHs is not recommended for a variety of reasons
+including the fact that it its extremely high precedence makes it
+impossible for system administrators to point at other locations using
+things like @env{LD_LIBRARY_PATH} and the inability to edit the RPATHs
+because limited space in the ELF header for the pathname prevents
+changing it to something suitable for file hierarchy appropriate to
+that system. Any RPATHs found in a binary or a library can found using
+the readelf command as follows.
+
+@pindex readelf
+@example
+$ readelf -d /usr/bin/apropos | grep RPATH
+0x000000000000000f (RPATH) Library rpath: [/usr/lib64/man-db]
+@end example
+
+@vindex LD_LIBRARY_PATH
+The first place that the run time linker looks for a NEEDED library
+after following RPATHs is in any directory found in the colon
+separated list of directories found in the @env{LD_LIBRARY_PATH}
+environmental variable. This list of directories is searched first to
+facilitate replacing libraries found elsewhere in the search
+path. This is particularly useful when debugging problems but
+extensive use of @env{LD_LIBRARY_PATH} is not recommended because it
+bypasses the caching of where to find libraries which is done later in
+the object search process. This caching greatly improves the
+performance of object search by avoiding the necessity to enumerate
+the contents of every directory containing libraries configured into
+the system. Thus extensive use of @env{LD_LIBRARY_PATH} could have
+substantial negative performance implications.
+
+@cindex RUNPATH
+@cindex DT_RUNPATH
+After processing @env{LD_LIBRARY_PATH}, an ELF directive similar to RPATH
+called RUNPATH is searched. This ELF directive is what libtool and
+other compile time linkers insert when linking with libraries in
+unusual directories specified on the link command line. Any RUNPATHs
+found in an ELF executable or library can be listed by printing the
+dynamic section of the ELF header.
+
+@pindex readelf
+@example
+$ readelf -d /usr/bin/tracker-control | grep RUNPATH
+0x000000000000001d (RUNPATH) Library runpath: [/usr/lib64/tracker-1.0]
+@end example
+
+Very occasionally RPATH and RUNPATH may include some macros that will
+be expanded before objects search is performed in the directories
+specified. Users are encouraged to look at the linux ld.so man page
+for more details.
+
+@pindex ldconfig
+@cindex ld.so.cache
+@vindex LD_LIBRARY_PATH
+While RPATH and RUNPATH ELF entries are quite rare and while use of
+@env{LD_LIBRARY_PATH} is well known its use is uncommon, the normal
+behavior of the run time linker starts out looking in the
+@file{/etc/ld.so.cache} which is created when @command{ldconfig} is
+run.
+
+@pindex ldconfig
+@cindex ld.so.conf
+@command{ldconfig} will cache the location of the libraries in the trusted
+library directories (@file{/lib} and @file{/usr/lib} and also
+@file{/lib64} and @file{/usr/lib64} on 64bit systems). The operating
+system provider or the local sysadmin may also include additional
+directories that the linker should search for libraries. These are
+specified in @file{/etc/ld.so.conf} but before they are searched, this
+configuration file must be compiled into @file{ld.so.cache} by the
+@command{ldconfig} command.
+
+@node Finding a Symbol
+@subsection Finding a Symbol
+When two objects are linked dynamically, the location of symbols which
+are referenced in one object file which exist an an other object file
+cannot be resolved until run time. This is because the location within
+a process's address space where a library will be loaded is
+intentionally slightly non-deterministic to make hacking more
+difficult and because different applications can load the same object
+file in different locations. This is why libraries must be compiled as
+position independent code. These unresolved symbols are known as
+relocations. You can use the @command{readelf} command to list the
+relocations needing to be satisfied within an object file.
+
+@example
+$ readelf --relocs /usr/bin/ls
+
+Relocation section '.rela.dyn' at offset 0x1688 contains 9 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name + Addend
+00000061af88  000800000006 R_X86_64_GLOB_DAT 0000000000000000 free + 0
+00000061af90  000f00000006 R_X86_64_GLOB_DAT 0000000000000000 stdout + 0
+00000061af98  001d00000006 R_X86_64_GLOB_DAT 0000000000000000 optind + 0
+00000061afa0  004500000006 R_X86_64_GLOB_DAT 0000000000000000 optarg + 0
+[...]
+
+Relocation section '.rela.plt' at offset 0x1760 contains 115 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name + Addend
+00000061b018  000100000007 R_X86_64_JUMP_SLO 0000000000000000 __ctype_toupper_loc + 0
+00000061b020  000200000007 R_X86_64_JUMP_SLO 0000000000000000 __uflow + 0
+00000061b028  000300000007 R_X86_64_JUMP_SLO 0000000000000000 getenv + 0
+00000061b030  000400000007 R_X86_64_JUMP_SLO 0000000000000000 cap_to_text + 0
+00000061b038  000600000007 R_X86_64_JUMP_SLO 0000000000000000 sigprocmask + 0
+00000061b040  000700000007 R_X86_64_JUMP_SLO 0000000000000000 raise + 0
+00000061b048  000800000007 R_X86_64_JUMP_SLO 0000000000000000 free + 0
+[...]
+@end example
+
+The dynamic linker's job is to find the required symbol in the shared
+libraries. The symbols available within an object file can be
+enumerated with the @command{readelf --dyn-sym} command.
+
+@example
+$ readelf --dyn-syms /usr/lib64/libc.so.6 | grep -v " _"
+
+Symbol table '.dynsym' contains 2224 entries:
+   Num:    Value          Size Type    Bind   Vis      Ndx Name
+     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
+     1: 000000000001f4f0     0 SECTION LOCAL  DEFAULT   12
+     2: 00000000003b3568     0 SECTION LOCAL  DEFAULT   22
+    10: 00000000000717c0   348 FUNC    GLOBAL DEFAULT   12 putwchar@@GLIBC_2.2.5
+    14: 0000000000115d70   192 FUNC    GLOBAL DEFAULT   12 setrpcent@@GLIBC_2.2.5
+    17: 0000000000100770    33 FUNC    GLOBAL DEFAULT   12 epoll_create@@GLIBC_2.3.2
+    18: 00000000000e42b0    33 FUNC    WEAK   DEFAULT   12 sched_get_priority_min@@GLIBC_2.2.5
+    20: 0000000000100980    33 FUNC    GLOBAL DEFAULT   12 klogctl@@GLIBC_2.2.5
+    22: 0000000000053920   143 FUNC    GLOBAL DEFAULT   12 dprintf@@GLIBC_2.2.5
+    [...]
+@end example
+
+All of the relocations needed by the executable and all its libraries
+will be satisfied by the objects loaded. For example two of the
+symbols needed by the @command{ls} can be found in the
+@file{/usr/lib64/libc.so.6} library.
+
+@example
+$ readelf --relocs /usr/bin/ls | egrep stdout\|opendir
+00000061af90  000f00000006 R_X86_64_GLOB_DAT 0000000000000000 stdout + 0
+00000061b0e0  001e00000007 R_X86_64_JUMP_SLO 0000000000000000 opendir + 0
+$ readelf --dyn-syms /usr/lib64/libc.so.6 | egrep " stdout| opendir"
+  1036: 00000000003b88e8     8 OBJECT  GLOBAL DEFAULT   32 stdout@@GLIBC_2.2.5
+  1270: 00000000000c0350    13 FUNC    WEAK   DEFAULT   12 opendir@@GLIBC_2.2.5
+@end example
+
+After the symbol is found in the object file, the reference to the
+symbol must be patched so that the code can referring to it can make
+use of it. This is known as binding a symbol.
+
+@node Binding a Variable
+@subsection Binding a Variable
+Binding a variable is the process of patching the location of a symbol
+in the processes current address space into the code which refers to
+it. There might be hundreds if not thousands of uses of a particular
+variabletherefore patching in the location into every one of those
+uses would increase the amount of time spent in the dynamic linker
+before main was started. Also patching the actual destination memory
+address into the code of the object that refers to it would change the
+in memory version of that object so that it could no longer be shared
+with all the other processes using that object. The solution to these
+two problems is to have indirect references to the external variables
+and to place tables of these indirect references in a region of memory
+not shared by users of that object. This indirection can be easily
+seen when looking at the assembly code for a simple function. In this
+case x86_64 is used but a similar mechanism is used for most
+architectures.
+
+@example
+$ cat test.c
+extern int foo;
+
+int function(void) @{
+    return foo;
+@}
+$ gcc -shared -fPIC -g -o libtest.so test.c
+$ gdb libtest.so -q -ex "disassemble function" -ex quit
+Reading symbols from libtest.so...done.
+Dump of assembler code for function function:
+   0x00000000000006d0 <+0>:	push   %rbp
+   0x00000000000006d1 <+1>:	mov    %rsp,%rbp
+   0x00000000000006d4 <+4>:	mov    0x200905(%rip),%rax        # 0x200fe0
+   0x00000000000006db <+11>:	mov    (%rax),%eax
+   0x00000000000006dd <+13>:	pop    %rbp
+   0x00000000000006de <+14>:	retq
+End of assembler dump.
+$ readelf --relocs libtest.so | egrep dyn\|Type\|foo
+Relocation section '.rela.dyn' at offset 0x470 contains 9 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name + Addend
+000000200fe0  000400000006 R_X86_64_GLOB_DAT 0000000000000000 foo + 0
+$ readelf --sections libtest.so | egrep -A1 Nr\|20\]\|Key\|order
+  [Nr] Name              Type             Address           Offset
+       Size              EntSize          Flags  Link  Info  Align
+--
+  [20] .got              PROGBITS         0000000000200fd0  00000fd0
+       0000000000000030  0000000000000008  WA       0     0     8
+--
+Key to Flags:
+  W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
+  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
+  O (extra OS processing required) o (OS specific), p (processor specific)
+@end example
+
+The address of the variable foo is located at the address 0x200905
+past the current instruction pointer. GDB nicely computes this for you
+to be 0x200fe0. This matches the address of the location in the
+relocation section. When you find that address in the list of sections
+within the ELF file you find that it is in a section called the
+``GOT'' which stands for the global offset table. We can see from the
+flags that this region is both wriable and dynamically allocated. At
+run time it is allocated and then then the dynamic linker inserts the
+location of foo into 0x200fe0. This is the process known as binding a
+symbol.
+
+@node Binding a Function
+@subsection Binding a Function
+
+@cindex procedure linkage table
+@cindex PLT
+Binding a function is very similar to binding a variable except there
+are a couple of other features and requirements that add a little bit
+of additional complexity. Some of the additional complexity is due to
+the need to make function calls between position independent code
+which needs to be in read only memory. A couple of other important
+features are lazy binding and the ability to audit function calls
+between objects.
+
+Like variable relocations, the requirement to have references in read
+only memory so executable sections can be shared necessitates the use
+of indirection. A simple approach would be to put the address to the
+function in the GOT. However, another layer of indirection is needed
+to support lazy binding of functions.
+
+The way this is accomplished is through another section of read-only
+executable code called the Procedure Linkage Table, or PLT. The
+executing code calls a tiny bit of stub code in the PLT. This stub
+code jumps to the location of an associated entry in the GOT. This is
+not a call, this is a jump and so returning the function's return
+value and call stack is not disturbed.
+
+@example
+$ cat test.c
+int foo(void);
+
+int function(void) @{
+    return foo();
+@}
+$ gcc -shared -fPIC -o libtest.so test.c
+$ gdb libtest.so -q -ex "disassemble function" -ex quit
+Reading symbols from libtest.so...done.
+Dump of assembler code for function function:
+   0x00000000000006e0 <+0>:	push   %rbp
+   0x00000000000006e1 <+1>:	mov    %rsp,%rbp
+   0x00000000000006e4 <+4>:	callq  0x5c0 <foo@@plt>
+   0x00000000000006e9 <+9>:	pop    %rbp
+   0x00000000000006ea <+10>:	retq
+End of assembler dump.
+$ gdb libtest.so -q -ex "disassemble 0x5c0" -ex quit
+Reading symbols from libtest.so...done.
+Dump of assembler code for function foo@@plt:
+   0x00000000000005c0 <+0>:	jmpq   *0x200a5a(%rip)        # 0x201020 <foo@@got.plt>
+   [...]
+End of assembler dump.
+$ readelf --relocs libtest.so
+[...]
+Relocation section '.rela.plt' at offset 0x530 contains 3 entries:
+  Offset          Info           Type           Sym. Value    Sym. Name + Addend
+[...]
+000000201020  000400000007 R_X86_64_JUMP_SLO 0000000000000000 foo + 0
+[...]
+@end example
+
+After a function is bound, the entry in the GOT pointed to by the PLT
+stub code will contain the address of the function in the process's
+address space. Before the function is bound, usually at the time when
+the object is loaded, the dynamic later inserts value in the GOT that
+enables lazy binding and auditing. This value and the mechanism by
+which these stub functions work is explained below.
+
+@cindex Lazy Binding
+@cindex Binding, Lazy
+When the dynamic linker loads an object, it doesn't take the time to
+process all the relocations for functions. Instead it preloads the
+entries for each function in the GOT with the value of the instruction
+immediately after the jump made from the PLT's stub function.
+
+Continuing with our example from above:
+
+@example
+$ gdb libtest.so -q -ex "disassemble 0x5c0" -ex "x 0x201020" -ex quit
+Reading symbols from libtest.so...done.
+Dump of assembler code for function foo@@plt:
+   0x00000000000005c0 <+0>:	jmpq   *0x200a5a(%rip)        # 0x201020 <foo@@got.plt>
+   0x00000000000005c6 <+6>:	pushq  $0x1
+   0x00000000000005cb <+11>:	jmpq   0x5a0
+End of assembler dump.
+0x201020 <foo@@got.plt>:	0x000005c6
+@end example
+
+So in this case the address 0x201020 from the current instruction
+would be initially set to the address of the pushq instruction found
+at the offset of 0x5c6.
+
+The push stores the function within the object on the stack. Then it
+jumps to 0x5a0 which is a special entry in the PLT called PLT0. It
+pushes the offset of the library onto the stack and then jumps to a
+resolver function which is in part of the dynamic linker. At the end
+of the resolution function, if the library is not being profiled or
+audited then, the resolver function will store the location of the
+function in the GOT.
+
+@example
+$ gdb libtest.so --quiet -ex "disassemble 0x5a0, 0x5ac" -ex quit
+Reading symbols from libtest.so...done.
+Dump of assembler code from 0x5a0 to 0x5ac:
+   0x00000000000005a0:	pushq  0x200a62(%rip)        # 0x201008
+   0x00000000000005a6:	jmpq   *0x200a64(%rip)        # 0x201010
+End of assembler dump.
+@end example
+
+While calling into some static stub code which does an indirect jump
+to a function pointer from the GOT is straight forward enough, this
+trick of preloading the GOT entries for a function with the
+instruction immediately after the indirect jump to the very next
+instruction after the indirect jump can be confusing at first. The
+trick to understanding it is realizing that after the function is
+bound, the code after that indirect jump is never reached.
+
+@node Linkage Tables
+@subsection Linkage Tables
+@findex dlopen
+@findex dlmopen
+Linkage tables are lists of the objects that the dynamic linker has
+loaded into the process's address space. They are defined in
+@file{<link.h>} and made up of the @code{link_map} structure. The
+executable, the libraries that it needs to run, and any object files
+that it opens with @code{dlopen} will be linked together in a doubly
+linked list in a base link map. However, a process which opens objects
+using @code{dlmopen} will have other link maps as well.
+
+These @code{link_map} structures should be considered read only and
+should not be modified. In addition to the the @code{l_next} and
+@code{l_prev} pointers connecting the list, each @code{link_map}
+structure has the @code{l_name} which is the name of the object
+represented by this structure. In most cases, this value is filled in,
+however the name of the executable object being run is not set because
+it is loaded before the dynamic linker object @code{ld_linux} is
+loaded. Each @code{link_map} structure also has a @code{l_addr} which
+provides the difference between the address in ELF file and the
+address of the object in memory. This can be used to associate the
+location in the object file with the associated location in
+memory. Finally, they also have a @code{l_ld} pointer which points to
+the object file's ELF dynamic section. The contents of the ELF dynamic
+section can be viewed using the @command{readelf} command.
+
+@example
+$ readelf -d /usr/bin/ls
+
+Dynamic section at offset 0x1ad88 contains 27 entries:
+  Tag        Type                         Name/Value
+ 0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
+ 0x0000000000000001 (NEEDED)             Shared library: [libcap.so.2]
+ 0x0000000000000001 (NEEDED)             Shared library: [libacl.so.1]
+ 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
+ 0x000000000000000c (INIT)               0x402228
+ 0x000000000000000d (FINI)               0x412bfc
+ 0x0000000000000019 (INIT_ARRAY)         0x61a290
+ 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
+ 0x000000000000001a (FINI_ARRAY)         0x61a298
+ 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
+ 0x000000006ffffef5 (GNU_HASH)           0x400298
+ 0x0000000000000005 (STRTAB)             0x400f30
+ 0x0000000000000006 (SYMTAB)             0x4002d0
+ 0x000000000000000a (STRSZ)              1468 (bytes)
+ 0x000000000000000b (SYMENT)             24 (bytes)
+ 0x0000000000000015 (DEBUG)              0x0
+ 0x0000000000000003 (PLTGOT)             0x61b000
+ 0x0000000000000002 (PLTRELSZ)           2760 (bytes)
+ 0x0000000000000014 (PLTREL)             RELA
+ 0x0000000000000017 (JMPREL)             0x401760
+ 0x0000000000000007 (RELA)               0x401688
+ 0x0000000000000008 (RELASZ)             216 (bytes)
+ 0x0000000000000009 (RELAENT)            24 (bytes)
+ 0x000000006ffffffe (VERNEED)            0x4015f8
+ 0x000000006fffffff (VERNEEDNUM)         2
+ 0x000000006ffffff0 (VERSYM)             0x4014ec
+ 0x0000000000000000 (NULL)               0x0
+@end example
+
+For further information regarding the dynamic section the @cite{Executable and Linkable Format (ELF)} standard.
+
+@node Environmental Variables
+@section Environmental Variables
+@c TODO: currently nothing here
+
+@env{LD_LIBRARY_PATH}
+@vindex LD_LIBRARY_PATH
+@c TODO
+
+@env{LD_PRELOAD}
+@vindex LD_PRELOAD
+@c TODO
+
+@env{LD_DEBUG}
+@vindex LD_DEBUG
+@c TODO
+
+@env{LD_DEBUG_OUTPUT}
+@vindex LD_DEBUG_OUTPUT
+@c TODO
+
+@env{LD_PROFILE}
+@vindex LD_PROFILE
+@c TODO
+
+@env{LD_PROFILE_OUTPUT}
+@vindex LD_PROFILE_OUTPUT
+@c TODO
+
+@env{LD_HWCAP}
+@vindex LD_HWCAP
+@c TODO
+
+@env{LD_AUDIT}
+@vindex LD_AUDIT
+@c TODO
+
+@env{LD_ASSUME_KERNEL}
+@vindex LD_ASSUME_KERNEL
+@c TODO
+
+@env{LD_BIND_NOW}
+@vindex LD_BIND_NOW
+@c TODO
+
+@env{LD_BIND_NOT}
+@vindex LD_BIND_NOT
+@c TODO
+
+@env{LD_TRACE_LOADED_OBJECTS}
+@vindex LD_TRACE_LOADED_OBJECTS
+@c TODO
+
+@env{LD_TRACE_PRELINKING}
+@vindex LD_TRACE_PRELINKING
+@c TODO
+
+@env{LD_SHOW_AUXV}
+@vindex LD_SHOW_AUXV
+@c TODO
+
+@env{LD_USE_LOAD_BIAS}
+@vindex LD_USE_LOAD_BIAS
+@c TODO
+
+@env{LD_WARN}
+@vindex LD_WARN
+@c TODO
+
+@env{LD_VERBOSE}
+@vindex LD_VERBOSE
+@c TODO
+
+@env{LDD_ARGV0g}
+@vindex LDD_ARGV0g
+@c TODO
+
+@node Dynamic Linker API Functions
+@section Dynamic Linker API Functions
+@cindex Dynamic Linker API Functions
+@Theglibc in conjunction with the underlying operating system provides
+several functions which can be called from applications to load
+linkable objects, most frequently libraries and plugins, and find the
+addresses of symbols within them so that they can subsequently be
+called through a function pointer. These functions are well documented
+in their associated man pages.
+
+These functions are all defined in @file{<dlfcn.h>} and exist in the
+@file{libdl} library.
+
+@findex dlopen
+@deftypefun void *dlopen(const char *@var{filename}, int @var{flag})
+@safety{@prelim{}@mtsafe{}@asunsafe{}@acunsafe{}}
+@c TODO
+@end deftypefun
+
+@findex dlmopen
+@deftypefun void *dlmopen(Lmid_t @var{lmid}, const char *@var{filename},  int @var{flag})
+@safety{@prelim{}@mtsafe{}@asunsafe{}@acunsafe{}}
+@c TODO - there isn't even a man page for this
+@end deftypefun
+
+@findex dlerror
+@deftypefun char *dlerror()
+@safety{@prelim{}@mtsafe{}@asunsafe{}@acunsafe{}}
+@c TODO
+@end deftypefun
+
+@findex dlsym
+@deftypefun void *dlsym(void *@var{handle}, const char @var{*symbol})
+@safety{@prelim{}@mtsafe{}@asunsafe{}@acunsafe{}}
+@c TODO
+@end deftypefun
+
+@findex dlclose
+@deftypefun int dlclose(void *@var{handle})
+@safety{@prelim{}@mtsafe{}@asunsafe{}@acunsafe{}}
+@c TODO
+@end deftypefun
+@node Audit Interface
+@section Audit Interface
+@cindex rtld-audit
+@cindex Audit, dynamic linking
+
+The dynamic linker provides an interface to monitor and intercept its
+functioning. Since this interface was modeled after the Solaris's
+audit interface, a good reference to it's operation is the Oracle
+@cite{Solaris Linker and Libraries Guide}.
+@c The linux man page for
+@c rtld-audit(7) has a brief summary of the interface.
+
+@vindex LD_AUDIT
+To run a program with an audit library, set the @env{LD_AUDIT}
+environment variable to a colon separated list of shared libraries
+which implement any subset of the functions listed above containing
+@code{la_version()} which is required to be present in all audit libraries.
+@findex la_version
+
+The current implementation of the run time linker audit interface
+currently includes the following functions.
+
+@menu
+* la_version:: Negotiate the version of the audit interface.
+* la_objsearch:: Called when searching for a library.
+* la_activity::  Called the link map is updated.
+* la_objopen:: Called when an object file is opened.
+* la_objclose:: Called just before the object file is unloaded.
+* la_preinit:: Called after libraries are loaded but before main is called.
+* la_symbind:: Called when a symbol is bound.
+* la_pltenter:: Called when entering the PLT.
+* la_pltexit:: Called when exiting the PLT.
+@end menu
+
+@node la_version
+@subsection la_version
+@deftypefun unsigned int la_version(unsigned int @var{version})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+@findex la_version
+
+This is the only function guaranteed to be implemented by the every
+version of the audit interface. It is also the only function required
+to be defined in every audit library.
+
+The parameter passed in, is the highest version of the audit interface
+that the run time linker implements. An audit library should check
+this version to make sure that the run time linker implements a
+version of the audit interface that is compatible and sufficient for
+its needs. The audit library should return the version of the
+interface that it intends to use to use. While this is likely to be
+the same as the version passed in as a parameter, it can also be an
+older version. This allows an older audit library to still work with a
+newer version of the audit interface. Currently, the run time linker
+supports all previous versions of the audit interface and it is
+expected that it will continue to provide backward compatibility with
+these older versions of the interface for the foreseeable future. It
+is unlikely that this guarantee of backward compatibility will be
+broken during the lifetime of the ELF, Executable and Linkable File,
+file format, but if the run time linker cannot support the version of
+the audit interface returned by the auditing library's la_version()
+function then that audit library will be ignored. One example where
+this might be the case is if an audit library was compiled against a
+newer version of glibc which implemented a newer version of the
+interface and it required those new capabilities to run properly. The
+audit library can also choose to return zero and the run time linker
+will then ignore that audit library.
+
+The current version of the audit interface implemented by the run time
+linker is defined as LAV_CURRENT in @file{link.h}. Thus a suggested
+implementation of @code{la_version()} without the capability to run against
+version one of the audit interface would be:
+
+@example
+#define _GNU_SOURCE
+#include <link.h>
+
+#define LAV_DESIGN 2
+#if LAV_DESIGN > LAV_CURRENT
+#error Please compile against a newer version of glibc
+#endif
+
+unsigned int la_version(unsigned int version)@{
+  if(version >= LAV_CURRENT)
+    return version;
+  return 0;
+@}
+@end example
+
+Since the difference between version one and version two of the audit
+interface are very minor. It is very likely that almost all audit
+libraries were either designed to be run against version one of the
+interface or can easily be modified to run in a backward compatibility
+mode with version one of the audit interface.
+@end deftypefun
+
+@node la_objsearch
+@subsection la_objsearch
+@deftypefun char *la_objsearch(const char *@var{name}, uintptr_t *@var{cookie}, unsigned int @var{flag})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+@findex la_objsearch
+
+Within a run time linker audit library @code{la_obsearch()} is
+invoked each time the run time dynamic linker is going to search for
+an object. This function may be called multiple times during the
+process of resolving the location of a library. Initially, the run
+time linker passes in the name of the object found from DT_NEEDED
+record in the dynamic section of the ELF header or the name passed
+into the @code{dlopen()} function. This results in the first
+invocation of the @code{la_objsearch()} function with the name of the
+name of the object being searched for and the flag being set to
+LA_SER_ORIG. Subsequent steps in the object resolution process such as
+RPATH and RUNPATH records in the ELF header or @env{LD_LIBRARY_PATH}
+passed in through the environment will result in invocations of the
+@code{la_objsearch()} function. For example a simple program that just
+needs libc for printf will result in two invocations of
+@code{la_objsearch()}. The first will be the initial search and the
+second will be from the paths found in the @file{ld.so.cache}.
+
+@pindex nm
+@pindex readelf
+@example
+$ nm ./main | grep `` U ``
+                 U __libc_start_main@@GLIBC_2.2.5
+                 U printf@@GLIBC_2.2.5
+$ readelf -d ./main | egrep ``NEEDED|RPATH|RUNPATH''
+ 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
+$ LD_AUDIT=./audit.so ./main
+name=libc.so.6 cookie=0x7f7bc625b5c8 flag=LA_SER_ORIG
+name=/lib64/libc.so.6 cookie=0x7f7bc625b5c8 flag=LA_SER_CONFIG
+@end example
+
+The possible values for flag are:
+
+@var{LA_SER_ORIG} This is the original name either found in the ELF
+dynamic header or the parameter passed in by dlopen(3).
+
+@var{LA_SER_CONFIG} This is the name found in
+@file{/etc/ld.so.cache}. Most of the time system libraries will be
+found in the cache rather than being found by using
+@var{LA_SER_DEFAULT}.
+
+@var{LA_SER_DEFAULT} This is much more unusual than might be
+expected. This will only happen if ldconfig has never been run or if
+new libraries were added to the default directories since the last
+time that ldconfig(8) was run.
+
+@var{LA_SER_LIBPATH} This flag is returned when the library is found in one
+of the directories specified in the environment variable
+@env{LD_LIBRARY_PATH}.
+@vindex LD_LIBRARY_PATH
+
+@var{LA_SER_RUNPATH} This flag is returned when the library is found
+in a directory specified in either the RPATH or RUNPATH ELF headers.
+
+The @var{cookie} is an opaque handle that refers to the object file
+which requested the object be opened. In the case of shared libraries
+needed by the original executable's object file, the @var{cookie} will
+refer to an unnamed object at the root of the link-map. When an object
+being searched for is required by another object as is the case when
+you have library dependencies, the cookie will refer to the object
+which has the dependency. In the case, where @code{dlopen} or
+@code{dlmopen} is called the cookie will refer to the object which
+initiated one of those function calls.
+@findex dlopen
+@findex dlmopen
+@end deftypefun
+
+@node la_activity
+@subsection la_activity
+@findex la_activity
+@deftypefun void la_activity( uintptr_t *@var{cookie}, unsigned int @var{flag})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+@findex dlmopen
+The dynamic linker will call the @code{la_activity()} function any
+time that it is updating the link-map. @var{cookie} identifies the
+head of the chain of link maps that is being updated. Most
+applications will have a single link-map that will be updated, the
+global link map. However an application that makes use of
+@code{dlmopen()} will have other link maps. The @var{flag} will be one
+of the following values.
+
+@vindex LA_ACT_ADD
+@var{LA_ACT_ADD} indicates that new objects are being added to the
+link map. During initial executable startup, the object that you are
+executing and ld.so and a third unnamed object that is part of the
+dynamic linker are inserted into the base link map before
+@code{la_activity} is called for the first time with @var{LA_ACT_ADD}
+indicating that the link map is going to be added to. It may be
+important for some audit libraries expecting a static link map to
+recognize that the link map may be updated without notification before
+the first call of @code{la_activity} with @var{LA_ACT_ADD}.
+
+@findex dlclose
+@vindex LA_ACT_DELETE
+@var{LA_ACT_DELETE} indicates that objects are being removed from the link
+map. This only will happen as a result of a @code{dlclose} function
+call.
+
+@vindex LA_ACT_CONSISTENT
+@var{LA_ACT_CONSISTENT} indicates that the link-map activity has finished
+and that the link-map is now consistent.
+
+If an application doesn't call any of the @code{dl*} functions, then
+before starting @code{main} then the dynamic linker will first add the
+shared libraries and then report that the link map is consistent. It
+does not repeatedly call la_activity each and every time a library is
+added to the link map. For that, an audit library should implement
+@code{la_objopen()}.
+@findex la_objopen
+
+@example
+$ readelf -d /usr/bin/ls | grep NEEDED
+0x0000000000000001 (NEEDED)             Shared library: [libselinux.so.1]
+0x0000000000000001 (NEEDED)             Shared library: [libcap.so.2]
+0x0000000000000001 (NEEDED)             Shared library: [libacl.so.1]
+0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
+$ LD_AUDIT=./audit.so ls
+cookie=0x7fcd7463d5c8  flag=LA_ACT_ADD
+cookie=0x7fcd7463d5c8  flag=LA_ACT_CONSISTENT
+@end example
+@end deftypefun
+
+@node la_objopen
+@subsection la_objopen
+@findex la_objopen
+@deftypefun unsigned int la_objopen( struct link_map *@var{map}, Lmid_t @var{lmid}, uintptr_t *@var{cookie})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+The @code{la_objopen} function is called every time an object is added
+to the link map. The first time that it is called is when the actual
+binary that you are running is loaded. Since this is before even the
+dynamic linker is fully loaded, the @var{l_name} is not set. The next
+time it is run is when the dynamic linker itself being loaded. This
+brings along another unnamed object in the link map. After that, every
+shared library triggers a call to @code{la_objopen}.
+
+@findex la_symbind
+@findex la_pltenter
+@findex la_pltexit
+Implementing @code{la_objopen} is practically required in every audit
+library that is interested in implementing @code{la_symbind},
+@code{la_pltenter}, @code{la_pltexit} because it must set flags when
+the object is being opened that indicate to the dynamic linker that
+further auditing is desired.
+
+@findex dlopen
+@findex dlmopen
+@vindex LM_ID_BASE
+@vindex LM_ID_NEWLM
+There can be multiple @code{link_maps}. When an object is loaded at
+process startup or with the normal @code{dlopen} function, then
+@var{lmid} will be set to @var{LM_ID_BASE}. However when an object is
+opened with @code{dlmopen}, lmid will be set to @var{LM_ID_NEWLM}
+indicating that the object has been loaded into its own link map.
+
+The link map is the top of a NULL terminated doubly linked list of
+@code{link_map} structures. In the case of the base link map, at the
+root of the list are three objects. The first is the executable being
+run and the other two are part of the dynamic linker itself.
+
+The cookie is an opaque handle that associates operations pertaining
+to that object to an object being loaded. Since, this is the first use
+of each cookie, the cookie provided to @code{la_objopen} serves as the
+declaration of cookie for subsequent use.
+
+@vindex LA_FLG_NOBIND
+@vindex LA_FLG_BINDFROM
+@vindex LA_FLG_BINDTO
+@findex la_symbind
+The return value of the function is either @var{LA_FLG_NOBIND} which
+is defined to be zero, or it is a bitwise OR of one or more of
+@var{LA_FLG_BINDFROM} and @var{LA_FLG_BINDTO}.  For the
+@code{la_symbind} function to be called, the symbol being referenced
+must be in an object where the return value of @code{la_objopen} must
+include @var{LA_FLG_BINDTO} and the object from where it is referenced
+must have had a return value that included @var{LA_FLG_BINDFROM}.
+
+If you wanted to see all the places where a particular executable
+calls a function from libc, the @code{la_objopen} might include a
+fragment of code like:
+@example
+  if(map->l_prev==NULL) // the main executable
+     retval=LA_FLG_BINDFROM;
+  if( strstr(map->l_name,"libc.so")!=NULL)
+    retval=LA_FLG_BINDTO;
+  return retval;
+@end example
+
+@vindex LA_FLG_NOBIND
+The return value of either @var{LA_FLG_NOBIND} or 0 indicates that
+no further monitoring is desired for this particular object by this
+auditing library. In other words you are not interested in auditing
+the binding of symbols within this object.
+
+Unless it is needed, it is advisable to not audit the binding of
+symbols. The auditing of the binding of symbols not without costs. In
+the normal case when a function in a separate object is first
+referenced, the location is determined and it is stored in the GOT so
+that subsequent calls do not incur additional overhead. However, when
+an object's symbol binding is audited, then each reference is
+intercepted for auditing.
+
+@vindex LA_FLG_BINDTO
+The @var{LA_FLG_BINDTO} flag is set when auditing symbols that exists
+in the object currently being opened. These are the symbols being called.
+
+@vindex LA_FLG_BINDFROM
+The @var{LA_FLG_BINDFROM} flag is set when auditing references to
+symbols that exist in other objects. These are the calls from this
+object to symbols found in other objects.
+@end deftypefun
+
+@node la_objclose
+@subsection la_objclose
+@findex la_objclose
+@deftypefun unsigned int la_objclose(uintptr_t *@var{cookie})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+This function is called after any termination code in the object has
+been executed and just prior to the object being unloaded from
+memory. The @var{cookie} is the one for the object returned by
+@var{la_objload}. Currently the return value from this function being
+is ignored.
+
+@findex dlclose
+When the libraries are loaded as part of the standard process startup,
+they are not closed when a process exits therefore this function is
+not called except as a result of @code{dlclose()}
+@end deftypefun
+
+@node la_preinit
+@subsection la_preinit
+@findex la_preinit
+@deftypefun void la_preinit(uintptr_t *@var{cookie})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+The @code{la_preinit} is called after all the shared libraries are
+loaded, the link map is consistent, and after @code{__libc_start_main}
+but before the executable object's @code{main} is called.
+
+The cookie passed in refers to the executable object being run.
+@end deftypefun
+
+@node la_symbind
+@subsection la_symbind
+@findex la_symbind
+@deftypefun uintptr_t la_symbind(Elf_Sym *@var{sym}, unsigned int @var{ndx}, uintptr_t *@var{refcook}, uintptr_t *@var{defcook}, unsigned int *@var{flags}, const char *@var{symname})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+@code{uintptr_t la_symbind(Elf_Sym *@var{sym}, unsigned int @var{ndx}, uintptr_t *@var{refcook}, uintptr_t *@var{defcook}, unsigned int *@var{flags}, const char *@var{symname})}
+
+@code{uintptr_t la_symbind64(Elf64_Sym *@var{sym}, unsigned int @var{ndx}, uintptr_t *@var{refcook}, uintptr_t *@var{defcook}, unsigned int *@var{flags}, const char *@var{symname})}
+
+The exact name and argument types of vary from architecture to
+architecture. The definition or definitions appropriate to your
+architecture can be found in @file{/usr/include/bits/link.h}. The one
+used above as an example is from the x86_64 where there are two
+versions of @code{la_symbind} one for 32 bit symbols and one for 64
+bit symbols.
+
+@findex la_objopen
+@findex la_pltenter
+@vindex LA_FLG_BINDFROM
+@vindex LA_FLG_BINDTO
+One of these functions is invoked when symbol binding occurs between
+objects. It is only called when the object from which the binding was
+triggered is marked @var{LA_FLG_BINDFROM} and the function being
+called is in an object marked @var{LA_FLG_BINDTO} by
+@code{la_obopen}. Usually, with normal lazy binding, this symbol
+binding occurs when the function is first called. This symbol binding
+occurs before the @code{la_pltenter} function is called. This symbol
+binding can occur at different times if lazy binding is not being
+used.
+
+@vindex st_name, Elf_Sym
+@var{sym} is a pointer to a Elf structure defined in
+@file{elf.h}. There are different versions of this structure with
+different word sizes for multilib systems. The structure
+includes @var{st_value} which is the function pointer to the function
+which is being called.
+
+@var{ndx} refers to the index into the table of symbols within the
+object being referred to by @var{defcook}, the cookie for the object
+where the symbol is defined. From the command line this same table
+along with its indexes can be printed by using the @command{readelf
+-s} command.
+
+The symbol is being called from the symbol referred to by
+@var{refcook}, the cookie for the object referencing the symbol.
+
+@vindex LA_SYMB_DLSYM
+@vindex LA_SYMB_ALTVALUE
+@findex dlsym
+The flags parameter is a pointer to a bit mask. The
+@var{LA_SYMB_DLSYM} indicates that the symbol was as a result of a
+call through @code{dlsym}. The other flag @var{LA_SYMB_ALTVALUE}
+indicates that @code{la_symbind} provided an alternative value for the
+symbol.
+
+@vindex LA_SYMB_NOPLTENTER
+@vindex LA_SYMB_NOPLTEXIT
+Applications wishing to prevent subsequent passes through the
+@code{ls_pltenter} or the @code{ls_pltexit} functions can or in
+@var{LA_SYMB_NOPLTENTER} and/or @var{LA_SYMB_NOPLTEXT}
+respectively. These flags can be subsequently re-enabled if
+desired. However, modifying the variable pointed to by the @var{flags}
+parameter outside of the scope of this function will lead to
+unspecified behavior.
+@end deftypefun
+
+@node la_pltenter
+@subsection la_pltenter
+@findex la_pltenter
+@deftypefun Elf64_Addr la_x86_64_gnu_pltenter (Elf64_Sym *@var{sym}, unsigned int @var{ndx}, uintptr_t *@var{refcook}, uintptr_t *@var{defcook}, La_x86_64_regs *@var{regs}, unsigned int *@var{flags}, const char *@var{symname}, long int *@var{framesizep})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+The exact name and argument types of vary from architecture to
+architecture. The definition or definitions appropriate to your
+architecture can be found in @file{/usr/include/bits/link.h}. The one
+used above as an example is from the x86_64.
+
+@vindex LA_FLG_BINDFROM
+@vindex LA_FLG_BINDTO
+@findex la_symbind
+@findex la_pltexit
+@vindex LA_SYMB_NOPLTENTER
+This function is invoked just before calling a function through the
+PLT. It is only called when the the object making the call is marked
+@var{LA_FLG_BINDFROM} and the function being called is in an object
+marked @var{LA_FLG_BINDTO} and when no previous calls to
+@code{la_sybind}, @code{la_pltenter}, or @code{la_pltexit} have set
+the @var{LA_SYMB_NOPLTENTER} bit in their @var{flags} parameter.
+
+@vindex st_name, Elf_Sym
+@var{sym} is a pointer to a Elf structure defined in
+@file{elf.h}. There are different versions of this structure with
+different word sizes for multilib systems. The structure
+includes @var{st_value} which is the function pointer to the function
+which is being called.
+
+@var{ndx} refers to the index into the table of symbols within the
+object being referred to by @var{defcook}. From the command line this
+same table along with its indexes can be printed by using the
+@command{readelf -s} command.
+
+The symbol is being called from the symbol referred to by @var{refcook}.
+
+The @var{regs} parameter is highly architecturally specific. It
+contains the registers that are used for the call to this PLT
+entry. It is defined in @file{/usr/include/bits/link.h}.
+
+@vindex LA_SYMB_DLSYM
+@vindex LA_SYMB_ALTVALUE
+@findex dlsym
+@findex la_symbind
+The flags parameter is a pointer to a bit mask and has the same
+meaning as it does as when used in la_symbind. The @var{LA_SYMB_DLSYM}
+indicates that the symbol was as a result of a call through
+@code{dlsym}. The other flag @var{LA_SYMB_ALTVALUE} indicates that
+@code{la_symbind} provided an alternative value for the symbol.
+
+@findex ls_pltenter
+@findex ls_pltexit
+@vindex LA_SYMB_NOPLTENTER
+@vindex LA_SYMB_NOPLTEXIT
+Applications wishing to prevent subsequent passes through the
+@code{ls_pltenter} or the @code{ls_pltexit} functions can or in
+@var{LA_SYMB_NOPLTENTER} and/or @var{LA_SYMB_NOPLTEXIT}
+respectively. These flags can be subsequently re-enabled if
+desired. However, modifying the variable pointed to by the @var{flags}
+parameter outside of the scope of this function will lead to
+unspecified behavior.
+
+The @var{framesizep} parameter is used to communicate back to the
+dynamic linker the size of the stack frame needed by fucntion actually
+being called when modifying the arguments to the function being
+called. Modifing the arguments to the function being called must be
+done in accordance with the ABI for the architecture. This technique
+is needed when calling functions whose ABI does not match the one for
+the original function linked to by the referring object.
+
+@end deftypefun
+
+@node la_pltexit
+@subsection la_pltexit
+@findex la_pltexit
+@deftypefun unsigned int la_i86_gnu_pltexit(Elf32_Sym *@var{sym}, unsigned int @var{ndx}, uintptr_t *@var{refcook}, uintptr_t *@var{defcook}, const La_i86_regs *@var{inregs}, La_i86_retval *@var{outregs}, const char *@var{symname})
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{}}
+
+The exact name and argument types of vary from architecture to
+architecture. The definition or definitions appropriate to your
+architecture can be found in @file{/usr/include/bits/link.h}. The one
+used above as an example is from the x86_64.
+
+@findex la_objopen
+@findex la_pltenter
+@vindex LA_FLG_BINDFROM
+@vindex LA_FLG_BINDTO
+@findex la_sybind
+This function is invoked just before control returns to the caller for
+the symbol referenced by this PLT entry. It is only called when the
+the object making the call is marked @var{LA_FLG_BINDFROM} and the
+function being called is in an object marked @var{LA_FLG_BINDTO} and
+the function being called is in an object marked @var{LA_FLG_BINDTO}
+and when no previous calls to @code{la_sybind}, @code{la_pltenter}, or
+@code{la_pltexit} have set the @var{LA_SYMB_NOPLTEXIT} bit in their
+@var{flags} parameter.
+
+@vindex st_name, Elf_Sym
+@var{sym} is a pointer to a Elf structure defined in
+@file{elf.h}. There are different versions of this structure with
+different word sizes for multilib systems. The structure
+includes @var{st_value} which is the function pointer to the function
+which is being called.
+
+@var{ndx} refers to the index into the table of symbols within the
+object being referred to by @var{defcook}. From the command line this
+same table along with its indexes can be printed by using the
+@command{readelf -s} command.
+
+The symbol is being called from the symbol referred to by @var{refcook}.
+
+The @var{inregs} and @var{outregs} are both architecture dependent
+and are defined by in @file{/usr/include/bits/link.h}. The
+@var{inregs} parameter points to a structure containing the registers
+used to call this PLT entry. Similarly, @var{outregs} points to a
+structure containing the return values for the call to this PLT
+entry. This value can be modified and the changes will be visible to
+the caller of this PLT entry.
+
+The return value for this function is currently ignored.
+@end deftypefun
diff --git a/manual/libdl.texi b/manual/libdl.texi
deleted file mode 100644
index e3fe0452d9..0000000000
--- a/manual/libdl.texi
+++ /dev/null
@@ -1,10 +0,0 @@ 
-@c FIXME these are undocumented:
-@c dladdr
-@c dladdr1
-@c dlclose
-@c dlerror
-@c dlinfo
-@c dlmopen
-@c dlopen
-@c dlsym
-@c dlvsym
diff --git a/manual/signal.texi b/manual/signal.texi
index 9577ff091d..8e2b900b49 100644
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -1,4 +1,4 @@ 
-@node Signal Handling, Program Basics, Non-Local Exits, Top
+@node Signal Handling, Dynamic Linking, Non-Local Exits, Top
 @c %MENU% How to send, block, and handle signals
 @chapter Signal Handling