diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2014-12-30 20:05:19 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2014-12-30 20:05:19 +0000 |
commit | 7ef497b1f5758bb19ecac851a1f7918a5f029377 (patch) | |
tree | 695cb749a4fb826f259f5b1b42e98f48605e68fa /llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | |
parent | a7ee2734cf8d7756ea134936ce6a7ae995d736c0 (diff) | |
download | bcm5719-llvm-7ef497b1f5758bb19ecac851a1f7918a5f029377.tar.gz bcm5719-llvm-7ef497b1f5758bb19ecac851a1f7918a5f029377.zip |
x86_64: Fix calls to __morestack under the large code model.
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.
Differential Revision: http://reviews.llvm.org/D6787
llvm-svn: 225003
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 97ef12c8328..ff8fc60e603 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1011,6 +1011,23 @@ bool AsmPrinter::doFinalization(Module &M) { // Emit llvm.ident metadata in an '.ident' directive. EmitModuleIdents(M); + // Emit __morestack address if needed for indirect calls. + if (MMI->usesMorestackAddr()) { + const MCSection *ReadOnlySection = + getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly(), + /*C=*/nullptr); + OutStreamer.SwitchSection(ReadOnlySection); + + MCSymbol *AddrSymbol = + OutContext.GetOrCreateSymbol(StringRef("__morestack_addr")); + OutStreamer.EmitLabel(AddrSymbol); + + const DataLayout &DL = *TM.getSubtargetImpl()->getDataLayout(); + unsigned PtrSize = DL.getPointerSize(0); + OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("__morestack"), + PtrSize); + } + // If we don't have any trampolines, then we don't require stack memory // to be executable. Some targets have a directive to declare this. Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); |