source: mainline/uspace/app/dltest/dltest.c@ 2db5c83

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2db5c83 was 8e3bc063, checked in by Jiri Svoboda <jiri@…>, 7 years ago

dltest needs test that calls a function

During bringup of dynamic linking on a platform it is difficult to test
dynamic function calls (via PLT) if the binaries (including dltest)
are statically linked. We can do that by adding a function to libdltest
that calls another function. Since we don't use -Bsymbolic, the call
will be made via PLT.

  • Property mode set to 100644
File size: 22.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#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 directly calling function that returns a constant */
574static bool test_lnk_dl_get_constant(void)
575{
576 int val;
577
578 printf("Call linked dl_get_constant...\n");
579
580 val = dl_get_constant();
581
582 printf("Got %d, expected %d... ", val, dl_constant);
583 if (val != dl_constant) {
584 printf("FAILED\n");
585 return false;
586 }
587
588 printf("Passed\n");
589 return true;
590}
591
592/** Test directly calling function that calls a function that returns a constant */
593static bool test_lnk_dl_get_constant_via_call(void)
594{
595 int val;
596
597 printf("Call linked dl_get_constant_via_call...\n");
598
599 val = dl_get_constant_via_call();
600
601 printf("Got %d, expected %d... ", val, dl_constant);
602 if (val != dl_constant) {
603 printf("FAILED\n");
604 return false;
605 }
606
607 printf("Passed\n");
608 return true;
609}
610
611/** Test dircetly calling a function that returns contents of a private
612 * initialized variable.
613 */
614static bool test_lnk_dl_get_private_var(void)
615{
616 int val;
617
618 printf("Call linked dl_get_private_var...\n");
619
620 val = dl_get_private_var();
621
622 printf("Got %d, expected %d... ", val, dl_private_var_val);
623 if (val != dl_private_var_val) {
624 printf("dl_get_private_var_addr -> %p\n",
625 dl_get_private_var_addr());
626 printf("FAILED\n");
627 return false;
628 }
629
630 printf("Passed\n");
631 return true;
632}
633
634/** Test dircetly calling a function that returns contents of a private
635 * uninitialized variable.
636 */
637static bool test_lnk_dl_get_private_uvar(void)
638{
639 int val;
640
641 printf("Call linked dl_get_private_uvar...\n");
642
643 val = dl_get_private_uvar();
644
645 printf("Got %d, expected %d... ", val, 0);
646 if (val != 0) {
647 printf("dl_get_private_uvar_addr -> %p\n",
648 dl_get_private_uvar_addr());
649 printf("FAILED\n");
650 return false;
651 }
652
653 printf("Passed\n");
654 return true;
655}
656
657/** Test directly calling a function that returns the contents of a public
658 * initialized variable.
659 */
660static bool test_lnk_dl_get_public_var(void)
661{
662 int val;
663
664 printf("Call linked dl_get_public_var...\n");
665
666 val = dl_get_public_var();
667
668 printf("Got %d, expected %d... ", val, dl_public_var_val);
669 if (val != dl_public_var_val) {
670 printf("dl_get_public_var_addr -> %p\n",
671 dl_get_public_var_addr());
672 printf("FAILED\n");
673 return false;
674 }
675
676 printf("Passed\n");
677 return true;
678}
679
680/** Test directly calling a function that returns the contents of a public
681 * uninitialized variable.
682 */
683static bool test_lnk_dl_get_public_uvar(void)
684{
685 int val;
686
687 printf("Call linked dl_get_public_uvar...\n");
688
689 val = dl_get_public_uvar();
690
691 printf("Got %d, expected %d... ", val, 0);
692 if (val != 0) {
693 printf("dl_get_public_uvar_addr -> %p\n",
694 dl_get_public_uvar_addr());
695 printf("FAILED\n");
696 return false;
697 }
698
699 printf("Passed\n");
700 return true;
701}
702
703/** Test directly reading a public initialized variable. */
704static bool test_lnk_read_public_var(void)
705{
706 int val;
707
708 printf("Read linked dl_public_var...\n");
709
710 val = dl_public_var;
711
712 printf("Got %d, expected %d... ", val, dl_public_var_val);
713 if (val != dl_public_var_val) {
714 printf("&dl_public_var = %p, dl_get_public_var_addr -> %p\n",
715 &dl_public_var, dl_get_public_var_addr());
716 printf("FAILED\n");
717 return false;
718 }
719
720 printf("Passed\n");
721 return true;
722}
723
724/** Test directly reading a public uninitialized variable. */
725static bool test_lnk_read_public_uvar(void)
726{
727 int val;
728
729 printf("Read linked dl_public_uvar...\n");
730
731 val = dl_public_uvar;
732
733 printf("Got %d, expected %d... ", val, 0);
734 if (val != 0) {
735 printf("&dl_public_uvar = %p, dl_get_public_uvar_addr -> %p\n",
736 &dl_public_uvar, dl_get_public_uvar_addr());
737 printf("FAILED\n");
738 return false;
739 }
740
741 printf("Passed\n");
742 return true;
743}
744
745/** Test dircetly calling a function that returns contents of a private
746 * initialized fibril-local variable.
747 */
748static bool test_lnk_dl_get_private_fib_var(void)
749{
750 int val;
751
752 printf("Call linked dl_get_private_fib_var...\n");
753
754 val = dl_get_private_fib_var();
755
756 printf("Got %d, expected %d... ", val, dl_private_fib_var_val);
757 if (val != dl_private_fib_var_val) {
758 printf("dl_get_private_fib_var_addr -> %p\n",
759 dl_get_private_fib_var_addr());
760 printf("FAILED\n");
761 return false;
762 }
763
764 printf("Passed\n");
765 return true;
766}
767
768/** Test dircetly calling a function that returns contents of a private
769 * uninitialized fibril-local variable.
770 */
771static bool test_lnk_dl_get_private_fib_uvar(void)
772{
773 int val;
774
775 printf("Call linked dl_get_private_fib_uvar...\n");
776
777 val = dl_get_private_fib_uvar();
778
779 printf("Got %d, expected %d... ", val, 0);
780 if (val != 0) {
781 printf("dl_get_private_fib_uvar_addr -> %p\n",
782 dl_get_private_fib_var_addr());
783 printf("FAILED\n");
784 return false;
785 }
786
787 printf("Passed\n");
788 return true;
789}
790
791/** Test directly calling a function that returns the contents of a public
792 * initialized fibril-local variable.
793 */
794static bool test_lnk_dl_get_public_fib_var(void)
795{
796 int val;
797
798 printf("Call linked dl_get_public_fib_var...\n");
799
800 val = dl_get_public_fib_var();
801
802 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
803 if (val != dl_public_fib_var_val) {
804 printf("dl_get_public_fib_var_addr -> %p\n",
805 dl_get_public_fib_var_addr());
806 printf("FAILED\n");
807 return false;
808 }
809
810 printf("Passed\n");
811 return true;
812}
813
814/** Test directly calling a function that returns the contents of a public
815 * uninitialized fibril-local variable.
816 */
817static bool test_lnk_dl_get_public_fib_uvar(void)
818{
819 int val;
820
821 printf("Call linked dl_get_public_fib_uvar...\n");
822
823 val = dl_get_public_fib_uvar();
824
825 printf("Got %d, expected %d... ", val, 0);
826 if (val != 0) {
827 printf("dl_get_public_fib_uvar_addr -> %p\n",
828 dl_get_public_fib_uvar_addr());
829 printf("FAILED\n");
830 return false;
831 }
832
833 printf("Passed\n");
834 return true;
835}
836
837/** Test directly reading a public initialized fibril-local variable. */
838static bool test_lnk_read_public_fib_var(void)
839{
840 int val;
841
842 printf("Read linked dl_public_fib_var...\n");
843
844 val = dl_public_fib_var;
845
846 printf("Got %d, expected %d... ", val, dl_public_fib_var_val);
847 if (val != dl_public_fib_var_val) {
848 printf("&dl_public_fib_var = %p, "
849 "dl_get_public_fib_var_addr -> %p\n",
850 &dl_public_fib_var, dl_get_public_fib_var_addr());
851 printf("FAILED\n");
852 return false;
853 }
854
855 printf("Passed\n");
856 return true;
857}
858
859/** Test directly reading a public uninitialized fibril-local variable. */
860static bool test_lnk_read_public_fib_uvar(void)
861{
862 int val;
863
864 printf("Read linked dl_public_fib_uvar...\n");
865
866 val = dl_public_fib_uvar;
867
868 printf("Got %d, expected %d... ", val, 0);
869 if (val != 0) {
870 printf("&dl_public_fib_uvar = %p, "
871 "dl_get_public_fib_uvar_addr -> %p\n",
872 &dl_public_fib_uvar, dl_get_public_fib_uvar_addr());
873 printf("FAILED\n");
874 return false;
875 }
876
877 printf("Passed\n");
878 return true;
879}
880
881#endif /* DLTEST_LINKED */
882
883static int test_dlfcn(void)
884{
885 printf("dlopen()... ");
886 handle = dlopen("libdltest.so.0", 0);
887 if (handle == NULL) {
888 printf("FAILED\n");
889 return 1;
890 }
891
892 printf("Passed\n");
893
894 if (!test_dlsym())
895 return 1;
896
897 if (!test_dlfcn_dl_get_constant())
898 return 1;
899
900 if (!test_dlfcn_dl_get_constant_via_call())
901 return 1;
902
903 if (!test_dlfcn_dl_get_private_var())
904 return 1;
905
906 if (!test_dlfcn_dl_get_private_uvar())
907 return 1;
908
909 if (!test_dlfcn_dl_get_public_var())
910 return 1;
911
912 if (!test_dlfcn_dl_get_public_uvar())
913 return 1;
914
915 if (!test_dlfcn_read_public_var())
916 return 1;
917
918 if (!test_dlfcn_read_public_uvar())
919 return 1;
920
921#ifndef STATIC_EXE
922 if (!test_dlfcn_dl_get_private_fib_var())
923 return 1;
924
925 if (!test_dlfcn_dl_get_private_fib_uvar())
926 return 1;
927
928 if (!test_dlfcn_dl_get_public_fib_var())
929 return 1;
930
931 if (!test_dlfcn_dl_get_public_fib_uvar())
932 return 1;
933
934 if (!test_dlfcn_read_public_fib_var())
935 return 1;
936
937 if (!test_dlfcn_read_public_fib_uvar())
938 return 1;
939#endif /* STATIC_EXE */
940
941#if 0
942 printf("dlclose()... ");
943 dlclose(handle);
944 printf("Passed\n");
945#endif
946
947 return 0;
948}
949
950#ifdef DLTEST_LINKED
951
952static int test_lnk(void)
953{
954 if (!test_lnk_dl_get_constant())
955 return 1;
956
957 if (!test_lnk_dl_get_constant_via_call())
958 return 1;
959
960 if (!test_lnk_dl_get_private_var())
961 return 1;
962
963 if (!test_lnk_dl_get_private_uvar())
964 return 1;
965
966 if (!test_lnk_dl_get_public_var())
967 return 1;
968
969 if (!test_lnk_dl_get_public_uvar())
970 return 1;
971
972 if (!test_lnk_read_public_var())
973 return 1;
974
975 if (!test_lnk_read_public_uvar())
976 return 1;
977
978 if (!test_lnk_dl_get_private_fib_var())
979 return 1;
980
981 if (!test_lnk_dl_get_private_fib_uvar())
982 return 1;
983
984 if (!test_lnk_dl_get_public_fib_var())
985 return 1;
986
987 if (!test_lnk_dl_get_public_fib_uvar())
988 return 1;
989
990 if (!test_lnk_read_public_fib_var())
991 return 1;
992
993 if (!test_lnk_read_public_fib_uvar())
994 return 1;
995
996 return 0;
997}
998
999#endif /* DLTEST_LINKED */
1000
1001static void print_syntax(void)
1002{
1003 fprintf(stderr, "syntax: dltest [-n]\n");
1004 fprintf(stderr, "\t-n Do not run dlfcn tests\n");
1005}
1006
1007int main(int argc, char *argv[])
1008{
1009 printf("Dynamic linking test\n");
1010
1011 if (argc > 1) {
1012 if (argc > 2) {
1013 print_syntax();
1014 return 1;
1015 }
1016
1017 if (str_cmp(argv[1], "-n") == 0) {
1018 no_dlfcn = true;
1019 } else {
1020 print_syntax();
1021 return 1;
1022 }
1023 }
1024
1025 if (!no_dlfcn) {
1026 if (test_dlfcn() != 0)
1027 return 1;
1028 }
1029
1030#ifdef DLTEST_LINKED
1031 if (test_lnk() != 0)
1032 return 1;
1033#endif
1034
1035 printf("All passed.\n");
1036 return 0;
1037}
1038
1039/**
1040 * @}
1041 */
Note: See TracBrowser for help on using the repository browser.