ARM MC: Fix the initial DWARF CFI unwind info at the start of a function
authorMark Seaborn <mseaborn@chromium.org>
Mon, 27 Jan 2014 22:38:14 +0000 (22:38 +0000)
committerMark Seaborn <mseaborn@chromium.org>
Mon, 27 Jan 2014 22:38:14 +0000 (22:38 +0000)
This brings MC into line with GNU 'as' on ARM, and it brings the ARM
target into line with most other LLVM targets, which declare the
initial CFI state with addInitialFrameState().

Without this, functions generated with .cfi_startproc/endproc on ARM
will tend to cause GDB to abort with:
  gdb/dwarf2-frame.c:1132: internal-error: Unknown CFA rule.

I've also tested this by comparing the output of "readelf -w" on the
object files produced by llvm-mc and gas when given the .s file added
here.

This change is part of addressing PR18636.

Differential Revision: http://llvm-reviews.chandlerc.com/D2597

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200255 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
test/MC/ARM/dwarf-cfi-initial-state.s [new file with mode: 0644]

index 2d7c25f31d8cfb8b4b526c17c00656ef9a5f8733..4581f4113043779ae9b25992e3be249fb525d4c0 100644 (file)
@@ -212,10 +212,16 @@ static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
 static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
   Triple TheTriple(TT);
 
+  MCAsmInfo *MAI;
   if (TheTriple.isOSBinFormatMachO())
-    return new ARMMCAsmInfoDarwin();
+    MAI = new ARMMCAsmInfoDarwin();
+  else
+    MAI = new ARMELFMCAsmInfo();
 
-  return new ARMELFMCAsmInfo();
+  unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
+  MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0));
+
+  return MAI;
 }
 
 static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM,
diff --git a/test/MC/ARM/dwarf-cfi-initial-state.s b/test/MC/ARM/dwarf-cfi-initial-state.s
new file mode 100644 (file)
index 0000000..2d638e9
--- /dev/null
@@ -0,0 +1,16 @@
+# RUN: llvm-mc < %s -triple=armv7-linux-gnueabi -filetype=obj -o - \
+# RUN:     | llvm-dwarfdump - | FileCheck %s
+
+.cfi_sections .debug_frame
+.cfi_startproc
+bx lr
+.cfi_endproc
+
+# CHECK: .debug_frame contents:
+# CHECK: CIE
+# CHECK-NOT: DW_CFA
+# When llvm-dwarfdump prints the full info for the DW_CFA_def_cfa
+# field, we can check that here too.
+# CHECK: DW_CFA_def_cfa:
+# CHECK-NOT: DW_CFA
+# CHECK: FDE