Index: llvm/include/llvm/BinaryFormat/XCOFF.h =================================================================== --- llvm/include/llvm/BinaryFormat/XCOFF.h +++ llvm/include/llvm/BinaryFormat/XCOFF.h @@ -401,9 +401,12 @@ TB_RESERVED = 0x40, ///< Reserved for compiler TB_SSP_CANARY = 0x20, ///< stack smasher canary present on stack TB_OS2 = 0x10, ///< Reserved for OS use + TB_EH_INFO = 0x08, ///< Exception handling info presents. TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists }; +SmallString<32> getExtendedTBTableFlagString(uint8_t Flag); + } // end namespace XCOFF } // end namespace llvm Index: llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -21,6 +21,7 @@ class GlobalValue; class MachineModuleInfo; +class MachineFunction; class MCContext; class MCExpr; class MCSection; @@ -220,6 +221,10 @@ TargetLoweringObjectFileXCOFF() = default; ~TargetLoweringObjectFileXCOFF() override = default; + static bool ShouldEmitEHBlock(const MachineFunction *MF); + + static MCSymbol *getEHInfoTableSymbol(const MachineFunction *MF); + void Initialize(MCContext &Ctx, const TargetMachine &TM) override; bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, Index: llvm/lib/BinaryFormat/XCOFF.cpp =================================================================== --- llvm/lib/BinaryFormat/XCOFF.cpp +++ llvm/lib/BinaryFormat/XCOFF.cpp @@ -148,4 +148,29 @@ return ParmsType; } +SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) { + SmallString<32> Res; + + if (Flag & ExtendedTBTableFlag::TB_OS1) + Res += "TB_OS1 "; + if (Flag & ExtendedTBTableFlag::TB_RESERVED) + Res += "TB_RESERVED "; + if (Flag & ExtendedTBTableFlag::TB_SSP_CANARY) + Res += "TB_SSP_CANARY "; + if (Flag & ExtendedTBTableFlag::TB_OS2) + Res += "TB_OS2 "; + if (Flag & ExtendedTBTableFlag::TB_EH_INFO) + Res += "TB_EH_INFO "; + if (Flag & ExtendedTBTableFlag::TB_LONGTBTABLE2) + Res += "TB_LONGTBTABLE2 "; + + // Two of the bits that haven't got used in the mask. + if (Flag & 0x06) + Res += "Unknown "; + + // Pop the last space. + Res.pop_back(); + return Res; +} + #undef RELOC_CASE Index: llvm/lib/CodeGen/AsmPrinter/AIXException.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AIXException.cpp +++ llvm/lib/CodeGen/AsmPrinter/AIXException.cpp @@ -13,6 +13,7 @@ #include "DwarfException.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -37,8 +38,8 @@ Asm->OutStreamer->SwitchSection( Asm->getObjFileLowering().getCompactUnwindSection()); - MCSymbol *EHInfoLabel = MMI->getContext().getOrCreateSymbol( - "__ehinfo." + Twine(Asm->getFunctionNumber())); + MCSymbol *EHInfoLabel = + TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(Asm->MF); Asm->OutStreamer->emitLabel(EHInfoLabel); // Version number. @@ -60,20 +61,14 @@ } void AIXException::endFunction(const MachineFunction *MF) { - const Function &F = MF->getFunction(); - bool HasLandingPads = !MF->getLandingPads().empty(); - const Function *Per = nullptr; - if (F.hasPersonalityFn()) - Per = dyn_cast(F.getPersonalityFn()->stripPointerCasts()); - bool EmitEHBlock = - HasLandingPads || (F.hasPersonalityFn() && - !isNoOpWithoutInvoke(classifyEHPersonality(Per)) && - F.needsUnwindTableEntry()); - - if (!EmitEHBlock) + if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF)) return; const MCSymbol *LSDALabel = emitExceptionTable(); + + const Function &F = MF->getFunction(); + const Function *Per = + dyn_cast(F.getPersonalityFn()->stripPointerCasts()); const MCSymbol *PerSym = Asm->TM.getSymbol(Per); emitExceptionInfoTable(LSDALabel, PerSym); Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2108,6 +2108,29 @@ //===----------------------------------------------------------------------===// // XCOFF //===----------------------------------------------------------------------===// +bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock( + const MachineFunction *MF) { + if (!MF->getLandingPads().empty()) + return true; + + const Function &F = MF->getFunction(); + if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry()) + return false; + + const Function *Per = + dyn_cast(F.getPersonalityFn()->stripPointerCasts()); + if (isNoOpWithoutInvoke(classifyEHPersonality(Per))) + return false; + + return true; +} + +MCSymbol * +TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) { + return MF->getMMI().getContext().getOrCreateSymbol( + "__ehinfo." + Twine(MF->getFunctionNumber())); +} + MCSymbol * TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV, const TargetMachine &TM) const { Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1890,6 +1890,10 @@ (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1); // Set the 6th byte of mandatory field. + bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF); + if (ShouldEmitEHBlock) + SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask; + uint32_t GPRSaved = 0; // X13 is reserved under 64-bit environment. @@ -1983,6 +1987,35 @@ OutStreamer->AddComment("AllocaUsed"); OutStreamer->emitIntValueInHex(Alloc_Reg, sizeof(Alloc_Reg)); } + + uint8_t ExtensionTableFlag = 0; + if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) { + if (ShouldEmitEHBlock) + ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO; + + CommentOS << "ExtensionTableFlag = " + << getExtendedTBTableFlagString(ExtensionTableFlag); + outputCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag)); + } + + if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) { + auto &Ctx = OutStreamer->getContext(); + MCSymbol *EHInfoSym = + TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF); + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym); + const MCSymbol *TOCBaseSym = + cast(getObjFileLowering().getTOCBaseSection()) + ->getQualNameSymbol(); + const MCExpr *Exp = + MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), + MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); + + const DataLayout &DL = getDataLayout(); + OutStreamer->emitValueToAlignment(4); + OutStreamer->AddComment("EHInfo Table"); + OutStreamer->emitValue(Exp, DL.getPointerSize()); + } + #undef GENBOOLCOMMENT #undef GENVALUECOMMENT } Index: llvm/test/CodeGen/PowerPC/aix-exception.ll =================================================================== --- llvm/test/CodeGen/PowerPC/aix-exception.ll +++ llvm/test/CodeGen/PowerPC/aix-exception.ll @@ -1,9 +1,9 @@ ; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \ -; RUN: -mattr=-altivec < %s | \ +; RUN: -mattr=-altivec -xcoff-traceback-table < %s | \ ; RUN: FileCheck --check-prefixes=ASM,ASM32 %s ; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \ -; RUN: -mattr=-altivec < %s | \ +; RUN: -mattr=-altivec -xcoff-traceback-table < %s | \ ; RUN: FileCheck --check-prefixes=ASM,ASM64 %s @_ZTIi = external constant i8* @@ -98,6 +98,29 @@ ; ASM: bl .__cxa_end_catch[PR] ; ASM: nop ; ASM: b L..BB1_2 + +; ASM: L.._Z9catchFuncv0: +; ASM: .vbyte 4, 0x00000000 # Traceback table begin +; ASM: .byte 0x00 # Version = 0 +; ASM: .byte 0x09 # Language = C++ +; ASM: .byte 0xa0 # +IsGlobaLinkage,-IsOutOfLineEpilogOrPrologue +; ASM: # +HasTraceBackTableOffset,-IsInternalProcedure +; ASM: # -HasControlledStorage,-IsTOCless +; ASM: # -IsFloatingPointPresent +; ASM: # -IsFloatingPointOperationLogOrAbortEnabled +; ASM: .byte 0x41 # -IsInterruptHandler,+IsFunctionNamePresent,-IsAllocaUsed +; ASM: # OnConditionDirective = 0,-IsCRSaved,+IsLRSaved +; ASM: .byte 0x80 # +IsBackChainStored,-IsFixup,NumOfFPRsSaved = 0 +; ASM: .byte 0x40 # +HasExtensionTable,-HasVectorInfo,NumOfGPRsSaved = 0 +; ASM: .byte 0x00 # #NumberOfFixedParms = 0 +; ASM: .byte 0x01 # #NumberOfFPParms = 0,+HasParmsOnStack +; ASM: .vbyte 4, L.._Z9catchFuncv0-._Z9catchFuncv # Function size +; ASM: .vbyte 2, 0x000d # Function name len = 13 +; ASM: .byte '_,'Z,'9,'c,'a,'t,'c,'h,'F,'u,'n,'c,'v # Function Name +; ASM: .byte 0x08 # ExtensionTableFlag = TB_EH_INFO +; ASM: .align 2 +; ASM32: .vbyte 4, L..C1-TOC[TC0] # EHInfo Table +; ASM64: .vbyte 8, L..C1-TOC[TC0] # EHInfo Table ; ASM: L..func_end0: ; ASM: .csect .gcc_except_table[RO],2 @@ -129,6 +152,7 @@ ; ASM64: .vbyte 8, L..C0-TOC[TC0] # TypeInfo 1 ; ASM: L..ttbase0: ; ASM: .align 2 + ; ASM: .csect .eh_info_table[RW],2 ; ASM: __ehinfo.1: ; ASM: .vbyte 4, 0 @@ -142,6 +166,8 @@ ; ASM: .toc ; ASM: L..C0: ; ASM: .tc _ZTIi[TC],_ZTIi[UA] +; ASM: L..C1: +; ASM: .tc __ehinfo.1[TC],__ehinfo.1 declare i8* @__cxa_allocate_exception(i32) declare void @__cxa_throw(i8*, i8*, i8*)