*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->IRIX man pages -> dso (5)              
Title
Content
Arch
Section
 

d(1)

Contents


DSO(5)						      Last changed: 1-29-99

NAME    [Toc]    [Back]

     DSO - Dynamic Shared Object (DSO)

IMPLEMENTATION    [Toc]    [Back]

     IRIX systems

DESCRIPTION    [Toc]    [Back]

     This man page describes Dynamic Shared Objects (DSOs).

     It	is divided into	the following 4	sections:

     * Overview

     * Linking and building DSOs

     * Performance considerations

     * Frequently asked	questions

OVERVIEW    [Toc]    [Back]

     A DSO is an ELF format object file.  It is	very similar in	structure
     to	an executable program, but it has no main program.  It has the
     following components:

     * A shared	component, which consists of shared text and read-only
       data.

     * A private component, which consists of data and the Global Offset
       Table (GOT).

     * Several sections	that hold information needed to	load and link the
       object.

     * A liblist, which	is the list of other DSOs referenced by	this
       object.	Most libraries supported on IRIX platforms are available as
       DSOs.

   Position Independent	Code (PIC)
     A DSO is relocatable at runtime; it can be	loaded at any virtual
     address.  A consequence of	this is	that all references to external
     symbols must be resolved at runtime.

     References	from a private region (that is,	from private data) are
     resolved at load time.  References	from a shared region (that is, from
     shared text) go through the indirection table, which is also called
     the Global	Offset Table (GOT), and	incur a	small performance penalty.

     The GOT helps facilitate Position Independent Code	(PIC).	PIC is code
     that satisfies references indirectly by using the GOT, which allows
     code to be	relocated simply by updating the GOT.  Each executable and
     each DSO has its own GOT.	The GOT	is a data table	with the actual
     addresses of global data with appropriate code generation and linking
     support.  The linker, ld(1), constructs the GOT.

     PIC satisfies references indirectly by using the GOT, which allows
     code to be	relocated simply by updating the GOT.  PIC can be shared by
     multiple users.  Each program must	have its own data space.  Code
     sharing and independent data is arranged automatically by the
     compilation and run-time systems.

     Code compiled for use in a	DSO is PIC.  Non-PIC code is usually
     referred to as non-shared.	 Non-shared code and PIC cannot	be mixed in
     the same object.

   What	Happens	at Runtime?
     The runtime events	are as follows:

     1.	exec(2)	loads the main program and then	loads one of the following
	interpreters as	specified in the main program:

	* /usr/lib/libc.so.1 is	loaded for programs compiled with the -32
	  compiler option.

	* /usr/lib32/libc.so.1 is loaded for programs compiled with the
	  -n32 compiler	option.

	* /usr/lib64/libc.so.1 is loaded for programs compiled with the	-64
	  compiler option.

     2.	The interpreter	loads rld(5), the runtime linking loader, which
	finishes the exec(2) operation.	 Starting with the main	program's
	liblist, rld(5)	loads each DSO on the list that	is not marked to be
	delay-loaded.  rld(5) reads that object's liblist and repeats the
	operation until	all DSOs have been loaded, in a	breadth-first
	manner.	 The breadth first loading process, which ignores objects
	marked to be delay-loaded, results in defining a sequence of
	objects.

     3.	rld(5) allocates storage for COMMON block symbols and fixes up
	symbolic references in each loaded object.  This is necessary
	because	the location at	which the object will be loaded	is not
	known until runtime.  To look up a given symbol	in the process of
	fixing up symbolic references, rld(5) examines each object's
	dynamic	symbol table.  If rld(5) finds a strong	symbol that
	satisfies the reference	(that is, it has the name of the given
	symbol and is an external definition) it stops with that symbol.
	If it does not find a strong definition	with that name,	then the
	first weak symbol found	is accepted as the definition.

     4.	Each object's -init code is executed.  This is code specified as an
	argument to the	-init option on	the ld(1) command.  For	information
	on -init code, see ld(1).

     5.	Control	transfers to __start in	the main program.

     The sequence at which the -init code is run is important to
     applications and DSOs that	have -init code.  By default, objects are
     taken in reverse order of the sequence defined in loading.	 If -init
     code in one DSO calls a DSO with -init code that has not yet run, then
     the -init code in the called DSO is run before the	called DSO routine
     is	actually called.  Thus,	the default order is not followed.

     It	is not an error	for DSOs to mutually call one another, even
     indirectly, from within -init sections, but the resulting DSO ordering
     can be confusing and can vary depending on	actions	in the application
     -init code.  The -init code in delay-loaded DSOs is not run until the
     DSO is actually loaded, and the delay-loaded DSO is loaded	when some
     routine in	the delay-loaded DSO is	called.

     Do	not include calls to sproc(2), nsproc(2), sprocsp(2), or any POSIX
     threads (pthreads)	routines from within -init or -fini code.  The
     following table describes the problem with	-init and -fini	code in
     pthreads and sproc(2) applications:

     --------------------------------------------------------------------
			 sigprocmask(2)	Getting	  sigprocmask(2) Setting
     Threads?		 Mask Bits		  Mask Bits
     --------------------------------------------------------------------
     sproc(2) threads	 Sees more masked than	  Settings lost	on exit
			 non-init.		  of -init and -fini.
     pthreads		 Sees more masked than	  Application settings
			 non-init.		  preserved.
     No	threads		 Sees true setting.	  Application settings
						  preserved.
     --------------------------------------------------------------------

     The preceding table entries can be	explained as follows:

     * In the Threads? column, An sproc(2) threads application is one that
       is using	sproc(2), nsproc(2), or	sprocsp(2).  A pthreads	application
       is one that has libpthread.so linked in.	 A No threads application
       is any other application.

     * Sees more masked	than non-init means that -init and -fini code do
       not get the true	mask bits.  Instead, nearly all	signals	are marked
       as masked.

     * Settings	lost on	exit of	-init and -fini	means that on exit of the
       nested set of -init or -fini functions, the set of mask bits set	on
       entry to	the functions is restored.  Any	setting	done by	the -init
       or -fini	code is	lost.

     * Application settings preserved means that the sigprocmask(2) bit
       settings	that are made by the -init or -fini code are preserved on
       exit of the -init or -fini function set.

     * Sees true setting means that the	mask bits that sigprocmask(2)
       returns to -init	and -fini code are the true application	mask bits.

     As	the preceding table shows, the complexities with signal	masks
     inhibit successful	sigprocmask(2) operation in -init or -fini code.
     Generally,	the results are	not going to be	what is	desired.

     Also ignored, in theory, are symbols in any DSO that is loaded at
     runtime because it	is on the liblist of a DSO opened by dlopen(3C)	or
     sgidlopen_version(3C).  rld(5) makes the liblist DSO symbols visible,
     but no application	should count on	this visibility.  However, if a
     DSO's symbols are visible for any reason (for example, because it was
     in	the main program's liblist), that DSO is not hidden just because it
     is	also on	the library list of a DSO opened with dlopen(3C) or
     sgidlopen_version(3C).

     When execution terminates,	the -fini code of each DSO and the base
     a.out file	is run in the opposite order the actual	-init code was run
     (or would have been run, in the case of DSOs with -fini code but no
     -init code).  -fini code and -init	code consist of	code specified as
     an	argument to the	ld(1) For more information on -fini code and -init
     code, see the rest	of this	man page and see ld(1).

     Other factors can affect the general load process,	too.  For more
     information, see the information on Quickstart and	delayed	loads on
     this man page and see the sgidladd(3C), sgidlopen_version(3C), and
     dlopen(3C)	man pages.

   -init Code Runtime Ordering
     The general order in which	the base executable DSO's -init	code is	run
     is	specified by the MIPS Application Binary Interface (API).  For more
     information on this ABI, see the URLs mentioned in	the SEE	ALSO
     section.

     Before an -init in	object A is run, you can assume	that all -init
     sections in DSOs that A depends on	have been run.	However, if -init
     code calls	a DSO with -init code that has not yet run, the	-init code
     of	the called DSO is run first.

     The physical ordering starts with the last	DSO in rld(5)'s	list and
     works toward the executable file.	This is	a depth-first postorder
     call of -init code.  This is a particular choice of ordering within
     the conceptual framework.	The physical ordering is not specified by
     the MIPS ABI.

     The run order of delay-loaded DSOs	and DSOs that have been	opened by
     dlopen(3C)	is recorded so that -fini operations occur in reverse
     order.

     Any DSO that is delay-loaded during the execution of -init	code
     changes the order in which	-init sections are run.	 The actual manner
     of	the changes is difficult to predict.  At the time of the
     delay-load, the -init code	scan is	restarted anew (new due	to the new
     DSO) at the end of	rld(5)'s list.

   -fini Code Runtime Ordering
     The -fini code of the DSOs	in the base executable is run choosing DSOs
     in	the opposite order the actual -init code was run (or would have
     been run, in the case of DSOs with	-fini code but no -init	code).

   Limitations on -init	and -fini Code
     In	most versions of rld(5), -init and -fini code could not
     successfully perform delay-load operations, such as dlopen(3C),
     sgidladd(3C), dlsym(3C), dlclose(3C), or implicit delay-load
     operations, if the	application used sproc(2), sprocsp(2), nsproc(2),
     or	pthreads.  Threaded applications hung if such operations were
     included in -init or -fini	code or	were nested codes outside of -init
     or	-fini code.

     The current release of rld(5), however, supports nested delay-load
     operations, but it	is unwise to depend too	much on	this support.  For
     example, it is unwise to use delay-loading	with C++ global
     initialization code because much about the	interaction of name
     resolution	(name binding and symbol binding) with nested delay-load
     operations	is unspecified.

     For example, calling a delay-load routine or calling delay-loaded
     functions in different orders depending on	startup	conditions means
     that the ordering of DSOs on rld(5)'s list	of DSOs	may vary.  If the
     order varies and there are	multiple definitions of	an external
     (different	functions with the same	name), exactly what is executed
     from run to run may differ.  Considering that is it difficult, in C++,
     to	control	the sequence in	which different	compilation units -init
     code is executed, and potentially,	you have serious application
     problems.

     It	is also	difficult to debug such	code as	debuggers often	have
     difficulting intercepting calls in	-init sections.

     In	multithreaded programs,	-init and -fini	code should avoid attempts
     to	acquire	(by using pthread_mutex_lock(3P), for example) resources
     owned by other threads, unless it can be guaranteed that the other
     thread can	release	the resource without performing	a delay-load
     operation or lazy text resolution.	 Should	the thread owning the
     resource make a call into rld(5), the threads deadlock.

     It	is difficult to	predict	whether	execution of a given section of
     code requires lazy	text resolution.  A DSO's GOT can be reset to point
     at	function stubs when it fails to	Quickstart or after delay-load
     operations	that might affect resolution of	its symbols.  See the
     section on	Quickstart in the PERFORMANCE CONSIDERATIONS section of
     this man page for more information	on function resolution.

     The C++ runtime system uses the -init and -fini mechanism to construct
     and destroy static	objects.  Therefore, constructors and destructors
     for such objects should avoid blocking calls if DSOs using	them are to
     be	manipulated by dlopen(3C) or dlclose(3C) or are	to be delay-loaded
     within a multithreaded program.

