[PATCH] D144999: [RFC][MC][MachO]Only emits compact-unwind format for "canonical" personality symbols. For the rest, use DWARFs.

Vy Nguyen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 28 12:23:18 PST 2023


oontvoo created this revision.
oontvoo added reviewers: jyknight, thakis, int3.
Herald added subscribers: JDevlieghere, hiraditya.
Herald added a project: All.
oontvoo requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Details: https://github.com/rust-lang/rust/issues/102754

The MachO format uses 2 bits to encode these personality funtions, with 0 reserved for "no-personality".
This means we can only have up to 3 personality. There are already three popular personalities:  __gxx_personality_v0, __gcc_personality_v0, and __objc_personality_v0.
As a result, any system that needs custom-personality will run into a problem.

This patch implemented jyknight's proposal to simply force DWARFs for all non-canonical personality functions.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144999

Files:
  llvm/include/llvm/MC/MCDwarf.h
  llvm/lib/MC/MCDwarf.cpp
  llvm/lib/MC/MCStreamer.cpp


Index: llvm/lib/MC/MCStreamer.cpp
===================================================================
--- llvm/lib/MC/MCStreamer.cpp
+++ llvm/lib/MC/MCStreamer.cpp
@@ -573,6 +573,16 @@
     return;
   CurFrame->Personality = Sym;
   CurFrame->PersonalityEncoding = Encoding;
+
+  if (Sym && Sym.isMachO()) {
+    StringRef name = Sym.getName();
+    // FIXME: Could have a set here for quick lookup - but we only have 3
+    // entries.
+    CurFrame->IsCanonicalPersonality =
+        name.compare("__gxx_personality_v0,") == 0 ||
+        name.compare("__gcc_personality_v0,") == 0 ||
+        name.compare("__objc_personality_v0") == 0;
+  }
 }
 
 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
Index: llvm/lib/MC/MCDwarf.cpp
===================================================================
--- llvm/lib/MC/MCDwarf.cpp
+++ llvm/lib/MC/MCDwarf.cpp
@@ -1858,20 +1858,22 @@
   ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
 
   // Emit the compact unwind info if available.
+  // But only for canonical personality functions (gxx, gcc and objc).
   bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame();
   if (IsEH && MOFI->getCompactUnwindSection()) {
     Streamer.generateCompactUnwindEncodings(MAB);
     bool SectionEmitted = false;
     for (const MCDwarfFrameInfo &Frame : FrameArray) {
-      if (Frame.CompactUnwindEncoding == 0) continue;
+      if (Frame.CompactUnwindEncoding == 0 || !Frame.IsCanonicalPersonality)
+        continue;
       if (!SectionEmitted) {
         Streamer.switchSection(MOFI->getCompactUnwindSection());
         Streamer.emitValueToAlignment(Align(AsmInfo->getCodePointerSize()));
         SectionEmitted = true;
       }
-      NeedsEHFrameSection |=
-        Frame.CompactUnwindEncoding ==
-          MOFI->getCompactUnwindDwarfEHFrameOnly();
+      NeedsEHFrameSection |= Frame.CompactUnwindEncoding ==
+                                 MOFI->getCompactUnwindDwarfEHFrameOnly() ||
+                             !Frame.IsCanonicalPersonality;
       Emitter.EmitCompactUnwind(Frame);
     }
   }
@@ -1902,10 +1904,14 @@
   for (auto I = FrameArrayX.begin(), E = FrameArrayX.end(); I != E;) {
     const MCDwarfFrameInfo &Frame = *I;
     ++I;
-    if (CanOmitDwarf && Frame.CompactUnwindEncoding !=
-          MOFI->getCompactUnwindDwarfEHFrameOnly())
+    if (CanOmitDwarf &&
+        Frame.CompactUnwindEncoding !=
+            MOFI->getCompactUnwindDwarfEHFrameOnly() &&
+        Frame.IsCanonicalPersonality)
       // Don't generate an EH frame if we don't need one. I.e., it's taken care
       // of by the compact unwind encoding.
+      // But if the frame contains non-canonical personality, then always emits
+      // DWARF.
       continue;
 
     CIEKey Key(Frame);
Index: llvm/include/llvm/MC/MCDwarf.h
===================================================================
--- llvm/include/llvm/MC/MCDwarf.h
+++ llvm/include/llvm/MC/MCDwarf.h
@@ -696,6 +696,9 @@
   unsigned RAReg = static_cast<unsigned>(INT_MAX);
   bool IsBKeyFrame = false;
   bool IsMTETaggedFrame = false;
+  // If true, this frame's personality symbol is one of the three "canonical":
+  // __gxx_personality_v0, __gcc_personality_v0,__objc_personality_v0.
+  bool IsCanonicalPersonality = false;
 };
 
 class MCDwarfFrameEmitter {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144999.501261.patch
Type: text/x-patch
Size: 3333 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230228/439861af/attachment.bin>


More information about the llvm-commits mailing list