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

Last change on this file was 32254d6, checked in by GitHub <noreply@…>, 5 months ago

init RTLD runtime at load time even for statically linked binaries (#242)

init RTLD runtime at load time even for statically linked binaries

  • Property mode set to 100644
File size: 23.2 KB
Line 
1/*
2 * Copyright (c) 2024 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#include <str.h>
44
45/** libdltest library handle */
46static void *handle;
47
48/** If true, do not run dlfcn tests */
49static bool no_dlfcn = false;
50
51/** Test dlsym() function */
52static bool test_dlsym(void)
53{
54 int (*p_dl_get_constant)(void);
55
56 printf("dlsym()... ");
57 p_dl_get_constant = dlsym(handle, "dl_get_constant");
58 if (p_dl_get_constant == NULL) {
59 printf("FAILED\n");
60 return false;
61 }
62
63 printf("Passed\n");
64 return true;
65}
66
67/** Test calling function that returns a constant */
68static bool test_dlfcn_dl_get_constant(void)
69{
70 int (*p_dl_get_constant)(void);
71 int val;
72
73 printf("Call dlsym/dl_get_constant...\n");
74
75 p_dl_get_constant = dlsym(handle, "dl_get_constant");
76 if (p_dl_get_constant == NULL) {
77 printf("FAILED\n");
78 return false;
79 }
80
81 val = p_dl_get_constant();
82
83 printf("Got %d, expected %d... ", val, dl_constant);
84 if (val != dl_constant) {
85 printf("FAILED\n");
86 return false;
87 }
88
89 printf("Passed\n");
90 return true;
91}
92
93/** Test calling function that calls a function that returns a constant */
94static bool test_dlfcn_dl_get_constant_via_call(void)
95{
96 int (*p_dl_get_constant)(void);
97 int val;
98
99 printf("Call dlsym/dl_get_constant_via_call...\n");
100
101 p_dl_get_constant = dlsym(handle, "dl_get_constant_via_call");
102 if (p_dl_get_constant == NULL) {
103 printf("FAILED\n");
104 return false;
105 }
106
107 val = p_dl_get_constant();
108
109 printf("Got %d, expected %d... ", val, dl_constant);
110 if (val != dl_constant) {
111 printf("FAILED\n");
112 return false;
113 }
114
115 printf("Passed\n");
116 return true;
117}
118
119/** Test calling a function that returns contents of a private initialized
120 * variable.
121 */
122static bool test_dlfcn_dl_get_private_var(void)
123{
124 int (*p_dl_get_private_var)(void);
125 int *(*p_dl_get_private_var_addr)(void);
126 int val;
127
128 printf("Call dlsym/dl_get_private_var...\n");
129
130 p_dl_get_private_var = dlsym(handle, "dl_get_private_var");
131 if (p_dl_get_private_var == NULL) {
132 printf("FAILED\n");
133 return false;
134 }
135
136 p_dl_get_private_var_addr = dlsym(handle, "dl_get_private_var_addr");
137 if (p_dl_get_private_var_addr == NULL) {
138 printf("FAILED\n");
139 return false;
140 }
141
142 val = p_dl_get_private_var();
143
144 printf("Got %d, expected %d... ", val, dl_private_var_val);
145 if (val != dl_private_var_val) {
146 printf("dl_get_private_var_addr -> %p\n",
147 p_dl_get_private_var_addr());
148 printf("FAILED\n");
149 return false;
150 }
151
152 printf("Passed\n");
153 return true;
154}
155
156/** Test calling a function that returns contents of a private uninitialized
157 * variable.
158 */
159static bool test_dlfcn_dl_get_private_uvar(void)
160{
161 int (*p_dl_get_private_uvar)(void);
162 int *(*p_dl_get_private_uvar_addr)(void);
163 int val;
164
165 printf("Call dlsym/dl_get_private_uvar...\n");
166
167 p_dl_get_private_uvar = dlsym(handle, "dl_get_private_uvar");
168 if (p_dl_get_private_uvar == NULL) {
169 printf("FAILED\n");
170 return false;
171 }
172
173 p_dl_get_private_uvar_addr = dlsym(handle, "dl_get_private_uvar_addr");
174 if (p_dl_get_private_uvar_addr == NULL) {
175 printf("FAILED\n");
176 return false;
177 }
178
179 val = p_dl_get_private_uvar();
180
181 printf("Got %d, expected %d... ", val, 0);
182 if (val != 0) {
183 printf("dl_get_private_uvar_addr -> %p\n",
184 p_dl_get_private_uvar_addr());
185 printf("FAILED\n");
186 return false;
187 }
188
189 printf("Passed\n");
190 return true;
191}
192
193/** Test calling a function that returns the contents of a public initialized
194 * variable.
195 */
196static bool test_dlfcn_dl_get_public_var(void)
197{
198 int (*p_dl_get_public_var)(void);
199 int *(*p_dl_get_public_var_addr)(void);
200 int val;
201
202 printf("Call dlsym/dl_get_public_var...\n");
203
204 p_dl_get_public_var = dlsym(handle, "dl_get_public_var");
205 if (p_dl_get_public_var == NULL) {
206 printf("FAILED\n");
207 return false;
208 }
209
210 p_dl_get_public_var_addr = dlsym(handle, "dl_get_public_var_addr");
211 if (p_dl_get_public_var_addr == NULL) {
212 printf("FAILED\n");
213 return false;
214 }
215
216 val = p_dl_get_public_var();
217
218 printf("Got %d, expected %d... ", val, dl_public_var_val);
219 if (val != dl_public_var_val) {
220 printf("dl_get_public_var_addr -> %p\n",
221 p_dl_get_public_var_addr());
222 printf("FAILED\n");
223 return false;
224 }
225
226 printf("Passed\n");
227 return true;
228}
229
230/** Test calling a function that returns the contents of a public uninitialized
231 * variable.
232 */
233static bool test_dlfcn_dl_get_public_uvar(void)
234{
235 int (*p_dl_get_public_uvar)(void);
236 int *(*p_dl_get_public_uvar_addr)(void);
237 int val;
238
239 printf("Call dlsym/dl_get_public_uvar...\n");
240
241 p_dl_get_public_uvar = dlsym(handle, "dl_get_public_uvar");
242 if (p_dl_get_public_uvar == NULL) {
243 printf("FAILED\n");
244 return false;
245 }
246
247 p_dl_get_public_uvar_addr = dlsym(handle, "dl_get_public_uvar_addr");
248 if (p_dl_get_public_uvar_addr == NULL) {
249 printf("FAILED\n");
250 return false;
251 }
252
253 val = p_dl_get_public_uvar();
254
255 printf("Got %d, expected %d... ", val, 0);
256 if (val != 0) {
257 printf("dl_get_public_uvar_addr -> %p\n",
258 p_dl_get_public_uvar_addr());
259 printf("FAILED\n");
260 return false;
261 }
262
263 printf("Passed\n");
264 return true;
265}
266
267/** Test directly reading a public initialized variable whose address was
268 * obtained using dlsym.
269 */
270static bool test_dlfcn_read_public_var(void)
271{
272 int *p_dl_public_var;
273 int *(*p_dl_get_public_var_addr)(void);
274 int val;
275
276 printf("Read dlsym/dl_public_var...\n");
277
278 p_dl_public_var = dlsym(handle, "dl_public_var");
279 if (p_dl_public_var == NULL) {
280 printf("FAILED\n");
281 return false;
282 }
283
284 p_dl_get_public_var_addr = dlsym(handle, "dl_get_public_var_addr");
285 if (p_dl_get_public_var_addr == NULL) {
286 printf("FAILED\n");
287 return false;
288 }
289
290 val = *p_dl_public_var;
291
292 printf("Got %d, expected %d... ", val, dl_public_var_val);
293 if (val != dl_public_var_val) {
294 printf("&dl_public_var = %p, "
295 "dl_get_public_var_addr -> %p\n",
296 p_dl_public_var, p_dl_get_public_var_addr());
297 printf("FAILED\n");
298 return false;
299 }
300
301 printf("Passed\n");
302 return true;
303}
304
305/** Test directly reading a public uninitialized variable whose address was
306 * obtained using dlsym.
307 */
308static bool test_dlfcn_read_public_uvar(void)
309{
310 int *p_dl_public_uvar;
311 int *(*p_dl_get_public_uvar_addr)(void);
312 int val;
313
314 printf("Read dlsym/dl_public_uvar...\n");
315
316 p_dl_public_uvar = dlsym(handle, "dl_public_uvar");
317 if (p_dl_public_uvar == NULL) {
318 printf("FAILED\n");
319 return false;
320 }
321
322 p_dl_get_public_uvar_addr = dlsym(handle, "dl_get_public_uvar_addr");
323 if (p_dl_get_public_uvar_addr == NULL) {
324 printf("FAILED\n");
325 return false;
326 }
327
328 val = *p_dl_public_uvar;
329
330 printf("Got %d, expected %d... ", val, 0);
331 if (val != 0) {
332 printf("&dl_public_uvar = %p, "
333 "dl_get_public_uvar_addr -> %p\n",
334 p_dl_public_uvar, p_dl_get_public_uvar_addr());
335 printf("FAILED\n");
336 return false;
337 }
338
339 printf("Passed\n");
340 return true;
341}
342
343#ifndef STATIC_EXE
344
345/** Test calling a function that returns contents of a private initialized
346 * fibril-local variable.
347 */
348static bool test_dlfcn_dl_get_private_fib_var(void)
349{
350 int (*p_dl_get_private_fib_var)(void);
351 int *(*p_dl_get_private_fib_var_addr)(void);
352 int val;
353
354 printf("Call dlsym/dl_get_private_fib_var...\n");
355
356 p_dl_get_private_fib_var = dlsym(handle, "dl_get_private_fib_var");
357 if (p_dl_get_private_fib_var == NULL) {
358 printf("FAILED\n");
359 return false;
360 }
361
362 p_dl_get_private_fib_var_addr = dlsym(handle, "dl_get_private_fib_var_addr");
363 if (p_dl_get_private_fib_var_addr == NULL) {
364 printf("FAILED\n");
365 return false;
366 }
367
368 val = p_dl_get_private_fib_var();
369
370 printf("Got %d, expected %d... ", val, dl_private_fib_var_val);
371 if (val != dl_private_fib_var_val) {
372 printf("dl_get_private_fib_var_addr -> %p\n",
373 p_dl_get_private_fib_var_addr());
374 printf("FAILED\n");
375 return false;
376 }
377
378 printf("Passed\n");
379 return true;
380}
381
382/** Test calling a function that returns contents of a private uninitialized
383 * fibril-local variable.
384 */
385static bool test_dlfcn_dl_get_private_fib_uvar(void)
386{
387 int (*p_dl_get_private_fib_uvar)(void);
388 int *(*p_dl_get_private_fib_uvar_addr)(void);
389 int val;
390
391 printf("Call dlsym/dl_get_private_fib_uvar...\n");
392
393 p_dl_get_private_fib_uvar = dlsym(handle, "dl_get_private_fib_uvar");
394 if (p_dl_get_private_fib_uvar == NULL) {
395 printf("FAILED\n");
396 return false;
397 }
398
399 p_dl_get_private_fib_uvar_addr = dlsym(handle, "dl_get_private_fib_uvar_addr");
400 if (p_dl_get_private_fib_uvar_addr == NULL) {
401 printf("FAILED\n");
402 return false;
403 }
404
405 val = p_dl_get_private_fib_uvar();
406
407 printf("Got %d, expected %d... ", val, 0);
408 if (val != 0) {
409 printf("dl_get_private_fib_uvar_addr -> %p\n",
410 p_dl_get_private_fib_uvar_addr());
411 printf("FAILED\n");
412 return false;
413 }
414
415 printf("Passed\n");
416 return true;
417}
418
419/** Test calling a function that returns the contents of a public initialized
420 * fibril-local variable.
421 */
422static bool test_dlfcn_dl_get_public_fib_var(void)
423{
424 int (*p_dl_get_public_fib_var)(void);
425 int *(*p_dl_get_public_fib_var_addr)(void);
426 int val;
427
428 printf("Call dlsym/dl_get_public_fib_var...\n");
429
430 p_dl_get_public_fib_var = dlsym(handle, "dl_get_public_fib_var");
431 if (p_dl_get_public_fib_var == NULL) {
432 printf("FAILED\n");
433 return false;
434 }
435
436 p_dl_get_public_fib_var_addr = dlsym(handle, "dl_get_public_fib_var_addr");
437 if (p_dl_get_public_fib_var_addr == NULL) {
438 printf("FAILED\n");
439 return false;
440 }
441
442 val = p_dl_get_public_fib_var();
443
444 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
445 if (val != dl_public_fib_var_val) {
446 printf("dl_get_public_fib_var_addr -> %p\n",
447 p_dl_get_public_fib_var_addr());
448 printf("FAILED\n");
449 return false;
450 }
451
452 printf("Passed\n");
453 return true;
454}
455
456/** Test calling a function that returns the contents of a public uninitialized
457 * fibril-local variable.
458 */
459static bool test_dlfcn_dl_get_public_fib_uvar(void)
460{
461 int (*p_dl_get_public_fib_uvar)(void);
462 int *(*p_dl_get_public_fib_uvar_addr)(void);
463 int val;
464
465 printf("Call dlsym/dl_get_public_fib_uvar...\n");
466
467 p_dl_get_public_fib_uvar = dlsym(handle, "dl_get_public_fib_uvar");
468 if (p_dl_get_public_fib_uvar == NULL) {
469 printf("FAILED\n");
470 return false;
471 }
472
473 p_dl_get_public_fib_uvar_addr = dlsym(handle, "dl_get_public_fib_uvar_addr");
474 if (p_dl_get_public_fib_uvar_addr == NULL) {
475 printf("FAILED\n");
476 return false;
477 }
478
479 val = p_dl_get_public_fib_uvar();
480
481 printf("Got %d, expected %d... ", val, 0);
482 if (val != 0) {
483 printf("dl_get_public_fib_uvar_addr -> %p\n",
484 p_dl_get_public_fib_uvar_addr());
485 printf("FAILED\n");
486 return false;
487 }
488
489 printf("Passed\n");
490 return true;
491}
492
493/** Test directly reading a public initialized fibril-local variable
494 * whose address was obtained using dlsym.
495 */
496static bool test_dlfcn_read_public_fib_var(void)
497{
498 int *p_dl_public_fib_var;
499 int *(*p_dl_get_public_fib_var_addr)(void);
500 int val;
501
502 printf("Read dlsym/dl_public_fib_var...\n");
503
504 p_dl_public_fib_var = dlsym(handle, "dl_public_fib_var");
505 if (p_dl_public_fib_var == NULL) {
506 printf("FAILED\n");
507 return false;
508 }
509
510 p_dl_get_public_fib_var_addr = dlsym(handle, "dl_get_public_fib_var_addr");
511 if (p_dl_get_public_fib_var_addr == NULL) {
512 printf("FAILED\n");
513 return false;
514 }
515
516 val = *p_dl_public_fib_var;
517
518 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
519 if (val != dl_public_fib_var_val) {
520 printf("&dl_public_fib_var = %p, "
521 "dl_get_public_fib_var_addr -> %p\n",
522 p_dl_public_fib_var, p_dl_get_public_fib_var_addr());
523 printf("FAILED\n");
524 return false;
525 }
526
527 printf("Passed\n");
528 return true;
529}
530
531/** Test directly reading a public uninitialized fibril-local variable
532 * whose address was obtained using dlsym.
533 */
534static bool test_dlfcn_read_public_fib_uvar(void)
535{
536 int *p_dl_public_fib_uvar;
537 int *(*p_dl_get_public_fib_uvar_addr)(void);
538 int val;
539
540 printf("Read dlsym/dl_public_fib_uvar...\n");
541
542 p_dl_public_fib_uvar = dlsym(handle, "dl_public_fib_uvar");
543 if (p_dl_public_fib_uvar == NULL) {
544 printf("FAILED\n");
545 return false;
546 }
547
548 p_dl_get_public_fib_uvar_addr = dlsym(handle, "dl_get_public_fib_uvar_addr");
549 if (p_dl_get_public_fib_uvar_addr == NULL) {
550 printf("FAILED\n");
551 return false;
552 }
553
554 val = *p_dl_public_fib_uvar;
555
556 printf("Got %d, expected %d... ", val, 0);
557 if (val != 0) {
558 printf("&dl_public_fib_uvar = %p, "
559 "dl_get_public_fib_uvar_addr -> %p\n",
560 p_dl_public_fib_uvar, p_dl_get_public_fib_uvar_addr());
561 printf("FAILED\n");
562 return false;
563 }
564
565 printf("Passed\n");
566 return true;
567}
568
569#endif /* STATIC_EXE */
570
571#ifdef DLTEST_LINKED
572
573/** Test if we can read the correct value of a public pointer variable.
574 *
575 * dl_public_ptr_var is initialized in libdltest to point to dl_public_var.
576 * This is done using a relocation. The main program (unless compiled with
577 * PIC or PIE) will contain a copy of dl_public_ptr_var. This needs
578 * to be copied using a COPY relocation. The relocations in the main
579 * program need to be processed after the relocations in the shared
580 * libraries (so that we copy the correct value).
581 */
582static bool test_public_ptr_var(void)
583{
584 int *ptr;
585
586 printf("Read dl_public_ptr_var directly...\n");
587 ptr = dl_public_ptr_var;
588
589 if (ptr != &dl_public_var) {
590 printf("FAILED\n");
591 return false;
592 }
593
594 printf("Passed\n");
595 return true;
596}
597
598/** Test directly calling function that returns a constant */
599static bool test_lnk_dl_get_constant(void)
600{
601 int val;
602
603 printf("Call linked dl_get_constant...\n");
604
605 val = dl_get_constant();
606
607 printf("Got %d, expected %d... ", val, dl_constant);
608 if (val != dl_constant) {
609 printf("FAILED\n");
610 return false;
611 }
612
613 printf("Passed\n");
614 return true;
615}
616
617/** Test directly calling function that calls a function that returns a constant */
618static bool test_lnk_dl_get_constant_via_call(void)
619{
620 int val;
621
622 printf("Call linked dl_get_constant_via_call...\n");
623
624 val = dl_get_constant_via_call();
625
626 printf("Got %d, expected %d... ", val, dl_constant);
627 if (val != dl_constant) {
628 printf("FAILED\n");
629 return false;
630 }
631
632 printf("Passed\n");
633 return true;
634}
635
636/** Test dircetly calling a function that returns contents of a private
637 * initialized variable.
638 */
639static bool test_lnk_dl_get_private_var(void)
640{
641 int val;
642
643 printf("Call linked dl_get_private_var...\n");
644
645 val = dl_get_private_var();
646
647 printf("Got %d, expected %d... ", val, dl_private_var_val);
648 if (val != dl_private_var_val) {
649 printf("dl_get_private_var_addr -> %p\n",
650 dl_get_private_var_addr());
651 printf("FAILED\n");
652 return false;
653 }
654
655 printf("Passed\n");
656 return true;
657}
658
659/** Test dircetly calling a function that returns contents of a private
660 * uninitialized variable.
661 */
662static bool test_lnk_dl_get_private_uvar(void)
663{
664 int val;
665
666 printf("Call linked dl_get_private_uvar...\n");
667
668 val = dl_get_private_uvar();
669
670 printf("Got %d, expected %d... ", val, 0);
671 if (val != 0) {
672 printf("dl_get_private_uvar_addr -> %p\n",
673 dl_get_private_uvar_addr());
674 printf("FAILED\n");
675 return false;
676 }
677
678 printf("Passed\n");
679 return true;
680}
681
682/** Test directly calling a function that returns the contents of a public
683 * initialized variable.
684 */
685static bool test_lnk_dl_get_public_var(void)
686{
687 int val;
688
689 printf("Call linked dl_get_public_var...\n");
690
691 val = dl_get_public_var();
692
693 printf("Got %d, expected %d... ", val, dl_public_var_val);
694 if (val != dl_public_var_val) {
695 printf("dl_get_public_var_addr -> %p\n",
696 dl_get_public_var_addr());
697 printf("FAILED\n");
698 return false;
699 }
700
701 printf("Passed\n");
702 return true;
703}
704
705/** Test directly calling a function that returns the contents of a public
706 * uninitialized variable.
707 */
708static bool test_lnk_dl_get_public_uvar(void)
709{
710 int val;
711
712 printf("Call linked dl_get_public_uvar...\n");
713
714 val = dl_get_public_uvar();
715
716 printf("Got %d, expected %d... ", val, 0);
717 if (val != 0) {
718 printf("dl_get_public_uvar_addr -> %p\n",
719 dl_get_public_uvar_addr());
720 printf("FAILED\n");
721 return false;
722 }
723
724 printf("Passed\n");
725 return true;
726}
727
728/** Test directly reading a public initialized variable. */
729static bool test_lnk_read_public_var(void)
730{
731 int val;
732
733 printf("Read linked dl_public_var...\n");
734
735 val = dl_public_var;
736
737 printf("Got %d, expected %d... ", val, dl_public_var_val);
738 if (val != dl_public_var_val) {
739 printf("&dl_public_var = %p, dl_get_public_var_addr -> %p\n",
740 &dl_public_var, dl_get_public_var_addr());
741 printf("FAILED\n");
742 return false;
743 }
744
745 printf("Passed\n");
746 return true;
747}
748
749/** Test directly reading a public uninitialized variable. */
750static bool test_lnk_read_public_uvar(void)
751{
752 int val;
753
754 printf("Read linked dl_public_uvar...\n");
755
756 val = dl_public_uvar;
757
758 printf("Got %d, expected %d... ", val, 0);
759 if (val != 0) {
760 printf("&dl_public_uvar = %p, dl_get_public_uvar_addr -> %p\n",
761 &dl_public_uvar, dl_get_public_uvar_addr());
762 printf("FAILED\n");
763 return false;
764 }
765
766 printf("Passed\n");
767 return true;
768}
769
770/** Test dircetly calling a function that returns contents of a private
771 * initialized fibril-local variable.
772 */
773static bool test_lnk_dl_get_private_fib_var(void)
774{
775 int val;
776
777 printf("Call linked dl_get_private_fib_var...\n");
778
779 val = dl_get_private_fib_var();
780
781 printf("Got %d, expected %d... ", val, dl_private_fib_var_val);
782 if (val != dl_private_fib_var_val) {
783 printf("dl_get_private_fib_var_addr -> %p\n",
784 dl_get_private_fib_var_addr());
785 printf("FAILED\n");
786 return false;
787 }
788
789 printf("Passed\n");
790 return true;
791}
792
793/** Test dircetly calling a function that returns contents of a private
794 * uninitialized fibril-local variable.
795 */
796static bool test_lnk_dl_get_private_fib_uvar(void)
797{
798 int val;
799
800 printf("Call linked dl_get_private_fib_uvar...\n");
801
802 val = dl_get_private_fib_uvar();
803
804 printf("Got %d, expected %d... ", val, 0);
805 if (val != 0) {
806 printf("dl_get_private_fib_uvar_addr -> %p\n",
807 dl_get_private_fib_var_addr());
808 printf("FAILED\n");
809 return false;
810 }
811
812 printf("Passed\n");
813 return true;
814}
815
816/** Test directly calling a function that returns the contents of a public
817 * initialized fibril-local variable.
818 */
819static bool test_lnk_dl_get_public_fib_var(void)
820{
821 int val;
822
823 printf("Call linked dl_get_public_fib_var...\n");
824
825 val = dl_get_public_fib_var();
826
827 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
828 if (val != dl_public_fib_var_val) {
829 printf("dl_get_public_fib_var_addr -> %p\n",
830 dl_get_public_fib_var_addr());
831 printf("FAILED\n");
832 return false;
833 }
834
835 printf("Passed\n");
836 return true;
837}
838
839/** Test directly calling a function that returns the contents of a public
840 * uninitialized fibril-local variable.
841 */
842static bool test_lnk_dl_get_public_fib_uvar(void)
843{
844 int val;
845
846 printf("Call linked dl_get_public_fib_uvar...\n");
847
848 val = dl_get_public_fib_uvar();
849
850 printf("Got %d, expected %d... ", val, 0);
851 if (val != 0) {
852 printf("dl_get_public_fib_uvar_addr -> %p\n",
853 dl_get_public_fib_uvar_addr());
854 printf("FAILED\n");
855 return false;
856 }
857
858 printf("Passed\n");
859 return true;
860}
861
862/** Test directly reading a public initialized fibril-local variable. */
863static bool test_lnk_read_public_fib_var(void)
864{
865 int val;
866
867 printf("Read linked dl_public_fib_var...\n");
868
869 val = dl_public_fib_var;
870
871 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
872 if (val != dl_public_fib_var_val) {
873 printf("&dl_public_fib_var = %p, "
874 "dl_get_public_fib_var_addr -> %p\n",
875 &dl_public_fib_var, dl_get_public_fib_var_addr());
876 printf("FAILED\n");
877 return false;
878 }
879
880 printf("Passed\n");
881 return true;
882}
883
884/** Test directly reading a public uninitialized fibril-local variable. */
885static bool test_lnk_read_public_fib_uvar(void)
886{
887 int val;
888
889 printf("Read linked dl_public_fib_uvar...\n");
890
891 val = dl_public_fib_uvar;
892
893 printf("Got %d, expected %d... ", val, 0);
894 if (val != 0) {
895 printf("&dl_public_fib_uvar = %p, "
896 "dl_get_public_fib_uvar_addr -> %p\n",
897 &dl_public_fib_uvar, dl_get_public_fib_uvar_addr());
898 printf("FAILED\n");
899 return false;
900 }
901
902 printf("Passed\n");
903 return true;
904}
905
906#endif /* DLTEST_LINKED */
907
908static int test_dlfcn(void)
909{
910 printf("dlopen()... ");
911 handle = dlopen("libdltest.so.0", 0);
912 if (handle == NULL) {
913 printf("FAILED\n");
914 return 1;
915 }
916
917 printf("Passed\n");
918
919 if (!test_dlsym())
920 return 1;
921
922 if (!test_dlfcn_dl_get_constant())
923 return 1;
924
925 if (!test_dlfcn_dl_get_constant_via_call())
926 return 1;
927
928 if (!test_dlfcn_dl_get_private_var())
929 return 1;
930
931 if (!test_dlfcn_dl_get_private_uvar())
932 return 1;
933
934 if (!test_dlfcn_dl_get_public_var())
935 return 1;
936
937 if (!test_dlfcn_dl_get_public_uvar())
938 return 1;
939
940 if (!test_dlfcn_read_public_var())
941 return 1;
942
943 if (!test_dlfcn_read_public_uvar())
944 return 1;
945
946#ifndef STATIC_EXE // FIXME: this define is not set anywhere
947
948 if (!test_dlfcn_dl_get_private_fib_var())
949 return 1;
950
951 if (!test_dlfcn_dl_get_private_fib_uvar())
952 return 1;
953
954 if (!test_dlfcn_dl_get_public_fib_var())
955 return 1;
956
957 if (!test_dlfcn_dl_get_public_fib_uvar())
958 return 1;
959
960 if (!test_dlfcn_read_public_fib_var())
961 return 1;
962
963 if (!test_dlfcn_read_public_fib_uvar())
964 return 1;
965#endif /* STATIC_EXE */
966
967#if 0
968 printf("dlclose()... ");
969 dlclose(handle);
970 printf("Passed\n");
971#endif
972
973 return 0;
974}
975
976#ifdef DLTEST_LINKED
977
978static int test_lnk(void)
979{
980 if (!test_lnk_dl_get_constant())
981 return 1;
982
983 if (!test_lnk_dl_get_constant_via_call())
984 return 1;
985
986 if (!test_lnk_dl_get_private_var())
987 return 1;
988
989 if (!test_lnk_dl_get_private_uvar())
990 return 1;
991
992 if (!test_lnk_dl_get_public_var())
993 return 1;
994
995 if (!test_lnk_dl_get_public_uvar())
996 return 1;
997
998 if (!test_lnk_read_public_var())
999 return 1;
1000
1001 if (!test_lnk_read_public_uvar())
1002 return 1;
1003
1004 if (!test_public_ptr_var())
1005 return 1;
1006
1007 if (!test_lnk_dl_get_private_fib_var())
1008 return 1;
1009
1010 if (!test_lnk_dl_get_private_fib_uvar())
1011 return 1;
1012
1013 if (!test_lnk_dl_get_public_fib_var())
1014 return 1;
1015
1016 if (!test_lnk_dl_get_public_fib_uvar())
1017 return 1;
1018
1019 if (!test_lnk_read_public_fib_var())
1020 return 1;
1021
1022 if (!test_lnk_read_public_fib_uvar())
1023 return 1;
1024
1025 return 0;
1026}
1027
1028#endif /* DLTEST_LINKED */
1029
1030static void print_syntax(void)
1031{
1032 fprintf(stderr, "syntax: dltest [-n]\n");
1033 fprintf(stderr, "\t-n Do not run dlfcn tests\n");
1034}
1035
1036int main(int argc, char *argv[])
1037{
1038 printf("Dynamic linking test\n");
1039
1040 if (argc > 1) {
1041 if (argc > 2) {
1042 print_syntax();
1043 return 1;
1044 }
1045
1046 if (str_cmp(argv[1], "-n") == 0) {
1047 no_dlfcn = true;
1048 } else {
1049 print_syntax();
1050 return 1;
1051 }
1052 }
1053
1054 if (!no_dlfcn) {
1055 if (test_dlfcn() != 0)
1056 return 1;
1057 }
1058
1059#ifdef DLTEST_LINKED
1060 if (test_lnk() != 0)
1061 return 1;
1062#endif
1063
1064 printf("All passed.\n");
1065 return 0;
1066}
1067
1068/**
1069 * @}
1070 */
Note: See TracBrowser for help on using the repository browser.