LINKING	AND BUILDING DSOs
     Assume that your library is in an archive libfoo.a	of object files,
     all of which have been compiled with the ld(1) command's -shared
     option.  The library references symbols found in libc.so.1, libgl.so,
     libX11.so,	and libnetls.so, but most programs never use the path that
     requires libnetls.so.  It is recommended that you build your DSO,
     libfoo.so,	in the following way:

	  ld
	  -elf
	  -shared
	  -no_unresolved
	  -rdata_shared
	  -soname libfoo.so
	  -o libfoo.so
	  -all libfoo.a
	  -lX11
	  -delay_load -lnetls
	  -lc
	  -lgl

     This builds a DSO called libfoo.so	that directs rld(5) to load
     libc.so.1,	libX11.so, and libgl.so	whenever libfoo.so is loaded.  This
     command line also loads libnetls.so if it is ever referenced.

     NOTE:     If you have any C++ object files	among the objects making up
	       your DSO, you must replace ld in	the previous example
	       command with CC.	 That is, your command line should be as
	       follows:

		    CC -elf -shared ...	-o libfoo.so -all libfoo.a ...

	       However,	you do not have	to do anything special at all to
	       use such	C++ DSOs when linking other programs against these
	       DSOs.  You can link C++ DSOs into C, C++, or Fortran
	       programs	using your usual link commands or link other DSOs
	       against these C++ DSOs without taking any special action.
	       For example, the	following command line links the preceding
	       C++ DSO libfoo.so properly:

		    f77	fortran_prog.o -lfoo

   Controlling Symbols Exported	by a DSO
     One benefit from using DSOs is the	ability	to release new versions	of
     an	object and be assured that objects linked against the old version
     will work with the	new version.  This is impossible to guarantee,
     however, if the set of symbols exported by	an object cannot easily	be
     understood	by the object's	creator.  ld(1)	provides several options to
     help you control the symbols that are exported by a DSO.

     By	default, ld(1) does not	export symbols that are	supplied by a
     linked-in archive or DSO.	The developer is probably only a consumer
     of	the linked-in object, not  an exporter.	 In a subsequent release,
     the developer may not require the linked-in object, and if	the symbols
     provided by the linked-in object had been exported	by the developer's
     object, the new object would no longer be upwardly	compatible with	the
     original version.	This behavior can be overridden	by using the
     -exports option on	the ld(1) command.  This default symbol	hiding
     behavior, with respect to archives, is also overridden when building a
     DSO from an archive using the -all	option.

     You can control the list of symbols that are exported by using the
     following ld(1) options:  -exported_symbol, -exports_file,	-exports,
     -hides, -hidden_symbol, and -hides_file.  The first two options let
     you specifically list the symbols to be exported by the DSO.  The
     exported_symbol option is followed	by a comma-sepatated list of names.
     The exports_file option accepts a file name that contains a
     space-separated (including	newlines) list of names.  If any symbols
     are specifically exported,	only those symbols are exported.  All other
     symbols are automatically hidden.	The last two options specify a list
     of	symbols	that are not to	be exported by the DSO.	 For more
     information on the	l
 man page.

     There are two consequences	of hiding symbols.  First, those symbols do
     not provide resolution to any undefined symbols in	an object that
     links in the DSO.	Second,	any references to those	symbols	within the
     DSO are resolved internally to the	hidden symbol.

   Rules of Thumb    [Toc]    [Back]
     The following list	contains things	to remember when using the ld(1)
     command:

     * Use the -no_unresolved option to	find unresolved	symbols.  It is	not
       always possible to supply all the DSOs that will	be referenced by
       libfoo.so on the	link line, but in general, libraries should be
       self-contained.	This is	especially true	for subsequent releases	of
       a DSO.  If a DSO	has any	unresolved references, they must be
       resolved	by some	other loaded object.  Having unresolved	symbols
       invites disaster	because	there is no guarantee that the symbols will
       be resolved.  Thus, the application may not run.

     * Link against the	minimum	set of .so files needed.  Loading a DSO
       carries a cost.	Linking	against	unneeded DSOs causes them to be
       loaded even if they are never referenced.  ld(1)	issues a message
       when you	have linked against a DSO that resolves	no symbols.

     * When building a C++ DSO,	specify	the -exports option for	any DSO
       that provides the definitions of	classes	from which classes in the
       object being created are	derived.  Specifying -exports in this case
       ensures that consumers of the object being created can create
       subclasses of classes provided by that object without having to know
       the complete set	of DSOs	that need to be	loaded.	 Using the -exports
       option in this case may bring in	unwanted symbols.  Use the
       -exported_symbol, -exports_file,	-hidden_symbol,	or -hides_file
       options where appropriate.

     * Use the -rdata_shared option to move all	read-only data into the
       shared segment.	Unfortunately, many programs write to supposedly
       read-only data.	The -rdata_shared option is disabled by	default	for
       this reason.  The -use_readonly_const compiler option is	enabled	by
       default.

     * If you reference	one of the graphics libraries, either libgl.so or
       libGL.so, put the library last in the link line.	 Often libgl.so
       cannot be Quickstarted.	Putting	it last	allows all prior objects to
       be Quickstarted.	 You can also choose to	delay-load the graphics
       libraries.  This	allows your application	to Quickstart.	For
       information on Quickstart, see the PERFORMANCE CONSIDERATIONS
       section of this man page.

     * Anytime a referenced object changes, you	should either relink, in
       order to	Quickstart, or you should run the reQuickstart tool rqs(1)
       on the object.

     * Try to minimize inter-DSO data references.

     * Try to minimize the use of global data.	In DSOs, it is generally
       more efficient to allocate space	when needed, using malloc(3C) or
       malloc(3F), rather than to use a	large static data structure.

     * Try to pack data	together that is likely	to be unmodified.  This
       allows the kernel to make more of the data pages	shared,
       copy-on-write.

     * Use the -delay_load option on any DSO on	the link line that is not
       often used.  This incurs	a small	performance penalty for	the
       references to it, but this can save time	and memory for those
       programs	that don't use it.  In addition, using this option on
       programs	that have -init	or -fini code also incurs a performance
       penalty.

     * Do not call any of the following	from code that may be executed
       during processing by the	-init or -fini options:	 dlclose(3C),
       dlerror(3C), dlopen(3C),	dlsym(3C), nsproc(2), sproc(2),	sprocsp(2),
       sgidladd(3C), and sgidlopen_version(3C).

     * Avoid having weak and strong versions of	a symbol that are loaded
       into memory at different	times (by a -delay-load	option or by
       sgidladd(3C) or dlopen(3C) calls).

     * Avoid performing	a dlclose(3C) on an object that	has been opened	by
       sgidladd(3C).

     * Try to avoid using -init	code by	not using the option and by
       avoiding	definition of C++ global objects that require -init code
       for construction.

