diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/ARMException.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfException.h | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp | 125 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/EHStreamer.h | 8 |
5 files changed, 51 insertions, 108 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp index 15cfbd5c40f..9011f025f59 100644 --- a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -91,7 +91,8 @@ void ARMException::endFunction(const MachineFunction *MF) { ATS.emitFnEnd(); } -void ARMException::emitTypeInfos(unsigned TTypeEncoding) { +void ARMException::emitTypeInfos(unsigned TTypeEncoding, + MCSymbol *TTBaseLabel) { const MachineFunction *MF = Asm->MF; const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos(); const std::vector<unsigned> &FilterIds = MF->getFilterIds(); @@ -112,6 +113,8 @@ void ARMException::emitTypeInfos(unsigned TTypeEncoding) { Asm->EmitTTypeReference(GV, TTypeEncoding); } + Asm->OutStreamer->EmitLabel(TTBaseLabel); + // Emit the Exception Specifications. if (VerboseAsm && !FilterIds.empty()) { Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index e6e8871361b..a1d6f3cbe17 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -43,15 +43,6 @@ void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const { OutStreamer->EmitSLEB128IntValue(Value); } -/// EmitULEB128 - emit the specified unsigned leb128 value. -void AsmPrinter::EmitPaddedULEB128(uint64_t Value, unsigned PadTo, - const char *Desc) const { - if (isVerbose() && Desc) - OutStreamer->AddComment(Desc); - - OutStreamer->EmitPaddedULEB128IntValue(Value, PadTo); -} - void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const { if (isVerbose() && Desc) OutStreamer->AddComment(Desc); @@ -59,6 +50,12 @@ void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const { OutStreamer->EmitULEB128IntValue(Value); } +/// Emit something like ".uleb128 Hi-Lo". +void AsmPrinter::EmitLabelDifferenceAsULEB128(const MCSymbol *Hi, + const MCSymbol *Lo) const { + OutStreamer->emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); +} + static const char *DecodeDWARFEncoding(unsigned Encoding) { switch (Encoding) { case dwarf::DW_EH_PE_absptr: @@ -67,6 +64,10 @@ static const char *DecodeDWARFEncoding(unsigned Encoding) { return "omit"; case dwarf::DW_EH_PE_pcrel: return "pcrel"; + case dwarf::DW_EH_PE_uleb128: + return "uleb128"; + case dwarf::DW_EH_PE_sleb128: + return "sleb128"; case dwarf::DW_EH_PE_udata4: return "udata4"; case dwarf::DW_EH_PE_udata8: diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfException.h b/llvm/lib/CodeGen/AsmPrinter/DwarfException.h index 80d5bd208ed..b57ea8fc632 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfException.h @@ -70,7 +70,7 @@ public: }; class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase { - void emitTypeInfos(unsigned TTypeEncoding) override; + void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) override; ARMTargetStreamer &getTargetStreamer(); public: diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp index 871699afcb6..d9db7832faa 100644 --- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp @@ -58,10 +58,10 @@ unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L, /// Compute the actions table and gather the first action index for each landing /// pad site. -unsigned EHStreamer:: -computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, - SmallVectorImpl<ActionEntry> &Actions, - SmallVectorImpl<unsigned> &FirstActions) { +void EHStreamer::computeActionsTable( + const SmallVectorImpl<const LandingPadInfo *> &LandingPads, + SmallVectorImpl<ActionEntry> &Actions, + SmallVectorImpl<unsigned> &FirstActions) { // The action table follows the call-site table in the LSDA. The individual // records are of two types: // @@ -161,8 +161,6 @@ computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, PrevLPI = LPI; } - - return SizeActions; } /// Return `true' if this is a call to a function marked `nounwind'. Return @@ -369,47 +367,23 @@ void EHStreamer::emitExceptionTable() { // landing pad site. SmallVector<ActionEntry, 32> Actions; SmallVector<unsigned, 64> FirstActions; - unsigned SizeActions = - computeActionsTable(LandingPads, Actions, FirstActions); + computeActionsTable(LandingPads, Actions, FirstActions); // Compute the call-site table. SmallVector<CallSiteEntry, 64> CallSites; computeCallSiteTable(CallSites, LandingPads, FirstActions); - // Final tallies. - - // Call sites. bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true; - unsigned CallSiteTableLength; - if (IsSJLJ) - CallSiteTableLength = 0; - else { - unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4 - unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4 - unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4 - CallSiteTableLength = - CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize); - } - - for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { - CallSiteTableLength += getULEB128Size(CallSites[i].Action); - if (IsSJLJ) - CallSiteTableLength += getULEB128Size(i); - } - // Type infos. MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); unsigned TTypeEncoding; - unsigned TypeFormatSize; if (!HaveTTData) { // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say // that we're omitting that bit. TTypeEncoding = dwarf::DW_EH_PE_omit; - // dwarf::DW_EH_PE_absptr - TypeFormatSize = Asm->getDataLayout().getPointerSize(); } else { // Okay, we have actual filters or typeinfos to emit. As such, we need to // pick a type encoding for them. We're about to emit a list of pointers to @@ -439,7 +413,6 @@ void EHStreamer::emitExceptionTable() { // in target-independent code. // TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); - TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding); } // Begin the exception table. @@ -460,64 +433,35 @@ void EHStreamer::emitExceptionTable() { Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); Asm->EmitEncodingByte(TTypeEncoding, "@TType"); - // The type infos need to be aligned. GCC does this by inserting padding just - // before the type infos. However, this changes the size of the exception - // table, so you need to take this into account when you output the exception - // table size. However, the size is output using a variable length encoding. - // So by increasing the size by inserting padding, you may increase the number - // of bytes used for writing the size. If it increases, say by one byte, then - // you now need to output one less byte of padding to get the type infos - // aligned. However this decreases the size of the exception table. This - // changes the value you have to output for the exception table size. Due to - // the variable length encoding, the number of bytes used for writing the - // length may decrease. If so, you then have to increase the amount of - // padding. And so on. If you look carefully at the GCC code you will see that - // it indeed does this in a loop, going on and on until the values stabilize. - // We chose another solution: don't output padding inside the table like GCC - // does, instead output it before the table. - unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; - unsigned CallSiteTableLengthSize = getULEB128Size(CallSiteTableLength); - unsigned TTypeBaseOffset = - sizeof(int8_t) + // Call site format - CallSiteTableLengthSize + // Call site table length size - CallSiteTableLength + // Call site table length - SizeActions + // Actions size - SizeTypes; - unsigned TTypeBaseOffsetSize = getULEB128Size(TTypeBaseOffset); - unsigned TotalSize = - sizeof(int8_t) + // LPStart format - sizeof(int8_t) + // TType format - (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size - TTypeBaseOffset; // TType base offset - unsigned PadBytes = (4 - TotalSize) & 3; - + MCSymbol *TTBaseLabel = nullptr; if (HaveTTData) { - // Account for any extra padding that will be added to the call site table - // length. - Asm->EmitPaddedULEB128(TTypeBaseOffset, TTypeBaseOffsetSize + PadBytes, - "@TType base offset"); - PadBytes = 0; + // N.B.: There is a dependency loop between the size of the TTBase uleb128 + // here and the amount of padding before the aligned type table. The + // assembler must sometimes pad this uleb128 or insert extra padding before + // the type table. See PR35809 or GNU as bug 4029. + MCSymbol *TTBaseRefLabel = Asm->createTempSymbol("ttbaseref"); + TTBaseLabel = Asm->createTempSymbol("ttbase"); + Asm->EmitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel); + Asm->OutStreamer->EmitLabel(TTBaseRefLabel); } bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); + // Emit the landing pad call site table. + MCSymbol *CstBeginLabel = Asm->createTempSymbol("cst_begin"); + MCSymbol *CstEndLabel = Asm->createTempSymbol("cst_end"); + Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); + Asm->EmitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel); + Asm->OutStreamer->EmitLabel(CstBeginLabel); + // SjLj Exception handling if (IsSJLJ) { - Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); - - // Add extra padding if it wasn't added to the TType base offset. - Asm->EmitPaddedULEB128(CallSiteTableLength, - CallSiteTableLengthSize + PadBytes, - "Call site table length"); - - // Emit the landing pad site information. unsigned idx = 0; for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { const CallSiteEntry &S = *I; - // Offset of the landing pad, counted in 16-byte bundles relative to the - // @LPStart address. + // Index of the call site entry. if (VerboseAsm) { Asm->OutStreamer->AddComment(">> Call Site " + Twine(idx) + " <<"); Asm->OutStreamer->AddComment(" On exception at call site "+Twine(idx)); @@ -557,14 +501,6 @@ void EHStreamer::emitExceptionTable() { // A missing entry in the call-site table indicates that a call is not // supposed to throw. - // Emit the landing pad call site table. - Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); - - // Add extra padding if it wasn't added to the TType base offset. - Asm->EmitPaddedULEB128(CallSiteTableLength, - CallSiteTableLengthSize + PadBytes, - "Call site table length"); - unsigned Entry = 0; for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { @@ -579,9 +515,7 @@ void EHStreamer::emitExceptionTable() { if (!EndLabel) EndLabel = Asm->getFunctionEnd(); - // Offset of the call site relative to the previous call site, counted in - // number of 16-byte bundles. The first call site is counted relative to - // the start of the procedure fragment. + // Offset of the call site relative to the start of the procedure. if (VerboseAsm) Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) + " <<"); Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); @@ -591,8 +525,7 @@ void EHStreamer::emitExceptionTable() { EndLabel->getName()); Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); - // Offset of the landing pad, counted in 16-byte bundles relative to the - // @LPStart address. + // Offset of the landing pad relative to the start of the procedure. if (!S.LPad) { if (VerboseAsm) Asm->OutStreamer->AddComment(" has no landing pad"); @@ -617,6 +550,7 @@ void EHStreamer::emitExceptionTable() { Asm->EmitULEB128(S.Action); } } + Asm->OutStreamer->EmitLabel(CstEndLabel); // Emit the Action Table. int Entry = 0; @@ -660,12 +594,15 @@ void EHStreamer::emitExceptionTable() { Asm->EmitSLEB128(Action.NextAction); } - emitTypeInfos(TTypeEncoding); + if (HaveTTData) { + Asm->EmitAlignment(2); + emitTypeInfos(TTypeEncoding, TTBaseLabel); + } Asm->EmitAlignment(2); } -void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) { +void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) { const MachineFunction *MF = Asm->MF; const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos(); const std::vector<unsigned> &FilterIds = MF->getFilterIds(); @@ -687,6 +624,8 @@ void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) { Asm->EmitTTypeReference(GV, TTypeEncoding); } + Asm->OutStreamer->EmitLabel(TTBaseLabel); + // Emit the Exception Specifications. if (VerboseAsm && !FilterIds.empty()) { Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); diff --git a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h index 28bceab3116..ab3bd5d419f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h +++ b/llvm/lib/CodeGen/AsmPrinter/EHStreamer.h @@ -72,9 +72,9 @@ protected: /// Compute the actions table and gather the first action index for each /// landing pad site. - unsigned computeActionsTable(const SmallVectorImpl<const LandingPadInfo*>&LPs, - SmallVectorImpl<ActionEntry> &Actions, - SmallVectorImpl<unsigned> &FirstActions); + void computeActionsTable(const SmallVectorImpl<const LandingPadInfo *> &LPs, + SmallVectorImpl<ActionEntry> &Actions, + SmallVectorImpl<unsigned> &FirstActions); void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads, RangeMapType &PadMap); @@ -110,7 +110,7 @@ protected: /// catches in the function. This tables is reversed indexed base 1. void emitExceptionTable(); - virtual void emitTypeInfos(unsigned TTypeEncoding); + virtual void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel); // Helpers for identifying what kind of clause an EH typeid or selector // corresponds to. Negative selectors are for filter clauses, the zero |