| lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame] | 1 | #include <dlfcn.h> | 
|  | 2 | #include <stdio.h> | 
|  | 3 | #include <stdlib.h> | 
|  | 4 |  | 
|  | 5 | #include <link.h> | 
|  | 6 |  | 
|  | 7 |  | 
|  | 8 | #define TEST_FUNCTION do_test () | 
|  | 9 | static int | 
|  | 10 | do_test (void) | 
|  | 11 | { | 
|  | 12 | static const char modname1[] = "$ORIGIN/tst-tlsmod3.so"; | 
|  | 13 | static const char modname2[] = "$ORIGIN/tst-tlsmod4.so"; | 
|  | 14 | int result = 0; | 
|  | 15 | int (*fp1) (void); | 
|  | 16 | int (*fp2) (int, int *); | 
|  | 17 | void *h1; | 
|  | 18 | void *h2; | 
|  | 19 | int i; | 
|  | 20 | size_t modid1 = (size_t) -1; | 
|  | 21 | size_t modid2 = (size_t) -1; | 
|  | 22 | int *bazp; | 
|  | 23 |  | 
|  | 24 | for (i = 0; i < 10; ++i) | 
|  | 25 | { | 
|  | 26 | h1 = dlopen (modname1, RTLD_LAZY); | 
|  | 27 | if (h1 == NULL) | 
|  | 28 | { | 
|  | 29 | printf ("cannot open '%s': %s\n", modname1, dlerror ()); | 
|  | 30 | exit (1); | 
|  | 31 | } | 
|  | 32 |  | 
|  | 33 | /* Dirty test code here: we peek into a private data structure. | 
|  | 34 | We make sure that the module gets assigned the same ID every | 
|  | 35 | time.  The value of the first round is used.  */ | 
|  | 36 | if (modid1 == (size_t) -1) | 
|  | 37 | modid1 = ((struct link_map *) h1)->l_tls_modid; | 
|  | 38 | else if (((struct link_map *) h1)->l_tls_modid != modid1) | 
|  | 39 | { | 
|  | 40 | printf ("round %d: modid now %zd, initially %zd\n", | 
|  | 41 | i, ((struct link_map *) h1)->l_tls_modid, modid1); | 
|  | 42 | result = 1; | 
|  | 43 | } | 
|  | 44 |  | 
|  | 45 | fp1 = dlsym (h1, "in_dso2"); | 
|  | 46 | if (fp1 == NULL) | 
|  | 47 | { | 
|  | 48 | printf ("cannot get symbol 'in_dso2' in %s\n", modname1); | 
|  | 49 | exit (1); | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | result |= fp1 (); | 
|  | 53 |  | 
|  | 54 |  | 
|  | 55 |  | 
|  | 56 | h2 = dlopen (modname2, RTLD_LAZY); | 
|  | 57 | if (h2 == NULL) | 
|  | 58 | { | 
|  | 59 | printf ("cannot open '%s': %s\n", modname2, dlerror ()); | 
|  | 60 | exit (1); | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | /* Dirty test code here: we peek into a private data structure. | 
|  | 64 | We make sure that the module gets assigned the same ID every | 
|  | 65 | time.  The value of the first round is used.  */ | 
|  | 66 | if (modid2 == (size_t) -1) | 
|  | 67 | modid2 = ((struct link_map *) h1)->l_tls_modid; | 
|  | 68 | else if (((struct link_map *) h1)->l_tls_modid != modid2) | 
|  | 69 | { | 
|  | 70 | printf ("round %d: modid now %zd, initially %zd\n", | 
|  | 71 | i, ((struct link_map *) h1)->l_tls_modid, modid2); | 
|  | 72 | result = 1; | 
|  | 73 | } | 
|  | 74 |  | 
|  | 75 | bazp = dlsym (h2, "baz"); | 
|  | 76 | if (bazp == NULL) | 
|  | 77 | { | 
|  | 78 | printf ("cannot get symbol 'baz' in %s\n", modname2); | 
|  | 79 | exit (1); | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | *bazp = 42 + i; | 
|  | 83 |  | 
|  | 84 | fp2 = dlsym (h2, "in_dso"); | 
|  | 85 | if (fp2 == NULL) | 
|  | 86 | { | 
|  | 87 | printf ("cannot get symbol 'in_dso' in %s\n", modname2); | 
|  | 88 | exit (1); | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | result |= fp2 (42 + i, bazp); | 
|  | 92 |  | 
|  | 93 | dlclose (h1); | 
|  | 94 | dlclose (h2); | 
|  | 95 |  | 
|  | 96 |  | 
|  | 97 | h1 = dlopen (modname1, RTLD_LAZY); | 
|  | 98 | if (h1 == NULL) | 
|  | 99 | { | 
|  | 100 | printf ("cannot open '%s': %s\n", modname1, dlerror ()); | 
|  | 101 | exit (1); | 
|  | 102 | } | 
|  | 103 |  | 
|  | 104 | /* Dirty test code here: we peek into a private data structure. | 
|  | 105 | We make sure that the module gets assigned the same ID every | 
|  | 106 | time.  The value of the first round is used.  */ | 
|  | 107 | if (((struct link_map *) h1)->l_tls_modid != modid1) | 
|  | 108 | { | 
|  | 109 | printf ("round %d: modid now %zd, initially %zd\n", | 
|  | 110 | i, ((struct link_map *) h1)->l_tls_modid, modid1); | 
|  | 111 | result = 1; | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | fp1 = dlsym (h1, "in_dso2"); | 
|  | 115 | if (fp1 == NULL) | 
|  | 116 | { | 
|  | 117 | printf ("cannot get symbol 'in_dso2' in %s\n", modname1); | 
|  | 118 | exit (1); | 
|  | 119 | } | 
|  | 120 |  | 
|  | 121 | result |= fp1 (); | 
|  | 122 |  | 
|  | 123 |  | 
|  | 124 |  | 
|  | 125 | h2 = dlopen (modname2, RTLD_LAZY); | 
|  | 126 | if (h2 == NULL) | 
|  | 127 | { | 
|  | 128 | printf ("cannot open '%s': %s\n", modname2, dlerror ()); | 
|  | 129 | exit (1); | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | /* Dirty test code here: we peek into a private data structure. | 
|  | 133 | We make sure that the module gets assigned the same ID every | 
|  | 134 | time.  The value of the first round is used.  */ | 
|  | 135 | if (((struct link_map *) h1)->l_tls_modid != modid2) | 
|  | 136 | { | 
|  | 137 | printf ("round %d: modid now %zd, initially %zd\n", | 
|  | 138 | i, ((struct link_map *) h1)->l_tls_modid, modid2); | 
|  | 139 | result = 1; | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | bazp = dlsym (h2, "baz"); | 
|  | 143 | if (bazp == NULL) | 
|  | 144 | { | 
|  | 145 | printf ("cannot get symbol 'baz' in %s\n", modname2); | 
|  | 146 | exit (1); | 
|  | 147 | } | 
|  | 148 |  | 
|  | 149 | *bazp = 62 + i; | 
|  | 150 |  | 
|  | 151 | fp2 = dlsym (h2, "in_dso"); | 
|  | 152 | if (fp2 == NULL) | 
|  | 153 | { | 
|  | 154 | printf ("cannot get symbol 'in_dso' in %s\n", modname2); | 
|  | 155 | exit (1); | 
|  | 156 | } | 
|  | 157 |  | 
|  | 158 | result |= fp2 (62 + i, bazp); | 
|  | 159 |  | 
|  | 160 | /* This time the dlclose calls are in reverse order.  */ | 
|  | 161 | dlclose (h2); | 
|  | 162 | dlclose (h1); | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | return result; | 
|  | 166 | } | 
|  | 167 |  | 
|  | 168 |  | 
|  | 169 | #include "../test-skeleton.c" |