Skip to content

Commit 99fba3c

Browse files
committedNov 5, 2015
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
1 parent f6ecf96 commit 99fba3c

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed
 

‎llvm/lib/Target/X86/X86MCInstLower.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -1140,12 +1140,27 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
11401140
EmitAndCountInstruction(MCInstBuilder(X86::CALLpcrel32)
11411141
.addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
11421142

1143+
const X86FrameLowering* FrameLowering =
1144+
MF->getSubtarget<X86Subtarget>().getFrameLowering();
1145+
bool hasFP = FrameLowering->hasFP(*MF);
1146+
1147+
bool NeedsDwarfCFI = MMI->usePreciseUnwindInfo();
1148+
int stackGrowth = -RI->getSlotSize();
1149+
1150+
if (NeedsDwarfCFI && !hasFP) {
1151+
OutStreamer->EmitCFIAdjustCfaOffset(-stackGrowth);
1152+
}
1153+
11431154
// Emit the label.
11441155
OutStreamer->EmitLabel(PICBase);
11451156

11461157
// popl $reg
11471158
EmitAndCountInstruction(MCInstBuilder(X86::POP32r)
11481159
.addReg(MI->getOperand(0).getReg()));
1160+
1161+
if (NeedsDwarfCFI && !hasFP) {
1162+
OutStreamer->EmitCFIAdjustCfaOffset(stackGrowth);
1163+
}
11491164
return;
11501165
}
11511166

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: llc < %s -mtriple=i686-pc-linux -relocation-model=pic | FileCheck %s
2+
3+
target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
4+
target triple = "i686-pc-linux"
5+
6+
; Function Attrs: nounwind
7+
define void @test() #0 {
8+
entry:
9+
call void bitcast (void (...)* @bar to void ()*)(), !dbg !11
10+
ret void, !dbg !12
11+
}
12+
13+
declare void @bar(...) #1
14+
15+
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" }
16+
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" }
17+
18+
!llvm.dbg.cu = !{!0}
19+
!llvm.module.flags = !{!7, !8, !9}
20+
!llvm.ident = !{!10}
21+
22+
!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)
23+
!1 = !DIFile(filename: "test.c", directory: "movpc-test")
24+
!2 = !{}
25+
!3 = !{!4}
26+
!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)
27+
!5 = !DISubroutineType(types: !6)
28+
!6 = !{null}
29+
!7 = !{i32 2, !"Dwarf Version", i32 4}
30+
!8 = !{i32 2, !"Debug Info Version", i32 3}
31+
!9 = !{i32 1, !"PIC Level", i32 2}
32+
!10 = !{!"clang version 3.8.0 (http://llvm.org/git/clang.git 3490ab8630d5643f71f1f04e46984f05b27b8d67) (http://llvm.org/git/llvm.git d2643e2ff955ed234944fe3c6b4ffc1250085843)"}
33+
!11 = !DILocation(line: 4, column: 3, scope: !4)
34+
!12 = !DILocation(line: 5, column: 1, scope: !4)
35+
36+
; CHECK: calll .L0$pb
37+
; CHECK-NEXT: .Ltmp3:
38+
; CHECK-NEXT: .cfi_adjust_cfa_offset 4
39+
; CHECK-NEXT: .L0$pb:
40+
; CHECK-NEXT: popl
41+
; CHECK-NEXT: .Ltmp4:
42+
; CHECK-NEXT: .cfi_adjust_cfa_offset -4

0 commit comments

Comments
 (0)
Please sign in to comment.