[llvm] a1e1dca - [XCOFF][AIX] Emit EH information in traceback table

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 16 06:35:56 PST 2020


Author: diggerlin
Date: 2020-12-16T09:34:59-05:00
New Revision: a1e1dcabe4fb1f24401f3153409583fe133ffd46

URL: https://github.com/llvm/llvm-project/commit/a1e1dcabe4fb1f24401f3153409583fe133ffd46
DIFF: https://github.com/llvm/llvm-project/commit/a1e1dcabe4fb1f24401f3153409583fe133ffd46.diff

LOG: [XCOFF][AIX] Emit EH information in traceback table

SUMMARY:

In order for the runtime on AIX to find the compact unwind section(EHInfo table),
we would need to set the following on the traceback table:

The 6th byte's longtbtable field to true to signal there is an Extended TB Table Flag.
The Extended TB Table Flag to be 0x08 to signal there is an exception handling info presents.
Emit the offset between ehinfo TC entry and TOC base after all other optional portions of traceback table.

The patch is authored by Jason Liu.

Reviewers: David Tenty, Digger Lin
Differential Revision: https://reviews.llvm.org/D92766

Added: 
    

Modified: 
    llvm/include/llvm/BinaryFormat/XCOFF.h
    llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
    llvm/lib/BinaryFormat/XCOFF.cpp
    llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/test/CodeGen/PowerPC/aix-exception.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index f2e11efef5cd..48e1baf72689 100644
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -395,14 +395,16 @@ struct TracebackTable {
 
 // Extended Traceback table flags.
 enum ExtendedTBTableFlag : uint8_t {
-  TB_OS1 = 0x80,         ///< Reserved for OS use
-  TB_RESERVED = 0x40,    ///< Reserved for compiler
-  TB_SSP_CANARY = 0x20,  ///< stack smasher canary present on stack
-  TB_OS2 = 0x10,         ///< Reserved for OS use
-  TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists
+  TB_OS1 = 0x80,         ///< Reserved for OS use.
+  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 present.
+  TB_LONGTBTABLE2 = 0x01 ///< Additional tbtable extension exists.
 };
 
 StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId);
+SmallString<32> getExtendedTBTableFlagString(uint8_t Flag);
 
 } // end namespace XCOFF
 } // end namespace llvm

diff  --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index a7389bb21371..31e08b7d1e63 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -21,6 +21,7 @@ namespace llvm {
 
 class GlobalValue;
 class MachineModuleInfo;
+class MachineFunction;
 class MCContext;
 class MCExpr;
 class MCSection;
@@ -219,6 +220,10 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
   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,

diff  --git a/llvm/lib/BinaryFormat/XCOFF.cpp b/llvm/lib/BinaryFormat/XCOFF.cpp
index fda4595971f3..0f270a5cea1b 100644
--- a/llvm/lib/BinaryFormat/XCOFF.cpp
+++ b/llvm/lib/BinaryFormat/XCOFF.cpp
@@ -128,4 +128,29 @@ SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
   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

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp b/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
index 21615d47f634..95d878e65be4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
+++ b/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 @@ void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
 
   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,16 @@ void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
 }
 
 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<Function>(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();
+  assert(F.hasPersonalityFn() &&
+         "Landingpads are presented, but no personality routine is found.");
+  const Function *Per =
+      dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
   const MCSymbol *PerSym = Asm->TM.getSymbol(Per);
 
   emitExceptionInfoTable(LSDALabel, PerSym);

diff  --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index b4d88fcb0702..6567aaaa3d82 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2054,6 +2054,29 @@ MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection(
 //===----------------------------------------------------------------------===//
 //                                  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<Function>(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 {

diff  --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 3c6db3002f63..87c4d1bd3ebc 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -1881,6 +1881,10 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
       (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.
@@ -1977,6 +1981,35 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
     OutStreamer->AddComment("AllocaUsed");
     OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
   }
+
+  uint8_t ExtensionTableFlag = 0;
+  if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
+    if (ShouldEmitEHBlock)
+      ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
+
+    CommentOS << "ExtensionTableFlag = "
+              << getExtendedTBTableFlagString(ExtensionTableFlag);
+    EmitCommentAndValue(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<MCSectionXCOFF>(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
 }

diff  --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll
index f2fc323e166f..4c9d15cafe0c 100644
--- a/llvm/test/CodeGen/PowerPC/aix-exception.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll
@@ -98,6 +98,29 @@ eh.resume:                                        ; preds = %catch.dispatch
 ; 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 = CPlusPlus
+; ASM:    .byte   0x22                            # -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                            # -HasVectorInfo, +HasExtensionTable, 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 @@ eh.resume:                                        ; preds = %catch.dispatch
 ; 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 @@ eh.resume:                                        ; preds = %catch.dispatch
 ; 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*)


        


More information about the llvm-commits mailing list