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

  man pages->IRIX man pages -> libdl/dlopen (3)              
Title
Content
Arch
Section
 

Contents


DLOPEN(3C)							    DLOPEN(3C)


NAME    [Toc]    [Back]

     dlopen - open a shared object

SYNOPSIS    [Toc]    [Back]

     cc	[flag ...] file	...  -lc [library ...]

     #include <dlfcn.h>

     void *dlopen(const	char *pathname,	int mode);

DESCRIPTION    [Toc]    [Back]

     dlopen is one of a	family of routines that	give the user direct access to
     the dynamic linking facilities. These routines are	available in a library
     which is loaded if	the option -lc is used with cc , f77 or	ld.

     dlopen makes a shared object available to a running process.  dlopen
     returns to	the process a handle which the process may use on subsequent
     calls to dlsym and	dlclose.  This handle should not be interpreted	in any
     way by the	process.  pathname is the path name of the object to be
     opened; it	may be an absolute path	or relative to the current directory.
     If	the value of pathname is 0, dlopen makes the symbols contained in the
     original a.out, and all of	the objects that were loaded at	program
     startup with the a.out, available through dlsym.

     When a shared object is brought into the address space of a process, it
     may contain references to symbols whose addresses are not known until the
     object is loaded.	These references must be relocated before the symbols
     can be accessed. The mode parameter governs when these relocations	take
     place and may have	the following values:

     RTLD_LAZY    [Toc]    [Back]
	  Only references to data symbols are relocated	when the object	is
	  loaded.  References to functions are not relocated until a given
	  function is invoked for the first time.  This	mode should result in
	  the best performance,	since a	process	may not	reference all of the
	  functions in any given shared	object.	 RTLD_LAZY cannot be combined
	  with RTLD_NOW.

     RTLD_NOW    [Toc]    [Back]
	  All necessary	relocations are	performed when the object is first
	  loaded.  This	may result in some wasted effort if relocations	are
	  performed for	functions that are never referenced, but is useful for
	  programs that	need to	know as	soon as	an object is loaded that all
	  symbols referenced during execution are available.  RTLD_NOW cannot
	  be combined with RTLD_LAZY.

     RTLD_GLOBAL    [Toc]    [Back]
	  modifies the treatment of the	symbols	in the DSO being opened	to be
	  identical to those of	sgi_dladd().  RTLD_GLOBAL may be or'd with
	  either RTLD_NOW or RTLD_LAZY (RTLD_GLOBAL cannot be the mode value
	  on its own).	RTLD_GLOBAL See	"NAMESPACE ISSUES" below for more on
	  the impact of	using or not using RTLD_GLOBAL.	 With RTLD_GLOBAL the



									Page 1






