From: Petar Jovanovic Date: Thu, 5 Nov 2015 17:19:59 +0000 (+0000) Subject: Add cfi instr for CFA calculation when movpc is expanded to call and pop X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=00e29ad54f83e459f1f1cc5d0c2c0e77b7a84c3e;p=oota-llvm.git 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 ** 0x08048409 <+9>: **pop %eax** 0x0804840a <+10>: add $0x1bf7,%eax 0x08048410 <+16>: mov %eax,%ebx 0x08048412 <+18>: call 0x80483f0 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252176 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86MCInstLower.cpp b/lib/Target/X86/X86MCInstLower.cpp index a59ddb7e995..6887f2e4c04 100644 --- a/lib/Target/X86/X86MCInstLower.cpp +++ b/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().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/test/CodeGen/X86/movpc32-check.ll b/test/CodeGen/X86/movpc32-check.ll new file mode 100644 index 00000000000..0835a1bb3c6 --- /dev/null +++ b/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