From cb4f8294d4b2037e80ff772c985f5ee370e7c956 Mon Sep 17 00:00:00 2001 From: Johan Anderholm Date: Wed, 7 Aug 2019 18:03:48 +0200 Subject: [PATCH] Use proper llvm-target for armv7 arm-unknown-linux-gnueabihf was incorrectly used as llvm-target instead of armv7-unknown-linux-gnueabihf when building for some Cortex A SoCs. This may cause segfaults in non trivial rust applications on ARMv7 when e.g. +a7 is passed to LLVM. It seems to differ between different versions of the compiler and LLVM versions. --- classes/rust-common.bbclass | 25 ++++++++++++++++++++++++- recipes-devtools/rust/rust.inc | 26 ++++++++++++++++++++------ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/classes/rust-common.bbclass b/classes/rust-common.bbclass index 7a455e8..ff7b9da 100644 --- a/classes/rust-common.bbclass +++ b/classes/rust-common.bbclass @@ -31,6 +31,24 @@ def determine_libc(d, thing): return libc +def target_is_armv7(d): + '''Determine if target is armv7''' + # TUNE_FEATURES may include arm* even if the target is not arm + # in the case of *-native packages + if d.getVar('TARGET_ARCH') != 'arm': + return False + + feat = d.getVar('TUNE_FEATURES') + feat = frozenset(feat.split()) + mach_overrides = d.getVar('MACHINEOVERRIDES') + mach_overrides = frozenset(mach_overrides.split(':')) + + v7=frozenset(['armv7a', 'armv7r', 'armv7m', 'armv7ve']) + if mach_overrides.isdisjoint(v7) and feat.isdisjoint(v7): + return False + else: + return True + # Responsible for taking Yocto triples and converting it to Rust triples def rust_base_triple(d, thing): ''' @@ -40,7 +58,12 @@ def rust_base_triple(d, thing): Note that os is assumed to be some linux form ''' - arch = d.getVar('{}_ARCH'.format(thing)) + # The llvm-target for armv7 is armv7-unknown-linux-gnueabihf + if thing == "TARGET" and target_is_armv7(d): + arch = "armv7" + else: + arch = d.getVar('{}_ARCH'.format(thing)) + # All the Yocto targets are Linux and are 'unknown' vendor = "-unknown" os = d.getVar('{}_OS'.format(thing)) diff --git a/recipes-devtools/rust/rust.inc b/recipes-devtools/rust/rust.inc index f1e9f5f..dfc8127 100644 --- a/recipes-devtools/rust/rust.inc +++ b/recipes-devtools/rust/rust.inc @@ -72,9 +72,9 @@ def llvm_features_from_tune(d): if 'mips32r2' in feat: f.append("+mips32r2") - v7=frozenset(['armv7a', 'armv7r', 'armv7m', 'armv7ve']) - if (not mach_overrides.isdisjoint(v7)) or (not feat.isdisjoint(v7)): - f.append("+v7") + if target_is_armv7(d): + f.append('+v7') + if ('armv6' in mach_overrides) or ('armv6' in feat): f.append("+v6") @@ -83,8 +83,8 @@ def llvm_features_from_tune(d): if 'thumb' in feat: if d.getVar('ARM_THUMB_OPT') is "thumb": - if (not mach_overrides.isdisjoint(v7)) or (not feat.isdisjoint(v7)): - f.append("+thumb2") + if target_is_armv7(d): + f.append('+thumb2') f.append("+thumb-mode") if 'cortexa5' in feat: @@ -154,6 +154,15 @@ TARGET_C_INT_WIDTH[arm] = "32" MAX_ATOMIC_WIDTH[arm] = "64" FEATURES[arm] = "+v6,+vfp2" +## armv7-unknown-linux-gnueabihf +DATA_LAYOUT[armv7] = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +LLVM_TARGET[armv7] = "${RUST_TARGET_SYS}" +TARGET_ENDIAN[armv7] = "little" +TARGET_POINTER_WIDTH[armv7] = "32" +TARGET_C_INT_WIDTH[armv7] = "32" +MAX_ATOMIC_WIDTH[armv7] = "64" +FEATURES[armv7] = "+v7,+vfp2,+thumb2" + ## aarch64-unknown-linux-{gnu, musl} DATA_LAYOUT[aarch64] = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" LLVM_TARGET[aarch64] = "${RUST_TARGET_SYS}" @@ -243,7 +252,10 @@ TARGET_C_INT_WIDTH[riscv64] = "64" MAX_ATOMIC_WIDTH[riscv64] = "64" def arch_for(d, thing): - return d.getVar('{}_ARCH'.format(thing)) + if thing == 'TARGET' and target_is_armv7(d): + return "armv7" + else: + return d.getVar('{}_ARCH'.format(thing)) def sys_for(d, thing): return d.getVar('{}_SYS'.format(thing)) @@ -260,6 +272,8 @@ def arch_to_rust_target_arch(arch): return "mips" elif arch == "mip64sel": return "mips64" + elif arch == "armv7": + return "arm" else: return arch