1 #include "mach_vm_tests.h"
4 #define TEST_TXT_FILE "/tmp/xnu.vm.sharing.test.txt"
6 static const char * lorem_text
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \
7 Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate\
8 velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
12 static struct stat sb
;
13 mach_port_t persistentReplyPort
;
16 mach_server_data_setup(void **buffer
)
18 if (0 != access(TEST_TXT_FILE
, F_OK
)) {
19 /* create a test file */
20 const size_t lorem_text_length
= strlen(lorem_text
);
21 int w_fd
= open(TEST_TXT_FILE
, O_WRONLY
| O_CREAT
| O_TRUNC
, (mode_t
)0666);
22 size_t required_length
= 450783;
24 size_t bytes_written
= 0;
25 while (bytes_written
< required_length
) {
26 bytes_written
+= (size_t)write(w_fd
, &lorem_text
[0], (size_t)(lorem_text_length
- 1));
27 if ((bytes_written
+ lorem_text_length
) > required_length
) {
28 bytes_written
+= (size_t)write(w_fd
, &lorem_text
[0], (size_t)(required_length
- bytes_written
));
35 /* Sample data set needs to be mapped in our space */
36 fd
= open(TEST_TXT_FILE
, O_RDONLY
| O_EXCL
, 0666);
39 printf("mach_server_data_setup: cannot open file %s - %d (%s).\n", TEST_TXT_FILE
, errno
, strerror(errno
));
43 if (fstat(fd
, &sb
) < 0) {
44 printf("mach_server_data_setup: cannot stat file %s - %d (%s).\n", TEST_TXT_FILE
, errno
, strerror(errno
));
49 *buffer
= mmap(NULL
, sb
.st_size
, PROT_READ
, MAP_FILE
| MAP_PRIVATE
, fd
, 0);
51 if (*buffer
== MAP_FAILED
) {
52 printf("mach_server_remap: mmap failed - %d (%s).\n", errno
, strerror(errno
));
56 kern_return_t kr
= KERN_SUCCESS
;
57 kr
= mach_vm_allocate(mach_task_self(), (mach_vm_address_t
*)buffer
, (mach_vm_size_t
)sb
.st_size
, VM_FLAGS_ANYWHERE
);
58 assert(kr
== KERN_SUCCESS
);
64 mach_server_data_cleanup(void *buffer
, mach_vm_address_t src
, mach_vm_size_t size
)
68 munmap(buffer
, sb
.st_size
);
71 mach_vm_deallocate(mach_task_self(), (mach_vm_address_t
)buffer
, (mach_vm_size_t
)sb
.st_size
);
75 mach_vm_deallocate(mach_task_self(), src
, size
);
84 mach_server_construct_header(ipc_message_t
*message
, mach_port_t replyPort
)
86 bzero(message
, sizeof(*message
));
87 message
->header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, MACH_MSG_TYPE_MAKE_SEND_ONCE
) | MACH_MSGH_BITS_COMPLEX
;
88 message
->header
.msgh_remote_port
= persistentReplyPort
;//serverPort;
89 message
->header
.msgh_local_port
= replyPort
;
90 message
->header
.msgh_size
= sizeof(*message
);
91 message
->header
.msgh_id
= 1;
95 mach_server_contruct_payload(ipc_message_t
*message
,
96 mach_vm_address_t src
,
99 mach_vm_offset_t misoffset
,
103 if (port
== MACH_PORT_NULL
) {
104 message
->address
= src
;//LD TODO: (src + 8193);
106 message
->body
.msgh_descriptor_count
= 1;
107 message
->port_descriptor
.name
= port
;
108 message
->port_descriptor
.disposition
= MACH_MSG_TYPE_COPY_SEND
;
109 message
->port_descriptor
.type
= MACH_MSG_PORT_DESCRIPTOR
;
112 message
->pid
= (uint64_t)getpid();
113 message
->size
= size
;
114 message
->vm_op
= vm_op
;
115 message
->copy
= copy
;
116 message
->misoffset
= misoffset
;
120 mach_server_create_allocation(mach_vm_address_t
*src
, mach_vm_size_t size
, void *buffer
)
122 kern_return_t kr
= KERN_SUCCESS
;
123 mach_vm_size_t chunk_size
= 0;
124 unsigned int chunk_count
= 0;
125 mach_vm_address_t localsrc
= 0;
127 kr
= mach_vm_allocate(mach_task_self(), &localsrc
, size
, VM_FLAGS_ANYWHERE
);
128 assert(KERN_SUCCESS
== kr
);
130 chunk_size
= MIN(size
, (mach_vm_size_t
)sb
.st_size
);
132 if (chunk_size
== 0) {
133 printf("mach_server_remap: Input size is 0\n");
137 chunk_count
= (unsigned int)(size
/ (mach_vm_size_t
)sb
.st_size
);
140 printf("Chunks of size: 0x%llx and count: %d\n", chunk_size
, chunk_count
);
143 for (unsigned int i
= 0; i
< chunk_count
; i
++) {
144 memcpy((void*)(localsrc
+ (i
* chunk_size
)), buffer
, chunk_size
);
151 server_error_out(mach_port_t port
)
153 /* All done here...*/
156 mach_msg_size_t messageSize
= sizeof(ipc_message_t
) + sizeof(mach_msg_trailer_t
) + 64;
157 ipc_message_t
*message
= (ipc_message_t
*)calloc(1, messageSize
);
159 message
->header
.msgh_bits
= MACH_MSGH_BITS_ZERO
;
160 message
->header
.msgh_size
= messageSize
;
161 message
->header
.msgh_remote_port
= MACH_PORT_NULL
;
162 message
->header
.msgh_local_port
= port
;
164 mach_server_construct_header(message
, port
);
165 message
->vm_op
= VM_OP_EXIT_ERROR
;
166 ret
= mach_msg(&message
->header
, MACH_SEND_MSG
, message
->header
.msgh_size
, 0, MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
, MACH_PORT_NULL
);
167 if (ret
!= KERN_SUCCESS
) {
168 T_LOG("ERROR: Failed to send message to client: (%d) %s\n", ret
, mach_error_string(ret
));
171 T_LOG("server_error_out. abort()\n");