Add support for the same encodings of the personality function that gnu as
supports.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122577 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 75c844f..9d26bec 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -509,7 +509,8 @@
 }
 
 static const MCSymbol &EmitCIE(MCStreamer &streamer,
-                               const MCSymbol *personality) {
+                               const MCSymbol *personality,
+                               unsigned personalityEncoding) {
   MCContext &context = streamer.getContext();
   const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
   const MCSection &section = *asmInfo.getEHFrameSection();
@@ -559,9 +560,44 @@
   streamer.EmitLabel(augmentationStart);
   if (personality) {
     // Personality Encoding
-    streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1);
+    streamer.EmitIntValue(personalityEncoding, 1);
     // Personality
-    streamer.EmitSymbolValue(personality, asmInfo.getPointerSize());
+    unsigned format = personalityEncoding & 0x0f;
+    unsigned application = personalityEncoding & 0xf0;
+    unsigned size;
+    switch (format) {
+    default:
+      assert(0 && "Unknown Encoding");
+      break;
+    case dwarf::DW_EH_PE_absptr:
+    case dwarf::DW_EH_PE_signed:
+      size = asmInfo.getPointerSize();
+      break;
+    case dwarf::DW_EH_PE_udata2:
+    case dwarf::DW_EH_PE_sdata2:
+      size = 2;
+      break;
+    case dwarf::DW_EH_PE_udata4:
+    case dwarf::DW_EH_PE_sdata4:
+      size = 4;
+      break;
+    case dwarf::DW_EH_PE_udata8:
+    case dwarf::DW_EH_PE_sdata8:
+      size = 8;
+      break;
+    }
+    switch (application) {
+    default:
+      assert(0 && "Unknown Encoding");
+      break;
+    case 0:
+    case dwarf::DW_EH_PE_indirect:
+      streamer.EmitSymbolValue(personality, size);
+      break;
+    case dwarf::DW_EH_PE_pcrel:
+      streamer.EmitPCRelSymbolValue(personality, size);
+      break;
+    }
   }
   // Encoding of the FDE pointers
   streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1);
@@ -620,13 +656,16 @@
   const MCContext &context = streamer.getContext();
   const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
   MCSymbol *fdeEnd = NULL;
-  DenseMap<const MCSymbol*, const MCSymbol*> Personalities;
+  typedef std::pair<const MCSymbol*, unsigned> personalityKey;
+  DenseMap<personalityKey, const MCSymbol*> personalities;
 
   for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
     const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
-    const MCSymbol *&cieStart = Personalities[frame.Personality];
+    personalityKey key(frame.Personality, frame.PersonalityEncoding);
+    const MCSymbol *&cieStart = personalities[key];
     if (!cieStart)
-      cieStart = &EmitCIE(streamer, frame.Personality);
+      cieStart = &EmitCIE(streamer, frame.Personality,
+                          frame.PersonalityEncoding);
     fdeEnd = EmitFDE(streamer, *cieStart, frame);
     if (i != n - 1)
       streamer.EmitLabel(fdeEnd);