diff --git a/platform/linux/cc.sh b/platform/linux/cc.sh index 6c24c8eefff93f4ab6dc7ad2a3f9538b5bad290b..987e338955dff0ff659f6507f15b0be1ed8cdff5 100755 --- a/platform/linux/cc.sh +++ b/platform/linux/cc.sh @@ -2,7 +2,7 @@ # zig cc for $ZIG_TARGET, as `cargo.sh` sets it: the C compiler and linker. zig rejects # rustc's --target, --no-undefined-version and -O1, and strips the symbol table with the debug # info, so the debug info goes after linking. -strip= output= previous= +strip= fix= output= previous= for arg do shift [ "$previous" = -o ] && output=$arg @@ -10,10 +10,28 @@ for arg do case $arg in --target=* | -Wl,--no-undefined-version | -Wl,-O1) ;; -Wl,--strip-debug) strip=1 ;; + -Wl,--fix-cortex-a53-843419) fix=1 ;; *) set -- "$@" "$arg" ;; esac done -zig cc -target "$ZIG_TARGET" "$@" || exit +if [ -n "$fix" ]; then + work=$(mktemp -d "${TMPDIR:-/tmp}/linux-link.XXXXXX") || exit + trap 'rm -rf "$work"' EXIT + work=$(cd "$work" && pwd) || exit + case $output in /*) ;; *) output=$PWD/$output ;; esac + # Zig rejects the erratum flag; LLD's response file preserves its resolved libc inputs. + LLD_REPRODUCE="$work/link.tar" \ + zig cc -target "$ZIG_TARGET" "$@" -o "$work/unpatched" || exit + tar -xOf "$work/link.tar" link/response.txt > "$work/response.txt" || exit + ( + unset LLD_REPRODUCE + cd / || exit + zig ld.lld "@$work/response.txt" --chroot / --fix-cortex-a53-843419 -o "$work/patched" + ) || exit + mv "$work/patched" "$output" || exit +else + zig cc -target "$ZIG_TARGET" "$@" || exit +fi [ -z "$strip" ] || "$(rustc --print sysroot)/lib/rustlib/$(rustc -vV | sed -n 's/^host: //p')/bin/rust-objcopy" \ --strip-debug "$output"