PERFORMANCE CONSIDERATIONS    [Toc]    [Back]

     The following subsections describe	verious	performance considerations.

   Quickstart    [Toc]    [Back]
     When building a DSO or an executable, ld(1) assigns addresses to the
     object and	attempts to resolve all	references.  At	runtime, if rld(5)
     verifies that the same set	of objects are loaded at the original
     addresses,	then rld(5) can	skip all the runtime relocation	work and
     let the program run.  This	saves time because the relocations are not
     performed,	and it saves memory because rld(5) does	not have to read in
     the sections that hold the	relocation information.

     At	static link time, ld(1)	resolves each unresolved function call.
     When an unresolved	function is called at runtime, rld(5) performs the
     relocation	needed for all future calls to the original function.  In
     this way, more programs can Quickstart even if some of the	function
     references	are not	resolved at static link	time.

     Quickstart	fails if the DSOs on a system do not match the objects used
     when linking either the application or the	DSOs upon which	the
     application depends.  This	can occur if a new version of a	DSO is
     released.

     You can use the rqs(1) command to recalculate the Quickstart
     information associated with an application	or a DSO.  rqs(1) must be
     called in proper order so that DSOs on an object's	liblist	are
     reQuickstarted before the object is reQuickstarted.  rqs(1) rewrites
     the object	it is reQuickstarting back in place.  You can use the ld(1)
     command's -no_rqs option to mark an object	as non-reQuickstartable.

   Avoiding Gratuitous Shared Object Loads    [Toc]    [Back]
     rld(5) does a considerable	amount of work and can use up large amounts
     of	real memory, so	it is better not to link against DSOs that are not
     needed.

   Reducing the	Number of Conflicts
     A conflict	arises whenever	more than one DSO (including the main
     program) needed by	an executable defines and uses the same	name for a
     symbol.  The name for which multiple definitions exist is recorded	in
     your program in the section named .conflict.  The names of	all
     conflicting symbols pertaining to a program can be	obtained by using
     -Dc flag to elfdump(1).  One example of a conflict	is the malloc
     routine, which is defined both in libc.so.1 and in	libmalloc.so.

     Conflicts represent extra work to be done at startup because the
     presence of a conflict means that the objects in the link may not have
     chosen a consistent instance of the symbol	in question.  This extra
     work is memory-intensive because even one conflict	can mean that many
     pages of memory must be examined by rld(5).  This intensive
     examination would otherwise not be	needed for a Quickstarting program.
     The ld(1) command's -quickstart_info option causes	ld(1) to issue a
     warning about every conflict it finds and to write	the names of two of
     the objects in which it is	defined.  Of course, sometimes conflicts
     are a necessary design component of certain applications.

   Delayed Loads    [Toc]    [Back]
     The overhead associated with objects that are referenced but seldom
     used can be mitigated by using dlopen(3C),	sgidlopen_version(3C),
     sgidladd(3C), or delayed loads.  Using any	of these delays	the loading
     of	a DSO (and the objects on its liblist) until it	is actually
     referenced.  The -delay_load option on the	ld(1) command is the
     easiest and most convenient to use.  All three require that there be
     no	references from	any other object's data	section	to the delay-loaded
     DSO.

