|
@@ -1648,12 +1648,36 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
|
|
|
}
|
|
|
|
|
|
// __morestack is in libgcc
|
|
|
- if (Is64Bit)
|
|
|
- BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32))
|
|
|
- .addExternalSymbol("__morestack");
|
|
|
- else
|
|
|
- BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32))
|
|
|
- .addExternalSymbol("__morestack");
|
|
|
+ if (Is64Bit && MF.getTarget().getCodeModel() == CodeModel::Large) {
|
|
|
+ // Under the large code model, we cannot assume that __morestack lives
|
|
|
+ // within 2^31 bytes of the call site, so we cannot use pc-relative
|
|
|
+ // addressing. We cannot perform the call via a temporary register,
|
|
|
+ // as the rax register may be used to store the static chain, and all
|
|
|
+ // other suitable registers may be either callee-save or used for
|
|
|
+ // parameter passing. We cannot use the stack at this point either
|
|
|
+ // because __morestack manipulates the stack directly.
|
|
|
+ //
|
|
|
+ // To avoid these issues, perform an indirect call via a read-only memory
|
|
|
+ // location containing the address.
|
|
|
+ //
|
|
|
+ // This solution is not perfect, as it assumes that the .rodata section
|
|
|
+ // is laid out within 2^31 bytes of each function body, but this seems
|
|
|
+ // to be sufficient for JIT.
|
|
|
+ BuildMI(allocMBB, DL, TII.get(X86::CALL64m))
|
|
|
+ .addReg(X86::RIP)
|
|
|
+ .addImm(0)
|
|
|
+ .addReg(0)
|
|
|
+ .addExternalSymbol("__morestack_addr")
|
|
|
+ .addReg(0);
|
|
|
+ MF.getMMI().setUsesMorestackAddr(true);
|
|
|
+ } else {
|
|
|
+ if (Is64Bit)
|
|
|
+ BuildMI(allocMBB, DL, TII.get(X86::CALL64pcrel32))
|
|
|
+ .addExternalSymbol("__morestack");
|
|
|
+ else
|
|
|
+ BuildMI(allocMBB, DL, TII.get(X86::CALLpcrel32))
|
|
|
+ .addExternalSymbol("__morestack");
|
|
|
+ }
|
|
|
|
|
|
if (IsNested)
|
|
|
BuildMI(allocMBB, DL, TII.get(X86::MORESTACK_RET_RESTORE_R10));
|