dyld-750.5.tar.gz
[apple/dyld.git] / testing / test-cases / dyld_shared_cache_some_image_overridden.dtest / main.c
1
2 // BUILD: $CC myzlib.c -dynamiclib -o $BUILD_DIR/override/libz.1.dylib -install_name /usr/lib/libz.1.dylib -compatibility_version 1.0
3 // BUILD: $CC main.c -o $BUILD_DIR/dyld_shared_cache_some_image_overridden.exe -lz
4 // BUILD: $DYLD_ENV_VARS_ENABLE $BUILD_DIR/dyld_shared_cache_some_image_overridden.exe
5 // BUILD: $CC main.c -o $BUILD_DIR/dyld_shared_cache_some_image_overridden-no-lz.exe -DNO_LZ
6 // BUILD: $DYLD_ENV_VARS_ENABLE $BUILD_DIR/dyld_shared_cache_some_image_overridden-no-lz.exe
7
8 // RUN: ./dyld_shared_cache_some_image_overridden.exe
9 // RUN: DYLD_LIBRARY_PATH=$RUN_DIR/override/ ./dyld_shared_cache_some_image_overridden.exe
10 // RUN: ./dyld_shared_cache_some_image_overridden-no-lz.exe
11 // RUN: DYLD_LIBRARY_PATH=$RUN_DIR/override/ ./dyld_shared_cache_some_image_overridden-no-lz.exe
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <zlib.h>
17 #include <stdbool.h>
18
19 #include <dlfcn.h>
20 #include <mach-o/dyld_priv.h>
21
22 #include "test_support.h"
23
24 // The test here is to override libz.1.dylib which is in the dyld cache with our own implementation.
25 // We then ensure that dyld_shared_cache_some_image_overridden returns the correct value to match whether we took a root
26
27 extern const char* zlibVersion();
28
29 int main(int argc, const char* argv[], const char* envp[], const char* apple[]) {
30 // If we aren't using a shared cache, eg, have DYLD_SHARED_REGION=avoid, then just assume we work
31 uuid_t currentCacheUUID;
32 if ( !_dyld_get_shared_cache_uuid(currentCacheUUID) ) {
33 if (dyld_shared_cache_some_image_overridden())
34 FAIL("Overriden but no shared cache ");
35 else
36 PASS("No shared cache");
37 }
38
39 #if NO_LZ
40 // This run doesn't link lz so instead dlopen's it
41 bool expectMyDylib = (getenv("DYLD_LIBRARY_PATH") != NULL);
42
43 void* handle = dlopen("/usr/lib/libz.1.dylib", RTLD_NOLOAD);
44 if ( handle != NULL ) {
45 // Uh oh. Someone else has started linking libz so we can't use it as our root any more
46 FAIL("libz is hard linked now. Update test to use a new dylib");
47 }
48
49 bool launchedWithOverriddenBinary = dyld_shared_cache_some_image_overridden();
50
51 // Now dlopen libz
52 handle = dlopen("/usr/lib/libz.1.dylib", RTLD_LAZY);
53 if ( handle == NULL ) {
54 FAIL("/usr/lib/libz.1.dylib could not be loaded, %s", dlerror());
55 }
56
57 // verify handle has the version symbol
58 __typeof(&zlibVersion) versionSymbol = (__typeof(&zlibVersion))dlsym(handle, "zlibVersion");
59 if ( versionSymbol == NULL ) {
60 FAIL("zlibVersion was not found");
61 }
62
63 bool usingMyDylib = (strcmp(versionSymbol(), "my") == 0);
64
65 if ( usingMyDylib != expectMyDylib ) {
66 // Not using the right dylib
67 FAIL("%s", expectMyDylib ? "my" : "os");
68 }
69
70 // Using the right dylib, so now see if we returned the correct value for dyld_shared_cache_some_image_overridden
71 if (usingMyDylib) {
72 if (!dyld_shared_cache_some_image_overridden()) {
73 FAIL("My dylib but not some dylib overridden");
74 }
75 } else if (!launchedWithOverriddenBinary) {
76 // We didn't have a root when we launched, so now we can make sure we do have a root after the dlopen
77 // Assume we aren't testing against a root of libz in the system itself...
78 if (dyld_shared_cache_some_image_overridden()) {
79 FAIL("System dylib was overridden");
80 }
81 } else {
82 // We can't actually be sure of the result here. There may be other roots on the system so call the API to
83 // make sure it doesn't crash, but don't actually check it.
84 dyld_shared_cache_some_image_overridden();
85 }
86 #else
87 // This run links libz directly
88 bool expectMyDylib = (getenv("DYLD_LIBRARY_PATH") != NULL);
89
90 bool usingMyDylib = (strcmp(zlibVersion(), "my") == 0);
91
92 if ( usingMyDylib != expectMyDylib ) {
93 // Not using the right dylib
94 FAIL("%s", expectMyDylib ? "my" : "os");
95 }
96
97 // Using the right dylib, so now see if we returned the correct value for dyld_shared_cache_some_image_overridden
98 if (usingMyDylib) {
99 if (!dyld_shared_cache_some_image_overridden()) {
100 FAIL("My dylib but not some dylib overridden");
101 }
102 } else {
103 // We can't actually be sure of the result here. There may be other roots on the system so call the API to
104 // make sure it doesn't crash, but don't actually check it.
105 dyld_shared_cache_some_image_overridden();
106 }
107 #endif
108 PASS("%s", expectMyDylib ? "my" : "os");
109
110 return 0;
111 }
112