aboutsummaryrefslogtreecommitdiff
path: root/REORG.TODO/elf/loadtest.c
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/elf/loadtest.c')
-rw-r--r--REORG.TODO/elf/loadtest.c202
1 files changed, 202 insertions, 0 deletions
diff --git a/REORG.TODO/elf/loadtest.c b/REORG.TODO/elf/loadtest.c
new file mode 100644
index 0000000000..727469b496
--- /dev/null
+++ b/REORG.TODO/elf/loadtest.c
@@ -0,0 +1,202 @@
+#include <assert.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <error.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/* How many load/unload operations do we do. */
+#define TEST_ROUNDS 1000
+
+
+static struct
+{
+ /* Name of the module. */
+ const char *name;
+ /* The handle. */
+ void *handle;
+} testobjs[] =
+{
+ { "testobj1.so", NULL },
+ { "testobj2.so", NULL },
+ { "testobj3.so", NULL },
+ { "testobj4.so", NULL },
+ { "testobj5.so", NULL },
+ { "testobj6.so", NULL },
+};
+#define NOBJS (sizeof (testobjs) / sizeof (testobjs[0]))
+
+
+static const struct
+{
+ /* Name of a function to call. */
+ const char *fname;
+ /* Index in status and handle array. */
+ int index;
+ /* Options while loading the module. */
+ int options;
+} tests[] =
+{
+ { "obj1func2", 0, RTLD_LAZY },
+ { "obj1func1", 0, RTLD_LAZY | RTLD_GLOBAL },
+ { "obj1func1", 0, RTLD_NOW, },
+ { "obj1func2", 0, RTLD_NOW | RTLD_GLOBAL },
+ { "obj2func2", 1, RTLD_LAZY },
+ { "obj2func1", 1, RTLD_LAZY | RTLD_GLOBAL, },
+ { "obj2func1", 1, RTLD_NOW, },
+ { "obj2func2", 1, RTLD_NOW | RTLD_GLOBAL },
+ { "obj3func2", 2, RTLD_LAZY },
+ { "obj3func1", 2, RTLD_LAZY | RTLD_GLOBAL },
+ { "obj3func1", 2, RTLD_NOW },
+ { "obj3func2", 2, RTLD_NOW | RTLD_GLOBAL },
+ { "obj4func2", 3, RTLD_LAZY },
+ { "obj4func1", 3, RTLD_LAZY | RTLD_GLOBAL },
+ { "obj4func1", 3, RTLD_NOW },
+ { "obj4func2", 3, RTLD_NOW | RTLD_GLOBAL },
+ { "obj5func2", 4, RTLD_LAZY },
+ { "obj5func1", 4, RTLD_LAZY | RTLD_GLOBAL },
+ { "obj5func1", 4, RTLD_NOW },
+ { "obj5func2", 4, RTLD_NOW | RTLD_GLOBAL },
+ { "obj6func2", 5, RTLD_LAZY },
+ { "obj6func1", 5, RTLD_LAZY | RTLD_GLOBAL },
+ { "obj6func1", 5, RTLD_NOW },
+ { "obj6func2", 5, RTLD_NOW | RTLD_GLOBAL },
+};
+#define NTESTS (sizeof (tests) / sizeof (tests[0]))
+
+
+#include <include/link.h>
+
+#define MAPS ((struct link_map *) _r_debug.r_map)
+
+#define OUT \
+ for (map = MAPS; map != NULL; map = map->l_next) \
+ if (map->l_type == lt_loaded) \
+ printf ("name = \"%s\", direct_opencount = %d\n", \
+ map->l_name, (int) map->l_direct_opencount); \
+ fflush (stdout)
+
+
+int
+main (int argc, char *argv[])
+{
+ int debug = argc > 1 && argv[1][0] != '\0';
+ int count = TEST_ROUNDS;
+ int result = 0;
+ struct link_map *map;
+
+ mtrace ();
+
+ /* Just a seed. */
+ srandom (TEST_ROUNDS);
+
+ if (debug)
+ {
+ puts ("in the beginning");
+ OUT;
+ }
+
+ while (count--)
+ {
+ int nr = random () % NTESTS;
+ int index = tests[nr].index;
+
+ printf ("%4d: %4d: ", count + 1, nr);
+ fflush (stdout);
+
+ if (testobjs[index].handle == NULL)
+ {
+ int (*fct) (int);
+
+ /* Load the object. */
+ testobjs[index].handle = dlopen (testobjs[index].name,
+ tests[nr].options);
+ if (testobjs[index].handle == NULL)
+ error (EXIT_FAILURE, 0, "cannot load `%s': %s",
+ testobjs[index].name, dlerror ());
+
+ /* Test the function call. */
+ fct = dlsym (testobjs[index].handle, tests[nr].fname);
+ if (fct == NULL)
+ error (EXIT_FAILURE, 0,
+ "cannot get function `%s' from shared object `%s': %s",
+ tests[nr].fname, testobjs[index].name, dlerror ());
+
+ fct (10);
+
+ printf ("successfully loaded `%s', handle %p\n",
+ testobjs[index].name, testobjs[index].handle);
+ }
+ else
+ {
+ if (dlclose (testobjs[index].handle) != 0)
+ {
+ printf ("failed to close %s\n", testobjs[index].name);
+ result = 1;
+ }
+ else
+ printf ("successfully unloaded `%s', handle %p\n",
+ testobjs[index].name, testobjs[index].handle);
+
+ testobjs[index].handle = NULL;
+
+ if (testobjs[0].handle == NULL
+ && testobjs[1].handle == NULL
+ && testobjs[5].handle == NULL)
+ {
+ /* In this case none of the objects above should be
+ present. */
+ for (map = MAPS; map != NULL; map = map->l_next)
+ if (map->l_type == lt_loaded
+ && (strstr (map->l_name, testobjs[0].name) != NULL
+ || strstr (map->l_name, testobjs[1].name) != NULL
+ || strstr (map->l_name, testobjs[5].name) != NULL))
+ {
+ printf ("`%s' is still loaded\n", map->l_name);
+ result = 1;
+ }
+ }
+ }
+
+ if (debug)
+ OUT;
+ }
+
+ /* Unload all loaded modules. */
+ for (count = 0; count < (int) NOBJS; ++count)
+ if (testobjs[count].handle != NULL)
+ {
+ printf ("\nclose: %s: l_initfini = %p, l_versions = %p\n",
+ testobjs[count].name,
+ ((struct link_map *) testobjs[count].handle)->l_initfini,
+ ((struct link_map *) testobjs[count].handle)->l_versions);
+
+ if (dlclose (testobjs[count].handle) != 0)
+ {
+ printf ("failed to close %s\n", testobjs[count].name);
+ result = 1;
+ }
+ }
+
+ /* Check whether all files are unloaded. */
+ for (map = MAPS; map != NULL; map = map->l_next)
+ if (map->l_type == lt_loaded)
+ {
+ printf ("name = \"%s\", direct_opencount = %d\n",
+ map->l_name, (int) map->l_direct_opencount);
+ result = 1;
+ }
+
+ return result;
+}
+
+
+extern int foo (int a);
+int
+foo (int a)
+{
+ return a - 1;
+}