dyld-732.8.tar.gz
[apple/dyld.git] / testing / test-cases / read-only-data.dtest / main.c
1
2 // BUILD: $CC foo.c -dynamiclib -o $BUILD_DIR/librotest.dylib -install_name $RUN_DIR/librotest.dylib -Wl,-data_const
3 // BUILD: $CC main.c -o $BUILD_DIR/read-only-data.exe $BUILD_DIR/librotest.dylib -Wl,-data_const -DRUN_DIR="$RUN_DIR"
4 // BUILD: $CC foo.c -bundle -o $BUILD_DIR/test.bundle -DBUNDLE=1 -Wl,-data_const
5
6
7 // RUN: ./read-only-data.exe
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
13 #include <mach/mach.h>
14 #include <mach/vm_region.h>
15 #include <dlfcn.h>
16 #include <mach-o/dyld.h>
17 #include <mach-o/dyld_priv.h>
18 #include <mach-o/getsect.h>
19
20 extern bool isReadOnly(const void* addr);
21 extern bool testLib();
22
23 const void* const funcs[] = { &malloc, &free, &strcmp, &printf };
24
25 typedef bool (*TestFunc)(void);
26
27 static bool sBadImage = false;
28
29 static void notify(const struct mach_header* mh, intptr_t slide)
30 {
31 // only look at images not in dyld shared cache
32 if ( (mh->flags & 0x80000000) == 0 ) {
33 //fprintf(stderr, "mh=%p flags=0x%08X\n", mh, mh->flags);
34 const char* path = dyld_image_path_containing_address(mh);
35 bool inTestDir = (strstr(path, RUN_DIR) != NULL);
36 unsigned long size;
37 #if __LP64__
38 uint8_t* p = getsectiondata((struct mach_header_64*)mh, "__DATA_CONST", "__const", &size);
39 #else
40 uint8_t* p = getsectiondata(mh, "__DATA_CONST", "__const", &size);
41 #endif
42 if ( (p != NULL) && inTestDir && !isReadOnly(p) ) {
43 printf("[FAIL] read-only-data __DATA_CONST,__const section not read-only in %p %s\n", mh, path);
44 sBadImage = true;
45 }
46 }
47 }
48
49
50 int main()
51 {
52 printf("[BEGIN] read-only-data\n");
53
54 // test __DATA_CONST in main is read-only
55 if ( !isReadOnly(&funcs[2]) ) {
56 printf("[FAIL] read-only-data main executable not read-only\n");
57 return 0;
58 }
59
60 // test __DATA_CONST in linked dylib is read-only
61 if ( !testLib() ) {
62 printf("[FAIL] read-only-data librotest.dylib not read-only\n");
63 return 0;
64 }
65
66 _dyld_register_func_for_add_image(&notify);
67
68 // test __DATA_CONST in dlopen'ed bundle is read-only
69 void* h = dlopen(RUN_DIR "/test.bundle", 0);
70 if ( h == NULL ) {
71 printf("[FAIL] read-only-data test.bundle not loaded\n");
72 return 0;
73 }
74 TestFunc tb = (TestFunc)dlsym(h, "testBundle");
75 if ( !tb() ) {
76 printf("[FAIL] read-only-data test.bundle not read-only\n");
77 return 0;
78 }
79
80 if ( !sBadImage )
81 printf("[PASS] read-only-data\n");
82
83 return 0;
84 }
85