about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-12-08 07:05:19 +0000
committerbors <bors@rust-lang.org>2016-12-08 07:05:19 +0000
commit816a34aca23f3ebd0fddf79ebdf96c9fae976f58 (patch)
tree32da20743c5025a11271cd758f5e8fa36cbec547
parentd9aae6362d566497d55a94da060ec163cd874a41 (diff)
parenta1882ca769ed82fa16a06f113f386fa48366c331 (diff)
downloadrust-816a34aca23f3ebd0fddf79ebdf96c9fae976f58.tar.gz
rust-816a34aca23f3ebd0fddf79ebdf96c9fae976f58.zip
Auto merge of #38146 - kali:master, r=alexcrichton
fix objc ABI in std::env::args

iOS use different calling convention for `objc_msgSend` depending on the platform. armv7 expect good old variadic arguments, but aarch64 wants "normal" convention: `objc_msgSend` has to be called mimicking the actual callee prototype.

https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaTouch64BitGuide/ConvertingYourAppto64-Bit/ConvertingYourAppto64-Bit.html#//apple_ref/doc/uid/TP40013501-CH3-SW26

This currently breaks std::env:args() on aarch64 iOS devices. As far as I can tell, in the standard library, this is the only occurrence of ObjectiveC dispatching.
-rw-r--r--src/libstd/sys/unix/args.rs17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index c04fd863674..0f447ff4ec4 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -172,10 +172,23 @@ mod imp {
 
         extern {
             fn sel_registerName(name: *const libc::c_uchar) -> Sel;
-            fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
             fn objc_getClass(class_name: *const libc::c_uchar) -> NsId;
         }
 
+        #[cfg(target_arch="aarch64")]
+        extern {
+            fn objc_msgSend(obj: NsId, sel: Sel) -> NsId;
+            #[link_name="objc_msgSend"]
+            fn objc_msgSend_ul(obj: NsId, sel: Sel, i: libc::c_ulong) -> NsId;
+        }
+
+        #[cfg(not(target_arch="aarch64"))]
+        extern {
+            fn objc_msgSend(obj: NsId, sel: Sel, ...) -> NsId;
+            #[link_name="objc_msgSend"]
+            fn objc_msgSend_ul(obj: NsId, sel: Sel, ...) -> NsId;
+        }
+
         #[link(name = "Foundation", kind = "framework")]
         #[link(name = "objc")]
         #[cfg(not(cargobuild))]
@@ -199,7 +212,7 @@ mod imp {
 
             let cnt: usize = mem::transmute(objc_msgSend(args, count_sel));
             for i in 0..cnt {
-                let tmp = objc_msgSend(args, object_at_sel, i);
+                let tmp = objc_msgSend_ul(args, object_at_sel, i as libc::c_ulong);
                 let utf_c_str: *const libc::c_char =
                     mem::transmute(objc_msgSend(tmp, utf8_sel));
                 let bytes = CStr::from_ptr(utf_c_str).to_bytes();