/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

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