source: mainline/uspace/app/dltest/dltest.c@ bab0f42

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bab0f42 was 29405ac, checked in by Jiri Svoboda <jiri@…>, 9 years ago

DTPMOD relocations with null symbol name should return the current module index. Implement TPOFF relocations. dltest -n to not run dlfcn tests. Now dltest -n works like a charm. Place TLS images in descending order for variant II just to be safe. Propagate TLS alignment info.

  • Property mode set to 100644
File size: 16.5 KB
Line 
1/*
2 * Copyright (c) 2016 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup dltest
30 * @{
31 */
32
33/**
34 * @file
35 * @brief Test dynamic linking
36 */
37
38#include <dlfcn.h>
39#include <libdltest.h>
40#include <stdbool.h>
41#include <stdio.h>
42#include <stdlib.h>
43
44/** libdltest library handle */
45static void *handle;
46
47/** If true, do not run dlfcn tests */
48static bool no_dlfcn = false;
49
50/** Test dlsym() function */
51static bool test_dlsym(void)
52{
53 int (*p_dl_get_constant)(void);
54
55 printf("dlsym()... ");
56 p_dl_get_constant = dlsym(handle, "dl_get_constant");
57 if (p_dl_get_constant == NULL) {
58 printf("FAILED\n");
59 return false;
60 }
61
62 printf("Passed\n");
63 return true;
64}
65
66/** Test calling function that returns a constant */
67static bool test_dlfcn_dl_get_constant(void)
68{
69 int (*p_dl_get_constant)(void);
70 int val;
71
72 printf("Call dlsym/dl_get_constant...\n");
73
74 p_dl_get_constant = dlsym(handle, "dl_get_constant");
75 if (p_dl_get_constant == NULL) {
76 printf("FAILED\n");
77 return false;
78 }
79
80 val = p_dl_get_constant();
81
82 printf("Got %d, expected %d... ", val, dl_constant);
83 if (val != dl_constant) {
84 printf("FAILED\n");
85 return false;
86 }
87
88 printf("Passed\n");
89 return true;
90}
91
92/** Test calling a function that returns contents of a private initialized
93 * variable.
94 */
95static bool test_dlfcn_dl_get_private_var(void)
96{
97 int (*p_dl_get_private_var)(void);
98 int val;
99
100 printf("Call dlsym/dl_get_private_var...\n");
101
102 p_dl_get_private_var = dlsym(handle, "dl_get_private_var");
103 if (p_dl_get_private_var == NULL) {
104 printf("FAILED\n");
105 return false;
106 }
107
108 val = p_dl_get_private_var();
109
110 printf("Got %d, expected %d... ", val, dl_private_var_val);
111 if (val != dl_private_var_val) {
112 printf("FAILED\n");
113 return false;
114 }
115
116 printf("Passed\n");
117 return true;
118}
119
120/** Test calling a function that returns contents of a private uninitialized
121 * variable.
122 */
123static bool test_dlfcn_dl_get_private_uvar(void)
124{
125 int (*p_dl_get_private_uvar)(void);
126 int val;
127
128 printf("Call dlsym/dl_get_private_uvar...\n");
129
130 p_dl_get_private_uvar = dlsym(handle, "dl_get_private_uvar");
131 if (p_dl_get_private_uvar == NULL) {
132 printf("FAILED\n");
133 return false;
134 }
135
136 val = p_dl_get_private_uvar();
137
138 printf("Got %d, expected %d... ", val, 0);
139 if (val != 0) {
140 printf("FAILED\n");
141 return false;
142 }
143
144 printf("Passed\n");
145 return true;
146}
147
148/** Test calling a function that returns the contents of a public initialized
149 * variable.
150 */
151static bool test_dlfcn_dl_get_public_var(void)
152{
153 int (*p_dl_get_public_var)(void);
154 int val;
155
156 printf("Call dlsym/dl_get_public_var...\n");
157
158 p_dl_get_public_var = dlsym(handle, "dl_get_public_var");
159 if (p_dl_get_public_var == NULL) {
160 printf("FAILED\n");
161 return false;
162 }
163
164 val = p_dl_get_public_var();
165
166 printf("Got %d, expected %d... ", val, dl_public_var_val);
167 if (val != dl_public_var_val) {
168 printf("FAILED\n");
169 return false;
170 }
171
172 printf("Passed\n");
173 return true;
174}
175
176/** Test calling a function that returns the contents of a public uninitialized
177 * variable.
178 */
179static bool test_dlfcn_dl_get_public_uvar(void)
180{
181 int (*p_dl_get_public_uvar)(void);
182 int val;
183
184 printf("Call dlsym/dl_get_public_uvar...\n");
185
186 p_dl_get_public_uvar = dlsym(handle, "dl_get_public_uvar");
187 if (p_dl_get_public_uvar == NULL) {
188 printf("FAILED\n");
189 return false;
190 }
191
192 val = p_dl_get_public_uvar();
193
194 printf("Got %d, expected %d... ", val, 0);
195 if (val != 0) {
196 printf("FAILED\n");
197 return false;
198 }
199
200 printf("Passed\n");
201 return true;
202}
203
204/** Test directly reading a public initialized variable whose address was
205 * obtained using dlsym.
206 */
207static bool test_dlfcn_read_public_var(void)
208{
209 int *p_dl_public_var;
210 int val;
211
212 printf("Read dlsym/dl_public_var...\n");
213
214 p_dl_public_var = dlsym(handle, "dl_public_var");
215 if (p_dl_public_var == NULL) {
216 printf("FAILED\n");
217 return false;
218 }
219
220 val = *p_dl_public_var;
221
222 printf("Got %d, expected %d... ", val, dl_public_var_val);
223 if (val != dl_public_var_val) {
224 printf("FAILED\n");
225 return false;
226 }
227
228 printf("Passed\n");
229 return true;
230}
231
232/** Test directly reading a public uninitialized variable whose address was
233 * obtained using dlsym.
234 */
235static bool test_dlfcn_read_public_uvar(void)
236{
237 int *p_dl_public_uvar;
238 int val;
239
240 printf("Read dlsym/dl_public_uvar...\n");
241
242 p_dl_public_uvar = dlsym(handle, "dl_public_uvar");
243 if (p_dl_public_uvar == NULL) {
244 printf("FAILED\n");
245 return false;
246 }
247
248 val = *p_dl_public_uvar;
249
250 printf("Got %d, expected %d... ", val, 0);
251 if (val != 0) {
252 printf("FAILED\n");
253 return false;
254 }
255
256 printf("Passed\n");
257 return true;
258}
259
260/** Test calling a function that returns contents of a private initialized
261 * fibril-local variable.
262 */
263static bool test_dlfcn_dl_get_private_fib_var(void)
264{
265 int (*p_dl_get_private_fib_var)(void);
266 int val;
267
268 printf("Call dlsym/dl_get_private_fib_var...\n");
269
270 p_dl_get_private_fib_var = dlsym(handle, "dl_get_private_fib_var");
271 if (p_dl_get_private_fib_var == NULL) {
272 printf("FAILED\n");
273 return false;
274 }
275
276 val = p_dl_get_private_fib_var();
277
278 printf("Got %d, expected %d... ", val, dl_private_fib_var_val);
279 if (val != dl_private_fib_var_val) {
280 printf("FAILED\n");
281 return false;
282 }
283
284 printf("Passed\n");
285 return true;
286}
287
288/** Test calling a function that returns contents of a private uninitialized
289 * fibril-local variable.
290 */
291static bool test_dlfcn_dl_get_private_fib_uvar(void)
292{
293 int (*p_dl_get_private_fib_uvar)(void);
294 int val;
295
296 printf("Call dlsym/dl_get_private_fib_uvar...\n");
297
298 p_dl_get_private_fib_uvar = dlsym(handle, "dl_get_private_fib_uvar");
299 if (p_dl_get_private_fib_uvar == NULL) {
300 printf("FAILED\n");
301 return false;
302 }
303
304 val = p_dl_get_private_fib_uvar();
305
306 printf("Got %d, expected %d... ", val, 0);
307 if (val != 0) {
308 printf("FAILED\n");
309 return false;
310 }
311
312 printf("Passed\n");
313 return true;
314}
315
316/** Test calling a function that returns the contents of a public initialized
317 * fibril-local variable.
318 */
319static bool test_dlfcn_dl_get_public_fib_var(void)
320{
321 int (*p_dl_get_public_fib_var)(void);
322 int val;
323
324 printf("Call dlsym/dl_get_public_fib_var...\n");
325
326 p_dl_get_public_fib_var = dlsym(handle, "dl_get_public_fib_var");
327 if (p_dl_get_public_fib_var == NULL) {
328 printf("FAILED\n");
329 return false;
330 }
331
332 val = p_dl_get_public_fib_var();
333
334 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
335 if (val != dl_public_fib_var_val) {
336 printf("FAILED\n");
337 return false;
338 }
339
340 printf("Passed\n");
341 return true;
342}
343
344/** Test calling a function that returns the contents of a public uninitialized
345 * fibril-local variable.
346 */
347static bool test_dlfcn_dl_get_public_fib_uvar(void)
348{
349 int (*p_dl_get_public_fib_uvar)(void);
350 int val;
351
352 printf("Call dlsym/dl_get_public_fib_uvar...\n");
353
354 p_dl_get_public_fib_uvar = dlsym(handle, "dl_get_public_fib_uvar");
355 if (p_dl_get_public_fib_uvar == NULL) {
356 printf("FAILED\n");
357 return false;
358 }
359
360 val = p_dl_get_public_fib_uvar();
361
362 printf("Got %d, expected %d... ", val, 0);
363 if (val != 0) {
364 printf("FAILED\n");
365 return false;
366 }
367
368 printf("Passed\n");
369 return true;
370}
371
372/** Test directly reading a public initialized fibril-local variable
373 * whose address was obtained using dlsym.
374 */
375static bool test_dlfcn_read_public_fib_var(void)
376{
377 int *p_dl_public_fib_var;
378 int val;
379
380 printf("Read dlsym/dl_public_fib_var...\n");
381
382 p_dl_public_fib_var = dlsym(handle, "dl_public_fib_var");
383 if (p_dl_public_fib_var == NULL) {
384 printf("FAILED\n");
385 return false;
386 }
387
388 val = *p_dl_public_fib_var;
389
390 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
391 if (val != dl_public_fib_var_val) {
392 printf("FAILED\n");
393 return false;
394 }
395
396 printf("Passed\n");
397 return true;
398}
399
400/** Test directly reading a public uninitialized fibril-local variable
401 * whose address was obtained using dlsym.
402 */
403static bool test_dlfcn_read_public_fib_uvar(void)
404{
405 int *p_dl_public_fib_uvar;
406 int val;
407
408 printf("Read dlsym/dl_public_fib_uvar...\n");
409
410 p_dl_public_fib_uvar = dlsym(handle, "dl_public_fib_uvar");
411 if (p_dl_public_fib_uvar == NULL) {
412 printf("FAILED\n");
413 return false;
414 }
415
416 val = *p_dl_public_fib_uvar;
417
418 printf("Got %d, expected %d... ", val, 0);
419 if (val != 0) {
420 printf("FAILED\n");
421 return false;
422 }
423
424 printf("Passed\n");
425 return true;
426}
427
428#ifdef DLTEST_LINKED
429
430/** Test directly calling function that returns a constant */
431static bool test_lnk_dl_get_constant(void)
432{
433 int val;
434
435 printf("Call linked dl_get_constant...\n");
436
437 val = dl_get_constant();
438
439 printf("Got %d, expected %d... ", val, dl_constant);
440 if (val != dl_constant) {
441 printf("FAILED\n");
442 return false;
443 }
444
445 printf("Passed\n");
446 return true;
447}
448
449/** Test dircetly calling a function that returns contents of a private
450 * initialized variable.
451 */
452static bool test_lnk_dl_get_private_var(void)
453{
454 int val;
455
456 printf("Call linked dl_get_private_var...\n");
457
458 val = dl_get_private_var();
459
460 printf("Got %d, expected %d... ", val, dl_private_var_val);
461 if (val != dl_private_var_val) {
462 printf("FAILED\n");
463 return false;
464 }
465
466 printf("Passed\n");
467 return true;
468}
469
470/** Test dircetly calling a function that returns contents of a private
471 * uninitialized variable.
472 */
473static bool test_lnk_dl_get_private_uvar(void)
474{
475 int val;
476
477 printf("Call linked dl_get_private_uvar...\n");
478
479 val = dl_get_private_uvar();
480
481 printf("Got %d, expected %d... ", val, 0);
482 if (val != 0) {
483 printf("FAILED\n");
484 return false;
485 }
486
487 printf("Passed\n");
488 return true;
489}
490
491/** Test directly calling a function that returns the contents of a public
492 * initialized variable.
493 */
494static bool test_lnk_dl_get_public_var(void)
495{
496 int val;
497
498 printf("Call linked dl_get_public_var...\n");
499
500 val = dl_get_public_var();
501
502 printf("Got %d, expected %d... ", val, dl_public_var_val);
503 if (val != dl_public_var_val) {
504 printf("FAILED\n");
505 return false;
506 }
507
508 printf("Passed\n");
509 return true;
510}
511
512/** Test directly calling a function that returns the contents of a public
513 * uninitialized variable.
514 */
515static bool test_lnk_dl_get_public_uvar(void)
516{
517 int val;
518
519 printf("Call linked dl_get_public_uvar...\n");
520
521 val = dl_get_public_uvar();
522
523 printf("Got %d, expected %d... ", val, 0);
524 if (val != 0) {
525 printf("FAILED\n");
526 return false;
527 }
528
529 printf("Passed\n");
530 return true;
531}
532
533/** Test directly reading a public initialized variable. */
534static bool test_lnk_read_public_var(void)
535{
536 int val;
537
538 printf("Read linked dl_public_var...\n");
539
540 val = dl_public_var;
541
542 printf("Got %d, expected %d... ", val, dl_public_var_val);
543 if (val != dl_public_var_val) {
544 printf("FAILED\n");
545 return false;
546 }
547
548 printf("Passed\n");
549 return true;
550}
551
552/** Test directly reading a public uninitialized variable. */
553static bool test_lnk_read_public_uvar(void)
554{
555 int val;
556
557 printf("Read linked dl_public_uvar...\n");
558
559 val = dl_public_uvar;
560
561 printf("Got %d, expected %d... ", val, 0);
562 if (val != 0) {
563 printf("FAILED\n");
564 return false;
565 }
566
567 printf("Passed\n");
568 return true;
569}
570
571/** Test dircetly calling a function that returns contents of a private
572 * initialized fibril-local variable.
573 */
574static bool test_lnk_dl_get_private_fib_var(void)
575{
576 int val;
577
578 printf("Call linked dl_get_private_fib_var...\n");
579
580 val = dl_get_private_fib_var();
581
582 printf("Got %d, expected %d... ", val, dl_private_fib_var_val);
583 if (val != dl_private_var_val) {
584 printf("FAILED\n");
585 return false;
586 }
587
588 printf("Passed\n");
589 return true;
590}
591
592/** Test dircetly calling a function that returns contents of a private
593 * uninitialized fibril-local variable.
594 */
595static bool test_lnk_dl_get_private_fib_uvar(void)
596{
597 int val;
598
599 printf("Call linked dl_get_private_fib_uvar...\n");
600
601 val = dl_get_private_fib_uvar();
602
603 printf("Got %d, expected %d... ", val, 0);
604 if (val != 0) {
605 printf("FAILED\n");
606 return false;
607 }
608
609 printf("Passed\n");
610 return true;
611}
612
613/** Test directly calling a function that returns the contents of a public
614 * initialized fibril-local variable.
615 */
616static bool test_lnk_dl_get_public_fib_var(void)
617{
618 int val;
619
620 printf("Call linked dl_get_public_fib_var...\n");
621
622 val = dl_get_public_fib_var();
623
624 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
625 if (val != dl_public_fib_var_val) {
626 printf("FAILED\n");
627 return false;
628 }
629
630 printf("Passed\n");
631 return true;
632}
633
634/** Test directly calling a function that returns the contents of a public
635 * uninitialized fibril-local variable.
636 */
637static bool test_lnk_dl_get_public_fib_uvar(void)
638{
639 int val;
640
641 printf("Call linked dl_get_public_fib_uvar...\n");
642
643 val = dl_get_public_fib_uvar();
644
645 printf("Got %d, expected %d... ", val, 0);
646 if (val != 0) {
647 printf("FAILED\n");
648 return false;
649 }
650
651 printf("Passed\n");
652 return true;
653}
654
655/** Test directly reading a public initialized fibril-local variable. */
656static bool test_lnk_read_public_fib_var(void)
657{
658 int val;
659
660 printf("Read linked dl_public_fib_var...\n");
661
662 val = dl_public_fib_var;
663
664 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
665 if (val != dl_public_fib_var_val) {
666 printf("FAILED\n");
667 return false;
668 }
669
670 printf("Passed\n");
671 return true;
672}
673
674/** Test directly reading a public uninitialized fibril-local variable. */
675static bool test_lnk_read_public_fib_uvar(void)
676{
677 int val;
678
679 printf("Read linked dl_public_fib_uvar...\n");
680
681 val = dl_public_fib_uvar;
682
683 printf("Got %d, expected %d... ", val, 0);
684 if (val != 0) {
685 printf("FAILED\n");
686 return false;
687 }
688
689 printf("Passed\n");
690 return true;
691}
692
693#endif
694
695static int test_dlfcn(void)
696{
697 printf("dlopen()... ");
698 handle = dlopen("libdltest.so.0", 0);
699 if (handle == NULL) {
700 printf("FAILED\n");
701 return 1;
702 }
703
704 printf("Passed\n");
705
706 if (!test_dlsym())
707 return 1;
708
709 if (!test_dlfcn_dl_get_constant())
710 return 1;
711
712 if (!test_dlfcn_dl_get_private_var())
713 return 1;
714
715 if (!test_dlfcn_dl_get_private_uvar())
716 return 1;
717
718 if (!test_dlfcn_dl_get_public_var())
719 return 1;
720
721 if (!test_dlfcn_dl_get_public_uvar())
722 return 1;
723
724 if (!test_dlfcn_read_public_var())
725 return 1;
726
727 if (!test_dlfcn_read_public_uvar())
728 return 1;
729
730 if (!test_dlfcn_dl_get_private_fib_var())
731 return 1;
732
733 if (!test_dlfcn_dl_get_private_fib_uvar())
734 return 1;
735
736 if (!test_dlfcn_dl_get_public_fib_var())
737 return 1;
738
739 if (!test_dlfcn_dl_get_public_fib_uvar())
740 return 1;
741
742 if (!test_dlfcn_read_public_fib_var())
743 return 1;
744
745 if (!test_dlfcn_read_public_fib_uvar())
746 return 1;
747
748// printf("dlclose()... ");
749// dlclose(handle);
750// printf("Passed\n");
751
752 return 0;
753}
754
755#ifdef DLTEST_LINKED
756
757static int test_lnk(void)
758{
759 if (!test_lnk_dl_get_constant())
760 return 1;
761
762 if (!test_lnk_dl_get_private_var())
763 return 1;
764
765 if (!test_lnk_dl_get_private_uvar())
766 return 1;
767
768 if (!test_lnk_dl_get_public_var())
769 return 1;
770
771 if (!test_lnk_dl_get_public_uvar())
772 return 1;
773
774 if (!test_lnk_read_public_var())
775 return 1;
776
777 if (!test_lnk_read_public_uvar())
778 return 1;
779
780 if (!test_lnk_dl_get_private_fib_var())
781 return 1;
782
783 if (!test_lnk_dl_get_private_fib_uvar())
784 return 1;
785
786 if (!test_lnk_dl_get_public_fib_var())
787 return 1;
788
789 if (!test_lnk_dl_get_public_fib_uvar())
790 return 1;
791
792 if (!test_lnk_read_public_fib_var())
793 return 1;
794
795 if (!test_lnk_read_public_fib_uvar())
796 return 1;
797
798 return 0;
799}
800
801#endif
802
803static void print_syntax(void)
804{
805 fprintf(stderr, "syntax: dltest [-n]\n");
806 fprintf(stderr, "\t-n Do not run dlfcn tests\n");
807}
808
809int main(int argc, char *argv[])
810{
811 printf("Dynamic linking test\n");
812
813 if (argc > 1) {
814 if (argc > 2) {
815 print_syntax();
816 return 1;
817 }
818
819 if (str_cmp(argv[1], "-n") == 0) {
820 no_dlfcn = true;
821 } else {
822 print_syntax();
823 return 1;
824 }
825 }
826
827 if (!no_dlfcn) {
828 if (test_dlfcn() != 0)
829 return 1;
830 }
831
832#ifdef DLTEST_LINKED
833 if (test_lnk() != 0)
834 return 1;
835#endif
836
837 printf("All passed.\n");
838 return 0;
839}
840
841/**
842 * @}
843 */
Note: See TracBrowser for help on using the repository browser.