 |
Index for Section 5 |
|
 |
Alphabetical listing for L |
|
 |
Bottom of page |
|
loader(5)
NAME
loader - Run-time linker and loader.
DESCRIPTION
The loader is the run-time linker and shared object loader. You invoke
loader when you run a dynamic executable. The loader maps in the main
object and any shared libraries used by it, resolves relocations as ld does
at static link time, and allocates common space in memory if required. The
loader is also referred to as rld, and some of the internal interfaces
currently reflect this naming.
The loader constructs an explicit shared object list from the list of
objects comprised by the executable. You can override the dynamic
executable's list at run time by defining the _RLD_LIST environment
variable to be a colon-separated list of objects and libraries. To append
new objects to the dynamic executable's list, specify the keyword DEFAULT
at the beginning of the new object list; to prepend new objects, specify
DEFAULT at the end of the new list. To add new objects to the middle of
the dynamic executable's list, you must explicitly enter the full object
list when defining _RLD_LIST.
The default shared library search paths include:
1. /usr/shlib
2. /usr/ccs/lib
3. /usr/lib/cmplrs/cc
4. /usr/lib
5. /usr/local/lib
6. /var/shlib
You can change and add to the shared library search paths by any of the
following mechanisms:
· Using the -soname option to the ld command when creating a shared
object.
The ld command records shared library dependencies using shared object
names (sonames). By default, an object's soname is its file name
(without a prepended path name). The -soname option allows you to
specify an alternative soname. If the soname you specify contains a
path name, the shared object loader searches for it only in the
indicated location, exactly as specified. If the soname contains a
file name, the shared object loader constructs a search path for the
object from the file name as described at the end of this list.
· Using the -rpath option to the ld command.
The -rpath option causes the linker to associate a list of shared
library search directories (separated by colons) with a call shared or
shared object. If an item in the path supplied to -rpath is of the
form $VARNAME or ${VARNAME}, the loader interprets it as an
environment variable. The rpath value used by the loader is the rpath
value from the main executable plus the rpath values of all the loaded
libraries, in load order.
· Defining the _RLD_ROOT environment variable.
The _RLD_ROOT environment variable defines a list of root directory
paths (separated by colons) that are, in turn, prepended to each
directory specified in the current rpath and to the default shared
library search paths. The _RLD_ROOT environment variable does not, by
itself, identify a list of directories to be searched. To search the
system default library directories when _RLD_ROOT is defined, you must
include the true root directory (/) as one of its entries.
· Defining the LD_LIBRARY_PATH environment variable.
The LD_LIBRARY_PATH environment variable defines a list of shared
library directories that are always searched as specified. The shared
object loader does not prepend to these directories the root directory
path prefixes defined by the _RLD_ROOT environment variable. If an
item in the list defined by the LD_LIBRARY_PATH environment variable
is of the form $VARNAME or ${VARNAME}, the loader interprets it as an
environment variable.
As mentioned in the preceding list, if the object's soname contains a path
name, the shared object loader searches for it only in the indicated
location, exactly as specified. If the soname contains a file name, the
shared object loader constructs its search path for shared objects in the
following manner:
1. The list of shared library search directories indicated by the rpath,
each prepended by any root paths defined by the _RLD_ROOT environment
variable
2. Any list of shared library search directories defined by the
LD_LIBRARY_PATH environment variable
3. The default shared library search paths, each prepended by any root
paths defined by the _RLD_ROOT environment variable
To ensure compatibility, applications may choose to disallow exec-time or
run-time library replacement. The ld(1) program supports a flag,
-no_library_replacement, to facilitate this feature.
Security also dictates that the loader will not allow library replacement
for setuid and setgid programs unless the user is root.
Loader Entry Points
The loader is invoked by the kernel to load a program for execution. The
lazy_text_resolve entry point implements lazy binding by resolving text
symbols on the fly at run time. The symbol __istart is bound to a handler
for .init sections, and is called by crt0. Before exiting, programs or
objects should call _rld_new_interface(_SHUT_DOWN) to ensure that the
program executes all of the .fini sections for all of the shared objects.
The crt0 and exit(2) library routines call _rld_new_interface(_SHUT_DOWN)
to ensure that programs linked using cc(1) will have standard handling of
.init and .fini sections.
Programmers are encouraged to use the higher level entry points dlopen(3),
dlsym(3), dlclose(3), and dlerror(3) to perform run-time library loading
and symbol resolution. The following facilities available through
_rld_new_interface are evolving and should not be used by portable
programs.
#include <rld_interface.h>
void *_rld_new_interface(Elf32_Word operation, ...)
This function returns different types of objects depending on the operation
code, so casting is required as indicated below. The following operation
codes implement some basic functionalities that are superseded for the most
part by dlopen(3), etc.:
/* Run fini routines */
(int)_rld_new_interface(_SHUT_DOWN)
/* Return first path name in object list */
(char *)_rld_new_interface(_RLD_FIRST_PATHNAME)
/* Return next path name in object list */
(char *)_rld_new_interface(_RLD_NEXT_PATHNAME)
/* Modify the object list, see rld_interface.h */
(char *)_rld_new_interface(_RLD_MODIFY_LIST,
Elf32_Word operation,
char *original_path name,
char *name)
/* Map a virtual address to a name */
(char *)_rld_new_interface(_RLD_ADDR_TO_NAME, Elf32_Addr address)
/* Map a name to a virtual address */
(Elf32_Addr)_rld_new_interface(_RLD_NAME_TO_ADDR, char *name)
/* Map an address to a symbol */
#include <dlfcn.h>
char * _rld_new_interface(_RLD_DLADDR,void *addr, Dl_info *dlip)
For /* Map an address to a symbol */, above, if the address cannot be
matched to a mapped object, a 0 is returned and both the dli_sname and
dli_saddr members (see below) are set to 0. Otherwise, a non-zero value is
returned and the dlip struct is filled in.
addr is the address to be mapped to a symbol and object. dlip is a pointer
to a preallocated Dl_info structure, whose members are:
dli_fname
Pointer to the filename of the containing object.
dli_fbase
Base address of the containing object.
dli_sname
Pointer to the symbol name nearest to the specified address. This
symbol either has the same address or is the nearest symbol with a
lower address.
dli_saddr
Contains the actual address of the above symbol.
The following operation codes are used to implement dlopen(3), etc.:
/* See dlopen(3) for details */
(void *)_rld_new_interface(_RLD_LDR_DLOPEN, char *libname, int mode)
/* See dlsym(3) for details */
(void *)_rld_new_interface(_RLD_LDR_DLSYM,
void *handle, char *symname)
/* See dlerror(3) for details */
(char *)_rld_new_interface(_RLD_LDR_DLERROR)
/* See dlclose(3) for details */
(int)_rld_new_interface(_RLD_LDR_DLCLOSE, void *handle)
The following operation codes are used internally by libc and dbx:
/* Old support for sbrk(2) */
(int)_rld_new_interface(_RLD_LDR_SBRK, int incr, char **p_oldbrk)
/* Old support for brk(2) */
(int)_rld_new_interface(_RLD_LDR_BRK, char *addr)
/* Run fini routines (the same as _RLD_SHUTDOWN) */
(int)_rld_new_interface(_RLD_LDR_CONTEXT_ATEXIT,
ldr_context_t ctxt)
/* See ldr_inq_region(3) */
(int)_rld_new_interface(_RLD_LDR_CONTEXT_INQ_REGION,
ldr_context_t ctxt,
ldr_module_t mod_id,
ldr_region_t region_no,
ldr_region_info_t *infop,
size_t sizeasked,
size_t *sizegot)
/* See ldr_inq_module(3) */
(int)_rld_new_interface(_RLD_LDR_CONTEXT_INQ_MODULE,
ldr_context_t ctxt,
ldr_module_t mod_id,
ldr_module_info_t *infop,
size_t sizeasked,
size_t *sizegot)
/* See ldr_next_module(3) */
(int)_rld_new_interface(_RLD_LDR_CONTEXT_NEXT_MODULE,
ldr_context_t ctxt,
ldr_module_t *mod_id_ptr)
In the preceding entry points, ctxt is a loader context, allowing the
possibility of querying and manipulating various environments. Currently,
ctxt must be set to ldr_process_context, which is a symbol resolved by the
loader to an internal data structure. This allows operations on the
current process.
LOADER OPTIONS
Users can specify loader options by setting the _RLD_ARGS environment
variable to a space separated list of any of the following options:
-clearstack
For programs that assume local variable to be initialized to zero upon
entry, this option forces the loader to zero any stack it uses before
returning to user code.
-ignore_all_versions
Ignore interface versions on all objects.
-ignore_version shared_object
Ignore the interface version checking on the object specified.
-ignore_unresolved
Does not complain or abort when the loader cannot resolve unresolved
data symbols.
-interact
The loader interactively prompts the user on stdin to fix problems in
the link. (The loader will ask the user to provide a full path name
for a missing shared object.)
-log file
Prints all messages to a log file instead of /dev/tty.
-log_stderr
Prints all messages to stderr instead of /dev/tty.
-log_stdout
Prints all messages to stdout instead of /dev/tty.
-reserve_taso_heap size
Changes the amount of space the loader reserves for the heap when
loading a taso application. Normally, the loader reserves approximately
256MB immediately after the main object's bss segment for use as the
heap. The size is specified as a hexadecimal number of bytes, without
a leading "0X". For example, the following environment variable
assignment will double the size of the heap to approximately 512MB:
setenv _RLD_ARGS "-reserve_taso_heap 20000000"
-start_text_packing number_of_dlopens
Determines how many shared libraries should be opened simultaneously
before the loader begins using a text-segment mapping technique that
conserves virtual address space. The default setting for
number_of_dlopens is 100. Setting this value lower increases the
chances that a process that dynamically loads a small number of shared
libraries will use more wired pages. Raising this value may reduce the
number of shared libraries that can be dynamically loaded by a process.
-stat
Prints loader statistics to /dev/tty.
-v Prints general actions.
-taso
Forces the loader to handle all objects as "truncated address space
option" objects. These are objects whose dependencies must be loaded
in the lower 31-bit-addressable virtual address range. Shared
libraries that have been linked outside this range will be relocated by
the loader.
-depth_ring_search
Forces the loader to use a depth_first, ring search method for
resolving symbol references between shared objects.
-allocator file-descriptor
-allocator_range address-range
These two options must be used together. The -allocator option
specifies an open file descriptor for the loader to use for its mmap()
calls when mapping any object whose link address is within the
address-range specified with the -allocator_range option.
The -allocator_range option specifies the lower and upper addresses
(inclusive) for which special memory allocation is to occur. The
address-range parameter consists of two hexadecimal values separated by
a colon. For example:
-allocator_range 20000000000:200ffffffff
The address range required for any segment must fall either entirely
outside or entirely within the range specified with -allocator_range.
No segment loaded in the range can conflict with the link address of
any other previously loaded segment. These options are invalid with
executables utilizing the SUID executable bit. When using these
options, you must ensure that mmap() returns memory that is suitable.
For setuid programs not run by the superuser, _RLD_ARGS is ignored.
SYMBOL BINDING
The loader can resolve symbols using either deferred or immediate binding.
Immediate binding requires that all symbols be resolved when an executable
program or shared library is loaded. Deferred ("lazy") binding allows text
symbols to be resolved at run time by the loader's lazy_text_resolve
entrypoint (described previously).
By default, programs are loaded with deferred binding. If the LD_BIND_NOW
environment variable is set to a non-null value, programs will be loaded
with immediate binding.
SYMBOL RESOLUTION
The loader's default symbol resolution policy uses a breadth-first search
of the entire dependence graph to resolve symbol references between shared
objects. The search starts from the call_shared executable, traverses
dependencies left-to-right, and ignores cycles or duplicates.
The depth ring search method is an alternative symbol resolution policy
that can be selected for an individual executable at link time, or for all
executables at run time. See ld(1) for link time options. At run time, the
loader switch -depth_ring_search is used to enable this symbol resolution
policy.
The depth ring search order is a depth-first search starting from the
referencing object, followed by a depth-first search starting from the
root. As with the default search policy, the traversal of dependencies is
performed left-to-right; cycles and duplicates are ignored.
To illustrate these differences, consider the following dependence graph:
a.out
/|\
/ | \
/ | \
/ | \
/ | \
libA libB \
| | \
| | |
libD libE |
| | |
|_____|______libC
The default symbol resolution policy uses a single breadth-first search
order to resolve symbol references for each of the objects in the preceding
dependence graph. The search order for the graph is:
Referencing Search
Object Order
All a.out libA libB libC libD libE
The depth ring search order depends on which object a symbol reference is
being resolved for. The search orders for resolving references from each
object in the sample dependence graph are as follows:
Referencing Search
Object Order
a.out a.out libA libD libC libB LibE
libA libA libD libC a.out libB LibE
libD libD libC a.out libA libB libE
libB libB libE libC a.out libA libD
libE libE libC a.out libA libD libB
The default symbol resolution policy ensures that the same symbol is
resolved for any object that references it. With depth ring search, you
can have multiple instances of a symbol, referenced from different objects.
This could introduce synchronization problems in execution, particularly if
I/O buffers are duplicated across multiple shared libraries.
Depth ring search order should be used with caution. Setting depth ring
search on an application may cause an undefined change of behavior for the
Tru64 UNIX system libraries used by the application.
SEE ALSO
ld(1), dlopen(3), dlsym(3), dlclose(3), dlerror(3), ldd(1).
 |
Index for Section 5 |
|
 |
Alphabetical listing for L |
|
 |
Top of page |
|