]> git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/image_infos-uuids.dtest/main.c
dyld-635.2.tar.gz
[apple/dyld.git] / testing / test-cases / image_infos-uuids.dtest / main.c
1
2 // BUILD: $CC foo.c -bundle -o $BUILD_DIR/test.bundle
3 // BUILD: $CC main.c -o $BUILD_DIR/image-list-uuid.exe -DRUN_DIR="$RUN_DIR"
4
5 // RUN: ./image-list-uuid.exe
6
7
8 #include <stdio.h>
9 #include <dlfcn.h>
10 #include <mach-o/loader.h>
11 #include <mach-o/dyld_images.h>
12 #include <uuid/uuid.h>
13
14 extern const struct mach_header __dso_handle;
15
16 static void printUUIDs(const struct dyld_all_image_infos* infos)
17 {
18 if ( infos->uuidArray != NULL ) {
19 for (int i=0; i < infos->uuidArrayCount; ++i) {
20 const struct dyld_uuid_info* nonCacheInfo = &infos->uuidArray[i];
21 uuid_string_t uuidStr;
22 uuid_unparse_upper(nonCacheInfo->imageUUID, uuidStr);
23 printf("%p %s\n", nonCacheInfo->imageLoadAddress, uuidStr);
24 }
25 }
26 }
27
28 int main()
29 {
30 printf("[BEGIN] image_infos-uuids\n");
31
32 // NOTE: dyld_all_image_infos is private, but currently looked at by kernel during stackshots
33 // This test is to validate that the data available to the kernel is correct
34
35 task_dyld_info_data_t task_dyld_info;
36 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
37 if ( task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count) ) {
38 printf("[FAIL] image_infos-uuids: task_info() failed\n");
39 return 0;
40 }
41 const struct dyld_all_image_infos* infos = (struct dyld_all_image_infos*)(uintptr_t)task_dyld_info.all_image_info_addr;
42
43
44 if ( infos->uuidArray == NULL ) {
45 printf("[FAIL] infos->uuidArray == NULL\n");
46 return 0;
47 }
48 if ( infos->uuidArrayCount < 2 ) {
49 // expect to contain main executable and dyld
50 printf("[FAIL] infos->uuidArrayCount != 2 (is %lu)\n", infos->uuidArrayCount);
51 return 0;
52 }
53 printUUIDs(infos);
54 uint32_t initialCount = infos->uuidArrayCount;
55
56 bool foundMain = false;
57 bool foundDyld = false;
58 for (int i=0; i < infos->uuidArrayCount; ++i) {
59 const struct dyld_uuid_info* nonCacheInfo = &infos->uuidArray[i];
60 if ( nonCacheInfo->imageLoadAddress == &__dso_handle )
61 foundMain = true;
62 if ( nonCacheInfo->imageLoadAddress->filetype == MH_DYLINKER )
63 foundDyld = true;
64 }
65 if ( !foundMain ) {
66 printf("[FAIL] image_infos-uuids uuid array does not contain main program\n");
67 return 0;
68 }
69 if ( !foundDyld ) {
70 printf("[FAIL] image_infos-uuids uuid array does not contain dyld\n");
71 return 0;
72 }
73
74 void* handle = dlopen(RUN_DIR "/test.bundle", RTLD_LAZY);
75 if ( handle == NULL ) {
76 printf("[FAIL] image_infos-uuids %s\n", dlerror());
77 return 0;
78 }
79 printf("loaded test.bundle\n");
80
81 // now expect UUID list to be three
82 if ( infos->uuidArrayCount != initialCount+1 ) {
83 // expect to contain main executable and dyld
84 printf("[FAIL] infos->uuidArrayCount was not incremented (is %lu)\n", infos->uuidArrayCount);
85 return 0;
86 }
87 printUUIDs(infos);
88
89 printf("[PASS] image_infos-uuids\n");
90 return 0;
91 }
92