Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:32

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2014 Chris Johns <chrisj@rtems.org>.
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
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_LOAD_SECT | \
0036                       RTEMS_RTL_TRACE_SYMBOL | \
0037                       RTEMS_RTL_TRACE_RELOC | \
0038                       RTEMS_RTL_TRACE_ALLOCATOR | \
0039                       RTEMS_RTL_TRACE_UNRESOLVED | \
0040                       RTEMS_RTL_TRACE_ARCHIVES | \
0041                       RTEMS_RTL_TRACE_GLOBAL_SYM | \
0042                       RTEMS_RTL_TRACE_DEPENDENCY)
0043  #define DL_DEBUG_TRACE DEBUG_TRACE /* RTEMS_RTL_TRACE_ALL */
0044  #define DL_RTL_CMDS    1
0045 #else
0046  #define DL_DEBUG_TRACE 0
0047  #define DL_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/rtl/rtl-shell.h>
0057 #include <rtems/rtl/rtl-trace.h>
0058 
0059 typedef int (*call_sig)(void);
0060 
0061 static void dl_load_dump (void)
0062 {
0063 #if DL_RTL_CMDS
0064   char* list[] = { "rtl", "list", NULL };
0065   char* sym[] = { "rtl", "sym", NULL };
0066   printf ("RTL List:\n");
0067   rtems_rtl_shell_command (2, list);
0068   printf ("RTL Sym:\n");
0069   rtems_rtl_shell_command (2, sym);
0070 #endif
0071 }
0072 
0073 static void dl_check_resolved(void* handle, bool has_unresolved)
0074 {
0075   int unresolved = 0;
0076   rtems_test_assert (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) == 0);
0077   if (has_unresolved)
0078   {
0079     if (unresolved == 0)
0080     {
0081       dl_load_dump();
0082       rtems_test_assert (unresolved != 0);
0083     }
0084   }
0085   else
0086   {
0087     if (unresolved != 0)
0088     {
0089       dl_load_dump();
0090       rtems_test_assert (unresolved == 0);
0091     }
0092   }
0093 }
0094 
0095 static void* dl_load_obj(const char* name, bool has_unresolved)
0096 {
0097   void* handle;
0098 
0099   printf("load: %s\n", name);
0100 
0101   handle = dlopen (name, RTLD_NOW | RTLD_GLOBAL);
0102   if (!handle)
0103   {
0104     printf("dlopen failed: %s\n", dlerror());
0105     return NULL;
0106   }
0107 
0108   dl_check_resolved (handle, has_unresolved);
0109 
0110   printf ("handle: %p loaded\n", handle);
0111 
0112   return handle;
0113 }
0114 
0115 static void dl_close (void* handle, const char* msg)
0116 {
0117   int r;
0118   printf ("%s: handle: %p closing\n", msg, handle);
0119   r = dlclose (handle);
0120   if (r != 0)
0121     printf("dlclose failed: %s\n", dlerror());
0122   rtems_test_assert (r == 0);
0123 }
0124 
0125 static int dl_call (void* handle, const char* func)
0126 {
0127   call_sig call = dlsym (handle, func);
0128   if (call == NULL)
0129   {
0130     printf("dlsym failed: symbol not found: %s\n", func);
0131     return 1;
0132   }
0133   call ();
0134   return 0;
0135 }
0136 
0137 int dl_load_test(void)
0138 {
0139   void* o1;
0140   void* o2;
0141   void* o3;
0142   void* o4;
0143   void* o5;
0144 
0145   printf ("Test source (link in strstr): %s\n", dl_localise_file (__FILE__));
0146 
0147 #if DL_DEBUG_TRACE
0148   rtems_rtl_trace_set_mask (DL_DEBUG_TRACE);
0149 #endif
0150 
0151   o1 = dl_load_obj("/dl07-o1.o", false);
0152   if (!o1)
0153     return 1;
0154   o2 = dl_load_obj("/dl07-o2.o", false);
0155   if (!o1)
0156     return 1;
0157   o3 = dl_load_obj("/dl07-o3.o", true);
0158   if (!o1)
0159     return 1;
0160   o4 = dl_load_obj("/dl07-o4.o", false);
0161   if (!o1)
0162     return 1;
0163   o5 = dl_load_obj("/dl07-o5.o", false);
0164   if (!o1)
0165     return 1;
0166 
0167   dl_check_resolved (o3, false);
0168 
0169   dl_load_dump ();
0170 
0171   printf ("\n\nRun mains in each module:\n\n");
0172   if (dl_call (o1, "rtems_main_o1"))
0173     return 1;
0174   if (dl_call (o2, "rtems_main_o2"))
0175     return 1;
0176   if (dl_call (o3, "rtems_main_o3"))
0177     return 1;
0178   if (dl_call (o4, "rtems_main_o4"))
0179     return 1;
0180   if (dl_call (o5, "rtems_main_o5"))
0181     return 1;
0182 
0183   /*
0184    * Try and close the dependent modules, we should get an error.
0185    */
0186   printf ("unload test: o1\n");
0187   rtems_test_assert (dlclose (o1) != 0);
0188   printf ("unload test: o2\n");
0189   rtems_test_assert (dlclose (o2) != 0);
0190   printf ("unload test: o4\n");
0191   rtems_test_assert (dlclose (o4) != 0);
0192   printf ("unload test: o5\n");
0193   rtems_test_assert (dlclose (o5) != 0);
0194 
0195   dl_close (o3, "o3");
0196   rtems_test_assert (dlclose (o1) != 0);
0197   dl_close (o4, "o4");
0198   rtems_test_assert (dlclose (o1) != 0);
0199   dl_close (o5, "o5");
0200   rtems_test_assert (dlclose (o1) != 0);
0201   dl_close (o2, "o2");
0202   dl_close (o1, "o1");
0203 
0204   return 0;
0205 }