[03139d5b] | 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 | |
---|
[bac53634] | 19 | #include <rtems/rtl/rtl-shell.h> |
---|
[03139d5b] | 20 | #include <rtems/rtl/rtl-trace.h> |
---|
| 21 | |
---|
| 22 | typedef int (*call_sig)(void); |
---|
| 23 | |
---|
| 24 | static void dl_load_dump (void) |
---|
| 25 | { |
---|
| 26 | #if DL07_RTL_CMDS |
---|
| 27 | char* list[] = { "rtl", "list", NULL }; |
---|
| 28 | char* sym[] = { "rtl", "sym", NULL }; |
---|
| 29 | printf ("RTL List:\n"); |
---|
| 30 | rtems_rtl_shell_command (2, list); |
---|
| 31 | printf ("RTL Sym:\n"); |
---|
| 32 | rtems_rtl_shell_command (2, sym); |
---|
| 33 | #endif |
---|
| 34 | } |
---|
| 35 | |
---|
| 36 | static void dl_check_resolved(void* handle, bool has_unresolved) |
---|
| 37 | { |
---|
| 38 | int unresolved = 0; |
---|
| 39 | rtems_test_assert (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) == 0); |
---|
| 40 | if (has_unresolved) |
---|
| 41 | { |
---|
| 42 | if (unresolved == 0) |
---|
| 43 | { |
---|
| 44 | dl_load_dump(); |
---|
| 45 | rtems_test_assert (unresolved != 0); |
---|
| 46 | } |
---|
| 47 | } |
---|
| 48 | else |
---|
| 49 | { |
---|
| 50 | if (unresolved != 0) |
---|
| 51 | { |
---|
| 52 | dl_load_dump(); |
---|
| 53 | rtems_test_assert (unresolved == 0); |
---|
| 54 | } |
---|
| 55 | } |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | static void* dl_load_obj(const char* name, bool has_unresolved) |
---|
| 59 | { |
---|
| 60 | void* handle; |
---|
| 61 | |
---|
| 62 | printf("load: %s\n", name); |
---|
| 63 | |
---|
| 64 | handle = dlopen (name, RTLD_NOW | RTLD_GLOBAL); |
---|
| 65 | if (!handle) |
---|
| 66 | { |
---|
| 67 | printf("dlopen failed: %s\n", dlerror()); |
---|
| 68 | return NULL; |
---|
| 69 | } |
---|
| 70 | |
---|
| 71 | dl_check_resolved (handle, has_unresolved); |
---|
| 72 | |
---|
| 73 | printf ("handle: %p loaded\n", handle); |
---|
| 74 | |
---|
| 75 | return handle; |
---|
| 76 | } |
---|
| 77 | |
---|
[bac53634] | 78 | static void dl_close (void* handle, const char* msg) |
---|
[03139d5b] | 79 | { |
---|
| 80 | int r; |
---|
[bac53634] | 81 | printf ("%s: handle: %p closing\n", msg, handle); |
---|
[03139d5b] | 82 | r = dlclose (handle); |
---|
| 83 | if (r != 0) |
---|
| 84 | printf("dlclose failed: %s\n", dlerror()); |
---|
| 85 | rtems_test_assert (r == 0); |
---|
| 86 | } |
---|
| 87 | |
---|
| 88 | static int dl_call (void* handle, const char* func) |
---|
| 89 | { |
---|
| 90 | call_sig call = dlsym (handle, func); |
---|
| 91 | if (call == NULL) |
---|
| 92 | { |
---|
| 93 | printf("dlsym failed: symbol not found: %s\n", func); |
---|
| 94 | return 1; |
---|
| 95 | } |
---|
| 96 | call (); |
---|
| 97 | return 0; |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | int dl_load_test(void) |
---|
| 101 | { |
---|
| 102 | void* o1; |
---|
| 103 | void* o2; |
---|
| 104 | void* o3; |
---|
| 105 | void* o4; |
---|
| 106 | void* o5; |
---|
| 107 | |
---|
| 108 | printf ("Test source (link in strstr): %s\n", dl_localise_file (__FILE__)); |
---|
| 109 | |
---|
| 110 | #if DL07_DEBUG_TRACE |
---|
| 111 | rtems_rtl_trace_set_mask (DL07_DEBUG_TRACE); |
---|
| 112 | #endif |
---|
| 113 | |
---|
| 114 | o1 = dl_load_obj("/dl07-o1.o", false); |
---|
| 115 | if (!o1) |
---|
| 116 | return 1; |
---|
| 117 | o2 = dl_load_obj("/dl07-o2.o", false); |
---|
| 118 | if (!o1) |
---|
| 119 | return 1; |
---|
| 120 | o3 = dl_load_obj("/dl07-o3.o", true); |
---|
| 121 | if (!o1) |
---|
| 122 | return 1; |
---|
| 123 | o4 = dl_load_obj("/dl07-o4.o", false); |
---|
| 124 | if (!o1) |
---|
| 125 | return 1; |
---|
| 126 | o5 = dl_load_obj("/dl07-o5.o", false); |
---|
| 127 | if (!o1) |
---|
| 128 | return 1; |
---|
| 129 | |
---|
| 130 | dl_check_resolved (o3, false); |
---|
| 131 | |
---|
| 132 | dl_load_dump (); |
---|
| 133 | |
---|
| 134 | printf ("\n\nRun mains in each module:\n\n"); |
---|
| 135 | if (dl_call (o1, "rtems_main_o1")) |
---|
| 136 | return 1; |
---|
| 137 | if (dl_call (o2, "rtems_main_o2")) |
---|
| 138 | return 1; |
---|
| 139 | if (dl_call (o3, "rtems_main_o3")) |
---|
| 140 | return 1; |
---|
| 141 | if (dl_call (o4, "rtems_main_o4")) |
---|
| 142 | return 1; |
---|
| 143 | if (dl_call (o5, "rtems_main_o5")) |
---|
| 144 | return 1; |
---|
| 145 | |
---|
| 146 | /* |
---|
| 147 | * Try and close the dependent modules, we should get an error. |
---|
| 148 | */ |
---|
[bac53634] | 149 | printf ("unload test: o1\n"); |
---|
[03139d5b] | 150 | rtems_test_assert (dlclose (o1) != 0); |
---|
[bac53634] | 151 | printf ("unload test: o2\n"); |
---|
[03139d5b] | 152 | rtems_test_assert (dlclose (o2) != 0); |
---|
[bac53634] | 153 | printf ("unload test: o4\n"); |
---|
[03139d5b] | 154 | rtems_test_assert (dlclose (o4) != 0); |
---|
[bac53634] | 155 | printf ("unload test: o5\n"); |
---|
[03139d5b] | 156 | rtems_test_assert (dlclose (o5) != 0); |
---|
| 157 | |
---|
[bac53634] | 158 | dl_close (o3, "o3"); |
---|
[03139d5b] | 159 | rtems_test_assert (dlclose (o1) != 0); |
---|
[bac53634] | 160 | dl_close (o4, "o4"); |
---|
[03139d5b] | 161 | rtems_test_assert (dlclose (o1) != 0); |
---|
[bac53634] | 162 | dl_close (o5, "o5"); |
---|
[03139d5b] | 163 | rtems_test_assert (dlclose (o1) != 0); |
---|
[bac53634] | 164 | dl_close (o2, "o2"); |
---|
| 165 | dl_close (o1, "o1"); |
---|
[03139d5b] | 166 | |
---|
| 167 | return 0; |
---|
| 168 | } |
---|