OSDN Git Service

Implement cfi_def_cfa. Also don't convert to dwarf reg numbers twice. Looks
authorRafael Espindola <rafael.espindola@gmail.com>
Wed, 29 Dec 2010 01:42:56 +0000 (01:42 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Wed, 29 Dec 2010 01:42:56 +0000 (01:42 +0000)
like 6 is a fixed point of that and so the previous tests were OK :-)

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

include/llvm/MC/MCStreamer.h
lib/MC/MCDwarf.cpp
lib/MC/MCParser/AsmParser.cpp
lib/MC/MCStreamer.cpp
test/MC/ELF/cfi-def-cfa.s [new file with mode: 0644]

index f75e910..7c2de30 100644 (file)
@@ -395,6 +395,7 @@ namespace llvm {
 
     virtual bool EmitCFIStartProc();
     virtual bool EmitCFIEndProc();
+    virtual bool EmitCFIDefCfa(int64_t Register, int64_t Offset);
     virtual bool EmitCFIDefCfaOffset(int64_t Offset);
     virtual bool EmitCFIDefCfaRegister(int64_t Register);
     virtual bool EmitCFIOffset(int64_t Register, int64_t Offset);
index f3ba2bb..e11da37 100644 (file)
@@ -440,10 +440,7 @@ static int getDataAlignmentFactor(MCStreamer &streamer) {
 }
 
 static void EmitCFIInstruction(MCStreamer &Streamer,
-                               const MCCFIInstruction &Instr,
-                               bool isEH) {
-  MCContext &context = Streamer.getContext();
-  const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
+                               const MCCFIInstruction &Instr) {
   int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
 
   switch (Instr.getOperation()) {
@@ -459,8 +456,7 @@ static void EmitCFIInstruction(MCStreamer &Streamer,
         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));
+        Streamer.EmitULEB128IntValue(Src.getReg());
       }
 
       Streamer.EmitULEB128IntValue(-Src.getOffset(), 1);
@@ -470,11 +466,11 @@ static void EmitCFIInstruction(MCStreamer &Streamer,
     if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
       assert(Dst.isReg() && "Machine move not supported yet.");
       Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
-      Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH));
+      Streamer.EmitULEB128IntValue(Dst.getReg());
       return;
     }
 
-    unsigned Reg = asmInfo.getDwarfRegNum(Src.getReg(), isEH);
+    unsigned Reg = Src.getReg();
     int Offset = Dst.getOffset() / dataAlignmentFactor;
 
     if (Offset < 0) {
@@ -505,7 +501,7 @@ static void EmitCFIInstruction(MCStreamer &Streamer,
 /// frame.
 static void EmitCFIInstructions(MCStreamer &streamer,
                                 const std::vector<MCCFIInstruction> &Instrs,
-                                MCSymbol *BaseLabel, bool isEH) {
+                                MCSymbol *BaseLabel) {
   for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
     const MCCFIInstruction &Instr = Instrs[i];
     MCSymbol *Label = Instr.getLabel();
@@ -521,7 +517,7 @@ static void EmitCFIInstructions(MCStreamer &streamer,
       }
     }
 
-    EmitCFIInstruction(streamer, Instr, isEH);
+    EmitCFIInstruction(streamer, Instr);
   }
 }
 
@@ -566,6 +562,17 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
   }
 }
 
+static const MachineLocation TranslateMachineLocation(
+                                                  const TargetAsmInfo &AsmInfo,
+                                                  const MachineLocation &Loc) {
+  unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ?
+    MachineLocation::VirtualFP :
+    unsigned(AsmInfo.getDwarfRegNum(Loc.getReg(), true));
+  const MachineLocation &NewLoc = Loc.isReg() ?
+    MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset());
+  return NewLoc;
+}
+
 static const MCSymbol &EmitCIE(MCStreamer &streamer,
                                const MCSymbol *personality,
                                unsigned personalityEncoding,
@@ -640,12 +647,16 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer,
   std::vector<MCCFIInstruction> Instructions;
 
   for (int i = 0, n = Moves.size(); i != n; ++i) {
-    MCCFIInstruction Inst(Moves[i].getLabel(), Moves[i].getDestination(),
-                          Moves[i].getSource());
+    MCSymbol *Label = Moves[i].getLabel();
+    const MachineLocation &Dst =
+      TranslateMachineLocation(asmInfo, Moves[i].getDestination());
+    const MachineLocation &Src =
+      TranslateMachineLocation(asmInfo, Moves[i].getSource());
+    MCCFIInstruction Inst(Label, Dst, Src);
     Instructions.push_back(Inst);
   }
 
-  EmitCFIInstructions(streamer, Instructions, NULL, true);
+  EmitCFIInstructions(streamer, Instructions, NULL);
 
   // Padding
   streamer.EmitValueToAlignment(4);
@@ -694,7 +705,7 @@ static MCSymbol *EmitFDE(MCStreamer &streamer,
   streamer.EmitLabel(augmentationEnd);
   // Call Frame Instructions
 
-  EmitCFIInstructions(streamer, frame.Instructions, frame.Begin, true);
+  EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
 
   // Padding
   streamer.EmitValueToAlignment(4);
index 76c309e..d8a166c 100644 (file)
@@ -244,6 +244,8 @@ public:
                                                               ".cfi_startproc");
     AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
                                                                 ".cfi_endproc");
