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"
5 // RUN: ./image-list-uuid.exe
10 #include <mach-o/loader.h>
11 #include <mach-o/dyld_images.h>
12 #include <uuid/uuid.h>
14 extern const struct mach_header __dso_handle
;
16 static void printUUIDs(const struct dyld_all_image_infos
* infos
)
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
);
30 printf("[BEGIN] image_infos-uuids\n");
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
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");
41 const struct dyld_all_image_infos
* infos
= (struct dyld_all_image_infos
*)(uintptr_t)task_dyld_info
.all_image_info_addr
;
44 if ( infos
->uuidArray
== NULL
) {
45 printf("[FAIL] infos->uuidArray == NULL\n");
48 if ( infos
->uuidArrayCount
< 2 ) {
49 // expect to contain main executable and dyld
50 printf("[FAIL] infos->uuidArrayCount != 2 (is %lu)\n", infos
->uuidArrayCount
);
54 uint32_t initialCount
= infos
->uuidArrayCount
;
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
)
62 if ( nonCacheInfo
->imageLoadAddress
->filetype
== MH_DYLINKER
)
66 printf("[FAIL] image_infos-uuids uuid array does not contain main program\n");
70 printf("[FAIL] image_infos-uuids uuid array does not contain dyld\n");
74 void* handle
= dlopen(RUN_DIR
"/test.bundle", RTLD_LAZY
);
75 if ( handle
== NULL
) {
76 printf("[FAIL] image_infos-uuids %s\n", dlerror());
79 printf("loaded test.bundle\n");
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
);
89 printf("[PASS] image_infos-uuids\n");