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 #include "test_support.h"
16 extern const struct mach_header __dso_handle
;
18 static void printUUIDs(const struct dyld_all_image_infos
* infos
)
20 if ( infos
->uuidArray
!= NULL
) {
21 for (int i
=0; i
< infos
->uuidArrayCount
; ++i
) {
22 const struct dyld_uuid_info
* nonCacheInfo
= &infos
->uuidArray
[i
];
23 uuid_string_t uuidStr
;
24 uuid_unparse_upper(nonCacheInfo
->imageUUID
, uuidStr
);
25 LOG("%p %s", nonCacheInfo
->imageLoadAddress
, uuidStr
);
30 int main(int argc
, const char* argv
[], const char* envp
[], const char* apple
[]) {
31 // NOTE: dyld_all_image_infos is private, but currently looked at by kernel during stackshots
32 // This test is to validate that the data available to the kernel is correct
34 task_dyld_info_data_t task_dyld_info
;
35 mach_msg_type_number_t count
= TASK_DYLD_INFO_COUNT
;
36 if ( task_info(mach_task_self(), TASK_DYLD_INFO
, (task_info_t
)&task_dyld_info
, &count
) ) {
37 FAIL("task_info() failed");
39 const struct dyld_all_image_infos
* infos
= (struct dyld_all_image_infos
*)(uintptr_t)task_dyld_info
.all_image_info_addr
;
42 if ( infos
->uuidArray
== NULL
) {
43 FAIL("infos->uuidArray == NULL");
45 if ( infos
->uuidArrayCount
< 2 ) {
46 // expect to contain main executable and dyld
47 FAIL("infos->uuidArrayCount != 2 (is %lu)", infos
->uuidArrayCount
);
50 uint32_t initialCount
= infos
->uuidArrayCount
;
52 bool foundMain
= false;
53 bool foundDyld
= false;
54 for (int i
=0; i
< infos
->uuidArrayCount
; ++i
) {
55 const struct dyld_uuid_info
* nonCacheInfo
= &infos
->uuidArray
[i
];
56 if ( nonCacheInfo
->imageLoadAddress
== &__dso_handle
)
58 if ( nonCacheInfo
->imageLoadAddress
->filetype
== MH_DYLINKER
)
62 FAIL("image_infos-uuids uuid array does not contain main program");
65 FAIL("image_infos-uuids uuid array does not contain dyld");
68 void* handle
= dlopen(RUN_DIR
"/test.bundle", RTLD_LAZY
);
69 if ( handle
== NULL
) {
70 FAIL("image_infos-uuids %s", dlerror());
72 LOG("loaded test.bundle");
74 // now expect UUID list to be three
75 if ( infos
->uuidArrayCount
!= initialCount
+1 ) {
76 // expect to contain main executable and dyld
77 FAIL("infos->uuidArrayCount was not incremented (is %lu)", infos
->uuidArrayCount
);