+    AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
+                                                         ".cfi_def_cfa");
     AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
                                                          ".cfi_def_cfa_offset");
     AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
@@ -278,6 +280,7 @@ public:
   bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
   bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
   bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
+  bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
   bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
   bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
   bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
@@ -2172,6 +2175,25 @@ bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) {
   return getStreamer().EmitCFIEndProc();
 }
 
+/// ParseDirectiveCFIDefCfa
+/// ::= .cfi_def_cfa register,  offset
+bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
+                                               SMLoc DirectiveLoc) {
+  int64_t Register = 0;
+  if (getParser().ParseAbsoluteExpression(Register))
+    return true;
+
+  if (getLexer().isNot(AsmToken::Comma))
+    return TokError("unexpected token in directive");
+  Lex();
+
+  int64_t Offset = 0;
+  if (getParser().ParseAbsoluteExpression(Offset))
+    return true;
+
+  return getStreamer().EmitCFIDefCfa(Register, Offset);
+}
+
 /// ParseDirectiveCFIDefCfaOffset
 /// ::= .cfi_def_cfa_offset offset
 bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef,
index 4d7d486..c5dc1c7 100644 (file)
@@ -172,6 +172,18 @@ bool MCStreamer::EmitCFIEndProc() {
   return false;
 }
 
+bool MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
+  EnsureValidFrame();
+  MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
+  MCSymbol *Label = getContext().CreateTempSymbol();
+  EmitLabel(Label);
+  MachineLocation Dest(MachineLocation::VirtualFP);
+  MachineLocation Source(Register, -Offset);
+  MCCFIInstruction Instruction(Label, Dest, Source);
+  CurFrame->Instructions.push_back(Instruction);
+  return false;
+}
+
 bool MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
   EnsureValidFrame();
   MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
diff --git a/test/MC/ELF/cfi-def-cfa.s b/test/MC/ELF/cfi-def-cfa.s
new file mode 100644 (file)
index 0000000..1ad427b
--- /dev/null
@@ -0,0 +1,42 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump  --dump-section-data | FileCheck %s
+
+f:
+       .cfi_startproc
+        nop
+       .cfi_def_cfa 7, 8
+        nop
+       .cfi_endproc
+
+// CHECK:      (('sh_name', 0x00000012) # '.eh_frame'
+// CHECK-NEXT:  ('sh_type', 0x00000001)
+// CHECK-NEXT:  ('sh_flags', 0x00000002)
+// CHECK-NEXT:  ('sh_addr', 0x00000000)
+// CHECK-NEXT:  ('sh_offset', 0x00000048)
+// CHECK-NEXT:  ('sh_size', 0x00000030)
+// 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 14000000 1c000000 00000000 02000000 00410c07 08000000')
+// CHECK-NEXT: ),
+
+
+// CHECK:      (('sh_name', 0x00000036) # '.rela.eh_frame'
+// CHECK-NEXT:  ('sh_type', 0x00000004)
+// CHECK-NEXT:  ('sh_flags', 0x00000000)
+// CHECK-NEXT:  ('sh_addr', 0x00000000)
+// CHECK-NEXT:  ('sh_offset', 0x00000158)
+// CHECK-NEXT:  ('sh_size', 0x00000018)
+// CHECK-NEXT:  ('sh_link', 0x00000006)
+// CHECK-NEXT:  ('sh_info', 0x00000004)
+// CHECK-NEXT:  ('sh_addralign', 0x00000008)
+// CHECK-NEXT:  ('sh_entsize', 0x00000018)
+// CHECK-NEXT:  ('_relocations', [
+// CHECK-NEXT:   # Relocation 0x00000000
+// CHECK-NEXT:   (('r_offset', 0x00000020)
+// CHECK-NEXT:    ('r_sym', 0x00000002)
+// CHECK-NEXT:    ('r_type', 0x00000002)
+// CHECK-NEXT:    ('r_addend', 0x00000000)
+// CHECK-NEXT:   ),
+// CHECK-NEXT:  ])
+// CHECK-NEXT: ),