@@ -39,14 +39,14 @@ const KERN_NO_SPACE: kern_return_t = 3;
39
39
const MACH_MSGH_BITS_COMPLEX : u32 = 0x80000000 ;
40
40
const MACH_MSG_IPC_KERNEL : kern_return_t = 0x00000800 ;
41
41
const MACH_MSG_IPC_SPACE : kern_return_t = 0x00002000 ;
42
- const MACH_MSG_PORT_DESCRIPTOR : u8 = 0 ;
42
+ const MACH_MSG_PORT_DESCRIPTOR : u32 = 0 ;
43
43
const MACH_MSG_SUCCESS : kern_return_t = 0 ;
44
44
const MACH_MSG_TIMEOUT_NONE : mach_msg_timeout_t = 0 ;
45
- const MACH_MSG_TYPE_COPY_SEND : u8 = 19 ;
46
- const MACH_MSG_TYPE_MAKE_SEND : u8 = 20 ;
47
- const MACH_MSG_TYPE_MAKE_SEND_ONCE : u8 = 21 ;
48
- const MACH_MSG_TYPE_MOVE_SEND : u8 = 17 ;
49
- const MACH_MSG_TYPE_PORT_SEND : u8 = MACH_MSG_TYPE_MOVE_SEND ;
45
+ const MACH_MSG_TYPE_COPY_SEND : u32 = 19 ;
46
+ const MACH_MSG_TYPE_MAKE_SEND : u32 = 20 ;
47
+ const MACH_MSG_TYPE_MAKE_SEND_ONCE : u32 = 21 ;
48
+ const MACH_MSG_TYPE_MOVE_SEND : u32 = 17 ;
49
+ const MACH_MSG_TYPE_PORT_SEND : u32 = MACH_MSG_TYPE_MOVE_SEND ;
50
50
const MACH_MSG_VM_KERNEL : kern_return_t = 0x00000400 ;
51
51
const MACH_MSG_VM_SPACE : kern_return_t = 0x00001000 ;
52
52
const MACH_NOTIFY_FIRST : i32 = 64 ;
@@ -174,7 +174,7 @@ impl OsIpcReceiver {
174
174
mach_task_self ( ) ,
175
175
port,
176
176
MACH_PORT_LIMITS_INFO ,
177
- & limits as * const mach_sys:: Struct_mach_port_limits as * mut i32 ,
177
+ & limits as * const mach_sys:: mach_port_limits as * mut i32 ,
178
178
1 ,
179
179
)
180
180
} ;
@@ -194,9 +194,8 @@ impl OsIpcReceiver {
194
194
fn sender ( & self ) -> Result < OsIpcSender , MachError > {
195
195
let port = self . port . get ( ) ;
196
196
debug_assert ! ( port != MACH_PORT_NULL ) ;
197
- let ( right, acquired_right) =
198
- mach_port_extract_right ( port, MACH_MSG_TYPE_MAKE_SEND as u32 ) ?;
199
- debug_assert ! ( acquired_right == MACH_MSG_TYPE_PORT_SEND as u32 ) ;
197
+ let ( right, acquired_right) = mach_port_extract_right ( port, MACH_MSG_TYPE_MAKE_SEND ) ?;
198
+ debug_assert ! ( acquired_right == MACH_MSG_TYPE_PORT_SEND ) ;
200
199
Ok ( OsIpcSender :: from_name ( right) )
201
200
}
202
201
@@ -249,7 +248,7 @@ impl OsIpcReceiver {
249
248
let mut port_descriptor = message. offset ( 1 ) as * mut mach_msg_port_descriptor_t ;
250
249
let mut descriptors_remaining = ( * message) . body . msgh_descriptor_count ;
251
250
while descriptors_remaining > 0 {
252
- if ( * port_descriptor) . type_ != MACH_MSG_PORT_DESCRIPTOR {
251
+ if ( * port_descriptor) . type_ ( ) != MACH_MSG_PORT_DESCRIPTOR {
253
252
break ;
254
253
}
255
254
let _ = ( * port_descriptor) . name ;
@@ -265,7 +264,9 @@ impl OsIpcReceiver {
265
264
let has_inline_data_ptr = shared_memory_descriptor as * mut bool ;
266
265
let has_inline_data = * has_inline_data_ptr;
267
266
let payload = if has_inline_data {
268
- let payload_size_ptr = has_inline_data_ptr. offset ( 1 ) as * mut usize ;
267
+ let padding_start = has_inline_data_ptr. offset ( 1 ) as * mut u8 ;
268
+ let padding_count = Message :: payload_padding ( padding_start as usize ) ;
269
+ let payload_size_ptr = padding_start. add ( padding_count) as * mut usize ;
269
270
let payload_size = * payload_size_ptr;
270
271
let max_payload_size = message as usize + ( ( * message) . header . msgh_size as usize )
271
272
- ( shared_memory_descriptor as usize ) ;
@@ -362,11 +363,10 @@ impl OsIpcSender {
362
363
unsafe {
363
364
let size = Message :: size_of ( data, ports. len ( ) , 0 ) ;
364
365
let message = libc:: malloc ( size as size_t ) as * mut Message ;
365
- ( * message) . header . msgh_bits = ( MACH_MSG_TYPE_COPY_SEND as u32 ) | MACH_MSGH_BITS_COMPLEX ;
366
+ ( * message) . header . msgh_bits = ( MACH_MSG_TYPE_COPY_SEND ) | MACH_MSGH_BITS_COMPLEX ;
366
367
( * message) . header . msgh_size = size as u32 ;
367
368
( * message) . header . msgh_local_port = MACH_PORT_NULL ;
368
369
( * message) . header . msgh_remote_port = self . port ;
369
- ( * message) . header . msgh_reserved = 0 ;
370
370
( * message) . header . msgh_id = 0 ;
371
371
( * message) . body . msgh_descriptor_count = ports. len ( ) as u32 ;
372
372
@@ -375,12 +375,13 @@ impl OsIpcSender {
375
375
( * port_descriptor_dest) . name = outgoing_port. port ( ) ;
376
376
( * port_descriptor_dest) . pad1 = 0 ;
377
377
378
- ( * port_descriptor_dest ) . disposition = match * outgoing_port {
378
+ let disposition = match * outgoing_port {
379
379
OsIpcChannel :: Sender ( _) => MACH_MSG_TYPE_MOVE_SEND ,
380
380
OsIpcChannel :: RawPort ( _) => MACH_MSG_TYPE_COPY_SEND ,
381
381
} ;
382
+ ( * port_descriptor_dest) . set_disposition ( disposition) ;
382
383
383
- ( * port_descriptor_dest) . type_ = MACH_MSG_PORT_DESCRIPTOR ;
384
+ ( * port_descriptor_dest) . set_type ( MACH_MSG_PORT_DESCRIPTOR ) ;
384
385
port_descriptor_dest = port_descriptor_dest. offset ( 1 ) ;
385
386
}
386
387
@@ -394,7 +395,11 @@ impl OsIpcSender {
394
395
* ( ( message as * mut u8 ) . offset ( size as isize - 4 ) as * mut u32 ) = 0 ;
395
396
396
397
let data_size = data. len ( ) ;
397
- let data_size_dest = is_inline_dest. offset ( 1 ) as * mut usize ;
398
+ let padding_start = is_inline_dest. offset ( 1 ) as * mut u8 ;
399
+ let padding_count = Message :: payload_padding ( padding_start as usize ) ;
400
+ // Zero out padding
401
+ padding_start. write_bytes ( 0 , padding_count) ;
402
+ let data_size_dest = padding_start. add ( padding_count) as * mut usize ;
398
403
* data_size_dest = data_size;
399
404
400
405
let data_dest = data_size_dest. offset ( 1 ) as * mut u8 ;
@@ -465,12 +470,19 @@ struct Message {
465
470
}
466
471
467
472
impl Message {
473
+ fn payload_padding ( unaligned : usize ) -> usize {
474
+ ( ( unaligned + 7 ) & !7 ) - unaligned // 8 byte alignment
475
+ }
476
+
468
477
fn size_of ( data : & [ u8 ] , port_length : usize , shared_memory_length : usize ) -> usize {
469
478
let mut size = mem:: size_of :: < Message > ( )
470
479
+ mem:: size_of :: < mach_msg_port_descriptor_t > ( ) * port_length
471
480
+ mem:: size_of :: < mach_msg_ool_descriptor_t > ( ) * shared_memory_length
472
481
+ mem:: size_of :: < bool > ( ) ;
473
482
483
+ // rustc panics in debug mode for unaligned accesses.
484
+ // so include padding to start payload at 8-byte aligned address
485
+ size += Self :: payload_padding ( size) ;
474
486
size += mem:: size_of :: < usize > ( ) + data. len ( ) ;
475
487
476
488
// Round up to the next 4 bytes; mach_msg_send returns an error for unaligned sizes.
0 commit comments