mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
[WinEH] Create an llvm.x86.seh.exceptioninfo intrinsic
This intrinsic is like framerecover plus a load. It recovers the EH registration stack allocation from the parent frame and loads the exception information field out of it, giving back a pointer to an EXCEPTION_POINTERS struct. It's designed for clang to use in SEH filter expressions instead of accessing the EXCEPTION_POINTERS parameter that is available on x64. This required a minor change to MC to allow defining a label variable to another absolute framerecover label variable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239567 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -449,7 +449,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
||||
Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
|
||||
GlobalValue::getRealLinkageName(HT.Handler->getName()));
|
||||
const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::create(
|
||||
ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
|
||||
ParentFrameOffset, Asm->OutContext);
|
||||
OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset
|
||||
}
|
||||
}
|
||||
@ -551,11 +551,26 @@ void WinException::extendIP2StateTable(const MachineFunction *MF,
|
||||
/// functionally equivalent to the __C_specific_handler table, except it is
|
||||
/// indexed by state number instead of IP.
|
||||
void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
|
||||
auto &OS = *Asm->OutStreamer;
|
||||
MCStreamer &OS = *Asm->OutStreamer;
|
||||
|
||||
// Define the EH registration node offset label in terms of its frameescape
|
||||
// label. The WinEHStatePass ensures that the registration node is passed to
|
||||
// frameescape. This allows SEH filter functions to access the
|
||||
// EXCEPTION_POINTERS field, which is filled in by the _except_handlerN.
|
||||
const Function *F = MF->getFunction();
|
||||
WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
|
||||
assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
|
||||
"no EH reg node frameescape index");
|
||||
StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
|
||||
MCSymbol *ParentFrameOffset =
|
||||
Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
|
||||
MCSymbol *FrameAllocSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
|
||||
FLinkageName, FuncInfo.EHRegNodeEscapeIndex);
|
||||
const MCSymbolRefExpr *FrameAllocSymRef =
|
||||
MCSymbolRefExpr::create(FrameAllocSym, Asm->OutContext);
|
||||
OS.EmitAssignment(ParentFrameOffset, FrameAllocSymRef);
|
||||
|
||||
// Emit the __ehtable label that we use for llvm.x86.seh.lsda.
|
||||
const Function *F = MF->getFunction();
|
||||
StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
|
||||
MCSymbol *LSDALabel = Asm->OutContext.getOrCreateLSDASymbol(FLinkageName);
|
||||
OS.EmitLabel(LSDALabel);
|
||||
|
||||
|
Reference in New Issue
Block a user