[llvm-commits] [llvm] r122566 - in /llvm/trunk: include/llvm/MC/MCStreamer.h lib/MC/MCDwarf.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCParser/AsmParser.cpp test/MC/ELF/cfi.s

Rafael Espindola rafael.espindola at gmail.com
Sun Dec 26 12:20:31 PST 2010


Author: rafael
Date: Sun Dec 26 14:20:31 2010
New Revision: 122566

URL: http://llvm.org/viewvc/llvm-project?rev=122566&view=rev
Log:
Add basic support for .cfi_personality.

Modified:
    llvm/trunk/include/llvm/MC/MCStreamer.h
    llvm/trunk/lib/MC/MCDwarf.cpp
    llvm/trunk/lib/MC/MCELFStreamer.cpp
    llvm/trunk/lib/MC/MCParser/AsmParser.cpp
    llvm/trunk/test/MC/ELF/cfi.s

Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=122566&r1=122565&r2=122566&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Sun Dec 26 14:20:31 2010
@@ -52,6 +52,10 @@
     void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
                          bool isPCRel, unsigned AddrSpace);
 
+    std::vector<MCDwarfFrameInfo> FrameInfos;
+    MCDwarfFrameInfo *getCurrentFrameInfo();
+    void EnsureValidFrame();
+
   protected:
     MCStreamer(MCContext &Ctx);
 
@@ -63,10 +67,6 @@
     /// is kept up to date by SwitchSection.
     const MCSection *PrevSection;
 
-    std::vector<MCDwarfFrameInfo> FrameInfos;
-    MCDwarfFrameInfo *getCurrentFrameInfo();
-    void EnsureValidFrame();
-
   public:
     virtual ~MCStreamer();
 

Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=122566&r1=122565&r2=122566&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Sun Dec 26 14:20:31 2010
@@ -475,8 +475,8 @@
         streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
       } else {
         streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
-        streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), isEH),
-                                     1);
+        streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(),
+                                                            isEH));
       }
 
       streamer.EmitULEB128IntValue(-Src.getOffset(), 1);
@@ -508,7 +508,8 @@
   }
 }
 
-static const MCSymbol &EmitCIE(MCStreamer &streamer) {
+static const MCSymbol &EmitCIE(MCStreamer &streamer,
+                               const MCSymbol *personality) {
   MCContext &context = streamer.getContext();
   const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
   const MCSection &section = *asmInfo.getEHFrameSection();
@@ -530,7 +531,10 @@
 
   // Augmentation String
   SmallString<8> Augmentation;
-  Augmentation += "zR";
+  Augmentation += "z";
+  if (personality)
+    Augmentation += "P";
+  Augmentation += "R";
   streamer.EmitBytes(Augmentation.str(), 0);
   streamer.EmitIntValue(0, 1);
 
@@ -553,6 +557,13 @@
 
   // Augmentation Data (optional)
   streamer.EmitLabel(augmentationStart);
+  if (personality) {
+    // Personality Encoding
+    streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1);
+    // Personality
+    streamer.EmitSymbolValue(personality, 8);
+  }
+  // Encoding of the FDE pointers
   streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1);
   streamer.EmitLabel(augmentationEnd);
 
@@ -563,7 +574,7 @@
   EmitFrameMoves(streamer, Moves, NULL, true);
 
   // Padding
-  streamer.EmitValueToAlignment(asmInfo.getPointerSize());
+  streamer.EmitValueToAlignment(4);
 
   streamer.EmitLabel(sectionEnd);
   return *sectionStart;
@@ -608,13 +619,19 @@
 void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) {
   const MCContext &context = streamer.getContext();
   const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
-  const MCSymbol &cieStart = EmitCIE(streamer);
   MCSymbol *fdeEnd = NULL;
+  DenseMap<const MCSymbol*, const MCSymbol*> Personalities;
+
   for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
-    fdeEnd = EmitFDE(streamer, cieStart, streamer.getFrameInfo(i));
+    const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
+    const MCSymbol *&cieStart = Personalities[frame.Personality];
+    if (!cieStart)
+      cieStart = &EmitCIE(streamer, frame.Personality);
+    fdeEnd = EmitFDE(streamer, *cieStart, frame);
     if (i != n - 1)
       streamer.EmitLabel(fdeEnd);
   }
+
   streamer.EmitValueToAlignment(asmInfo.getPointerSize());
   if (fdeEnd)
     streamer.EmitLabel(fdeEnd);

Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=122566&r1=122565&r2=122566&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Sun Dec 26 14:20:31 2010
@@ -488,7 +488,7 @@
 }
 
 void MCELFStreamer::Finish() {
-  if (!FrameInfos.empty())
+  if (getNumFrameInfos())
     MCDwarfFrameEmitter::Emit(*this);
 
   for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),

Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=122566&r1=122565&r2=122566&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Sun Dec 26 14:20:31 2010
@@ -2206,6 +2206,29 @@
   return getStreamer().EmitCFIOffset(Register, Offset);
 }
 
+static bool isValidEncoding(int64_t Encoding) {
+  if (Encoding & ~0xff)
+    return false;
+
+  if (Encoding == dwarf::DW_EH_PE_omit)
+    return true;
+
+  const unsigned Format = Encoding & 0xf;
+  if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 &&
+      Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 &&
+      Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 &&
+      Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed)
+    return false;
+
+  const unsigned Application = Encoding & 0xf0;
+  if (Application != dwarf::DW_EH_PE_absptr &&
+      Application != dwarf::DW_EH_PE_pcrel &&
+      Application != dwarf::DW_EH_PE_indirect)
+    return false;
+
+  return true;
+}
+
 /// ParseDirectiveCFIPersonalityOrLsda
 /// ::= .cfi_personality encoding, [symbol_name]
 /// ::= .cfi_lsda encoding, [symbol_name]
