[llvm] r238575 - [WinEH] Emit EH tables for __CxxFrameHandler3 on 32-bit x86
Reid Kleckner
reid at kleckner.net
Fri May 29 10:00:57 PDT 2015
Author: rnk
Date: Fri May 29 12:00:57 2015
New Revision: 238575
URL: http://llvm.org/viewvc/llvm-project?rev=238575&view=rev
Log:
[WinEH] Emit EH tables for __CxxFrameHandler3 on 32-bit x86
Small (really small!) C++ exception handling examples work on 32-bit x86
now.
This change disables the use of .seh_* directives in WinException when
CFI is not in use. It also uses absolute symbol references in the tables
instead of imagerel32 relocations.
Also fixes a cache invalidation bug in MMI personality classification.
Modified:
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h
llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/MC/MCStreamer.cpp
llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
llvm/trunk/test/CodeGen/X86/win32-eh.ll
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Fri May 29 12:00:57 2015
@@ -268,6 +268,7 @@ bool AsmPrinter::doInitialization(Module
default: llvm_unreachable("unsupported unwinding information encoding");
case WinEH::EncodingType::Invalid:
break;
+ case WinEH::EncodingType::X86:
case WinEH::EncodingType::Itanium:
ES = new WinException(this);
break;
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Fri May 29 12:00:57 2015
@@ -29,6 +29,7 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
@@ -38,9 +39,11 @@
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
-WinException::WinException(AsmPrinter *A)
- : EHStreamer(A), shouldEmitPersonality(false), shouldEmitLSDA(false),
- shouldEmitMoves(false) {}
+WinException::WinException(AsmPrinter *A) : EHStreamer(A) {
+ // MSVC's EH tables are always composed of 32-bit words. All known 64-bit
+ // platforms use an imagerel32 relocation to refer to symbols.
+ useImageRel32 = (A->getDataLayout().getPointerSizeInBits() == 64);
+}
WinException::~WinException() {}
@@ -55,11 +58,14 @@ void WinException::beginFunction(const M
// If any landing pads survive, we need an EH table.
bool hasLandingPads = !MMI->getLandingPads().empty();
+ const Function *F = MF->getFunction();
+ const Function *ParentF = MMI->getWinEHParent(F);
+
shouldEmitMoves = Asm->needsSEHMoves();
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();
- const Function *Per = MF->getMMI().getPersonality();
+ const Function *Per = MMI->getPersonality();
shouldEmitPersonality = hasLandingPads &&
PerEncoding != dwarf::DW_EH_PE_omit && Per;
@@ -68,12 +74,17 @@ void WinException::beginFunction(const M
shouldEmitLSDA = shouldEmitPersonality &&
LSDAEncoding != dwarf::DW_EH_PE_omit;
+ // If we're not using CFI, we don't want the CFI or the personality. Emit the
+ // LSDA if this is the parent function.
+ if (!Asm->MAI->usesWindowsCFI()) {
+ shouldEmitLSDA = (hasLandingPads && F == ParentF);
+ shouldEmitPersonality = false;
+ return;
+ }
// If this was an outlined handler, we need to define the label corresponding
// to the offset of the parent frame relative to the stack pointer after the
// prologue.
- const Function *F = MF->getFunction();
- const Function *ParentF = MMI->getWinEHParent(F);
if (F != ParentF) {
WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF);
auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F);
@@ -89,23 +100,20 @@ void WinException::beginFunction(const M
}
}
- if (!shouldEmitPersonality && !shouldEmitMoves)
- return;
+ if (shouldEmitMoves || shouldEmitPersonality)
+ Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym);
- Asm->OutStreamer->EmitWinCFIStartProc(Asm->CurrentFnSym);
-
- if (!shouldEmitPersonality)
- return;
-
- const MCSymbol *PersHandlerSym =
- TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
- Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
+ if (shouldEmitPersonality) {
+ const MCSymbol *PersHandlerSym =
+ TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
+ Asm->OutStreamer->EmitWinEHHandler(PersHandlerSym, true, true);
+ }
}
/// endFunction - Gather and emit post-function exception information.
///
void WinException::endFunction(const MachineFunction *MF) {
- if (!shouldEmitPersonality && !shouldEmitMoves)
+ if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
return;
EHPersonality Per = MMI->getPersonalityType();
@@ -116,16 +124,27 @@ void WinException::endFunction(const Mac
if (!isMSVCEHPersonality(Per))
MMI->TidyLandingPads();
- if (shouldEmitPersonality) {
+ if (shouldEmitPersonality || shouldEmitLSDA) {
Asm->OutStreamer->PushSection();
- // Emit an UNWIND_INFO struct describing the prologue.
- Asm->OutStreamer->EmitWinEHHandlerData();
+ if (shouldEmitMoves || shouldEmitPersonality) {
+ // Emit an UNWIND_INFO struct describing the prologue.
+ Asm->OutStreamer->EmitWinEHHandlerData();
+ } else {
+ // Just switch sections to the right xdata section. This use of
+ // CurrentFnSym assumes that we only emit the LSDA when ending the parent
+ // function.
+ MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
+ Asm->CurrentFnSym, Asm->OutContext);
+ Asm->OutStreamer->SwitchSection(XData);
+ }
// Emit the tables appropriate to the personality function in use. If we
// don't recognize the personality, assume it uses an Itanium-style LSDA.
if (Per == EHPersonality::MSVC_Win64SEH)
emitCSpecificHandlerTable();
+ else if (Per == EHPersonality::MSVC_X86SEH)
+ emitCSpecificHandlerTable(); // FIXME
else if (Per == EHPersonality::MSVC_CXX)
emitCXXFrameHandler3Table(MF);
else
@@ -133,20 +152,24 @@ void WinException::endFunction(const Mac
Asm->OutStreamer->PopSection();
}
- Asm->OutStreamer->EmitWinCFIEndProc();
+
+ if (shouldEmitMoves)
+ Asm->OutStreamer->EmitWinCFIEndProc();
}
-const MCExpr *WinException::createImageRel32(const MCSymbol *Value) {
+const MCExpr *WinException::create32bitRef(const MCSymbol *Value) {
if (!Value)
return MCConstantExpr::Create(0, Asm->OutContext);
- return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32,
+ return MCSymbolRefExpr::Create(Value, useImageRel32
+ ? MCSymbolRefExpr::VK_COFF_IMGREL32
+ : MCSymbolRefExpr::VK_None,
Asm->OutContext);
}
-const MCExpr *WinException::createImageRel32(const GlobalValue *GV) {
+const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
if (!GV)
return MCConstantExpr::Create(0, Asm->OutContext);
- return createImageRel32(Asm->getSymbol(GV));
+ return create32bitRef(Asm->getSymbol(GV));
}
/// Emit the language-specific data that __C_specific_handler expects. This
@@ -227,16 +250,16 @@ void WinException::emitCSpecificHandlerT
// Compute the label range. We may reuse the function begin and end labels
// rather than forming new ones.
const MCExpr *Begin =
- createImageRel32(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym);
+ create32bitRef(CSE.BeginLabel ? CSE.BeginLabel : EHFuncBeginSym);
const MCExpr *End;
if (CSE.EndLabel) {
// The interval is half-open, so we have to add one to include the return
// address of the last invoke in the range.
- End = MCBinaryExpr::CreateAdd(createImageRel32(CSE.EndLabel),
+ End = MCBinaryExpr::CreateAdd(create32bitRef(CSE.EndLabel),
MCConstantExpr::Create(1, Asm->OutContext),
Asm->OutContext);
} else {
- End = createImageRel32(EHFuncEndSym);
+ End = create32bitRef(EHFuncEndSym);
}
// Emit an entry for each action.
@@ -248,7 +271,7 @@ void WinException::emitCSpecificHandlerT
// emit '1' to indicate a catch-all.
const Function *F = Handler.FilterOrFinally;
if (F)
- Asm->OutStreamer->EmitValue(createImageRel32(Asm->getSymbol(F)), 4);
+ Asm->OutStreamer->EmitValue(create32bitRef(Asm->getSymbol(F)), 4);
else
Asm->OutStreamer->EmitIntValue(1, 4);
@@ -257,7 +280,7 @@ void WinException::emitCSpecificHandlerT
const BlockAddress *BA = Handler.RecoverBA;
if (BA)
Asm->OutStreamer->EmitValue(
- createImageRel32(Asm->GetBlockAddressSymbol(BA)), 4);
+ create32bitRef(Asm->GetBlockAddressSymbol(BA)), 4);
else
Asm->OutStreamer->EmitIntValue(0, 4);
}
@@ -273,91 +296,26 @@ void WinException::emitCXXFrameHandler3T
StringRef ParentLinkageName =
GlobalValue::getRealLinkageName(ParentF->getName());
- MCSymbol *FuncInfoXData =
- Asm->OutContext.getOrCreateSymbol(Twine("$cppxdata$", ParentLinkageName));
- OS.EmitValue(createImageRel32(FuncInfoXData), 4);
-
- // The Itanium LSDA table sorts similar landing pads together to simplify the
- // actions table, but we don't need that.
- SmallVector<const LandingPadInfo *, 64> LandingPads;
- const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
- LandingPads.reserve(PadInfos.size());
- for (const auto &LP : PadInfos)
- LandingPads.push_back(&LP);
-
- RangeMapType PadMap;
- computePadMap(LandingPads, PadMap);
-
- // The end label of the previous invoke or nounwind try-range.
- MCSymbol *LastLabel = Asm->getFunctionBegin();
-
- // Whether there is a potentially throwing instruction (currently this means
- // an ordinary call) between the end of the previous try-range and now.
- bool SawPotentiallyThrowing = false;
-
- int LastEHState = -2;
-
- // The parent function and the catch handlers contribute to the 'ip2state'
- // table.
-
- // Include ip2state entries for the beginning of the main function and
- // for catch handler functions.
- if (F == ParentF) {
- FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
- LastEHState = -1;
- } else if (FuncInfo.HandlerBaseState.count(F)) {
- FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel,
- FuncInfo.HandlerBaseState[F]));
- LastEHState = FuncInfo.HandlerBaseState[F];
- }
- for (const auto &MBB : *MF) {
- for (const auto &MI : MBB) {
- if (!MI.isEHLabel()) {
- if (MI.isCall())
- SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI);
- continue;
- }
-
- // End of the previous try-range?
- MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol();
- if (BeginLabel == LastLabel)
- SawPotentiallyThrowing = false;
-
- // Beginning of a new try-range?
- RangeMapType::const_iterator L = PadMap.find(BeginLabel);
- if (L == PadMap.end())
- // Nope, it was just some random label.
- continue;
-
- const PadRange &P = L->second;
- const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
- assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
- "Inconsistent landing pad map!");
-
- // FIXME: Should this be using FuncInfo.HandlerBaseState?
- if (SawPotentiallyThrowing && LastEHState != -1) {
- FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
- SawPotentiallyThrowing = false;
- LastEHState = -1;
- }
-
- if (LandingPad->WinEHState != LastEHState)
- FuncInfo.IPToStateList.push_back(
- std::make_pair(BeginLabel, LandingPad->WinEHState));
- LastEHState = LandingPad->WinEHState;
- LastLabel = LandingPad->EndLabels[P.RangeIndex];
- }
+ MCSymbol *FuncInfoXData = nullptr;
+ if (shouldEmitPersonality) {
+ FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
+ Twine("$cppxdata$", ParentLinkageName));
+ OS.EmitValue(create32bitRef(FuncInfoXData), 4);
+
+ extendIP2StateTable(MF, ParentF, FuncInfo);
+
+ // Defer emission until we've visited the parent function and all the catch
+ // handlers. Cleanups don't contribute to the ip2state table, so don't count
+ // them.
+ if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
+ return;
+ ++FuncInfo.NumIPToStateFuncsVisited;
+ if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
+ return;
+ } else {
+ FuncInfoXData = Asm->OutContext.getOrCreateLSDASymbol(ParentLinkageName);
}
- // Defer emission until we've visited the parent function and all the catch
- // handlers. Cleanups don't contribute to the ip2state table yet, so don't
- // count them.
- if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
- return;
- ++FuncInfo.NumIPToStateFuncsVisited;
- if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
- return;
-
MCSymbol *UnwindMapXData = nullptr;
MCSymbol *TryBlockMapXData = nullptr;
MCSymbol *IPToStateXData = nullptr;
@@ -377,9 +335,9 @@ void WinException::emitCXXFrameHandler3T
// UnwindMapEntry *UnwindMap;
// uint32_t NumTryBlocks;
// TryBlockMapEntry *TryBlockMap;
- // uint32_t IPMapEntries;
- // IPToStateMapEntry *IPToStateMap;
- // uint32_t UnwindHelp; // (x64/ARM only)
+ // uint32_t IPMapEntries; // always 0 for x86
+ // IPToStateMapEntry *IPToStateMap; // always 0 for x86
+ // uint32_t UnwindHelp; // non-x86 only
// ESTypeList *ESTypeList;
// int32_t EHFlags;
// }
@@ -389,12 +347,13 @@ void WinException::emitCXXFrameHandler3T
OS.EmitLabel(FuncInfoXData);
OS.EmitIntValue(0x19930522, 4); // MagicNumber
OS.EmitIntValue(FuncInfo.UnwindMap.size(), 4); // MaxState
- OS.EmitValue(createImageRel32(UnwindMapXData), 4); // UnwindMap
+ OS.EmitValue(create32bitRef(UnwindMapXData), 4); // UnwindMap
OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4); // NumTryBlocks
- OS.EmitValue(createImageRel32(TryBlockMapXData), 4); // TryBlockMap
+ OS.EmitValue(create32bitRef(TryBlockMapXData), 4); // TryBlockMap
OS.EmitIntValue(FuncInfo.IPToStateList.size(), 4); // IPMapEntries
- OS.EmitValue(createImageRel32(IPToStateXData), 4); // IPToStateMap
- OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp
+ OS.EmitValue(create32bitRef(IPToStateXData), 4); // IPToStateMap
+ if (Asm->MAI->usesWindowsCFI())
+ OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp
OS.EmitIntValue(0, 4); // ESTypeList
OS.EmitIntValue(1, 4); // EHFlags
@@ -406,7 +365,7 @@ void WinException::emitCXXFrameHandler3T
OS.EmitLabel(UnwindMapXData);
for (const WinEHUnwindMapEntry &UME : FuncInfo.UnwindMap) {
OS.EmitIntValue(UME.ToState, 4); // ToState
- OS.EmitValue(createImageRel32(UME.Cleanup), 4); // Action
+ OS.EmitValue(create32bitRef(UME.Cleanup), 4); // Action
}
}
@@ -443,7 +402,7 @@ void WinException::emitCXXFrameHandler3T
OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh
OS.EmitIntValue(CatchHigh, 4); // CatchHigh
OS.EmitIntValue(TBME.HandlerArray.size(), 4); // NumCatches
- OS.EmitValue(createImageRel32(HandlerMapXData), 4); // HandlerArray
+ OS.EmitValue(create32bitRef(HandlerMapXData), 4); // HandlerArray
}
for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
@@ -460,12 +419,6 @@ void WinException::emitCXXFrameHandler3T
// };
OS.EmitLabel(HandlerMapXData);
for (const WinEHHandlerType &HT : TBME.HandlerArray) {
- MCSymbol *ParentFrameOffset =
- Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
- GlobalValue::getRealLinkageName(HT.Handler->getName()));
- const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
- ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
-
// Get the frame escape label with the offset of the catch object. If
// the index is -1, then there is no catch object, and we should emit an
// offset of zero, indicating that no copy will occur.
@@ -482,10 +435,18 @@ void WinException::emitCXXFrameHandler3T
}
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
- OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type
+ OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
- OS.EmitValue(createImageRel32(HT.Handler), 4); // Handler
- OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset
+ OS.EmitValue(create32bitRef(HT.Handler), 4); // Handler
+
+ if (shouldEmitPersonality) {
+ MCSymbol *ParentFrameOffset =
+ Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
+ GlobalValue::getRealLinkageName(HT.Handler->getName()));
+ const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
+ ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
+ OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset
+ }
}
}
}
@@ -497,8 +458,86 @@ void WinException::emitCXXFrameHandler3T
if (IPToStateXData) {
OS.EmitLabel(IPToStateXData);
for (auto &IPStatePair : FuncInfo.IPToStateList) {
- OS.EmitValue(createImageRel32(IPStatePair.first), 4); // IP
+ OS.EmitValue(create32bitRef(IPStatePair.first), 4); // IP
OS.EmitIntValue(IPStatePair.second, 4); // State
}
}
}
+
+void WinException::extendIP2StateTable(const MachineFunction *MF,
+ const Function *ParentF,
+ WinEHFuncInfo &FuncInfo) {
+ const Function *F = MF->getFunction();
+
+ // The Itanium LSDA table sorts similar landing pads together to simplify the
+ // actions table, but we don't need that.
+ SmallVector<const LandingPadInfo *, 64> LandingPads;
+ const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
+ LandingPads.reserve(PadInfos.size());
+ for (const auto &LP : PadInfos)
+ LandingPads.push_back(&LP);
+
+ RangeMapType PadMap;
+ computePadMap(LandingPads, PadMap);
+
+ // The end label of the previous invoke or nounwind try-range.
+ MCSymbol *LastLabel = Asm->getFunctionBegin();
+
+ // Whether there is a potentially throwing instruction (currently this means
+ // an ordinary call) between the end of the previous try-range and now.
+ bool SawPotentiallyThrowing = false;
+
+ int LastEHState = -2;
+
+ // The parent function and the catch handlers contribute to the 'ip2state'
+ // table.
+
+ // Include ip2state entries for the beginning of the main function and
+ // for catch handler functions.
+ if (F == ParentF) {
+ FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
+ LastEHState = -1;
+ } else if (FuncInfo.HandlerBaseState.count(F)) {
+ FuncInfo.IPToStateList.push_back(
+ std::make_pair(LastLabel, FuncInfo.HandlerBaseState[F]));
+ LastEHState = FuncInfo.HandlerBaseState[F];
+ }
+ for (const auto &MBB : *MF) {
+ for (const auto &MI : MBB) {
+ if (!MI.isEHLabel()) {
+ if (MI.isCall())
+ SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI);
+ continue;
+ }
+
+ // End of the previous try-range?
+ MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol();
+ if (BeginLabel == LastLabel)
+ SawPotentiallyThrowing = false;
+
+ // Beginning of a new try-range?
+ RangeMapType::const_iterator L = PadMap.find(BeginLabel);
+ if (L == PadMap.end())
+ // Nope, it was just some random label.
+ continue;
+
+ const PadRange &P = L->second;
+ const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
+ assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
+ "Inconsistent landing pad map!");
+
+ // FIXME: Should this be using FuncInfo.HandlerBaseState?
+ if (SawPotentiallyThrowing && LastEHState != -1) {
+ FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
+ SawPotentiallyThrowing = false;
+ LastEHState = -1;
+ }
+
+ if (LandingPad->WinEHState != LastEHState)
+ FuncInfo.IPToStateList.push_back(
+ std::make_pair(BeginLabel, LandingPad->WinEHState));
+ LastEHState = LandingPad->WinEHState;
+ LastLabel = LandingPad->EndLabels[P.RangeIndex];
+ }
+ }
+}
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h Fri May 29 12:00:57 2015
@@ -17,26 +17,34 @@
#include "EHStreamer.h"
namespace llvm {
+class Function;
class GlobalValue;
class MachineFunction;
class MCExpr;
+struct WinEHFuncInfo;
class WinException : public EHStreamer {
/// Per-function flag to indicate if personality info should be emitted.
- bool shouldEmitPersonality;
+ bool shouldEmitPersonality = false;
/// Per-function flag to indicate if the LSDA should be emitted.
- bool shouldEmitLSDA;
+ bool shouldEmitLSDA = false;
/// Per-function flag to indicate if frame moves info should be emitted.
- bool shouldEmitMoves;
+ bool shouldEmitMoves = false;
+
+ /// True if this is a 64-bit target and we should use image relative offsets.
+ bool useImageRel32 = false;
void emitCSpecificHandlerTable();
void emitCXXFrameHandler3Table(const MachineFunction *MF);
- const MCExpr *createImageRel32(const MCSymbol *Value);
- const MCExpr *createImageRel32(const GlobalValue *GV);
+ void extendIP2StateTable(const MachineFunction *MF, const Function *ParentF,
+ WinEHFuncInfo &FuncInfo);
+
+ const MCExpr *create32bitRef(const MCSymbol *Value);
+ const MCExpr *create32bitRef(const GlobalValue *GV);
public:
//===--------------------------------------------------------------------===//
Modified: llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineModuleInfo.cpp Fri May 29 12:00:57 2015
@@ -308,6 +308,7 @@ void MachineModuleInfo::EndFunction() {
// Clean up exception info.
LandingPads.clear();
+ PersonalityTypeCache = EHPersonality::Unknown;
CallSiteMap.clear();
TypeInfos.clear();
FilterIds.clear();
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Fri May 29 12:00:57 2015
@@ -1102,9 +1102,9 @@ void MCAsmStreamer::EmitWinEHHandlerData
// We only do this so the section switch that terminates the handler
// data block is visible.
WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
- if (MCSection *XData = WinEH::UnwindEmitter::getXDataSection(
- CurFrame->Function, getContext()))
- SwitchSectionNoChange(XData);
+ MCSection *XData =
+ WinEH::UnwindEmitter::getXDataSection(CurFrame->Function, getContext());
+ SwitchSectionNoChange(XData);
OS << "\t.seh_handlerdata";
EmitEOL();
Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Fri May 29 12:00:57 2015
@@ -391,11 +391,17 @@ void MCStreamer::EmitCFIWindowSave() {
}
void MCStreamer::EnsureValidWinFrameInfo() {
+ const MCAsmInfo *MAI = Context.getAsmInfo();
+ if (!MAI->usesWindowsCFI())
+ report_fatal_error(".seh_* directives are not supported on this target");
if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
report_fatal_error("No open Win64 EH frame function!");
}
void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
+ const MCAsmInfo *MAI = Context.getAsmInfo();
+ if (!MAI->usesWindowsCFI())
+ report_fatal_error(".seh_* directives are not supported on this target");
if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
report_fatal_error("Starting a function before ending the previous one!");
Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp Fri May 29 12:00:57 2015
@@ -132,6 +132,11 @@ X86MCAsmInfoMicrosoft::X86MCAsmInfoMicro
PrivateLabelPrefix = ".L";
PointerSize = 8;
WinEHEncodingType = WinEH::EncodingType::Itanium;
+ } else {
+ // 32-bit X86 doesn't use CFI, so this isn't a real encoding type. It's just
+ // a place holder that the Windows EHStreamer looks for to suppress CFI
+ // output. In particular, usesWindowsCFI() returns false.
+ WinEHEncodingType = WinEH::EncodingType::X86;
}
ExceptionsType = ExceptionHandling::WinEH;
Modified: llvm/trunk/test/CodeGen/X86/win32-eh.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win32-eh.ll?rev=238575&r1=238574&r2=238575&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win32-eh.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win32-eh.ll Fri May 29 12:00:57 2015
@@ -87,6 +87,18 @@ catchall:
; CHECK: movl %[[next]], %fs:0
; CHECK: retl
+; CHECK: .section .xdata,"dr"
+; CHECK-LABEL: L__ehtable$use_CxxFrameHandler3:
+; CHECK-NEXT: .long 429065506
+; CHECK-NEXT: .long 2
+; CHECK-NEXT: .long ($stateUnwindMap$use_CxxFrameHandler3)
+; CHECK-NEXT: .long 1
+; CHECK-NEXT: .long ($tryMap$use_CxxFrameHandler3)
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 1
+
; CHECK-LABEL: ___ehhandler$use_CxxFrameHandler3:
; CHECK: movl $L__ehtable$use_CxxFrameHandler3, %eax
; CHECK: jmp ___CxxFrameHandler3 # TAILCALL
More information about the llvm-commits
mailing list