xref: /llvm-project/compiler-rt/test/msan/dladdr1_test.c (revision 6959332804579b0e9273c89ecb2d2cdbaa73d04d)
1 /* RUN: %clang_msan -g %s -o %t
2    RUN: %clang_msan -g %s -DBUILD_SO -fPIC -o %t-so.so -shared
3    RUN: %run %t 2>&1 | FileCheck %s
4 
5    REQUIRES: glibc{{.*}}
6 */
7 
8 #define _GNU_SOURCE
9 
10 #ifndef BUILD_SO
11 #include <assert.h>
12 #include <dlfcn.h>
13 #include <elf.h>
14 #include <link.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 
18 typedef volatile long *(* get_t)();
19 get_t GetTls;
20 
main(int argc,char * argv[])21 int main(int argc, char *argv[]) {
22   char path[4096];
23   snprintf(path, sizeof(path), "%s-so.so", argv[0]);
24   int i;
25 
26   void *handle = dlopen(path, RTLD_LAZY);
27   if (!handle) fprintf(stderr, "%s\n", dlerror());
28   assert(handle != 0);
29   GetTls = (get_t)dlsym(handle, "GetTls");
30   assert(dlerror() == 0);
31 
32   {
33     printf("Testing RTLD_DL_LINKMAP\n");
34     fflush(stdout);
35 
36     Dl_info info;
37     struct link_map *map_ptr;
38     int ret = dladdr1(GetTls, &info, (void**)(&map_ptr), RTLD_DL_LINKMAP);
39     assert(ret != 0);
40     printf("fname: %s\n", info.dli_fname);
41     printf("fbase: %p\n", info.dli_fbase);
42     printf("sname: %s\n", info.dli_sname);
43     // CHECK: sname: GetTls
44     printf("saddr: %p\n", info.dli_saddr);
45 
46     assert(map_ptr != NULL);
47     printf("map_ptr: %p\n", map_ptr);
48     fflush(stdout);
49 
50     // Find the start of the link map
51     while(map_ptr->l_prev != NULL) {
52       fflush(stdout);
53       map_ptr = map_ptr->l_prev;
54     }
55 
56     fflush(stdout);
57     while(map_ptr != NULL) {
58       assert(map_ptr->l_name != NULL);
59       printf("0x%lx: '%s', %p\n", map_ptr->l_addr, map_ptr->l_name, map_ptr->l_ld);
60       fflush(stdout);
61       map_ptr = map_ptr->l_next;
62     }
63     // CHECK: libc{{[\-]*.*}}.so
64     // CHECK: dladdr1_test
65   }
66 
67   // Test RTLD_DL_SYMENT
68 
69   {
70     printf("Testing RTLD_DL_SYMENT\n");
71     fflush(stdout);
72 
73     Dl_info info;
74     ElfW(Sym) *sym;
75     int ret = dladdr1(GetTls, &info, (void**)(&sym), RTLD_DL_SYMENT);
76     assert(ret != 0);
77     printf("fname: %s\n", info.dli_fname);
78     printf("fbase: %p\n", info.dli_fbase);
79     printf("sname: %s\n", info.dli_sname);
80     // CHECK: sname: GetTls
81     printf("saddr: %p\n", info.dli_saddr);
82 
83     printf("sym: %d %d %d %d %lu %lu\n",
84            sym->st_name, sym->st_info, sym->st_other,
85            sym->st_shndx, sym->st_value, sym->st_size);
86     // CHECK: sym:
87   }
88   return 0;
89 }
90 #else  // BUILD_SO
91 long var;
GetTls()92 long *GetTls() {
93   return &var;
94 }
95 #endif
96