summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorPetar Jovanovic <petar.jovanovic@imgtec.com>2015-11-05 17:19:59 +0000
committerPetar Jovanovic <petar.jovanovic@imgtec.com>2015-11-05 17:19:59 +0000
commit99fba3c1416447737bdc76c751ed8775d4abb106 (patch)
treea823454b443898d4b470b01fd0b7db2e4cf05c62 /llvm
parentf6ecf963902978e78d07e1588eeef20dc62dff05 (diff)
downloadbcm5719-llvm-99fba3c1416447737bdc76c751ed8775d4abb106.tar.gz
bcm5719-llvm-99fba3c1416447737bdc76c751ed8775d4abb106.zip
Add cfi instr for CFA calculation when movpc is expanded to call and pop
This fixes the issue of wrong CFA calculation in the following case: 0x08048400 <+0>: push %ebx 0x08048401 <+1>: sub $0x8,%esp 0x08048404 <+4>: **call 0x8048409 <test+9>** 0x08048409 <+9>: **pop %eax** 0x0804840a <+10>: add $0x1bf7,%eax 0x08048410 <+16>: mov %eax,%ebx 0x08048412 <+18>: call 0x80483f0 <bar> 0x08048417 <+23>: add $0x8,%esp 0x0804841a <+26>: pop %ebx 0x0804841b <+27>: ret The highlighted instructions are a product of movpc instruction. The call instruction changes the stack pointer, and pop instruction restores its value. However, the rule for computing CFA is not updated and is wrong on the pop instruction. So, e.g. backtrace in gdb does not work when on the pop instruction. This adds cfi instructions for both call and pop instructions. cfi_adjust_cfa_offset** instruction is used with the appropriate offset for setting the rules to calculate CFA correctly. Patch by Violeta Vukobrat. Differential Revision: http://reviews.llvm.org/D14021 llvm-svn: 252176
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86MCInstLower.cpp15
-rw-r--r--llvm/test/CodeGen/X86/movpc32-check.ll42
2 files changed, 57 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
index a59ddb7e995..6887f2e4c04 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -1140,12 +1140,27 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
EmitAndCountInstruction(MCInstBuilder(X86::CALLpcrel32)
.addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
+ const X86FrameLowering* FrameLowering =
+ MF->getSubtarget<X86Subtarget>().getFrameLowering();
+ bool hasFP = FrameLowering->hasFP(*MF);
+
+ bool NeedsDwarfCFI = MMI->usePreciseUnwindInfo();
+ int stackGrowth = -RI->getSlotSize();
+
+ if (NeedsDwarfCFI && !hasFP) {
+ OutStreamer->EmitCFIAdjustCfaOffset(-stackGrowth);
+ }
+
// Emit the label.
OutStreamer->EmitLabel(PICBase);
// popl $reg
EmitAndCountInstruction(MCInstBuilder(X86::POP32r)
.addReg(MI->getOperand(0).getReg()));
+
+ if (NeedsDwarfCFI && !hasFP) {
+ OutStreamer->EmitCFIAdjustCfaOffset(stackGrowth);
+ }
return;
}
diff --git a/llvm/test/CodeGen/X86/movpc32-check.ll b/llvm/test/CodeGen/X86/movpc32-check.ll
new file mode 100644
index 00000000000..0835a1bb3c6
--- /dev/null
+++ b/llvm/test/CodeGen/X86/movpc32-check.ll
@@ -0,0 +1,42 @@
+; RUN: llc < %s -mtriple=i686-pc-linux -relocation-model=pic | FileCheck %s
+
+target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i686-pc-linux"
+
+; Function Attrs: nounwind
+define void @test() #0 {
+entry:
+ call void bitcast (void (...)* @bar to void ()*)(), !dbg !11
+ ret void, !dbg !12
+}
+
+declare void @bar(...) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="i686" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="i686" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (http://llvm.org/git/clang.git 3490ab8630d5643f71f1f04e46984f05b27b8d67) (http://llvm.org/git/llvm.git d2643e2ff955ed234944fe3c6b4ffc1250085843)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
+!1 = !DIFile(filename: "test.c", directory: "movpc-test")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: false, function: void ()* @test, variables: !2)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null}
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"PIC Level", i32 2}
+!10 = !{!"clang version 3.8.0 (http://llvm.org/git/clang.git 3490ab8630d5643f71f1f04e46984f05b27b8d67) (http://llvm.org/git/llvm.git d2643e2ff955ed234944fe3c6b4ffc1250085843)"}
+!11 = !DILocation(line: 4, column: 3, scope: !4)
+!12 = !DILocation(line: 5, column: 1, scope: !4)
+
+; CHECK: calll .L0$pb
+; CHECK-NEXT: .Ltmp3:
+; CHECK-NEXT: .cfi_adjust_cfa_offset 4
+; CHECK-NEXT: .L0$pb:
+; CHECK-NEXT: popl
+; CHECK-NEXT: .Ltmp4:
+; CHECK-NEXT: .cfi_adjust_cfa_offset -4
OpenPOWER on IntegriCloud