DLOPEN(3C)							    DLOPEN(3C)



	  handle is less necessary than	without	it, since rld directly
	  resolves references to symbols when RTLD_GLOBAL is provided and
	  dlsym	is not needed.

     The following is an example of use, using -32.
	  dltry.c:
	  -------
	  /* Error handling code not shown.
	  */
	  #include <dlfcn.h>

	  typedef int (*xamplefuncptr)(int);
	  int main()
	  {
	     void *handle;
	     int   i;
	     xamplefuncptr fptr;

	     handle = dlopen("greetings.so", RTLD_LAZY);
	     fptr = (xamplefuncptr)dlsym(handle, "greetings");
	     i = (*fptr)(3);
	     return 0;
	  }

	  greetings.c:
	  -----------
	  #include <stdio.h>
	  int greetings(int num_greetings)
	  {
	     int i;

	     for (i=0; i < num_greetings; i++)
		printf ("hello world0);
	     return 1;
	  }


	  % cc -32 -c dltry.c greetings.c
	  % ld -32 -shared greetings.o \
	  -soname greetings.so -o greetings.so
	  % cc -32 dltry.o
	  % a.out
	  hello	world
	  hello	world
	  hello	world

NAMESPACE ISSUES    [Toc]    [Back]

     This section does not address symbol resolution from dlsym(3).  See dlsym
     for details on its	symbol resolution rules.






									Page 2






DLOPEN(3C)							    DLOPEN(3C)



     Name resolution can become	surprisingly complicated and non-intuitive in
     the presence of programs or DSOs using dlopen, sgidladd,
     sgi_dlopen_version, or LL_DELAY_LOAD (the ld -delay_load option).

     Any case in which there is	only one definition of a symbol	across all
     loaded DSOs is simple: that definition is used if it is visible
     (visibility is discussed below).

     Name searches are done in the order of a single list, the rld-list.  The
     first rld-list entry is the program itself.  Following that is the	list
     of	DSOs currently in the runtime of the program.  At program startup a
     breadth-first list	of DSOs	in the program (and, recursively their library
     lists) is formed in the rld-list.	No DSO is added	to the rld-list	twice
     (later encounters of a DSO	in simply use the earlier occurrence, but see
     NOTES below for an	exception).  For any DSO library list entry marked
     LL_DELAY_LOAD the DSO referenced is not loaded at program startup.

     The above name search rule	has an exception.  If a	DSO is marked as
     DT_SYMBOLIC (see the ld option -B symbolic) then all name searches	from
     within that DSO begin at the DSO itself and continue with the standard
     rld-list search.

     When, as a	result of a call to  a function	in a LL_DELAY_LOADed DSO, that
     DSO is loaded, the	new DSO	is added at the	end of the rld-list (if	it has
     any entries in its	library	list that are not marked LL_DELAY_LOAD the
     non-LL_DELAY_LOAD DSOs are	added, recursively (breadth-first)).  Thus,
     depending on the order of calls to	delay-loaded DSOs, the order of	DSOs
     on	the rld-list may be different from one run of a	program	to the next.

     The order of DSOs in the rld-list may not match the order in any given
     library list because if a DSO is already in the rld-list it is not	added
     a second time to the rld-list.

     As	a result of the	rule that the search order is rld-list order, the
     symbol found can be surprising.  Consider a symbol	A found	in DSOs	B and
     C and DSO B is before DSO C in E's	liblist	while DSO B is after DSO C in
     F's liblist.  Lets	specify	that neither DSO B nor DSO C are otherwise
     referenced.  If DSO E is dlopen(...RTLD_GLOBAL)ed before DSO F then the A
     from DSO B	is found by dlsym from either handle.  While if	DSO F is
     dlopen(...RTLD_GLOBAL)ed before DSO E then	the A from DSO C is found by
     dlsym from	either handle.	On the other hand, if only one of the DSOs E
     or	F is dlopen(...RTLD_GLOBAL)ed then one gets DSO	B's A from DSO E's
     handle and	one gets DSO C's A from	DSO F's	handle.

     Note that dlclose does not	cause any reordering of	the rld-list: when the
     last handle (direct or indirect) on a DSO is dlclosed the DSO is removed
     from the rld-list.	 Before	the final dlclose the DSO remains where	it was
     on	the rld-list.

     Now we turn to the	issue of symbol	visibility.





									Page 3






DLOPEN(3C)							    DLOPEN(3C)



     DSOs loaded by a single invocation	of dlopen may import symbols from one
     another or	from any DSO which is globally-visible,	but DSOs loaded	by one
     dlopen invocation may not directly	reference symbols from DSOs loaded by
     a different dlopen	invocation. Those symbols may, however,	be referenced
     indirectly	using dlsym.

     Globally-visible DSOs are those added at program startup or via delayload
 from a globally-visible object.  In addition,	any DSO	added by
     sgidladd or dlopen(...RTLD_GLOBAL...) or
     sgidlopen_version(...RTLD_GLOBAL...) is globally-visible.

     Even in a globally-visible	DSO a symbol is	invisible to any access	from
     outside the DSO if	the symbol is marked STO_HIDDEN	(see the ld options
     -hidden_symbol or -hides_file for example).  From within a	DSO, all
     symbols in	that DSO are visible.  From within a DSO, all globally-visible
     symbols are visible.

     Consider a	set of DSOs.

     ld	-shared	-all F.a -o F.so
     ld	-shared	-all G.a -o G.so
     ld	-shared	-all E.a F.so G.so -o E.so
     ld	-shared	-all H.a F.so  -o H.so

     Say a program does	dlopen("E.so",RTLD_LAZY) and and
     dlopen("H.so",RTLD_LAZY) and uses dlsym to	find functions through the two
     handles and calls these two functions. Say	each of	these calls a function
     that calls	ff() in	F.so. Say that ff() calls fg() which is	only defined
     in	G.so. Logically	one would say that the call through the	function
     accessed via E.so should resolve to fg() in G.so and one would think that
     the call thru the function	accessed via H.so should result	in an
     undefined function.  However, rld does not	attempt	to determine (by
     walking the run-time stack	or other means)	the exact call-stack to	ff()
     (the call-stack is	not really enough: rld needs to	know the handle	used
     to	derive the calls!).  The result	of the call to fg() is undefined.
     What happens is that fg() in G.so is called, since	such would be legal if
     the call path were	thru E.so's handle.  It	is unwise to depend on such
     behavior.

SEARCHING FOR SHARED OBJECTS    [Toc]    [Back]

     If	other shared objects were link edited with pathname when pathname was
     built, those objects are automatically loaded by dlopen (subject to the
     LL_DELAY_LOAD library list	flag).	The directory search path that is used
     to	find both pathname and the other needed	objects	is the same as that
     used by rld(1).  In particular, pathname is searched for in

     1)	the directory specified	by pathname if it is not a simple file name
     (i.e.  it contains	a / character).	 In this case, the exact file is the
     only placed searched; steps two through four below	are ignored.

     2)	any path specified via the -rpath argument to ld(1) when the
     executable	was statically linked.



									Page 4






