source: rtems/cpukit/libdl/dlfcn.c @ 4408603

5
Last change on this file since 4408603 was 89c59be, checked in by Chris Johns <chrisj@…>, on 12/17/18 at 05:36:48

libdl: Add symbol searching and loading from archives.

  • Load archive symbol tables to support searching of archives for symbols.
  • Search archive symbols and load the object file that contains the symbol.
  • Search the global and archives until all remaining unresolved symbols are not found. Group the loaded object files in the pending queue.
  • Run the object file and loaded dependents as a group before adding to the main object list.
  • Remove orphaned object files after references are removed.

Updates #3686

  • Property mode set to 100644
File size: 2.9 KB
Line 
1/*
2 *  COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj@rtems.org>
3 *
4 *  The license and distribution terms for this file may be
5 *  found in the file LICENSE in this distribution or at
6 *  http://www.rtems.org/license/LICENSE.
7 */
8/**
9 * @file
10 *
11 * @ingroup rtl
12 *
13 * @brief RTEMS POSIX Dynamic Module Loading Interface.
14 *
15 * This is the POSIX interface to run-time loading of code into RTEMS.
16 */
17
18#include <stdint.h>
19#include <dlfcn.h>
20#include <rtems/rtl/rtl.h>
21
22static rtems_rtl_obj*
23dl_get_obj_from_handle (void* handle)
24{
25  rtems_rtl_obj* obj;
26
27  /*
28   * Handle the special cases provided in NetBSD and Sun documentation.
29   *   http://download.oracle.com/docs/cd/E19253-01/816-5168/dlsym-3c/index.html
30   * We currently do not manage the loading dependences in the module mappings
31   * so we cannot handle the searching based on loading order where overriding
32   * can occur.
33   */
34
35  if ((handle == RTLD_DEFAULT) || (handle == RTLD_SELF))
36    obj = rtems_rtl_baseimage ();
37  else
38    obj = rtems_rtl_check_handle (handle);
39
40  return obj;
41}
42
43void*
44dlopen (const char* name, int mode)
45{
46  rtems_rtl_obj* obj = NULL;
47
48  if (!rtems_rtl_lock ())
49    return NULL;
50
51  _rtld_debug.r_state = RT_ADD;
52  _rtld_debug_state ();
53
54  if (name)
55    obj = rtems_rtl_load (name, mode);
56  else
57    obj = rtems_rtl_baseimage ();
58
59  _rtld_debug.r_state = RT_CONSISTENT;
60  _rtld_debug_state();
61
62  rtems_rtl_unlock ();
63
64  return obj;
65}
66
67int
68dlclose (void* handle)
69{
70  rtems_rtl_obj* obj;
71  int            r;
72
73  if (!rtems_rtl_lock ())
74    return -1;
75
76  obj = rtems_rtl_check_handle (handle);
77  if (!obj)
78  {
79    rtems_rtl_unlock ();
80    return -1;
81  }
82
83  _rtld_debug.r_state = RT_DELETE;
84  _rtld_debug_state ();
85
86  r = rtems_rtl_unload (obj) ? 0 : -1;
87
88  _rtld_debug.r_state = RT_CONSISTENT;
89  _rtld_debug_state ();
90
91  rtems_rtl_unlock ();
92
93  return r;
94}
95
96void*
97dlsym (void* handle, const char *symbol)
98{
99  rtems_rtl_obj*     obj;
100  rtems_rtl_obj_sym* sym = NULL;
101  void*              symval = NULL;
102
103  if (!rtems_rtl_lock ())
104    return NULL;
105
106  /*
107   * If the handle is "default" search the global symbol table.
108   */
109  if (handle == RTLD_DEFAULT)
110  {
111    sym = rtems_rtl_symbol_global_find (symbol);
112  }
113  else
114  {
115    obj = dl_get_obj_from_handle (handle);
116    if (obj)
117      sym = rtems_rtl_symbol_obj_find (obj, symbol);
118  }
119
120  if (sym)
121    symval = sym->value;
122
123  rtems_rtl_unlock ();
124
125  return symval;
126}
127
128const char*
129dlerror (void)
130{
131  static char msg[64];
132  int         eno;
133  eno = rtems_rtl_get_error (msg, sizeof (msg));
134  if (eno == 0)
135    return NULL;
136  return msg;
137}
138
139int
140dlinfo (void* handle, int request, void* p)
141{
142  rtems_rtl_obj* obj;
143  int            rc = -1;
144
145  if (!rtems_rtl_lock () || !p)
146    return -1;
147
148  obj = dl_get_obj_from_handle (handle);
149  if (obj)
150  {
151    switch (request)
152    {
153      case RTLD_DI_UNRESOLVED:
154        *((int*) p) = rtems_rtl_obj_unresolved (obj) ? 1 : 0;
155        rc = 0;
156        break;
157      default:
158        break;
159    }
160  }
161
162  rtems_rtl_unlock ();
163
164  return rc;
165}
Note: See TracBrowser for help on using the repository browser.