diff --git a/debian/changelog b/debian/changelog index 8787ae31..0a576b7c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,8 +2,10 @@ llvm-toolchain-4.0 (1:4.0.1-9) unstable; urgency=medium * Update of the copyright file (Closes: #878502) Thanks to Nicholas D Steeves for the work + * Take a patch for a stack alignment on sparc64 for rust + Thanks to John Paul Adrian Glaubitz for the work (Closes: #880221) - -- Sylvestre Ledru Thu, 19 Oct 2017 09:33:23 +0200 + -- Sylvestre Ledru Mon, 30 Oct 2017 19:41:20 +0100 llvm-toolchain-4.0 (1:4.0.1-8) unstable; urgency=medium diff --git a/debian/patches/series b/debian/patches/series index b3a3aa51..a7fbcd5f 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -58,3 +58,4 @@ rL306267.diff rL306353.diff rL306358.diff rL306379.diff +sparc64-fix-stack-alignment.diff diff --git a/debian/patches/sparc64-fix-stack-alignment.diff b/debian/patches/sparc64-fix-stack-alignment.diff new file mode 100644 index 00000000..2d63770a --- /dev/null +++ b/debian/patches/sparc64-fix-stack-alignment.diff @@ -0,0 +1,84 @@ +Description: Account for bias in stack readjustment + While trying to get rust running on Sparc64, I encountered an issue inside + llvm. For some reason I did not try to hunt down, rustc decides to do + strict (over-)alignment of some stack frames. At a certain point, it is + requesting an alignment of 64 bytes. This creates the following sparc + assembly code in the output from SparcFrameLowering.cpp: + + andn %sp,63,%sp + + This ensures (as intended) that the stack pointer has its low 6 bits + cleared and is perfectly aligned on 64 bytes. Alas, this does not take + Sparc64's stack pointer bias into account: The real register value is 2047 + (0x7ff) lower than the effective stack pointer address. As the stack an + Sparc64 is always 8-byte aligned, the stack pointer register modulo 8 has + to be 1. + + A crude fix to this is to not mask the lowest bit of the stack pointer + (which will keep it 0 on Sparc32 and 1 on Sparc64), which I have verified + to fix a Bus Error in rustc on Sparc64/Linux. + . + See: http://lists.llvm.org/pipermail/llvm-dev/2017-October/118620.html +Reported-By: Michael Karcher +Author: James Clarke + +--- +Origin: upstream +Bug: https://reviews.llvm.org/D39425 +Last-Update: 2017-10-30 + +--- llvm-toolchain-4.0-4.0.1.orig/lib/Target/Sparc/SparcFrameLowering.cpp ++++ llvm-toolchain-4.0-4.0.1/lib/Target/Sparc/SparcFrameLowering.cpp +@@ -88,10 +88,11 @@ void SparcFrameLowering::emitPrologue(Ma + + assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); + MachineFrameInfo &MFI = MF.getFrameInfo(); ++ const SparcSubtarget &Subtarget = MF.getSubtarget(); + const SparcInstrInfo &TII = +- *static_cast(MF.getSubtarget().getInstrInfo()); ++ *static_cast(Subtarget.getInstrInfo()); + const SparcRegisterInfo &RegInfo = +- *static_cast(MF.getSubtarget().getRegisterInfo()); ++ *static_cast(Subtarget.getRegisterInfo()); + MachineBasicBlock::iterator MBBI = MBB.begin(); + // Debug location must be unknown since the first debug location is used + // to determine the end of the prologue. +@@ -141,7 +142,7 @@ void SparcFrameLowering::emitPrologue(Ma + + // Adds the SPARC subtarget-specific spill area to the stack + // size. Also ensures target-required alignment. +- NumBytes = MF.getSubtarget().getAdjustedFrameSize(NumBytes); ++ NumBytes = Subtarget.getAdjustedFrameSize(NumBytes); + + // Finally, ensure that the size is sufficiently aligned for the + // data on the stack. +@@ -176,9 +177,27 @@ void SparcFrameLowering::emitPrologue(Ma + .addCFIIndex(CFIIndex); + + if (NeedsStackRealignment) { +- // andn %o6, MaxAlign-1, %o6 ++ int64_t Bias = Subtarget.getStackPointerBias(); ++ unsigned regUnbiased; ++ if (Bias) { ++ // This clobbers G1 which we always know is available here. ++ regUnbiased = SP::G1; ++ // add %o6, BIAS, %g1 ++ BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), regUnbiased) ++ .addReg(SP::O6).addImm(Bias); ++ } else ++ regUnbiased = SP::O6; ++ ++ // andn %regUnbiased, MaxAlign-1, %regUnbiased + int MaxAlign = MFI.getMaxAlignment(); +- BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), SP::O6).addReg(SP::O6).addImm(MaxAlign - 1); ++ BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), regUnbiased) ++ .addReg(regUnbiased).addImm(MaxAlign - 1); ++ ++ if (Bias) { ++ // add %o6, -BIAS, %g1 ++ BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), SP::O6) ++ .addReg(regUnbiased).addImm(-Bias); ++ } + } + } +