DLOPEN(3C)							    DLOPEN(3C)



     3)	any directory specified	by the environment variable LD_LIBRARY_PATH.
     This environment variable should contain a	colon-separated	list of
     directories, in the same format as	the PATH variable [see sh(1)].	64-bit
     programs examine the variable LD_LIBRARY64_PATH, and if it	is not set
     LD_LIBRARY_PATH is	examined.  New 32-bit ABI programs examine the
     variable LD_LIBRARYN32_PATH and if	it is not set LD_LIBRARY_PATH is
     examined.

     All of these variables are	ignored	if the process is running setuid or
     setgid [see exec(2)].

     4)	the default search paths are used.  These are /usr/lib:/lib for	32-bit
     programs, /usr/lib64:/lib64 for 64-bit programs, and /usr/lib32:/lib32
     for new 32-bit ABI	programs.

     The variable _RLD_ROOT has	its usual effect, as documented	on rld(1)
     (which means that if the process is running setuid	or setgid _RLD_ROOT is
     ignored).

SEE ALSO    [Toc]    [Back]

      
      
     dlerror(3), dlclose(3), sgidladd(3), sgidlopen_version(3),	dlsym(3),
     dso(5).

DIAGNOSTICS    [Toc]    [Back]

     If	pathname cannot	be found, cannot be opened for reading,	is not a
     shared object, or if an error occurs during the process of	loading
     pathname or relocating its	symbolic references, dlopen returns NULL.
     More detailed diagnostic information is available through dlerror.

NOTES    [Toc]    [Back]

     Objects whose names resolve to the	same absolute or relative path name
     may be opened any number of times using dlopen, however, the object
     referenced	is only	loaded once into the address space of the current
     process.  The same	object referenced by two different path	names,
     however, may be loaded multiple times.  For example, given	the object
     /usr/home/me/mylibs/mylib.so, and assuming	the current working directory
     is	/usr/home/me/workdir,

	  ...
	  void *handle1;
	  void *handle2;

	  handle1 = dlopen("../mylibs/mylib.so", RTLD_LAZY);
	  handle2 = dlopen("/usr/home/me/mylibs/mylib.so", RTLD_LAZY);
	  ...

     results in	mylibs.so being	loaded twice for the current process.  On the
     other hand, given the same	object and current working directory, if
     LD_LIBRARY_PATH=/usr/home/me/mylibs, then






									Page 5






DLOPEN(3C)							    DLOPEN(3C)



	  ...
	  void *handle1;
	  void *handle2;

	  handle1 = dlopen("mylib.so", RTLD_LAZY);
	  handle2 = dlopen("/usr/home/me/mylibs/mylib.so", RTLD_LAZY);
	  ...

     results in	mylibs.so being	loaded only once. Users	who wish to gain
     access to the symbol table	of the a.out itself using dlsym(0, mode)
     should be aware that some symbols defined in the a.out may	not be
     available to the dynamic linker.  The symbol table	created	by ld for use
     by	the dynamic linker might contain only a	subset of the symbols defined
     in	the a.out:  specifically those referenced by the shared	objects	with
     which the a.out is	linked.

     A program built non_shared	(with cc -non_shared for example) cannot
     usefully call dlopen(), dlsym(), dlerror(), sgidlopen_version(),
     sgidladd(), or dlclose() since there is no	defined	mechanism for dynamic
     loading in	non_shared programs.  The dynamic loading routines are not
     included in the non_shared	libc.a so attempting to	use them may result in
     a failure at link time.  Any program built	non_shared that	wishes to
     retain code calling the dynamic loading routines must implement its own
     versions of dlopen, dlsym(3), etc.	and simply return appropriate error
     values to avoid the link-time errors.  (Building programs non_shared is
     not generally recommended.	 Not all libraries are available non_shared.)

     Use of dlclose on a DSO can cause surprising side effects because dlclose
     forces many symbol	GOT entries to be reset	for re-lazy-evaluation.	 A
     result of this is that previously-saved (by the application or some
     library) function pointers	may hold values	that could be obsolete or no
     longer correct.  This is a	problem	for any	dlclose	but is more serious
     (can cause	more surprises)	when dlcloseing	a handle on a globally-visible
     DSO.

     Symbol lookups proceed in order on	a linear list, and a DSO is not	opened
     twice with	the same version number	 (unless different dlopen paths	make
     the DSO name appear different to rld).  When multiple sgidladds are done
     and an earlier DSO	is dlclosed this can change what symbol	a call is
     resolved to.  See "NAMESPACE ISSUES" above.


									PPPPaaaaggggeeee 6666
[ Back ]
 Similar pages
Name OS Title
shm_open FreeBSD open or create a shared memory object shm_unlink -- remove a shared memory object
sgidladd IRIX open a shared object and add its variables to the name space.
sgidlopen_version IRIX open a shared object with the specified interface version.
shm_open HP-UX create/open a shared memory object
shm_open Tru64 Opens a shared memory object, creating the object if necessary (P1003.1b)
dlclose IRIX close a shared object
dso IRIX Dynamic Shared Object (DSO)
shm_unlink HP-UX unlink a shared memory object
dladdr FreeBSD find the shared object containing a given address
dlsym IRIX get the address of a symbol in shared object
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service