about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2018-02-22 16:37:44 -0700
committerAlex Crichton <alex@alexcrichton.com>2018-02-26 08:51:39 -0800
commit5db73fc6dbf9e4ee1a498655cb609efdf5fa93ed (patch)
treeb74856d311e11ef8535477fdf0aaae83e6488b47 /src
parentbedbad61195d2eae69b43eca49c6d3e2aee8f208 (diff)
downloadrust-5db73fc6dbf9e4ee1a498655cb609efdf5fa93ed.tar.gz
rust-5db73fc6dbf9e4ee1a498655cb609efdf5fa93ed.zip
Encode linker arguments as UTF-16 on MSVC platforms
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/back/link.rs14
-rw-r--r--src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs25
-rw-r--r--src/test/run-make/long-linker-command-lines/foo.rs21
3 files changed, 50 insertions, 10 deletions
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index d7c75dea8d0..8f308e72686 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -849,7 +849,19 @@ fn exec_linker(sess: &Session, cmd: &mut Command, tmpdir: &Path)
         args.push_str("\n");
     }
     let file = tmpdir.join("linker-arguments");
-    fs::write(&file, args.as_bytes())?;
+    let bytes = if sess.target.target.options.is_like_msvc {
+        let mut out = vec![];
+        // start the stream with a UTF-16 BOM
+        for c in vec![0xFEFF].into_iter().chain(args.encode_utf16()) {
+            // encode in little endian
+            out.push(c as u8);
+            out.push((c >> 8) as u8);
+        }
+        out
+    } else {
+        args.into_bytes()
+    };
+    fs::write(&file, &bytes)?;
     cmd2.arg(format!("@{}", file.display()));
     return cmd2.output();
 
diff --git a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs
index f9168a82e22..67d8ad0b672 100644
--- a/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs
+++ b/src/test/run-make/long-linker-command-lines-cmd-exe/foo.rs
@@ -36,8 +36,11 @@ fn main() {
     let ok = tmpdir.join("ok");
     let not_ok = tmpdir.join("not_ok");
     if env::var("YOU_ARE_A_LINKER").is_ok() {
-        match env::args().find(|a| a.contains("@")) {
-            Some(file) => { fs::copy(&file[1..], &ok).unwrap(); }
+        match env::args_os().find(|a| a.to_string_lossy().contains("@")) {
+            Some(file) => {
+                let file = file.to_str().unwrap();
+                fs::copy(&file[1..], &ok).unwrap();
+            }
             None => { File::create(&not_ok).unwrap(); }
         }
         return
@@ -84,11 +87,23 @@ fn main() {
             continue
         }
 
-        let mut contents = String::new();
-        File::open(&ok).unwrap().read_to_string(&mut contents).unwrap();
+        let mut contents = Vec::new();
+        File::open(&ok).unwrap().read_to_end(&mut contents).unwrap();
 
         for j in 0..i {
-            assert!(contents.contains(&format!("{}{}", lib_name, j)));
+            let exp = format!("{}{}", lib_name, j);
+            let exp = if cfg!(target_env = "msvc") {
+                let mut out = Vec::with_capacity(exp.len() * 2);
+                for c in exp.encode_utf16() {
+                    // encode in little endian
+                    out.push(c as u8);
+                    out.push((c >> 8) as u8);
+                }
+                out
+            } else {
+                exp.into_bytes()
+            };
+            assert!(contents.windows(exp.len()).any(|w| w == &exp[..]));
         }
 
         break
diff --git a/src/test/run-make/long-linker-command-lines/foo.rs b/src/test/run-make/long-linker-command-lines/foo.rs
index e6fd6b65366..2ac240982af 100644
--- a/src/test/run-make/long-linker-command-lines/foo.rs
+++ b/src/test/run-make/long-linker-command-lines/foo.rs
@@ -27,7 +27,8 @@ fn main() {
     let tmpdir = PathBuf::from(env::var_os("TMPDIR").unwrap());
     let ok = tmpdir.join("ok");
     if env::var("YOU_ARE_A_LINKER").is_ok() {
-        if let Some(file) = env::args().find(|a| a.contains("@")) {
+        if let Some(file) = env::args_os().find(|a| a.to_string_lossy().contains("@")) {
+            let file = file.to_str().expect("non-utf8 file argument");
             fs::copy(&file[1..], &ok).unwrap();
         }
         return
@@ -76,11 +77,23 @@ fn main() {
             continue
         }
 
-        let mut contents = String::new();
-        File::open(&ok).unwrap().read_to_string(&mut contents).unwrap();
+        let mut contents = Vec::new();
+        File::open(&ok).unwrap().read_to_end(&mut contents).unwrap();
 
         for j in 0..i {
-            assert!(contents.contains(&format!("{}{}", lib_name, j)));
+            let exp = format!("{}{}", lib_name, j);
+            let exp = if cfg!(target_env = "msvc") {
+                let mut out = Vec::with_capacity(exp.len() * 2);
+                for c in exp.encode_utf16() {
+                    // encode in little endian
+                    out.push(c as u8);
+                    out.push((c >> 8) as u8);
+                }
+                out
+            } else {
+                exp.into_bytes()
+            };
+            assert!(contents.windows(exp.len()).any(|w| w == &exp[..]));
         }
 
         break