diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-09-29 22:33:36 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-09-29 22:33:36 +0000 |
commit | 91b0ab917280d2adf0293af6852f9824d742908b (patch) | |
tree | 41341a7ec5a15c3faa1cc407256ce5576aab9267 /llvm/lib/Target/X86/X86FrameLowering.cpp | |
parent | 4993d0eb5105ad6849df46489846ac6c6ab69337 (diff) | |
download | bcm5719-llvm-91b0ab917280d2adf0293af6852f9824d742908b.tar.gz bcm5719-llvm-91b0ab917280d2adf0293af6852f9824d742908b.zip |
[WinEH] Ensure that funclets obey the x64 ABI
The x64 ABI requires that epilogues do not contain code other than stack
adjustments and some limited control flow. However, we'd insert code to
initialize the return address after stack adjustments. Instead, insert
EAX/RAX with the current value before we create the stack adjustments in
the epilogue.
llvm-svn: 248839
Diffstat (limited to 'llvm/lib/Target/X86/X86FrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 0e6b5c4b404..b0bd6983654 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1093,9 +1093,26 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, if (STI.is32Bit()) { RestoreMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock()); MF.insert(TargetMBB, RestoreMBB); - MBB.transferSuccessors(RestoreMBB); + MBB.removeSuccessor(TargetMBB); MBB.addSuccessor(RestoreMBB); - MBBI->getOperand(0).setMBB(RestoreMBB); + RestoreMBB->addSuccessor(TargetMBB); + } + + // Fill EAX/RAX with the address of the target block. + unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX; + if (STI.is64Bit()) { + // LEA64r RestoreMBB(%rip), %rax + BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), ReturnReg) + .addReg(X86::RIP) + .addImm(0) + .addReg(0) + .addMBB(RestoreMBB) + .addReg(0); + } else { + // MOV32ri $RestoreMBB, %eax + BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri)) + .addReg(ReturnReg) + .addMBB(RestoreMBB); } // Pop EBP. @@ -1111,12 +1128,24 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::JMP_4)) .addMBB(TargetMBB); } - } else if (isFuncletReturnInstr(MBBI)) { + // Replace CATCHRET with the appropriate RET. + unsigned RetOp = STI.is64Bit() ? X86::RETQ : X86::RETL; + MachineBasicBlock::iterator NewExit = + BuildMI(MBB, MBBI, DL, TII.get(RetOp)).addReg(ReturnReg); + MBBI->eraseFromParent(); + MBBI = NewExit; + } else if (MBBI->getOpcode() == X86::CLEANUPRET) { NumBytes = MFI->getMaxCallFrameSize(); assert(hasFP(MF) && "EH funclets without FP not yet implemented"); BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), MachineFramePtr) .setMIFlag(MachineInstr::FrameDestroy); + // Replace CLEANUPRET with the appropriate RET. + unsigned RetOp = STI.is64Bit() ? X86::RETQ : X86::RETL; + MachineBasicBlock::iterator NewExit = + BuildMI(MBB, MBBI, DL, TII.get(RetOp)); + MBBI->eraseFromParent(); + MBBI = NewExit; } else if (hasFP(MF)) { // Calculate required stack adjustment. uint64_t FrameSize = StackSize - SlotSize; |