File indexing completed on 2025-05-11 08:24:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #define TEST_TRACE 0
0030 #if TEST_TRACE
0031 #define DEBUG_TRACE (RTEMS_RTL_TRACE_DETAIL | \
0032 RTEMS_RTL_TRACE_WARNING | \
0033 RTEMS_RTL_TRACE_LOAD | \
0034 RTEMS_RTL_TRACE_UNLOAD | \
0035 RTEMS_RTL_TRACE_SYMBOL | \
0036 RTEMS_RTL_TRACE_RELOC | \
0037 RTEMS_RTL_TRACE_ALLOCATOR | \
0038 RTEMS_RTL_TRACE_UNRESOLVED | \
0039 RTEMS_RTL_TRACE_ARCHIVES | \
0040 RTEMS_RTL_TRACE_DEPENDENCY | \
0041 RTEMS_RTL_TRACE_LOAD_SECT | \
0042 RTEMS_RTL_TRACE_BIT_ALLOC)
0043 #define DL09_DEBUG_TRACE DEBUG_TRACE
0044 #define DL09_RTL_CMDS 1
0045 #else
0046 #define DL09_DEBUG_TRACE 0
0047 #define DL09_RTL_CMDS 0
0048 #endif
0049
0050 #include <dlfcn.h>
0051
0052 #include "dl-load.h"
0053
0054 #include <tmacros.h>
0055
0056 #include <rtems/malloc.h>
0057 #include <rtems/rtl/rtl-shell.h>
0058 #include <rtems/rtl/rtl-trace.h>
0059
0060 extern void rtems_shell_print_heap_info(
0061 const char *c,
0062 const Heap_Information *h
0063 );
0064
0065 typedef struct
0066 {
0067 void* handle;
0068 void* space;
0069 } objects;
0070
0071 typedef struct
0072 {
0073 const char* name;
0074 bool has_unresolved;
0075 size_t space;
0076 } object_def;
0077
0078 #define MBYTES(_m) ((_m) * 1024UL * 1024UL)
0079 #define NUMOF(_a) (sizeof(_a) / sizeof(_a[0]))
0080
0081 typedef int (*call_sig)(void);
0082
0083 static void dl_load_dump (void)
0084 {
0085 #if DL09_RTL_CMDS
0086 char* list[] = { "rtl", "list", NULL };
0087 char* sym[] = { "rtl", "sym", NULL };
0088 Heap_Information_block info;
0089 malloc_info( &info );
0090 printf ("RTL List:\n");
0091 rtems_rtl_shell_command (2, list);
0092 printf ("RTL Sym:\n");
0093 rtems_rtl_shell_command (2, sym);
0094 printf ("Malloc:\n");
0095 rtems_shell_print_heap_info("free", &info.Free);
0096 #endif
0097 }
0098
0099 static void dl_check_resolved(void* handle, bool has_unresolved)
0100 {
0101 int unresolved = 0;
0102 rtems_test_assert (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) == 0);
0103 if (has_unresolved)
0104 {
0105 if (unresolved == 0)
0106 {
0107 dl_load_dump();
0108 rtems_test_assert (unresolved != 0);
0109 }
0110 }
0111 else
0112 {
0113 if (unresolved != 0)
0114 {
0115 dl_load_dump();
0116 rtems_test_assert (unresolved == 0);
0117 }
0118 }
0119 if (handle == RTLD_SELF)
0120 printf ("handle: RTL_SELF: %sunresolved externals\n",
0121 unresolved != 0 ? "" : "no ");
0122 else
0123 printf ("handle: %p: %sunresolved externals\n",
0124 handle, unresolved != 0 ? "" : "no ");
0125 }
0126
0127 static void* dl_load_obj (const char* name, bool has_unresolved)
0128 {
0129 void* handle;
0130
0131 printf("load: %s\n", name);
0132
0133 handle = dlopen (name, RTLD_NOW | RTLD_GLOBAL);
0134 if (!handle)
0135 {
0136 printf("dlopen failed: %s\n", dlerror());
0137 return NULL;
0138 }
0139
0140 dl_check_resolved (handle, has_unresolved);
0141
0142 printf ("handle: %p loaded\n", handle);
0143
0144 return handle;
0145 }
0146
0147 static void dl_close (void* handle)
0148 {
0149 int r;
0150 printf ("handle: %p closing\n", handle);
0151 r = dlclose (handle);
0152 if (r != 0)
0153 printf("dlclose failed: %s\n", dlerror());
0154 rtems_test_assert (r == 0);
0155 }
0156
0157 static int dl_call (void* handle, const char* func)
0158 {
0159 static call_sig last_call;
0160 call_sig call = dlsym (handle, func);
0161 if (call == NULL)
0162 {
0163 printf("dlsym failed: symbol not found: %s\n", func);
0164 return 1;
0165 }
0166 if (last_call != NULL && last_call != call)
0167 {
0168 printf("Call location different: moved by: %i (call:%p last:%p)\n",
0169 (int) (call - last_call),
0170 call, last_call);
0171 }
0172 last_call = call;
0173 call ();
0174 return 0;
0175 }
0176
0177 static void dl_object_open (object_def* od, objects* o)
0178 {
0179 o->handle = dl_load_obj(od->name, od->has_unresolved);
0180 rtems_test_assert (o->handle != NULL);
0181 if (!od->has_unresolved)
0182 dl_check_resolved (o->handle, false);
0183 if (od->space != 0)
0184 {
0185 o->space = malloc (od->space);
0186 printf("space alloc: %s: %zd: %p\n", od->name, od->space, o->space);
0187 rtems_test_assert (o->space != NULL);
0188 }
0189 dl_load_dump ();
0190 }
0191
0192 static void dl_object_close (objects* o)
0193 {
0194 dl_close (o->handle);
0195 printf("space dealloc: %p\n", o->space);
0196 free (o->space);
0197 }
0198
0199
0200
0201
0202 extern size_t rtems_rtl_elf_relocate_tramp_max_size (void);
0203 static size_t dl_alloc_size (void)
0204 {
0205
0206
0207
0208
0209 if (rtems_rtl_elf_relocate_tramp_max_size () == 0)
0210 return 0;
0211 return MBYTES(32);
0212 }
0213
0214 int dl_load_test(void)
0215 {
0216 object_def od[5] = { { "/dl09-o1.o", true, dl_alloc_size () },
0217 { "/dl09-o2.o", true, dl_alloc_size () },
0218 { "/dl09-o3.o", true, dl_alloc_size () },
0219 { "/dl09-o4.o", true, dl_alloc_size () },
0220 { "/dl09-o5.o", false, 0 } };
0221 objects o[5] = { 0 };
0222 size_t i;
0223
0224 printf ("Test source (link in strstr): %s\n", dl_localise_file (__FILE__));
0225 printf ("Allocation size: %zu\n", dl_alloc_size ());
0226
0227 #if DL09_DEBUG_TRACE
0228 rtems_rtl_trace_set_mask (DL09_DEBUG_TRACE);
0229 #endif
0230
0231 for (i = 0; i < NUMOF(od); ++i)
0232 dl_object_open (&od[i], &o[i]);
0233
0234 dl_load_dump ();
0235
0236
0237
0238
0239 printf ("Check is any unresolved externals exist:\n");
0240 dl_check_resolved (RTLD_SELF, false);
0241
0242 printf ("Running rtems_main_o1:\n");
0243 if (dl_call (o[0].handle, "rtems_main_o1"))
0244 return 1;
0245
0246 for (i = 0; i < NUMOF (od); ++i)
0247 dl_object_close (&o[i]);
0248
0249 return 0;
0250 }