source: rtems/testsuites/libtests/dl07/dl-load.c @ 03139d5b

Last change on this file since 03139d5b was 03139d5b, checked in by Chris Johns <chrisj@…>, on Nov 20, 2018 at 3:56:11 AM

libdl: Add object file dependencies to track references

Tracking references lets us manage when an object file can be
unloaded. If an object file has references to it, it cannot be
unloaded.

Modules that depend on each other cannot be unloaded.

Updates #3605

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/*
2 * Copyright (c) 2014 Chris Johns <chrisj@rtems.org>.
3 * All rights reserved.
4 *
5 * The license and distribution terms for this file may be
6 * found in the file LICENSE in this distribution or at
7 * http://www.rtems.org/license/LICENSE.
8 */
9
10#define DL07_DEBUG_TRACE 0 /* RTEMS_RTL_TRACE_ALL */
11#define DL07_RTL_CMDS    0
12
13#include <dlfcn.h>
14
15#include "dl-load.h"
16
17#include <tmacros.h>
18
19#include <rtems/rtl/rtl-trace.h>
20
21typedef int (*call_sig)(void);
22
23int rtems_rtl_shell_command (int argc, char* argv[]);
24
25static void dl_load_dump (void)
26{
27#if DL07_RTL_CMDS
28  char* list[] = { "rtl", "list", NULL };
29  char* sym[] = { "rtl", "sym", NULL };
30  printf ("RTL List:\n");
31  rtems_rtl_shell_command (2, list);
32  printf ("RTL Sym:\n");
33  rtems_rtl_shell_command (2, sym);
34#endif
35}
36
37static void dl_check_resolved(void* handle, bool has_unresolved)
38{
39  int unresolved = 0;
40  rtems_test_assert (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) == 0);
41  if (has_unresolved)
42  {
43    if (unresolved == 0)
44    {
45      dl_load_dump();
46      rtems_test_assert (unresolved != 0);
47    }
48  }
49  else
50  {
51    if (unresolved != 0)
52    {
53      dl_load_dump();
54      rtems_test_assert (unresolved == 0);
55    }
56  }
57}
58
59static void* dl_load_obj(const char* name, bool has_unresolved)
60{
61  void* handle;
62
63  printf("load: %s\n", name);
64
65  handle = dlopen (name, RTLD_NOW | RTLD_GLOBAL);
66  if (!handle)
67  {
68    printf("dlopen failed: %s\n", dlerror());
69    return NULL;
70  }
71
72  dl_check_resolved (handle, has_unresolved);
73
74  printf ("handle: %p loaded\n", handle);
75
76  return handle;
77}
78
79static void dl_close (void* handle)
80{
81  int r;
82  printf ("handle: %p closing\n", handle);
83  r = dlclose (handle);
84  if (r != 0)
85    printf("dlclose failed: %s\n", dlerror());
86  rtems_test_assert (r == 0);
87}
88
89static int dl_call (void* handle, const char* func)
90{
91  call_sig call = dlsym (handle, func);
92  if (call == NULL)
93  {
94    printf("dlsym failed: symbol not found: %s\n", func);
95    return 1;
96  }
97  call ();
98  return 0;
99}
100
101int dl_load_test(void)
102{
103  void* o1;
104  void* o2;
105  void* o3;
106  void* o4;
107  void* o5;
108
109  printf ("Test source (link in strstr): %s\n", dl_localise_file (__FILE__));
110
111#if DL07_DEBUG_TRACE
112  rtems_rtl_trace_set_mask (DL07_DEBUG_TRACE);
113#endif
114
115  o1 = dl_load_obj("/dl07-o1.o", false);
116  if (!o1)
117    return 1;
118  o2 = dl_load_obj("/dl07-o2.o", false);
119  if (!o1)
120    return 1;
121  o3 = dl_load_obj("/dl07-o3.o", true);
122  if (!o1)
123    return 1;
124  o4 = dl_load_obj("/dl07-o4.o", false);
125  if (!o1)
126    return 1;
127  o5 = dl_load_obj("/dl07-o5.o", false);
128  if (!o1)
129    return 1;
130
131  dl_check_resolved (o3, false);
132
133  dl_load_dump ();
134
135  printf ("\n\nRun mains in each module:\n\n");
136  if (dl_call (o1, "rtems_main_o1"))
137    return 1;
138  if (dl_call (o2, "rtems_main_o2"))
139    return 1;
140  if (dl_call (o3, "rtems_main_o3"))
141    return 1;
142  if (dl_call (o4, "rtems_main_o4"))
143    return 1;
144  if (dl_call (o5, "rtems_main_o5"))
145    return 1;
146
147  /*
148   * Try and close the dependent modules, we should get an error.
149   */
150  rtems_test_assert (dlclose (o1) != 0);
151  rtems_test_assert (dlclose (o2) != 0);
152  rtems_test_assert (dlclose (o4) != 0);
153  rtems_test_assert (dlclose (o5) != 0);
154
155  dl_close (o3);
156  rtems_test_assert (dlclose (o1) != 0);
157  dl_close (o4);
158  rtems_test_assert (dlclose (o1) != 0);
159  dl_close (o5);
160  rtems_test_assert (dlclose (o1) != 0);
161  dl_close (o2);
162  dl_close (o1);
163
164  return 0;
165}
Note: See TracBrowser for help on using the repository browser.