PageRenderTime 43ms CodeModel.GetById 33ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/src/wrappers/posix/dynamic-linking/library/dynamic_linking_loader.e

http://github.com/tybor/Liberty
Specman e | 142 lines | 26 code | 22 blank | 94 comment | 1 complexity | b626bdf2768753a52320d2528e85cc17 MD5 | raw file
  1deferred class DYNAMIC_LINKING_LOADER
  2	-- Access to the dynamic linking loader provided by the operative system.
  3
  4	-- When you inserts this class your namespace gets "polluted" with all the
  5	-- low-level C symbols of its implementation. If you want to avoid this
  6	-- "clutter" you may use its expanded version, DL_LOADER.
  7insert 
  8	DL_FLAGS
  9	DLFCN_EXTERNALS
 10
 11feature {ANY} -- Queries
 12	alreadey_loaded (a_library: ABSTRACT_STRING): BOOLEAN
 13		-- Has `a_library' already been loaded?
 14
 15		-- Note: this features require Glibc and is not POSIX
 16	do
 17		-- using dlopen with rtld_noload flag: we don't load the library. if
 18		-- dlopen returns NULL if the library is not already loaded/resident or
 19		-- the library's handle if it is resident.
 20		Result:= dlopen(a_library.to_external,rtld_now|rtld_noload).is_not_null
 21	end
 22
 23	main_program: DYNAMIC_SHARED_OBJECT
 24		-- The main program accessible as a dynamic shared object.
 25
 26		-- Symbols will be searched in the main program, followed by all shared
 27		-- libraries loaded at program startup, and then all shared libraries
 28		-- loaded by with the flag RTLD_GLOBAL.
 29	once
 30		create Result.from_external_pointer(dlopen(default_pointer, rtld_now))
 31	end
 32
 33	new_dynamic_shared_object (a_filename: ABSTRACT_STRING; some_flags: INTEGER): DYNAMIC_SHARED_OBJECT
 34		-- A newly allocated dynamic shared object (also known as "library")
 35		-- located at `a_filename'. If `a_filename' contains a slash ("/"),
 36		-- then it is interpreted as a (relative or absolute) pathname.
 37		-- Otherwise, the dynamic linker searches for the library as detailed
 38		-- in ld.so(8) manpage. 
 39
 40		-- If the library has dependencies on other shared libraries, then
 41		-- these are also automatically loaded by the dynamic linker using the
 42		-- same rules. This process may occur recursively, if those libraries
 43		-- in turn  have  dependencies, and so on.
 44	
 45		-- `some_flags' must contain one of the following two values:
 46
 47		-- rtld_lazy: Perform lazy binding.  Only resolve symbols as the code
 48		-- that references them is executed.  If the symbol is never
 49		-- referenced, then it is never resolved.  (Lazy binding is only
 50		-- performed for function references; references to variables are
 51		-- always immediately bound when the library is loaded.)
 52	
 53		-- rtld_now: all undefined symbols are immediatly resolved; if this
 54		-- cannot be done Current will be invalid. This behaviour is forced
 55		-- when the environment variable LD_BIND_NOW is set to a non-empty
 56		-- string.
 57
 58		-- Zero of more of the following values may also be (logically) ORed in `some_flags':
 59	
 60		-- rtld_global: The  symbols  defined  by  this library will be made
 61		-- available for symbol resolution of subsequently loaded libraries.
 62
 63		-- rtld_local: This is the converse of rtld_global, and the default if
 64		-- neither flag is specified.  Symbols defined in this library are not
 65		-- made available to resolve references in subsequently loaded
 66		-- libraries.
 67 
 68		-- rtld_nodelete: (since glibc 2.2) Do no  unloa  the library when
 69		-- Current is disposed.  Consequently, the library's static variables
 70		-- are not reinitialized if the library is reloaded with
 71		-- `new_dynamic_shared_object'. This flag is not specified in
 72		-- POSIX.1-2001.
 73
 74		-- rtld_deepbind: (since glibc 2.3.4) Place the lookup scope of the
 75		-- symbols in this library ahead of the global scope. This means that a
 76		-- self-contained library will use its own symbols in preference to
 77		-- global symbols with the same name contained in libraries that have
 78		-- already been loaded. This flag is not specified in POSIX.1-2001.
 79		
 80		-- External references in the library are resolved using the libraries in that  library's  dependency  list  and  any
 81		-- other  libraries  previously  opened with the RTLD_GLOBAL flag.  If the executable was linked with the flag "-rdynamic" (or, synonymously, "--export-dynamic"), then the global symbols in the executable  will  also  be  used  to
 82		-- resolve references in a dynamically loaded library.
 83		 
 84		-- If  the  same  library  is loaded again with dlopen(), the same file handle is returned.  The dl library maintains
 85		-- reference counts for library handles, so a dynamic library is not deallocated until dlclose() has been  called  on
 86		-- it  as  many  times as dlopen() has succeeded on it.  The _init() routine, if present, is only called once.  But a
 87		-- subsequent call with RTLD_NOW may force symbol resolution for a library earlier loaded with RTLD_LAZY.
 88
 89		-- Result will be Void in case of failure.
 90
 91		require
 92			a_filename/=Void
 93			are_valid_dlflags(some_flags)
 94		local p: POINTER
 95		do
 96			p:=dlopen(a_filename.to_external,some_flags)
 97			if p.is_not_null then
 98				create Result.from_external_pointer(p)
 99				Result.set_name(a_filename)
100			end
101		end
102
103		
104-- NOTES
105--        The symbols RTLD_DEFAULT and RTLD_NEXT are defined by <dlfcn.h> only when _GNU_SOURCE was defined before including
106--        it.
107-- 
108--        Since  glibc  2.2.3, atexit(3) can be used to register an exit handler that is automatically called when a library
109--        is unloaded.
110-- 
111--    History
112--        The dlopen interface standard comes from SunOS.  That system also has dladdr(), but not dlvsym().
113-- 
114-- BUGS
115--        Sometimes, the function pointers you pass to dladdr() may surprise you.  On some architectures (notably  i386  and
116--        x86_64),  dli_fname  and  dli_fbase may end up pointing back at the object from which you called dladdr(), even if
117--        the function used as an argument should come from a dynamically linked library.
118-- 
119--        The problem is that the function pointer will still be resolved at compile time, but merely point to the plt (Pro‐
120--        cedure Linkage Table) section of the original object (which dispatches the call after asking the dynamic linker to
121--        resolve the symbol).  To work around this, you can try to compile the code to be position-independent:  then,  the
122--        compiler  cannot prepare the pointer at compile time anymore and today's gcc(1) will generate code that just loads
123--        the final symbol address from the got (Global Offset Table) at run time before passing it to dladdr().
124-- 
125end -- class DYNAMIC_LINKING_LOADER
126-- Liberty Eiffel wrappers for GNU C library Copyright (C) 2013-2017: Paolo Redaelli, Free Software Foundation
127-- 
128-- The GNU C Library is free software; you can redistribute it and/or
129-- modify it under the terms of the GNU Lesser General Public
130-- License as published by the Free Software Foundation; either
131-- version 2.1 of the License, or (at your option) any later version.
132-- 
133-- The GNU C Library is distributed in the hope that it will be useful,
134-- but WITHOUT ANY WARRANTY; without even the implied warranty of
135-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
136-- Lesser General Public License for more details.
137-- 
138-- You should have received a copy of the GNU Lesser General Public
139-- License along with the GNU C Library; if not, write to the Free
140-- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
141-- 02110-1301 USA
142