Skip to content

Commit 1ddfd9b

Browse files
Add workaround for assembling crypto instructions on arm (#311)
* Return multiple args from filter_linker_arg * Add workaround for assembling crypto instructions on arm
1 parent 5f11d00 commit 1ddfd9b

File tree

1 file changed

+43
-30
lines changed

1 file changed

+43
-30
lines changed

src/zig.rs

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,17 @@ impl Zig {
127127
skip_next_arg = false;
128128
continue;
129129
}
130-
let arg = if arg.starts_with('@') && arg.ends_with("linker-arguments") {
131-
Some(self.process_linker_response_file(
130+
let args = if arg.starts_with('@') && arg.ends_with("linker-arguments") {
131+
vec![self.process_linker_response_file(
132132
arg,
133133
&rustc_ver,
134134
&zig_version,
135135
&target_info,
136-
)?)
136+
)?]
137137
} else {
138138
self.filter_linker_arg(arg, &rustc_ver, &zig_version, &target_info)
139139
};
140-
if let Some(arg) = arg {
140+
for arg in args {
141141
if arg == "-Wl,-exported_symbols_list" {
142142
// Filter out this and the next argument
143143
skip_next_arg = true;
@@ -212,7 +212,7 @@ impl Zig {
212212
};
213213
let mut link_args: Vec<_> = content
214214
.split('\n')
215-
.filter_map(|arg| self.filter_linker_arg(arg, &rustc_ver, &zig_version, &target_info))
215+
.flat_map(|arg| self.filter_linker_arg(arg, &rustc_ver, &zig_version, &target_info))
216216
.collect();
217217
if self.has_undefined_dynamic_lookup(&link_args) {
218218
link_args.push("-Wl,-undefined=dynamic_lookup".to_string());
@@ -242,35 +242,35 @@ impl Zig {
242242
rustc_ver: &rustc_version::Version,
243243
zig_version: &semver::Version,
244244
target_info: &TargetInfo,
245-
) -> Option<String> {
245+
) -> Vec<String> {
246246
if arg == "-lgcc_s" {
247247
// Replace libgcc_s with libunwind
248-
return Some("-lunwind".to_string());
248+
return vec!["-lunwind".to_string()];
249249
} else if arg.starts_with("--target=") {
250250
// We have already passed target via `-target`
251-
return None;
251+
return vec![];
252252
}
253253
if (target_info.is_arm || target_info.is_windows_gnu)
254254
&& arg.ends_with(".rlib")
255255
&& arg.contains("libcompiler_builtins-")
256256
{
257257
// compiler-builtins is duplicated with zig's compiler-rt
258-
return None;
258+
return vec![];
259259
}
260260
if target_info.is_windows_gnu {
261261
#[allow(clippy::if_same_then_else)]
262262
if arg == "-lgcc_eh" {
263263
// zig doesn't provide gcc_eh alternative
264264
// We use libc++ to replace it on windows gnu targets
265-
return Some("-lc++".to_string());
265+
return vec!["-lc++".to_string()];
266266
} else if arg == "-Wl,-Bdynamic" && (zig_version.major, zig_version.minor) >= (0, 11) {
267267
// https://github.com/ziglang/zig/pull/16058
268268
// zig changes the linker behavior, -Bdynamic won't search *.a for mingw, but this may be fixed in the later version
269269
// here is a workaround to replace the linker switch with -search_paths_first, which will search for *.dll,*lib first,
270270
// then fallback to *.a
271-
return Some("-Wl,-search_paths_first".to_owned());
271+
return vec!["-Wl,-search_paths_first".to_owned()];
272272
} else if arg == "-lwindows" || arg == "-l:libpthread.a" || arg == "-lgcc" {
273-
return None;
273+
return vec![];
274274
} else if arg == "-Wl,--disable-auto-image-base"
275275
|| arg == "-Wl,--dynamicbase"
276276
|| arg == "-Wl,--large-address-aware"
@@ -281,22 +281,22 @@ impl Zig {
281281
// https://github.com/rust-lang/rust/blob/2fb0e8d162a021f8a795fb603f5d8c0017855160/compiler/rustc_target/src/spec/windows_gnu_base.rs#L22
282282
// https://github.com/rust-lang/rust/blob/f0bc76ac41a0a832c9ee621e31aaf1f515d3d6a5/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs#L16
283283
// zig doesn't support --disable-auto-image-base, --dynamicbase and --large-address-aware
284-
return None;
284+
return vec![];
285285
} else if arg == "-lmsvcrt" {
286-
return None;
286+
return vec![];
287287
}
288288
} else if arg == "-Wl,--no-undefined-version" {
289289
// https://github.com/rust-lang/rust/blob/542ed2bf72b232b245ece058fc11aebb1ca507d7/compiler/rustc_codegen_ssa/src/back/linker.rs#L723
290290
// zig doesn't support --no-undefined-version
291-
return None;
291+
return vec![];
292292
}
293293
if target_info.is_musl || target_info.is_ohos {
294294
// Avoids duplicated symbols with both zig musl libc and the libc crate
295295
if arg.ends_with(".o") && arg.contains("self-contained") && arg.contains("crt") {
296-
return None;
296+
return vec![];
297297
} else if arg == "-Wl,-melf_i386" {
298298
// unsupported linker arg: -melf_i386
299-
return None;
299+
return vec![];
300300
}
301301
if rustc_ver.major == 1
302302
&& rustc_ver.minor < 59
@@ -305,51 +305,64 @@ impl Zig {
305305
{
306306
// Rust distributes standalone libc.a in self-contained for musl since 1.59.0
307307
// See https://github.com/rust-lang/rust/pull/90527
308-
return None;
308+
return vec![];
309309
}
310310
if arg == "-lc" {
311-
return None;
311+
return vec![];
312312
}
313313
}
314314
if arg.starts_with("-march=") {
315315
// Ignore `-march` option for arm* targets, we use `generic` + cpu features instead
316316
if target_info.is_arm || target_info.is_i386 {
317-
return None;
317+
return vec![];
318318
} else if target_info.is_riscv64 {
319-
return Some("-march=generic_rv64".to_string());
319+
return vec!["-march=generic_rv64".to_string()];
320320
} else if arg.starts_with("-march=armv8-a") {
321-
if target_info
321+
let mut args_march = if target_info
322322
.target
323323
.as_ref()
324324
.map(|x| x.starts_with("aarch64-macos"))
325325
.unwrap_or_default()
326326
{
327-
return Some(arg.replace("armv8-a", "apple_m1"));
327+
vec![arg.replace("armv8-a", "apple_m1")]
328328
} else if target_info
329329
.target
330330
.as_ref()
331331
.map(|x| x.starts_with("aarch64-linux"))
332332
.unwrap_or_default()
333333
{
334-
return Some(
335-
arg.replace("armv8-a", "generic+v8a")
336-
.replace("simd", "neon"),
337-
);
334+
vec![arg
335+
.replace("armv8-a", "generic+v8a")
336+
.replace("simd", "neon")]
337+
} else {
338+
vec![arg.to_string()]
339+
};
340+
if arg == "-march=armv8-a+crypto" {
341+
// Workaround for building sha1-asm on aarch64
342+
// See:
343+
// https://github.com/rust-cross/cargo-zigbuild/issues/149
344+
// https://github.com/RustCrypto/asm-hashes/blob/master/sha1/build.rs#L17-L19
345+
// https://github.com/ziglang/zig/issues/10411
346+
args_march.append(&mut vec![
347+
"-Xassembler".to_owned(),
348+
"-march=armv8-a+crypto".to_owned(),
349+
]);
338350
}
351+
return args_march;
339352
}
340353
}
341354
if target_info.is_macos {
342355
if arg.starts_with("-Wl,-exported_symbols_list,") {
343356
// zig doesn't support -exported_symbols_list arg
344357
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-exported_symbols_list
345-
return None;
358+
return vec![];
346359
}
347360
if arg == "-Wl,-dylib" {
348361
// zig doesn't support -dylib
349-
return None;
362+
return vec![];
350363
}
351364
}
352-
Some(arg.to_string())
365+
vec![arg.to_string()]
353366
}
354367

355368
fn has_undefined_dynamic_lookup(&self, args: &[String]) -> bool {

0 commit comments

Comments
 (0)