summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Riss <friss@apple.com>2015-02-26 19:48:07 +0000
committerFrederic Riss <friss@apple.com>2015-02-26 19:48:07 +0000
commitadbb3f207fba14e40f737c968bb78c63dc12b65a (patch)
tree0886ae1516c2f68c7235b6679714174e2b9529c3
parent83f8824a7567a87208d9118c50e9c8c1ccc3a721 (diff)
downloadbcm5719-llvm-adbb3f207fba14e40f737c968bb78c63dc12b65a.tar.gz
bcm5719-llvm-adbb3f207fba14e40f737c968bb78c63dc12b65a.zip
[MC] Use the non-EH register mapping in the debug_frame section.
On 32bits x86 Darwin, the register mappings for the eh_frane and debug_frame sections are different. Thus the same CFI instructions should result in different registers in the object file. The problem isn't target specific though, but it requires that the mappings for EH register numbers be different from the standard Dwarf one. The patch looks a bit clumsy. LLVM uses the EH mapping as canonical for everything frame related. Thus we need to do a double conversion EH -> LLVM -> Non-EH, when emitting the debug_frame section. Fixes PR22363. Differential Revision: http://reviews.llvm.org/D7593 llvm-svn: 230670
-rw-r--r--llvm/lib/MC/MCDwarf.cpp24
-rw-r--r--llvm/test/MC/X86/i386-darwin-frame-register.ll38
2 files changed, 58 insertions, 4 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 5effb011826..5d969140379 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -1045,11 +1045,16 @@ static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) {
void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
const MCCFIInstruction &Instr) {
int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
+ auto *MRI = Streamer.getContext().getRegisterInfo();
switch (Instr.getOperation()) {
case MCCFIInstruction::OpRegister: {
unsigned Reg1 = Instr.getRegister();
unsigned Reg2 = Instr.getRegister2();
+ if (!IsEH) {
+ Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1, true), false);
+ Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2, true), false);
+ }
Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
Streamer.EmitULEB128IntValue(Reg1);
Streamer.EmitULEB128IntValue(Reg2);
@@ -1082,8 +1087,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
return;
}
case MCCFIInstruction::OpDefCfa: {
+ unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
- Streamer.EmitULEB128IntValue(Instr.getRegister());
+ Streamer.EmitULEB128IntValue(Reg);
CFAOffset = -Instr.getOffset();
Streamer.EmitULEB128IntValue(CFAOffset);
@@ -1091,8 +1099,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
}
case MCCFIInstruction::OpDefCfaRegister: {
+ unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
- Streamer.EmitULEB128IntValue(Instr.getRegister());
+ Streamer.EmitULEB128IntValue(Reg);
return;
}
@@ -1103,6 +1114,9 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
Instr.getOperation() == MCCFIInstruction::OpRelOffset;
unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
+
int Offset = Instr.getOffset();
if (IsRelative)
Offset -= CFAOffset;
@@ -1136,6 +1150,8 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
}
case MCCFIInstruction::OpRestore: {
unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
return;
}
@@ -1290,10 +1306,10 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
if (CIEVersion == 1) {
assert(MRI->getRARegister() <= 255 &&
"DWARF 2 encodes return_address_register in one byte");
- streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1);
+ streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1);
} else {
streamer.EmitULEB128IntValue(
- MRI->getDwarfRegNum(MRI->getRARegister(), true));
+ MRI->getDwarfRegNum(MRI->getRARegister(), IsEH));
}
// Augmentation Data Length (optional)
diff --git a/llvm/test/MC/X86/i386-darwin-frame-register.ll b/llvm/test/MC/X86/i386-darwin-frame-register.ll
new file mode 100644
index 00000000000..dd8c88de30f
--- /dev/null
+++ b/llvm/test/MC/X86/i386-darwin-frame-register.ll
@@ -0,0 +1,38 @@
+; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump -debug-dump=frames - | FileCheck %s
+
+; IR reduced from a dummy:
+; void foo() {}
+
+; x86 Darwin uses different register mappings for eh_frame and debug_frame
+; sections. Check that the right mapping is used in debug_frame.
+; In the debug_frame mapping, regsiter 4 is ESP, thus the below tests that
+; the CFA is ESP+4 upon function entry.
+
+; CHECK: .debug_frame contents:
+; CHECK: ffffffff CIE
+; CHECK-NOT: {{CIE|FDE}}
+; CHECK: DW_CFA_def_cfa: reg4 +4
+
+; ModuleID = 'foo.c'
+target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"
+target triple = "i386-apple-macosx10.10.0"
+
+; Function Attrs: nounwind ssp
+define void @foo() #0 {
+entry:
+ ret void
+}
+
+attributes #0 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = !{!"0x11\0012\00clang version 3.7.0 (trunk 230514) (llvm/trunk 230518)\000\00\000\00\001", !1, !2, !2, !2, !2, !2} ; [ DW_TAG_compile_unit ] [/tmp/foo.c] [DW_LANG_C99]
+!1 = !{!"foo.c", !"/tmp"}
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 2}
+!4 = !{i32 2, !"Debug Info Version", i32 2}
+!5 = !{i32 1, !"PIC Level", i32 2}
+!6 = !{!"clang version 3.7.0 (trunk 230514) (llvm/trunk 230518)"}
OpenPOWER on IntegriCloud