FREQUENTLY ASKED QUESTIONS    [Toc]    [Back]

     This section contains answers to frequently asked questions.  The
     questions and their answers are as	follows:

     1.	What is	a DSO?

     DSO stands	for Dynamic Shared Object.  DSOs give applications the
     ability to	share the text of heavily used libraries, which	need not be
     included in the executable	file.

     2.	How do I maintain binary compatibility between versions	of DSOs?

     Binary compatibility is maintained	as long	as the DSOs maintain the
     same exported symbols, add	new symbols without removing any or
     changing semantics, and don't change exported structures.	The
     ordering of symbols, routines, and	global data is irrelevant.

     3.	What object file format	do DSOs	use?

     DSOs use the ELF object file format as defined in the SVR4	ABI.

     4.	How do I install the tools so I	can use	DSOs on	my system?

     To	compile	and build DSOs,	you need to nstall the IRIX Development
     Foundation	(IDF) and the IRIX Development Libraries (IDL);	these were
     formerly known as the Developer's Option.	In addition, you must have
     a compiler.

     5.	How do I build an executable file that uses a DSO?

     A command line like the following links myfile.c with libmine.so and
     with libc.so.1:

	  cc myfile.c -lmine

     If	libmine.so is not available, but libmine.a is available, libmine.a
     is	used along with	libc.so.1, and you get dynamic linking.	 To
     explicitly	state that you want the	DSO to be used,	add the
     -call_shared option to the	cc(1) line, as follows:

	  cc -call_shared myfile.c -lmine

     6.	How do I build an executable file that does not	use shared linking?

     Use the -non_shared option, as follows:

	  cc -non_shared myfile.c -lmine

     Some libraries are	not available as nonshared.  The ones that are
     available are not installed by default, so	you must request their
     installation.  In general,	the -non_shared	option is outmoded.

     7.	How do I tell if an executable file will use dynamic linking?

     Entering the following command generates the ELF program header:

	  elfdump -o

     This header contains all the information necessary	for exec(2) and
     rld(5) to run the program or DSO.	Only a.out files that use dynamic
     linking have a PHDR, INTERP, or DYNAMIC entry.  An	example	and a more
     detailed description is as	follows:

% elfdump -o /bin/cat

		  ***PROGRAM HEADER***
