sgidladd(3C)
RLD(5) Last changed: 3-17-00
NAME
rld, rld.debug - Runtime linker and runtime linker with debugging
support
IMPLEMENTATION
IRIX systems
DESCRIPTION
rld, the runtime linker, exists in appropriate versions for
executables in each Application Binary Interface (ABI) available. rld
is invoked when running a dynamic executable. It maps in shared
objects used by the executable, resolves relocations as ld(1) does at
static link time, and allocates common, if required.
When any dynamic executable is run, the system first runs an
interpreter, which is responsible for collecting the appropriate
objects, mapping them into memory, and resolving references during
runtime. The name of the interpreter is included in the executable
file. Dynamic execution is only supported with ELF-format
executables. Such executables will have an INTERP section that
specifies the name of the interpreter. The default name of the
interpreter is /usr/lib/libc.so.1. Any binary that hopes to conform
to the old 32-bit MIPS SVR4 ABI should name /usr/lib/libc.so.1 as its
interpreter.
For 64-bit ABI programs, the name of the interpreter is
/usr/lib64/libc.so.1. The information on this man page applies to
64-bit programs if the directory /usr/lib64 is substituted for the
directory /usr/lib, and the directory /lib64 is substituted for /lib.
For new 32-bit ABI programs, the name of the interpreter is
/usr/lib32/libc.so.1. The information on this man page applies to new
32-bit ABI programs if the directory /usr/lib32 is substituted for the
directory /usr/lib, and the directory /lib32 is substituted for /lib.
The file /usr/lib/libc.so.1 is the standard C (or system) library in
the form of a shared object. In addition, /usr/lib/libc.so.1 contains
code that loads the interpreter into its address space and sets it to
work. The default interpreter is /lib/rld.
One of the primary features of dynamic linking is that it gives users
the ability to change library implementations without recompiling the
executable. Some mechanisms for doing this are listed below.
However, /usr/lib/libc.so.1 is not subject to any of the mechanisms
listed below, since it is known to the executable as the interpreter
as well as a needed shared object. If you want to substitute
/usr/lib/libc.so.1, the best way is to make use of ld(1) command's -I
option. The -I option can be passed from the compiler command line by
specifying the -Wl,-I,myinterpname option. However, any such shared
object specified must be able to act as interpreter (or invoke rld).
rld constructs an explicit shared object list based on the information
listed in the .liblist section. For old 32-bit ABI programs, if the
environment variable _RLD_LIST is set, it overrides the dynamic
executable's original list (after the original list is constructed).
The corresponding environment variable for 64-bit programs is
_RLD64_LIST, and for new 32-bit ABI programs it is _RLDN32_LIST.
For new 32-bit ABI or 64-bit ABI programs, if _RLDN32_LIST or
_RLD64_LIST is not specified, rld honors _RLD_LIST, if specified.
The user can include DEFAULT in _RLD_LIST (or _RLDN32_LIST or
_RLD64_LIST) to include the executable's original object list and
instruct rld to add new shared objects just before and/or after it.
The object list is specified as a colon-separated list of shared
objects. The liblists of shared objects newly added from _RLD_LIST,
_RLDN32_LIST, or _RLD64_LIST are intentionally not processed: it is
up to the user to make the list complete.
LIBRARY SEARCH PATHS
NOTE: Because there are three distinct ABIs used by IRIX programs
with accompanying libraries, there are three distinct sets of rld
search paths. In addition, there are usually 3 environment variables
for each purpose, one for each ABI.
The default library search path for old 32-bit ABI programs is
/usr/lib:/usr/lib/internal:/lib:/lib/cmplrs/cc:/usr/lib/cmplrs/cc:/opt/lib,
which can be overridden by either the _RLD_ROOT or the LD_LIBRARY_PATH
environment variable.
The default library search path for 64-bit ABI programs is
/usr/lib64:/usr/lib64/internal:/lib64:/opt/lib64, which can be
overridden by either the _RLD64_ROOT or the LD_LIBRARY64_PATH
environment variable.
The default library search path for new 32-bit ABI programs is
/usr/lib32:/usr/lib32/internal:/lib32:/opt/lib32, which can be
overridden by either the _RLDN32_ROOT or the LD_LIBRARYN32_PATH
environment variable.
For new 32-bit or 64-bit programs, if LD_LIBRARYN32_PATH or
LD_LIBRARY64_PATH is not specified, rld honors LD_LIBRARY_PATH, if
specified. As a result, if LD_LIBRARY_PATH is set for an old 32-bit
program, it is recommended that you also set LD_LIBRARYN32_PATH and
LD_LIBRARY64_PATH to something ("", for example) to avoid having
LD_LIBRARY_PATH apply accidentally to new 32-bit and 64-bit
applications in that environment.
The search path for shared objects is as follows:
1. The path of the shared object, if specified in the liblist. That
is, if the soname of the shared object has a path. For more
information, see the ld(1) man page.
2. DT_RPATH, if it is defined in the executable or any DSO that rld
has opened.
3. Use LD_LIBRARY_PATH, if it is defined in the environment at the
time of execution.
4. The default library search path.
DT_RPATH is a colon-separated list of directories. In the library
search algorithm outlined above, DT_RPATH refers to the net list of
paths at the time the search is done. It is actually a tag in the
.dynamic section of a DSO or executable whose value is a string.
DT_RPATH is set in any given DSO or the executable by specifying the
-rpath option to the ld(1) command when the executable or DSO is
created. Each DT_RPATH appends to the list of directories at the time
the executable or DSO is loaded. There is no mechanism to remove
anything from the list of directories that rld builds for the
executable.
LD_LIBRARY_PATH is a colon-separated list of directories. If defined,
it specifies an extra set of directories in which rld is to look when
searching for shared objects. LD_LIBRARY64_PATH and
LD_LIBRARYN32_PATH are treated in a similar fashion.
_RLD_ROOT is a colon-separated list of directories. If defined, the
list is appended to the front of DT_RPATH and the default path.
_RLD64_ROOT and _RLDN32_ROOT are treated in a similar fashion.
To ensure compatibility, applications can choose to disallow library
replacement at exec(2) execution time or at runtime. If the
dynamic-section flag, RHF_NO_LIBRARY_REPLACE, is set in an executable
or DSO and if the application's real userid is not zero (root), then
from the time the executable or DSO with RHF_NO_LIBRARY_REPLACE set is
mapped in to the end of the execution, LD_LIBRARY[n]_PATH and any
_RLD[n]_ROOT specifications are ignored. RHF_NO_LIBRARY_REPLACE can
be set at link time by specifying the ld(1) command's
-no_library_replace option.
Security dictates that rld should not allow library replacement or
other rld environment variables to be honored for setuid and setgid
programs unless the user is root. If capabilities apply to an
executable, the capability change also creates security concerns. In
these cases, library replacement and other rld environment variables
are not honored. For more information on capabilities, see exec(2),
capability(4) and capabilities(4).
Users can replace the default rld binary by setting the environment
variable _RLD_PATH to the full path of another runtime linker.
rld.debug is a version of rld that has debugging support. By setting
the environment variable _RLD_PATH to /usr/lib/rld.debug, it replaces
the default rld as the runtime linker, and the debugging features it
supports are available. For 64-bit programs, the environment variable
is _RLD64_PATH, and the debugging version of rld is
/usr/lib64/rld.debug. For new 32-bit ABI programs, the environment
variable is _RLDN32_PATH, and the debugging version of rld is
/usr/lib32/rld.debug.
rld also supports the environment variable LD_BIND_NOW, as documented
in the System V Application Binary Interface, Revised First Edition,
Prentice-Hall, ISBN 0-13-880410-9. If LD_BIND_NOW is set to 1 or on,
the dynamic linker processes all relocation before transferring
control to the program; if LD_BIND_NOW is set to 0 or off, or if it
does not occur in the environment, the dynamic linker can perform
symbol resolution and relocation for functions lazily, meaning that it
avoids them until the functions are called.
RUNTIME LINKING INTERFACE
dlopen(3C), dlsym(3C), dlclose(3C), dlerror(3C) sgidlopen_version(3C),
and sgidladd(3C) are provided to supply users with the on-demand
loading of objects. These routines are found in /usr/lib/libc.so.1.
No special options are needed at link time to access them.
RLD OPTIONS
The rld options are not needed to run properly coded and linked
executables, but they may be useful in special situations and for
debugging. To specify rld options, set the _RLD_ARGS environment
variable to any combination of the following options:
Option Purpose
-clearstack For programs that assume local variables to be
initialized to zero upon function entry, this option
forces rld to zero any stack it uses before before
calling the application's main program. Properly
written programs never assume that the stack is zeroed;
therefore, properly written programs do not expect
local variables to be automatically initialized except
as provided for in the programming language definition.
At startup, if a program or any of its DSOs' dynamic
section flags do not have RHF_SGI_ONLY set, -clearstack
is automatically turned on.
-f Fast mode. Turns off reresolution of symbols on
dlclose(3C). This option is on by default. It makes
rld's behavior closer to that of other systems with
dynamic loading and can substantially improve
dlclose(3C) performance. To turn off this mode and
specify slower, full reresolution, specify the -s
option.
When this option is specified, any symbol from the
application that is bound to a symbol in the DSO closed
by dlclose(3C) is a stale binding. Any reference to a
stale binding can crash the application.
-idv Ignores delay-loaded versions. By default, rld honors
version checking when loading a delay-loaded DSO. For
more information on version checking, see dso(5).
This behavior is nonstandard. It matches the behavior
of rld in previous releases. Specifying this option
restores previous behavior so that erroneous
applications can be made to work.
-ignore_all_versions
Ignores versions on all objects.
-ignore_version shared_object
Ignores the version stamp checking on the object
specified. This option can be specified multiple times
(in case multiple shared objects should have their
versions ignored).
-ignore_unresolved
Does not issue messages or abort when rld cannot
resolve unresolved data symbols.
-log file Prints all messages to file instead of to the device
/dev/tty. If /dev/tty is not available, the system log
/var/adm/SYSLOG is used instead.
-s Slow mode. Performs full reresolution of symbols on
dlclose(3C). Behavior obtained when this option is
specified is the opposite of that obtained when -f is
specified. This makes dlclose(3C) slower and can
result in a symbol binding effectively moving from a
previous binding (eliminated by the dlclose(3C) itself)
to a new one.
This behavior is nonstandard. It matches the behavior
of rld in previous releases. Specifying this option
restores previous behavior so that erroneous
applications can be made to work.
RLD.DEBUG OPTIONS
For rld.debug to be invoked, certain environment variables must be
set, as follows:
ABI Environment Variable and Setting
Old 32-bit ABI _RLD_PATH set to /usr/lib/rld.debug
New 32-bit ABI _RLDN32_PATH set to /usr/lib32/rld.debug
64-bit ABI _RLD64_PATH set to /usr/lib64/rld.debug.
The options to rld described in the previous section are honored by
rld.debug. In addition to those options, rld.debug supports
additional options; these, too, must be set in the _RLD_ARGS
environment variable. The rld.debug options are as follows:
Option Purpose
-debug symbol Prints a verbose description of the actions taken
resolving all symbols. The option consists of the
two literal words debug and symbol. This produces
a lot of output, so it is normally most useful to
also use the -log option to direct the output to a
file. If you know the symbols you are interested
in, use one or more instances of the -y option.
-quickstart_info Informs the user whether or not Quickstart has
failed.
-trace Shows rld code flow and prints individual symbol
actions.
-v Prints rld actions at the level of the DSO not at
the symbol level. -v is less verbose than -trace.
-yname Prints a verbose description of the actions taken
resolving name. Note that there is no space
permitted after the -y. As many -y options as
needed can be specified. For example, to print
descriptions of the actions on symbols pear and
grape, specify the following:
-ypear -ygrape
RLD ENTRY POINTS
rld commences execution when exec(2) starts up a program using a DSO
and when lazy text resolution commences during program execution.
When exiting, programs or objects call _rld_new_interface(_SHUT_DOWN)
to ensure that the program executes all of the code specified by the
-fini option to ld(1). _exit(2) calls _rld_new_interface(_SHUT_DOWN).
Any call to _rld_new_interface(_SHUT_DOWN) runs the -fini code on all
objects, meaning that it cannot safely be done just anywhere. Note
that _rld_new_interface(_SHUT_DOWN) is an internal routine and should
not be called by any application.
SYSTEM DEVELOPER'S INTERFACE
rld keeps a doubly linked list of structures. crt1.o contains a
pointer, __rld_obj_head, to the head of the list of object structures.
This pointer's targets depend on the ABI, as follows:
* For an old 32-bit executable, __rld_obj_head points to a linked list
of objList structures (/usr/include/obj_list.h). Each of these
structures has a data element that is a pointer to a struct obj
(/usr/include/obj.h), even though the field is not declared as a
pointer.
* For a new 32-bit executable, __rld_obj_head points to a linked list
of Elf32_Obj_Info structures: /usr/include/objlist.h.
* For a 64-bit executable, __rld_obj_head points to a linked list of
Elf64_Obj_Info structures: /usr/include/objlist.h.
The oi_magic element of each Elf32_Obj_Info or Elf64_Obj_Info is allbits-on (0xffffffff) to make it easier to determine which list type in
use is a 32-bit executable.
ENTRY POINTS
NOTE: The interfaces described in this subsection are for system
development only. They are not recommended nor supported for use in
end-user code. They are described here for the benefit of system
developers.
The declarations for the interfaces are in
/usr/include/rld_interface.h.
The following is a list of currently defined operations:
* (int)_rld_new_interface(_SHUT_DOWN). This function calls the
routine specified by the -fini option to ld(1) on all open DSOs (and
the main program) in the reverse of the order that the -init
sections were run.
* (char *)_rld_new_interface(_RLD_FIRST_PATHNAME). This function
returns the string MAIN and resets an rld internal pointer to set up
for calls to (char *)_rld_new_interface(_RLD_NEXT_PATHNAME)
This interface is not thread-safe. Multiple threads doing this will
get erroneous results. Any call to
_rld_new_interface(_RLD_MODIFY_LIST,p) after calling
_rld_new_interface(_RLD_FIRST_PATHNAME) and before calling
_rld_new_interface(_RLD_NEXT_PATHNAME) interferes with the
correctness of the rld_new_interface(_RLD_NEXT_PATHNAME) returns.
Any operation (including delay-loading a DSO as a result of lazy
function evaluation) that causes the DSO list to be altered can
interfere with the correctness of
_rld_new_interface(_RLD_NEXT_PATHNAME) returns.
* (char *)_rld_new_interface(_RLD_NEXT_PATHNAME). This function
returns the next path name in rld's object list and increments its
internal pointer. It returns NULL when rld reaches the end of the
list. This interface is not thread-safe; multiple threads doing
this will get erroneous results.
Calls to _rld_new_interface(_RLD_NEXT_PATHNAME) cannot be
interspersed with calls to _rld_new_interface(_RLD_MODIFY_LIST,....
Doing so will interfere with the correctness of the
_rld_new_interface(_RLD_NEXT_PATHNAME) returns. Any operation,
including delay-loading a DSO as a result of lazy function
evaluation, that alters the DSO list may interfere with the
correctness of the _rld_new_interface(_RLD_NEXT_PATHNAME) returns.
* (char *)_rld_new_interface(_RLD_MODIFY_LIST, Elf32_Word operation,
char *original_pathname, char *name). This function allows users to
link and unlink objects. When users insert or add an object, they
must specify the new object in name. They may specify a full path
or take advantage of rld's searching mechanism. Users are not
allowed to insert before MAIN. If original_pathname is zero, rld
operates on the last element in the list. The exact function
performed depends on the parameter operation, which can take the
following values:
operation Function Performed
_RLD_OP_NONE Does nothing.
_RLD_OP_INSERT Adds a new object specified by name before the
object specified by original_pathname. Objects
cannot be added before main().
_RLD_OP_ADD Adds a new object specified by name after the
object specified by original_pathname. If
original_pathname is omitted, the new object is
appended to the object list.
_RLD_OP_DELETE Deletes original_pathname from the object list.
_RLD_OP_REPLACE Replaces original_pathname with the object
specified by name in the object list.
* (char *)_rld_new_interface(_RLD_ADDR_TO_NAME, Elf32_Addr address).
This function returns either the symbol name of address argument or
NULL (if no symbol corresponds to that address in the current
process). In a 64-bit application, the second argument is of type
Elf64_Addr.
* (Elf32_Addr)_rld_new_interface(_RLD_NAME_TO_ADDR, char *name). This
function returns the actual address of name. It returns NULL if rld
cannot find the passed argument. In a 64-bit application, the value
returned is of type Elf64_addr.
* (char *)_rld_new_interface(_RLD_VERSION_EXPECTED, char *soname).
This function returns the version string in MAIN's liblist entry for
soname.
* (Elf32_Addr)_rld_new_interface(_RLD_SPROC_NOTIFY). This function
signals to rld that sproc(2) has been called and that rld has to
handle multiple sproc threads. The call is made by libc.so.
* (Elf32_Addr)_rld_new_interface(_RLD_SHUTDOWN_THREAD). This function
signals to rld that a thread is trying to exit. Currently does
nothing when invoked.
* (Elf32_Addr)_rld_new_interface(_RLD_SPROC_FINI). This function
signals to rld that multiple sproc(2) threads support can be turned
off. It is called on behalf of, and in, the child process after a
fork(2) by the fork code in libc.so.
EXAMPLES
The following csh(1) aliases control rld tracing. There are three
sets of tracing aliases, one for each ABI. See file(1) for
information on how to identify the ABI of a particular executable.
The following alias pertains to old 32-bit executables:
# trace o32 rld issues
alias ra \
'setenv _RLD_PATH /usr/lib/rld.debug ;'\
'setenv _RLD_ARGS "\!*" ;'
alias nora \
'unsetenv _RLD_ARGS ;'\
'setenv _RLD_PATH /lib/rld ;'
The following alias pertains to new 32-bit executables:
# trace n32 rld issues
alias ra32 \
'setenv _RLDN32_PATH /usr/lib32/rld.debug ;'\
'setenv _RLD_ARGS "\!*" ;'
alias nora32 \
'unsetenv _RLD_ARGS ;'\
'setenv _RLDN32_PATH /lib32/rld ;'
The following alias pertains to 64-bit executables:
# trace 64 rld issues
alias ra64 \
'setenv _RLD64_PATH /usr/lib64/rld.debug ;'\
'setenv _RLD_ARGS "\!*" ;'
alias nora64 \
'unsetenv _RLD_ARGS ;'\
'setenv _RLD64_PATH /lib64/rld ;'
The following examples shows how the aliases are used.
The first traces rld when it is running an old 32-bit binary (ls(1)):
% ra -trace <-- turns on tracing of o32 rld
% ls
27312:[rld] Entering RLD through MAIN
27312:ls: [rld] mapped ls at 0x400000
27312:ls: [rld] mapped /lib/libc.so.1 at 0xfa00000
27312:ls: [rld] found _end in ls for libc.so.1 at 0x10007000
27312:ls: [rld] number of objs in the objlist is 2
27312:ls: [rld] Exiting RLD through MAIN
RCS libX11.so.2 libc.so libl.a setup
acrt1.o libXaw.a libc.so.1 libm.a sgicc.cfg
crt1.o libXext.a libc.so.O libmld.a sgild.cfg
% nora <-- turns off all o32 rld debugging options.
The following traces rld when it is running a new 32-bit binary
(ci(1)):
% ra32 -v <-- turns on verbose mode in n32 rld
% ci -l c.c
14891:_RLD_ARGS = "-v"
14891:_RLD_ROOT = /
14891:LD_LIBRARYN32_PATH = none
14891:ci: mapped ci at 0x10000000
14891:ci: mapped /usr/lib32/libc.so.1 at 0xfa00000
RCS/c.c,v <-- c.c
file is unchanged; reverting to previous revision 1.1
done
% nora32 <-- turns off all n32 rld debugging options.
ERROR REPORTING
Most error messages are written to /dev/tty. If rld encounters an
error condition for a process without a valid /dev/tty attached, it
writes the message to /var/adm/SYSLOG. The system log is written
using calls to syslog(3C).
CHANGING ROOT
A copy of the device /dev/zero is essential to the operation of rld.
In most uses of chroot(1M), it is necessary to put a copy of /dev/zero
in the newly-created root.
NOTES
Listing a particular DSO in _RLD_LIST is likely to lead to problems
and failures unless all three ABI-specific environment variables are
set. A typical result is a message such as the following:
rld: Fatal Error: Cannot Successfully map soname
For example, consider an old 32-bit test application a.out and a
specific old 32-bit DSO, /tmp/mydso.so:
unsetenv _RLDN32_LIST _RLD64_LIST
setenv _RLD_LIST "/tmp/mydso.so:DEFAULT"
./a.out
This will likely fail because some command, or the application itself,
will attempt to fork(2) or exec(2) some new 32-bit application, and
/tmp/mydso.so is an old 32-bit DSO, not a new 32-bit DSO.
_RLDN32_LIST and _RLD64_LIST do not suffer from this; they are only
interpreted in a single ABI each. See the description of _RLD_LIST
earlier in this man page.
Adding the following will fix the problem in this example:
setenv _RLDN32_LIST DEFAULT
setenv _RLD64_LIST DEFAULT
DIAGNOSTICS
The meaning of the following message from rld is difficult to
understand:
The aggregate IEEE exceptions required (OEX_FPU_MIN)
(0xnn) not as complete as the aggregate IEEE
exceptions permitted (OEX_FPU_MAX>>8)(0xnn).
As the executable and each DSO is accessed before the application
begins to run, information in the .MIPS.options section is used to
compute an aggregate set of floating-point exceptions to enable. The
.MIPS.options section can be examined with the elfdump(1) command's
-op option.
For example, specifying the -trapuv compiler option results in a
request that invalid exception trapping be enabled. Using certain
high optimizations in conjunction with the -mips4 and -mips3 compiler
options, however, requires that those exceptions be turned off so that
speculative loads of floating-point values can be executed silently.
For more information, see the compiler options
-TARG:exc_max=[I][U][O][Z][V], -TARG:exc_min=[I][U][O][Z][V], and
-TENV:X=0..5.
Delay-loaded DSOs and DSOs opened with dlopen(3C) or loaded with
or
dlopen(3C) is called. The OEX_FPU_MIN field of each object is OR'd
with the others. The nonzero bits represent the set of floating-point
exceptions that the application wants to catch (more precisely,
exceptions that some part of the application or a DSO want to catch).
The OR'd-together OEX_FPU_MIN fields are used to determine what
set_fpc_csr() fields to set to 1; rld never sets any set_fpc_csr()
fields to zero.
The OEX_FPU_MAX field of each object is AND'd with the others. The
zero bits represent floating-point exceptions that must not be caught.
For example, if the code generator is issuing speculative loads, the
invalid-value exception should not be caught. If some bits are OFF in
OEX_FPU_MAX that are ON in OEX_FPU_MIN, that represents an impossible
scenario: exceptions must be caught and simultaneously must not be.
For example, this could happen if an object is compiled requesting
that uninitialized variables be trapped and a high optimization that
results in the code generator issuing speculative loads.
As each DSO is opened with dlopen(3C), delay-loaded, loaded using
sgidladd(3C), or closed with dlclose(3C), these flags are
recalculated. If user or library code has changed the five
exception-flag-enable fields from a previous setting by using rld, rld
stops updating the exception-enable fields for the execution.
rld never turns off exception-enable flags once it has turned them on.
Use the following to see the OEX fields of an executable or DSOs:
elfdump -op objectname
SEE ALSO
cc(1), chroot(1M), ci(1), csh(1), elfdump(1), file(1), ld(1), ls(1).
exec(2), exit(2), fork(2), sproc(2).
dlclose(3C), dlerror(3C), dlopen(3C), dlsym(3C), sgidladd(3C),
sgidlopen_version(3C), sgigetdsoversion(3C), syslog(3C).
capabilities(4), capability(4).
dso(5), gp_overflow(5).
System V Application Binary Interface
System V Application Binary Interface: MIPS Processor Supplement
MIPSpro N32 ABI Handbook
This man page is available only online.
RLD(5) Last changed: 3-17-00
NAME
rld, rld.debug - Runtime linker and runtime linker with debugging
support
IMPLEMENTATION
IRIX systems
DESCRIPTION
rld, the runtime linker, exists in appropriate versions for
executables in each Application Binary Interface (ABI) available. rld
is invoked when running a dynamic executable. It maps in shared
objects used by the executable, resolves relocations as ld(1) does at
static link time, and allocates common, if required.
When any dynamic executable is run, the system first runs an
interpreter, which is responsible for collecting the appropriate
objects, mapping them into memory, and resolving references during
runtime. The name of the interpreter is included in the executable
file. Dynamic execution is only supported with ELF-format
executables. Such executables will have an INTERP section that
specifies the name of the interpreter. The default name of the
interpreter is /usr/lib/libc.so.1. Any binary that hopes to conform
to the old 32-bit MIPS SVR4 ABI should name /usr/lib/libc.so.1 as its
interpreter.
For 64-bit ABI programs, the name of the interpreter is
/usr/lib64/libc.so.1. The information on this man page applies to
64-bit programs if the directory /usr/lib64 is substituted for the
directory /usr/lib, and the directory /lib64 is substituted for /lib.
For new 32-bit ABI programs, the name of the interpreter is
/usr/lib32/libc.so.1. The information on this man page applies to new
32-bit ABI programs if the directory /usr/lib32 is substituted for the
directory /usr/lib, and the directory /lib32 is substituted for /lib.
The file /usr/lib/libc.so.1 is the standard C (or system) library in
the form of a shared object. In addition, /usr/lib/libc.so.1 contains
code that loads the interpreter into its address space and sets it to
work. The default interpreter is /lib/rld.
One of the primary features of dynamic linking is that it gives users
the ability to change library implementations without recompiling the
executable. Some mechanisms for doing this are listed below.
However, /usr/lib/libc.so.1 is not subject to any of the mechanisms
listed below, since it is known to the executable as the interpreter
as well as a needed shared object. If you want to substitute
/usr/lib/libc.so.1, the best way is to make use of ld(1) command's -I
option. The -I option can be passed from the compiler command line by
specifying the -Wl,-I,myinterpname option. However, any such shared
object specified must be able to act as interpreter (or invoke rld).
rld constructs an explicit shared object list based on the information
listed in the .liblist section. For old 32-bit ABI programs, if the
environment variable _RLD_LIST is set, it overrides the dynamic
executable's original list (after the original list is constructed).
The corresponding environment variable for 64-bit programs is
_RLD64_LIST, and for new 32-bit ABI programs it is _RLDN32_LIST.
For new 32-bit ABI or 64-bit ABI programs, if _RLDN32_LIST or
_RLD64_LIST is not specified, rld honors _RLD_LIST, if specified.
The user can include DEFAULT in _RLD_LIST (or _RLDN32_LIST or
_RLD64_LIST) to include the executable's original object list and
instruct rld to add new shared objects just before and/or after it.
The object list is specified as a colon-separated list of shared
objects. The liblists of shared objects newly added from _RLD_LIST,
_RLDN32_LIST, or _RLD64_LIST are intentionally not processed: it is
up to the user to make the list complete.
LIBRARY SEARCH PATHS
NOTE: Because there are three distinct ABIs used by IRIX programs
with accompanying libraries, there are three distinct sets of rld
search paths. In addition, there are usually 3 environment variables
for each purpose, one for each ABI.
The default library search path for old 32-bit ABI programs is
/usr/lib:/usr/lib/internal:/lib:/lib/cmplrs/cc:/usr/lib/cmplrs/cc:/opt/lib,
which can be overridden by either the _RLD_ROOT or the LD_LIBRARY_PATH
environment variable.
The default library search path for 64-bit ABI programs is
/usr/lib64:/usr/lib64/internal:/lib64:/opt/lib64, which can be
overridden by either the _RLD64_ROOT or the LD_LIBRARY64_PATH
environment variable.
The default library search path for new 32-bit ABI programs is
/usr/lib32:/usr/lib32/internal:/lib32:/opt/lib32, which can be
overridden by either the _RLDN32_ROOT or the LD_LIBRARYN32_PATH
environment variable.
For new 32-bit or 64-bit programs, if LD_LIBRARYN32_PATH or
LD_LIBRARY64_PATH is not specified, rld honors LD_LIBRARY_PATH, if
specified. As a result, if LD_LIBRARY_PATH is set for an old 32-bit
program, it is recommended that you also set LD_LIBRARYN32_PATH and
LD_LIBRARY64_PATH to something ("", for example) to avoid having
LD_LIBRARY_PATH apply accidentally to new 32-bit and 64-bit
applications in that environment.
The search path for shared objects is as follows:
1. The path of the shared object, if specified in the liblist. That
is, if the soname of the shared object has a path. For more
information, see the ld(1) man page.
2. DT_RPATH, if it is defined in the executable or any DSO that rld
has opened.
3. Use LD_LIBRARY_PATH, if it is defined in the environment at the
time of execution.
4. The default library search path.
DT_RPATH is a colon-separated list of directories. In the library
search algorithm outlined above, DT_RPATH refers to the net list of
paths at the time the search is done. It is actually a tag in the
.dynamic section of a DSO or executable whose value is a string.
DT_RPATH is set in any given DSO or the executable by specifying the
-rpath option to the ld(1) command when the executable or DSO is
created. Each DT_RPATH appends to the list of directories at the time
the executable or DSO is loaded. There is no mechanism to remove
anything from the list of directories that rld builds for the
executable.
LD_LIBRARY_PATH is a colon-separated list of directories. If defined,
it specifies an extra set of directories in which rld is to look when
searching for shared objects. LD_LIBRARY64_PATH and
LD_LIBRARYN32_PATH are treated in a similar fashion.
_RLD_ROOT is a colon-separated list of directories. If defined, the
list is appended to the front of DT_RPATH and the default path.
_RLD64_ROOT and _RLDN32_ROOT are treated in a similar fashion.
To ensure compatibility, applications can choose to disallow library
replacement at exec(2) execution time or at runtime. If the
dynamic-section flag, RHF_NO_LIBRARY_REPLACE, is set in an executable
or DSO and if the application's real userid is not zero (root), then
from the time the executable or DSO with RHF_NO_LIBRARY_REPLACE set is
mapped in to the end of the execution, LD_LIBRARY[n]_PATH and any
_RLD[n]_ROOT specifications are ignored. RHF_NO_LIBRARY_REPLACE can
be set at link time by specifying the ld(1) command's
-no_library_replace option.
Security dictates that rld should not allow library replacement or
other rld environment variables to be honored for setuid and setgid
programs unless the user is root. If capabilities apply to an
executable, the capability change also creates security concerns. In
these cases, library replacement and other rld environment variables
are not honored. For more information on capabilities, see exec(2),
capability(4) and capabilities(4).
Users can replace the default rld binary by setting the environment
variable _RLD_PATH to the full path of another runtime linker.
rld.debug is a version of rld that has debugging support. By setting
the environment variable _RLD_PATH to /usr/lib/rld.debug, it replaces
the default rld as the runtime linker, and the debugging features it
supports are available. For 64-bit programs, the environment variable
is _RLD64_PATH, and the debugging version of rld is
/usr/lib64/rld.debug. For new 32-bit ABI programs, the environment
variable is _RLDN32_PATH, and the debugging version of rld is
/usr/lib32/rld.debug.
rld also supports the environment variable LD_BIND_NOW, as documented
in the System V Application Binary Interface, Revised First Edition,
Prentice-Hall, ISBN 0-13-880410-9. If LD_BIND_NOW is set to 1 or on,
the dynamic linker processes all relocation before transferring
control to the program; if LD_BIND_NOW is set to 0 or off, or if it
does not occur in the environment, the dynamic linker can perform
symbol resolution and relocation for functions lazily, meaning that it
avoids them until the functions are called.
RUNTIME LINKING INTERFACE
dlopen(3C), dlsym(3C), dlclose(3C), dlerror(3C) sgidlopen_version(3C),
and sgidladd(3C) are provided to supply users with the on-demand
loading of objects. These routines are found in /usr/lib/libc.so.1.
No special options are needed at link time to access them.
RLD OPTIONS
The rld options are not needed to run properly coded and linked
executables, but they may be useful in special situations and for
debugging. To specify rld options, set the _RLD_ARGS environment
variable to any combination of the following options:
Option Purpose
-clearstack For programs that assume local variables to be
initialized to zero upon function entry, this option
forces rld to zero any stack it uses before before
calling the application's main program. Properly
written programs never assume that the stack is zeroed;
therefore, properly written programs do not expect
local variables to be automatically initialized except
as provided for in the programming language definition.
At startup, if a program or any of its DSOs' dynamic
section flags do not have RHF_SGI_ONLY set, -clearstack
is automatically turned on.
-f Fast mode. Turns off reresolution of symbols on
dlclose(3C). This option is on by default. It makes
rld's behavior closer to that of other systems with
dynamic loading and can substantially improve
dlclose(3C) performance. To turn off this mode and
specify slower, full reresolution, specify the -s
option.
When this option is specified, any symbol from the
application that is bound to a symbol in the DSO closed
by dlclose(3C) is a stale binding. Any reference to a
stale binding can crash the application.
-idv Ignores delay-loaded versions. By default, rld honors
version checking when loading a delay-loaded DSO. For
more information on version checking, see dso(5).
This behavior is nonstandard. It matches the behavior
of rld in previous releases. Specifying this option
restores previous behavior so that erroneous
applications can be made to work.
-ignore_all_versions
Ignores versions on all objects.
-ignore_version shared_object
Ignores the version stamp checking on the object
specified. This option can be specified multiple times
(in case multiple shared objects should have their
versions ignored).
-ignore_unresolved
Does not issue messages or abort when rld cannot
resolve unresolved data symbols.
-log file Prints all messages to file instead of to the device
/dev/tty. If /dev/tty is not available, the system log
/var/adm/SYSLOG is used instead.
-s Slow mode. Performs full reresolution of symbols on
dlclose(3C). Behavior obtained when this option is
specified is the opposite of that obtained when -f is
specified. This makes dlclose(3C) slower and can
result in a symbol binding effectively moving from a
previous binding (eliminated by the dlclose(3C) itself)
to a new one.
This behavior is nonstandard. It matches the behavior
of rld in previous releases. Specifying this option
restores previous behavior so that erroneous
applications can be made to work.
RLD.DEBUG OPTIONS
For rld.debug to be invoked, certain environment variables must be
set, as follows:
ABI Environment Variable and Setting
Old 32-bit ABI _RLD_PATH set to /usr/lib/rld.debug
New 32-bit ABI _RLDN32_PATH set to /usr/lib32/rld.debug
64-bit ABI _RLD64_PATH set to /usr/lib64/rld.debug.
The options to rld described in the previous section are honored by
rld.debug. In addition to those options, rld.debug supports
additional options; these, too, must be set in the _RLD_ARGS
environment variable. The rld.debug options are as follows:
Option Purpose
-debug symbol Prints a verbose description of the actions taken
resolving all symbols. The option consists of the
two literal words debug and symbol. This produces
a lot of output, so it is normally most useful to
also use the -log option to direct the output to a
file. If you know the symbols you are interested
in, use one or more instances of the -y option.
-quickstart_info Informs the user whether or not Quickstart has
failed.
-trace Shows rld code flow and prints individual symbol
actions.
-v Prints rld actions at the level of the DSO not at
the symbol level. -v is less verbose than -trace.
-yname Prints a verbose description of the actions taken
resolving name. Note that there is no space
permitted after the -y. As many -y options as
needed can be specified. For example, to print
descriptions of the actions on symbols pear and
grape, specify the following:
-ypear -ygrape
RLD ENTRY POINTS
rld commences execution when exec(2) starts up a program using a DSO
and when lazy text resolution commences during program execution.
When exiting, programs or objects call _rld_new_interface(_SHUT_DOWN)
to ensure that the program executes all of the code specified by the
-fini option to ld(1). _exit(2) calls _rld_new_interface(_SHUT_DOWN).
Any call to _rld_new_interface(_SHUT_DOWN) runs the -fini code on all
objects, meaning that it cannot safely be done just anywhere. Note
that _rld_new_interface(_SHUT_DOWN) is an internal routine and should
not be called by any application.
SYSTEM DEVELOPER'S INTERFACE
rld keeps a doubly linked list of structures. crt1.o contains a
pointer, __rld_obj_head, to the head of the list of object structures.
This pointer's targets depend on the ABI, as follows:
* For an old 32-bit executable, __rld_obj_head points to a linked list
of objList structures (/usr/include/obj_list.h). Each of these
structures has a data element that is a pointer to a struct obj
(/usr/include/obj.h), even though the field is not declared as a
pointer.
* For a new 32-bit executable, __rld_obj_head points to a linked list
of Elf32_Obj_Info structures: /usr/include/objlist.h.
* For a 64-bit executable, __rld_obj_head points to a linked list of
Elf64_Obj_Info structures: /usr/include/objlist.h.
The oi_magic element of each Elf32_Obj_Info or Elf64_Obj_Info is allbits-on (0xffffffff) to make it easier to determine which list type in
use is a 32-bit executable.
ENTRY POINTS
NOTE: The interfaces described in this subsection are for system
development only. They are not recommended nor supported for use in
end-user code. They are described here for the benefit of system
developers.
The declarations for the interfaces are in
/usr/include/rld_interface.h.
The following is a list of currently defined operations:
* (int)_rld_new_interface(_SHUT_DOWN). This function calls the
routine specified by the -fini option to ld(1) on all open DSOs (and
the main program) in the reverse of the order that the -init
sections were run.
* (char *)_rld_new_interface(_RLD_FIRST_PATHNAME). This function
returns the string MAIN and resets an rld internal pointer to set up
for calls to (char *)_rld_new_interface(_RLD_NEXT_PATHNAME)
This interface is not thread-safe. Multiple threads doing this will
get erroneous results. Any call to
_rld_new_interface(_RLD_MODIFY_LIST,p) after calling
_rld_new_interface(_RLD_FIRST_PATHNAME) and before calling
_rld_new_interface(_RLD_NEXT_PATHNAME) interferes with the
correctness of the rld_new_interface(_RLD_NEXT_PATHNAME) returns.
Any operation (including delay-loading a DSO as a result of lazy
function evaluation) that causes the DSO list to be altered can
interfere with the correctness of
_rld_new_interface(_RLD_NEXT_PATHNAME) returns.
* (char *)_rld_new_interface(_RLD_NEXT_PATHNAME). This function
returns the next path name in rld's object list and increments its
internal pointer. It returns NULL when rld reaches the end of the
list. This interface is not thread-safe; multiple threads doing
this will get erroneous results.
Calls to _rld_new_interface(_RLD_NEXT_PATHNAME) cannot be
interspersed with calls to _rld_new_interface(_RLD_MODIFY_LIST,....
Doing so will interfere with the correctness of the
_rld_new_interface(_RLD_NEXT_PATHNAME) returns. Any operation,
including delay-loading a DSO as a result of lazy function
evaluation, that alters the DSO list may interfere with the
correctness of the _rld_new_interface(_RLD_NEXT_PATHNAME) returns.
* (char *)_rld_new_interface(_RLD_MODIFY_LIST, Elf32_Word operation,
char *original_pathname, char *name). This function allows users to
link and unlink objects. When users insert or add an object, they
must specify the new object in name. They may specify a full path
or take advantage of rld's searching mechanism. Users are not
allowed to insert before MAIN. If original_pathname is zero, rld
operates on the last element in the list. The exact function
performed depends on the parameter operation, which can take the
following values:
operation Function Performed
_RLD_OP_NONE Does nothing.
_RLD_OP_INSERT Adds a new object specified by name before the
object specified by original_pathname. Objects
cannot be added before main().
_RLD_OP_ADD Adds a new object specified by name after the
object specified by original_pathname. If
original_pathname is omitted, the new object is
appended to the object list.
_RLD_OP_DELETE Deletes original_pathname from the object list.
_RLD_OP_REPLACE Replaces original_pathname with the object
specified by name in the object list.
* (char *)_rld_new_interface(_RLD_ADDR_TO_NAME, Elf32_Addr address).
This function returns either the symbol name of address argument or
NULL (if no symbol corresponds to that address in the current
process). In a 64-bit application, the second argument is of type
Elf64_Addr.
* (Elf32_Addr)_rld_new_interface(_RLD_NAME_TO_ADDR, char *name). This
function returns the actual address of name. It returns NULL if rld
cannot find the passed argument. In a 64-bit application, the value
returned is of type Elf64_addr.
* (char *)_rld_new_interface(_RLD_VERSION_EXPECTED, char *soname).
This function returns the version string in MAIN's liblist entry for
soname.
* (Elf32_Addr)_rld_new_interface(_RLD_SPROC_NOTIFY). This function
signals to rld that sproc(2) has been called and that rld has to
handle multiple sproc threads. The call is made by libc.so.
* (Elf32_Addr)_rld_new_interface(_RLD_SHUTDOWN_THREAD). This function
signals to rld that a thread is trying to exit. Currently does
nothing when invoked.
* (Elf32_Addr)_rld_new_interface(_RLD_SPROC_FINI). This function
signals to rld that multiple sproc(2) threads support can be turned
off. It is called on behalf of, and in, the child process after a
fork(2) by the fork code in libc.so.
EXAMPLES
The following csh(1) aliases control rld tracing. There are three
sets of tracing aliases, one for each ABI. See file(1) for
information on how to identify the ABI of a particular executable.
The following alias pertains to old 32-bit executables:
# trace o32 rld issues
alias ra \
'setenv _RLD_PATH /usr/lib/rld.debug ;'\
'setenv _RLD_ARGS "\!*" ;'
alias nora \
'unsetenv _RLD_ARGS ;'\
'setenv _RLD_PATH /lib/rld ;'
The following alias pertains to new 32-bit executables:
# trace n32 rld issues
alias ra32 \
'setenv _RLDN32_PATH /usr/lib32/rld.debug ;'\
'setenv _RLD_ARGS "\!*" ;'
alias nora32 \
'unsetenv _RLD_ARGS ;'\
'setenv _RLDN32_PATH /lib32/rld ;'
The following alias pertains to 64-bit executables:
# trace 64 rld issues
alias ra64 \
'setenv _RLD64_PATH /usr/lib64/rld.debug ;'\
'setenv _RLD_ARGS "\!*" ;'
alias nora64 \
'unsetenv _RLD_ARGS ;'\
'setenv _RLD64_PATH /lib64/rld ;'
The following examples shows how the aliases are used.
The first traces rld when it is running an old 32-bit binary (ls(1)):
% ra -trace <-- turns on tracing of o32 rld
% ls
27312:[rld] Entering RLD through MAIN
27312:ls: [rld] mapped ls at 0x400000
27312:ls: [rld] mapped /lib/libc.so.1 at 0xfa00000
27312:ls: [rld] found _end in ls for libc.so.1 at 0x10007000
27312:ls: [rld] number of objs in the objlist is 2
27312:ls: [rld] Exiting RLD through MAIN
RCS libX11.so.2 libc.so libl.a setup
acrt1.o libXaw.a libc.so.1 libm.a sgicc.cfg
crt1.o libXext.a libc.so.O libmld.a sgild.cfg
% nora <-- turns off all o32 rld debugging options.
The following traces rld when it is running a new 32-bit binary
(ci(1)):
% ra32 -v <-- turns on verbose mode in n32 rld
% ci -l c.c
14891:_RLD_ARGS = "-v"
14891:_RLD_ROOT = /
14891:LD_LIBRARYN32_PATH = none
14891:ci: mapped ci at 0x10000000
14891:ci: mapped /usr/lib32/libc.so.1 at 0xfa00000
RCS/c.c,v <-- c.c
file is unchanged; reverting to previous revision 1.1
done
% nora32 <-- turns off all n32 rld debugging options.
ERROR REPORTING
Most error messages are written to /dev/tty. If rld encounters an
error condition for a process without a valid /dev/tty attached, it
writes the message to /var/adm/SYSLOG. The system log is written
using calls to syslog(3C).
CHANGING ROOT
A copy of the device /dev/zero is essential to the operation of rld.
In most uses of chroot(1M), it is necessary to put a copy of /dev/zero
in the newly-created root.
NOTES
Listing a particular DSO in _RLD_LIST is likely to lead to problems
and failures unless all three ABI-specific environment variables are
set. A typical result is a message such as the following:
rld: Fatal Error: Cannot Successfully map soname
For example, consider an old 32-bit test application a.out and a
specific old 32-bit DSO, /tmp/mydso.so:
unsetenv _RLDN32_LIST _RLD64_LIST
setenv _RLD_LIST "/tmp/mydso.so:DEFAULT"
./a.out
This will likely fail because some command, or the application itself,
will attempt to fork(2) or exec(2) some new 32-bit application, and
/tmp/mydso.so is an old 32-bit DSO, not a new 32-bit DSO.
_RLDN32_LIST and _RLD64_LIST do not suffer from this; they are only
interpreted in a single ABI each. See the description of _RLD_LIST
earlier in this man page.
Adding the following will fix the problem in this example:
setenv _RLDN32_LIST DEFAULT
setenv _RLD64_LIST DEFAULT
DIAGNOSTICS
The meaning of the following message from rld is difficult to
understand:
The aggregate IEEE exceptions required (OEX_FPU_MIN)
(0xnn) not as complete as the aggregate IEEE
exceptions permitted (OEX_FPU_MAX>>8)(0xnn).
As the executable and each DSO is accessed before the application
begins to run, information in the .MIPS.options section is used to
compute an aggregate set of floating-point exceptions to enable. The
.MIPS.options section can be examined with the elfdump(1) command's
-op option.
For example, specifying the -trapuv compiler option results in a
request that invalid exception trapping be enabled. Using certain
high optimizations in conjunction with the -mips4 and -mips3 compiler
options, however, requires that those exceptions be turned off so that
speculative loads of floating-point values can be executed silently.
For more information, see the compiler options
-TARG:exc_max=[I][U][O][Z][V], -TARG:exc_min=[I][U][O][Z][V], and
-TENV:X=0..5.
Delay-loaded DSOs and DSOs opened with dlopen(3C) or loaded with
or
dlopen(3C) is called. The OEX_FPU_MIN field of each object is OR'd
with the others. The nonzero bits represent the set of floating-point
exceptions that the application wants to catch (more precisely,
exceptions that some part of the application or a DSO want to catch).
The OR'd-together OEX_FPU_MIN fields are used to determine what
set_fpc_csr() fields to set to 1; rld never sets any set_fpc_csr()
fields to zero.
The OEX_FPU_MAX field of each object is AND'd with the others. The
zero bits represent floating-point exceptions that must not be caught.
For example, if the code generator is issuing speculative loads, the
invalid-value exception should not be caught. If some bits are OFF in
OEX_FPU_MAX that are ON in OEX_FPU_MIN, that represents an impossible
scenario: exceptions must be caught and simultaneously must not be.
For example, this could happen if an object is compiled requesting
that uninitialized variables be trapped and a high optimization that
results in the code generator issuing speculative loads.
As each DSO is opened with dlopen(3C), delay-loaded, loaded using
sgidladd(3C), or closed with dlclose(3C), these flags are
recalculated. If user or library code has changed the five
exception-flag-enable fields from a previous setting by using rld, rld
stops updating the exception-enable fields for the execution.
rld never turns off exception-enable flags once it has turned them on.
Use the following to see the OEX fields of an executable or DSOs:
elfdump -op objectname
SEE ALSO
cc(1), chroot(1M), ci(1), csh(1), elfdump(1), file(1), ld(1), ls(1).
exec(2), exit(2), fork(2), sproc(2).
dlclose(3C), dlerror(3C), dlopen(3C), dlsym(3C), sgidladd(3C),
sgidlopen_version(3C), sgigetdsoversion(3C), syslog(3C).
capabilities(4), capability(4).
dso(5), gp_overflow(5).
System V Application Binary Interface
System V Application Binary Interface: MIPS Processor Supplement
MIPSpro N32 ABI Handbook
This man page is available only online.
[ Back ] |