@@ -2214,10 +2237,10 @@
   int64_t Encoding = 0;
   if (getParser().ParseAbsoluteExpression(Encoding))
     return true;
-  if (Encoding == 255)
+  if (Encoding == dwarf::DW_EH_PE_omit)
     return false;
 
-  if (Encoding != 0)
+  if (!isValidEncoding(Encoding))
     return TokError("unsupported encoding.");
 
   if (getLexer().isNot(AsmToken::Comma))

Modified: llvm/trunk/test/MC/ELF/cfi.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi.s?rev=122566&r1=122565&r2=122566&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/cfi.s (original)
+++ llvm/trunk/test/MC/ELF/cfi.s Sun Dec 26 14:20:31 2010
@@ -7,6 +7,18 @@
 
 f2:
         .cfi_startproc
+        .cfi_personality 0x00, foo
+        nop
+        .cfi_endproc
+
+f3:
+        .cfi_startproc
+        nop
+        .cfi_endproc
+
+f4:
+        .cfi_startproc
+        .cfi_personality 0x00, foo
         nop
         .cfi_endproc
 
@@ -16,12 +28,12 @@
 // CHECK-NEXT:  ('sh_flags', 0x00000002)
 // CHECK-NEXT:  ('sh_addr', 0x00000000)
 // CHECK-NEXT:  ('sh_offset', 0x00000048)
-// CHECK-NEXT:  ('sh_size', 0x00000040)
+// CHECK-NEXT:  ('sh_size', 0x00000088)
 // CHECK-NEXT:  ('sh_link', 0x00000000)
 // CHECK-NEXT:  ('sh_info', 0x00000000)
 // CHECK-NEXT:  ('sh_addralign', 0x00000008)
 // CHECK-NEXT:  ('sh_entsize', 0x00000000)
-// CHECK-NEXT:  ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 10000000 30000000 00000000 01000000 00000000')
+// CHECK-NEXT:  ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a000000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 10000000 64000000 00000000 01000000 00000000 10000000 4c000000 00000000 01000000 00000000')
 // CHECK-NEXT: ),
 
 // CHECK:      # Section 0x00000008
@@ -29,8 +41,8 @@
 // CHECK-NEXT:  ('sh_type', 0x00000004)
 // CHECK-NEXT:  ('sh_flags', 0x00000000)
 // CHECK-NEXT:  ('sh_addr', 0x00000000)
-// CHECK-NEXT:  ('sh_offset', 0x00000180)
-// CHECK-NEXT:  ('sh_size', 0x00000030)
+// CHECK-NEXT:  ('sh_offset', 0x00000220)
+// CHECK-NEXT:  ('sh_size', 0x00000078)
 // CHECK-NEXT:  ('sh_link', 0x00000006)
 // CHECK-NEXT:  ('sh_info', 0x00000004)
 // CHECK-NEXT:  ('sh_addralign', 0x00000008)
@@ -38,15 +50,33 @@
 // CHECK-NEXT:  ('_relocations', [
 // CHECK-NEXT:   # Relocation 0x00000000
 // CHECK-NEXT:   (('r_offset', 0x00000020)
-// CHECK-NEXT:    ('r_sym', 0x00000003)
+// CHECK-NEXT:    ('r_sym', 0x00000005)
 // CHECK-NEXT:    ('r_type', 0x00000002)
 // CHECK-NEXT:    ('r_addend', 0x00000000)
 // CHECK-NEXT:   ),
 // CHECK-NEXT:   # Relocation 0x00000001
-// CHECK-NEXT:   (('r_offset', 0x00000034)
-// CHECK-NEXT:    ('r_sym', 0x00000003)
+// CHECK-NEXT:   (('r_offset', 0x0000003e)
+// CHECK-NEXT:    ('r_sym', 0x00000009)
+// CHECK-NEXT:    ('r_type', 0x00000001)
+// CHECK-NEXT:    ('r_addend', 0x00000000)
+// CHECK-NEXT:   ),
+// CHECK-NEXT:   # Relocation 0x00000002
+// CHECK-NEXT:   (('r_offset', 0x00000054)
+// CHECK-NEXT:    ('r_sym', 0x00000005)
 // CHECK-NEXT:    ('r_type', 0x00000002)
 // CHECK-NEXT:    ('r_addend', 0x00000001)
 // CHECK-NEXT:   ),
+// CHECK-NEXT:   # Relocation 0x00000003
+// CHECK-NEXT:   (('r_offset', 0x00000068)
+// CHECK-NEXT:    ('r_sym', 0x00000005)
+// CHECK-NEXT:    ('r_type', 0x00000002)
+// CHECK-NEXT:    ('r_addend', 0x00000002)
+// CHECK-NEXT:   ),
+// CHECK-NEXT:   # Relocation 0x00000004
+// CHECK-NEXT:   (('r_offset', 0x0000007c)
+// CHECK-NEXT:    ('r_sym', 0x00000005)
+// CHECK-NEXT:    ('r_type', 0x00000002)
+// CHECK-NEXT:    ('r_addend', 0x00000003)
+// CHECK-NEXT:   ),
 // CHECK-NEXT:  ])
 // CHECK-NEXT: ),





More information about the llvm-commits mailing list