Type	 Offset	     Vaddr	Paddr	  Filesz      Memsz	 Align RWX
   PHDR	0x00000034 0x00400034 0x00400034 0x000000c0 0x00000000 0x00000004 r--
 INTERP	0x00000100 0x00400100 0x00400100 0x00000009 0x00000009 0x00000004 r--
REGINFO	0x00000110 0x00400110 0x00400110 0x00000018 0x00000018 0x00000004 r--
DYNAMIC	0x00000150 0x00400150 0x00400150 0x00000a70 0x00000a70 0x00000010 r--
   LOAD	0x00000000 0x00400000 0x00400000 0x00003000 0x00003000 0x00001000 r-x
   LOAD	0x00003000 0x10000000 0x10000000 0x00001000 0x00001290 0x00010000 rwx

     Each line is an entry in the program header and refers to a segment of
     the file, as follows:

     Line      Segment

     PHDR      Points to the program header itself within the file.  Only
	       executable files	that use dynamic linking have this field.

     INTERP    Points to the location of the name of the interpreter
	       required	for this program.  For any old 32-bit ABI object,
	       compiled	with -32, this is /usr/lib/libc.so.1.  For any new
	       32-bit ABI object, compiled with	-n32, this is
	       /usr/lib32/libc.so.1.  For any 64-bit ABI object, compiled
	       with -64, this is /usr/lib64/libc.so.1.

     REGINFO   Points to the location of the register setup information.
	       This information	can be seen by entering	the elfdump -reg
	       command.	 For the old 32-bit ABI, obtained when compiling
	       with -32, this consists of the correct global pointer (gp)
	       value for this object.  For the new 32-bit or 64-bit ABIs,
	       obtained	when compiling with -n32 or -64, this entry does
	       not appear in this table; for these ABIs, the information is
	       in .MIPS.options, which can be seen by entering the
	       elfdump -reg or elfdump -op commands.

     DYNAMIC   Points to information in	the file needed	by rld(5).
	       Includes	the liblist (which can be seen by entering the
	       elfdump -Dl command), a symbol table (which can be seen by
	       entering	the elfdump -Dt	command), and other information.

     LOAD      Points to segments that are to be mapped	into the memory
	       image.

     The columns give various information about	each segment, as follows:

     Column    Content

     Offset    The offset in the file to the beginning of the segment.

     Vaddr     The virtual address of the beginning of the segment in the
	       memory image of the file, assuming that it was mapped as
	       described in the	LOAD entries.

     Paddr     The same	as Vaddr.

     Filesz    The size	of the segment in the file.

     Memsz     The size	of the segment in the memory image.  When Memsz	is
	       greater than Filesz, the	bytes after Filesz are zero-filled.

     Align     The alignment required by this section.	If a segment is	to
	       be mapped somewhere into	memory other than at Vaddr, the	new
	       address must be congruent to Vaddr modulo the alignment.	 In
	       the preceding example, the first	segment	must always be
	       loaded at a page	boundary, and the second must always be
	       loaded at a 64K boundary.

     RWX       Specifies the protections, read,	write, or execute, for the
	       segment.

     Programs that are linked with the -non_shared option on the compiler
     command line do not have a	PHDR, INTERP, or DYNAMIC section.  Thus,
     the elfdump -o command is a convenient way	to determine whether a
     program is	linked as nonshared.  For more information on this command,
     see the elfdump(1)	man page.

     8.	How do I build a DSO?

     Perform the following steps:

     1.	Build a	file.o or file.a that contains all the routines	you want to
	have in	your file.so (your DSO).  This can be done with	a compiler
	and ar(1).

     2.	Invoke ld(1) with the -shared option.  Normally, the extension .so
	is used	to designate DSOs.

     Example 1:

	  cc -c	myobj.c
	  ld -shared myobj.o -o	myobj.so

     Example 2:

	  cc -c	myobj.c
	  cc -shared myobj.o -o	myobj.so

     Example 3:

	  <build libmine.a the usual way>
	  ld -shared -all libmine.a -o libmine.so

     The -all option in	the third example directs ld(1)	to include all the
     routines in the library.  This option is needed because there are not
     undefined references in the program, which	is the usual way for ld(1)
     to	determine whether to load files	from an	archive.

     9.	Where does the system look for DSOs at runtime?

     The search	path for DSOs is acquired in the following order for
     programs compiled with the	-32 compiler option:

     1.	The path of the	DSO if given in	the liblist

     2.	In any directories specified with the -rpath option when the
	executable file	was built

     3.	In any directory specified by the LD_LIBRARY_PATH environment
	variable, if it	is defined

     4.	In the directories in the default path,	which is /usr/lib,
	/usr/lib/internal, /lib, /lib/cmplrs/cc, /usr/lib/cmplrs/cc,
	/opt/lib.

     If	the _RLD_ROOT environment variable is defined, then its	value is
     appended to the front of any path specified by the	-rpath option and
     the default path.	_RLD_ROOT itself is a colon (:)	separated list.

     For programs compiled with	the -n32 compiler option, the rules are
     similar, but the following	differences exist:

     * The LD_LIBRARYN32_PATH is used if LD_LIBRARY_PATH is defined.

     * _RLDN32_ROOT is used for	the list of paths

     * The default path	directory list is /usr/lib32, /usr/lib32/internal,
       /lib32, /opt/lib32.

     For programs compiled with	the -64	compiler option, the rules are
     similar, but the following	differences exist:

     * The LD_LIBRARY64_PATH is	used if	LD_LIBRARY_PATH	is defined.

     * _RLD64_ROOT is used for the list	of paths.

     * The default path	directory list is /usr/lib64, /usr/lib64/internal,
       /lib64, /opt/lib64.

     See the rld(5) man	page for more details.

     10. What is Quickstart?

     Quickstart	is an optimization.  Using an so_locations file, ld(1)
     prerelocates each DSO as if it had	been loaded (or	linked,	which is
     the term often used) by ld(1)) at the address in the so_locations
     file.  If no errors occur at startup, all DSOs map	to their Quickstart
     addresses,	and rld(5) does	not need to perform a relocation pass.
     When new software is installed with inst(1M) or swmgr(1M),	rqsall(1)
     changes many DSO virtual addresses, attempting to ensure that all
     registered	applications (written to /var/inst/.rqsfiles) can be
     Quickstarted.  At the same	time, rqsall(1)	updates	so_locations.

     If	more than one DSO attempts to map to the same address, the IRIX
     kernel moves one of them to an unused address range, and rld(5)
     performs a	relocation pass	to fix the address references.

     If	one or more of the DSOs	linked against at static link time has
     changed by	the time the program executes, rld(5) performs extra work
     to	ensure that symbols have been resolved to their	proper value.

     11. What is the the /usr/lib/so_locations file?

     After you build a DSO, a file called so_locations is placed in the
     directory with the	DSO.  This file	is a registry of DSOs.	It
     maintains the default, or Quickstart, addresses of	a group	of DSOs
     that are guaranteed to never have their default locations overlap with
     one another.  It is generated and updated by ld(1)	each time it builds
     a DSO.

     If	you make substantial library changes between one build of the
     library and another, you should remove the	so_locations file before
     rebuilding	the library.  You do this because the information derived
     from the older build and put in the so_locations files can	make the
     new library build unsuccessful.

     rqsall(1) and rqs(1) can rearrange	a.out files and	DSOs to	restore
     Quickstartability,	so the so_locations file is less important than	it
     was before	rqs(1) existed.	 For information on address ranges, see	the
     following files:  /usr/lib/so_locations, /usr/lib32/so_locations, and
     /usr/lib64/so_locations.

     /usr/lib/so_locations applies to programs compiled	with the -32
     compiler option.  /usr/lib32/so_locations applies to programs compiled
     with the -n32 compiler option.  /usr/lib64/so_locations applies to
     programs compiled with the	-64 compiler option.  These files represent
     the default layout	for the	system DSOs in the respective ABIs.  Those
     who build DSOs may	find it	interesting to consult these files in order
     to	avoid collisions between their DSOs and	system DSOs.  You do not
     need to consult this file if you merely run programs that use DSOs.

     If	you build DSOs,	two ld(1) command options may be useful	to you:
     -check_registry and -update_registry.  The
     -update_registry location_file option examines location_file and
     builds the	current	.so at a location that does not	conflict with
     anything in the file (unless the current one is listed). The
     -update_registry option examines locations_file, as does
     -check_registry, and attempts to write an entry for the .so file being
     built into	locations_file.	 The -check_registry location_file option
     does not write to locations_file.	If locations_file is not writable,
     the -update_registry option performs like the -check_registry option.
     If	locations_file is not readable or writable, the	-check_registry	and
     -update_registry options may cause	ld(1) to generate one or more error
     messages.

     12. What directives can be	put into a so_locations	file?

     The following directives control the placement of new DSOs:

     * $text_align_size=align padding=pad_size
       and
       $data_align_size=align padding=pad_size
	  These	two directives specify the alignment and padding
	  requirements for text	and data segments, respectively.  The size
	  value	in so_location is calculated based on:	section	size +
	  padding, aligned to the section align	size.  The align values	for
	  text and data, as well as the	padding	values,	must be	aligned	to
	  a bucket size.  If not, ld(1)	generates a warning message and
	  aligns these values to the bucket size.

     * $start_address=addr
	  Specifies the	beginning address for DSOs.

     * $data_after_text=[ 1 | 0	]
	  Instructs the	linker to place	data immediately after the text	at
	  specified text and data alignment requirements.  The default is
	  0.

     * so_name [ :st = { .text | .data | $range] } base_addr,pad_size :	] *
	  This directive consists of the following elements:

	  Element	 Composition

	  so_name	 Full path name	(or trailing component)	of a DSO.

	  st		 String	that identifies	the start of the segment
			 description.

	  .text	or .data or $range
			 Specify either	a segment type,	text or	data, or a
			 range.	 Specifying a range limits the range of
			 addresses that	can be used.  Specifications of
			 .text or .data	are for	internal use only.

	  base_addr	 Address at which the segment starts.

	  pad_size	 Padded	size of	the segment

     WARNING:  The format and use of the so_locations file is under review
	       and may in the future move to a simpler format.	Currently,
	       only $range should be specified,	not .text or .data, in the
	       specification.

	       When building a DSO with	the -check_registry or
	       -update_registry	option of the ld(1) command when there is
	       already an entry	that corresponds to this DSO in	the
	       so_location file, the linker attempts to	assign the same
	       addresses for text and data.  However, if the size of the
	       DSO changes and does not	fit in the specified location, the
	       linker searches for another location.  If the optional
	       $range comment is specified, the	linker places the DSO in
	       the specified range of addresses.  If there is not enough
	       room, a message is generated.

     A comment line can	be inserted at any point a directive can be
     inserted.	A comment is a line beginning with the number sign (#)
     character.

     13. If I don't have a valid so_locations file, can	I generate one from
     all the .so files in /usr/lib?

     Not easily.  It is	an error if the	so_locations is	missing.  Every
     so_locations file is different because rqsall(1) reQuickstarts
     everything.

     If	/var/inst/.rqsfiles is present,	you could get a	set of so_locations
     files from	a similar system and rerun rqsall(1) as	inst(1M) and
     swmgr(1M) do.  If you do this, make a back-up copy	of .rqsfiles before
     starting rqsall(1).

     NOTE:     If anything destroys or results in the loss of .rqsfiles,
	       the only	way to recreate	.rqsfiles is to	reinstall
	       everything on the system.  Make a back-up copy of .rqsfiles.

     14. How expensive is it, at runtime, NOT to use the -update_registry
     option?

     If	you use	rqsall(1) or rqs(1) to reQuickstart an application and its
     DSOs, then	there need not be any cost.  rqs(1) can	make the DSOs
     Quickstartable regardless how the DSO addresses were determined.

     If	you do not use rqs(1), then the	lack of	an updated registry can
     impose startup costs.  It is very difficult to say	how much a
     particular	executable will	suffer because it depends on which DSOs	the
     program uses and whether they have	been Quickstarted for the same
     address.  When there is a conflict	between	two objects, one will be
     moved, which means	that all addresses referring to	names in that
     object need to be relocated.

     15. How and when will Quickstart be used?

     The linker	uses Quickstart	unless there are unresolved symbols at
     static link time.

     Every executable and every	DSO contains a list of objects that were
     examined at static	link time when the object was made.  This list also
     contains timestamps and checksums for each	of the objects.	 Various
     levels of extra work are required if the timestamp	or checksum changed
     in	the library at runtime.

     16. What about runtime loading under user control?

     The library allows	you to dynamically load	your own DSOs as needed.
     The individual library calls are as follows:

     * dlopen(3C), which opens a DSO.

     * dlsym(3C), which	finds the value	of a name defined in an	object.

     * dlclose(3C), which closes a DSO.

     * dlerror(3C), which reports errors.

     * sgidladd(3C), which functions much like dlopen(3C), but it exposes
       all symbols to the rest of the program.

     * sgidlopen_version(3C), which functions much like	dlopen(3C), but	it
       allows specifying a specific required version of	the DSO.

     Consult the individual man	pages for details.

     17. What benefits will I get from DSOs?

     Executables linked	with DSOs are smaller because the DSOs are not part
     of	the executable file image.

     Executables that use a DSO	need not be relinked if	a DSO is changed.
     After the updated DSO is installed, the executable	picks it up
     automatically.

     DSOs allow	application designers to make more machine-independent
     software.	System-dependent routines can be given a uniform interface,
     and a DSO that implements that interface can be built for each
     different platform.  Actual applications can be shipped to	various
     platforms and run on them all.

     DSOs give applications the	ability	to change the binding of symbols at
     runtime and under user control.

     18. What costs are	associated with	DSOs?

     A DSO incurs two costs, both against performance.

     The first is a start-up cost incurred while rld(5)	maps in	the various
     objects, performs symbol resolution, etc.	This cost is usually small
     compared to the time it takes to contact the X server, for	example.

     The second	is the cost incurred when using	position-independent code.
     A DSO's text must be compiled with	the -KPIC option in effect in order
     for the object file to be put into	a DSO without further modification.
     Because this option is in effect by default, it is	not necessary to
     specifiy it.  By default, PIC is slower by	5% to 15%.  With full
     optimization, however, the	speed reduction	can be near zero.  PIC code
     seems to be worst on very small-leaf routines that	access global data.

     Routines written in assembly language for non-PIC use (for	example,
     routines written before PIC was available for IRIX) need to be
     modified before the -KPIC option can be used.  For	more information on
     modifying your code, see the MIPSpro Assembly Language Programmer's
     Guide.

     19. Must main programs that want to use DSOs use -KPIC for
     compilation?

     Yes.  DSOs	use -KPIC so that PIC code is generated.  Main programs	are
     not generally position-independent, but they must still use the DSO
     calling convention	when calling a routine that is defined in a DSO.
     In	particular, this means that a main program must	have a Global
     Offset Table (GOT)	and the	code that is generated must use	it.

     Modules that will become part of main programs and	modules	that become
     part of DSOs must be compiled with	the -KPIC option in effect, which
     is	enabled	by default.

     20. What options do I have	when building a	DSO?

     If	you specify the	-B dynamic option while	linking	a DSO, symbols in
     the DSO are resolved in a nondefault manner.  In particular, the
     runtime linker first tries	to resolve symbols referenced in the object
     to	symbols	defined	in the object instead of looking for definitions in
     objects in	the order specified on the link	line.

     The effect	is that	all symbols defined and	used in	such objects are
     non-preemptable.  Ordinarily, symbol definitions could be preempted by
     a definition in an	earlier	DSO.  When -B symbolic is specified,
     however, this is not the case.

     For more information on the -B dynamic and	-B symbolic options, see
     the ld(1) man page.

     21. What difficulties may be associated with DSOs?

     Behind most unexpected behavior is	the fact that linking semantics	are
     fundamentally different, but only in a subtle way.	 Assume	that a
     program links with	three libraries, libA, libB, and libC, in that
     order.  Further assume that both libA and libC define symbol x but
     don't use it.  Further, assume that libB contains a reference to x.
     Archive linking (the old way) would resolve libB's	reference to x to
     the definition in libC, whereas DSO linking resolves libB's reference
     to	x to the definition in libA.  This is true because with	archive
     linking, when libA	is examined, there is no outstanding reference to
     x.	 The definition	of x is	not extracted from the archive.	 Later,
     when libC is examined, there is a reference to x, so it is	loaded.

     With DSOs,	all the	constituent object files have been joined into one
     object, so	all symbol definitions are always present.  The	resolution
     rule is simple: take the definition in the	object listed first.  Thus,
     the definition in libA is used.

     Another unexpected	occurrence is a	runtime	dangling reference.  These
     occur when	you build and link an application with no errors or
     warnings but later	receive	a message from rld(5) stating that your
     program has unresolvable symbols.

     The problem here is that if you build a DSO as part of your program,
     the linker	typically does not generate messages about undefined
     symbols during a link of a	DSO.  This is because undefined	symbols	are
     expected during such a build and are perfectly acceptable.	 If the
     main program does not use a symbol, however, it is	not flagged as
     undefined during static linking.  You can use the -no_unresolved
     option to the ld(1) command to avoid such unexpected behavior.

     If	a particular object in an archive file (libl.a,	for example) has an
     external reference	to a data symbol, and the data symbol is expected
     to	be defined in the main program,	the linker does	not try	to resolve
     that external reference unless the	object file in question	was
     actually referenced by the	main program.  If that archive is turned
     into a DSO, the external data reference must be resolved whenever ANY
     function in the DSO is used, even if no function in the object file in
     question is ever called and no use	is made	of the external	data symbol
     in	question.

     This can lead to a	scenario in which a link that worked with the
     archives builds a program that is terminated by the runtime linker
     (rld(5)).	Do not assume that you can convert libraries that contain
     external data symbols into	DSOs.

     One remedy	is to split the	archive	into several DSOs and place them on
     the liblist of a master DSO.  By default, rld(5) does not try to
     resolve data symbols until	the first call is made to a particular
     object.  You can, however,	inhibit	the linker's attempt to	resolve	an
     offending external	data symbol until a call is made to the	object in
     which it is referenced.  For example, suppose that	ext_data.o is an
     object that contains an undefined external	reference.  It resides in
     archive libxyz.a.	Here is	how to isolate that external data
     reference:

     1.	Make ext_data.o	into a DSO all its own:

	  % ar x libxyz.a has_ext_data.o
	  % ld -shared ext_data.o -o ext_data.so

     2.	Make libxyz.so,	excluding ext_data.o from being	included directly.
	Instead, put it	in the liblist of libxyz.so:

    % ld -shared -all -exclude ext_data.o libxyz.a ext_data.so -o libxyz.so

     In	addition to the	previously mentioned caveats, applications should
     not call dlopen(3C), sgidladd(3C),	dlclose(3C), sgidlopen_version(3C),
     or	dlerror(3C) from within	a signal handler.  This	means that calling
     from within a signal handler calling a function that results in a DSO
     being delay-loaded	is also	wrong.	Ensure that functions called
     (directly or indirectly) from signal handlers are already loaded
     before a signal handler is	set up.	 Very few functions are	safe to
     call from within a	signal handler (POSIX specifies	a few),	and the
     delay-load	functions (dlopen(3C), and so on) are not among	them.

     22. What should I do about	Global Offset Table (GOT) overflow?  GOT
     overflow has occured if you receive messages from the linker saying
     GP-relative sections overflow by 0x??? bytes, GOT overflow, or GOT
     unreachable.

     To	fix this situation, perform one	of more	of the following steps:

     * Recompile with the -TENV:large_got=ON option on your compiler
       command line.  Only the large input file	that is	causing	overflow
       needs to	be recompiled with this	option.

     * Break the large input file.o into two or	more smaller files.

     * Use the -m option on the	ld(1) command to obtian	a link map.  This
       map indicates large objects that	you can	recompile with -G0 or some
       other small -G value.

       Data objects affected by	the -Gnum option are numeric literals,
       addreses	(including those generated by the compiler), all C/C++
       static veriables, and, if the -static option is in effect, all
       Fortran local variables.	 For more information on the -Gnum option,
       see your	compiler command line.

     23. How are multiple versions of DSOs supported?

     You can associate DSOs and	executables with a version number.  This is
     intended to support interface changes.

     A version string consists of 3 parts and a	period (.), as follows.
     The first part is the string sgi.	The second part	is a decimal
     number, which is the major	number.	 The third part	is the period (.).
     The fourth	part is	a decimal number, which	is the minor number.  Hence
     the format:  sgimajor.minor.

     For a DSO to be versioned as sgi1.0, add the -set_version sgi1.0
     option to the compiler or loader command line to build the	DSO (cc	-
     shared, ld	-shared, and so	on).

     Whenever you make a compatible change, update the minor version number
     (the one after the	period)	and add	the latest version string to
     colon-separated list of version strings.  For example:
     -set_version sgi1.0:sgi1.1:sgi1.3.

     Whenever you make an incompatible change, update the major	version
     number.  For example, use -set_version sgi2.0.  Change the	file name
     of	the old	DSO by adding a	period followed	by the previous	major
     number to the file	name of	the DSO.  Do not change	the soname of the
     object.  No change	to the file contents are necessary or desirable.
     Simply rename the file.

     24. How does versioning work?

     Note that in this answer, items marked SGI	ONLY do	not apply to MSIG
     ABI binaries; they	apply only to binaries generated on IRIX systems
     using a means other than the abicc(1) or abild(1) commands.

     Versioning	is available for NON-ABI executables only.  The	ABI does
     not require objects to have versioning, nor does it require systems to
     recognize versioning.  It allows objects to contain version strings,
     but it does not require systems to	do anything with this information.

     NON-ABI compliant executables have	the RHF_SGI_ONLY bit turned on in
     the .dynamic section.  This flag is reported by the elfdump(1) command
     when elfdump -L -long is entered.	Only executables with this flag
     turned on receive the versioning treatment	described in this answer.
     RHF_SGI_ONLY is turned on by default.

     When an executable	is linked against a DSO, the last entry	of the
     DSO's version string is recorded in the executable	as part	of the
     liblist.  This can	be examined by using the -Dl option to the
     elfdump(1)	command.

     When an executable	is linked, you may specify the -require_minor or
     -ignore_minor options for each DSO	linked against.	 If -require_minor
     is	specified, a bit will be set in	the flags field	of the liblist
     entry for the DSO in question.  The default is -ignore_minor.

     When an executable	(ABI

 Similar pages
Name OS Title
shm_open FreeBSD open or create a shared memory object shm_unlink -- remove a shared memory object
ldd_ia HP-UX list dynamic dependencies of executable files or shared libraries
ldd Tru64 List dynamic dependencies of executable files or shared objects
ldd HP-UX list dynamic dependencies of executable files or shared libraries
st_dyn_tag Tru64 Access routines for dynamic header information in shared objects
st_dyn_addr Tru64 Access routines for dynamic header information in shared objects
st_dyn_start Tru64 Access routines for dynamic header information in shared objects
st_dyn_count Tru64 Access routines for dynamic header information in shared objects
ldd_pa HP-UX list dynamic dependencies of executable files or shared libraries
st_dyn_value Tru64 Access routines for dynamic header information in shared objects
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service