1*7c3d14c8STreehugger Robot // Test that globals from different shared objects all get registered.
2*7c3d14c8STreehugger Robot
3*7c3d14c8STreehugger Robot // This source file is compiled into three different source object files. Each
4*7c3d14c8STreehugger Robot // object file declares a global buffer. The first two are linked together, and
5*7c3d14c8STreehugger Robot // the third is loaded at runtime. We make sure that out-of-bounds accesses
6*7c3d14c8STreehugger Robot // are caught for all three buffers.
7*7c3d14c8STreehugger Robot
8*7c3d14c8STreehugger Robot // RUN: %clang_asan -c -o %t-one.o -DMAIN_FILE %s
9*7c3d14c8STreehugger Robot // RUN: %clang_asan -c -o %t-two.o -DSECONDARY_FILE %s
10*7c3d14c8STreehugger Robot // RUN: %clang_asan -o %t %t-one.o %t-two.o %libdl
11*7c3d14c8STreehugger Robot // RUN: %clang_asan -o %t-dynamic.so -shared -fPIC -DSHARED_LIBRARY_FILE %s
12*7c3d14c8STreehugger Robot // RUN: not %run %t 1 2>&1 | FileCheck --check-prefix ASAN-CHECK-1 %s
13*7c3d14c8STreehugger Robot // RUN: not %run %t 2 2>&1 | FileCheck --check-prefix ASAN-CHECK-2 %s
14*7c3d14c8STreehugger Robot // RUN: not %run %t 3 2>&1 | FileCheck --check-prefix ASAN-CHECK-3 %s
15*7c3d14c8STreehugger Robot
16*7c3d14c8STreehugger Robot #if MAIN_FILE
17*7c3d14c8STreehugger Robot
18*7c3d14c8STreehugger Robot #include <dlfcn.h>
19*7c3d14c8STreehugger Robot #include <stdio.h>
20*7c3d14c8STreehugger Robot #include <stdlib.h>
21*7c3d14c8STreehugger Robot #include <string.h>
22*7c3d14c8STreehugger Robot
23*7c3d14c8STreehugger Robot extern char buffer1[1];
24*7c3d14c8STreehugger Robot extern char buffer2[1];
25*7c3d14c8STreehugger Robot char buffer1[1] = { 0 };
26*7c3d14c8STreehugger Robot
main(int argc,char * argv[])27*7c3d14c8STreehugger Robot int main(int argc, char *argv[]) {
28*7c3d14c8STreehugger Robot int n = atoi(argv[1]);
29*7c3d14c8STreehugger Robot if (n == 1) {
30*7c3d14c8STreehugger Robot buffer1[argc] = 0;
31*7c3d14c8STreehugger Robot // ASAN-CHECK-1: {{0x.* is located 1 bytes .* 'buffer1'}}
32*7c3d14c8STreehugger Robot } else if (n == 2) {
33*7c3d14c8STreehugger Robot buffer2[argc] = 0;
34*7c3d14c8STreehugger Robot // ASAN-CHECK-2: {{0x.* is located 1 bytes .* 'buffer2'}}
35*7c3d14c8STreehugger Robot } else if (n == 3) {
36*7c3d14c8STreehugger Robot char *libsuffix = "-dynamic.so";
37*7c3d14c8STreehugger Robot char *libpath = malloc(strlen(argv[0]) + strlen(libsuffix) + 1);
38*7c3d14c8STreehugger Robot sprintf(libpath, "%s%s", argv[0], libsuffix);
39*7c3d14c8STreehugger Robot
40*7c3d14c8STreehugger Robot void *handle = dlopen(libpath, RTLD_NOW);
41*7c3d14c8STreehugger Robot if (!handle) {
42*7c3d14c8STreehugger Robot fprintf(stderr, "dlopen: %s\n", dlerror());
43*7c3d14c8STreehugger Robot return 1;
44*7c3d14c8STreehugger Robot }
45*7c3d14c8STreehugger Robot
46*7c3d14c8STreehugger Robot char *buffer = (char *)dlsym(handle, "buffer3");
47*7c3d14c8STreehugger Robot if (!buffer) {
48*7c3d14c8STreehugger Robot fprintf(stderr, "dlsym: %s\n", dlerror());
49*7c3d14c8STreehugger Robot return 1;
50*7c3d14c8STreehugger Robot }
51*7c3d14c8STreehugger Robot
52*7c3d14c8STreehugger Robot buffer[argc] = 0;
53*7c3d14c8STreehugger Robot // ASAN-CHECK-3: {{0x.* is located 1 bytes .* 'buffer3'}}
54*7c3d14c8STreehugger Robot }
55*7c3d14c8STreehugger Robot
56*7c3d14c8STreehugger Robot return 0;
57*7c3d14c8STreehugger Robot }
58*7c3d14c8STreehugger Robot
59*7c3d14c8STreehugger Robot #elif SECONDARY_FILE
60*7c3d14c8STreehugger Robot
61*7c3d14c8STreehugger Robot extern char buffer2[1];
62*7c3d14c8STreehugger Robot char buffer2[1] = { 0 };
63*7c3d14c8STreehugger Robot
64*7c3d14c8STreehugger Robot #elif SHARED_LIBRARY_FILE
65*7c3d14c8STreehugger Robot
66*7c3d14c8STreehugger Robot extern char buffer3[1];
67*7c3d14c8STreehugger Robot char buffer3[1] = { 0 };
68*7c3d14c8STreehugger Robot
69*7c3d14c8STreehugger Robot #endif
70