Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit c55ae3f

Browse files
committed
Fix .cfi_restore with register numbers > 64
Summary: DW_CFA_restore can only encode register numbers up to 64 (6 bits unsigned int). For regsiter numbers > 64 we have to use DW_CFA_restore_extended instead which uses a ULEB128 value. I discovered this problem in the out-of-tree CHERI target since we use DWARF register number 89 for our return capability register. Reviewers: probinson, dblaikie, aprantl, espindola Reviewed By: dblaikie Subscribers: JohnReagan, emaste, JDevlieghere, llvm-commits Differential Revision: https://reviews.llvm.org/D54420 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@346751 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 71ee93d commit c55ae3f

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

lib/MC/MCDwarf.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,12 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) {
14181418
unsigned Reg = Instr.getRegister();
14191419
if (!IsEH)
14201420
Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg);
1421-
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
1421+
if (Reg < 64) {
1422+
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
1423+
} else {
1424+
Streamer.EmitIntValue(dwarf::DW_CFA_restore_extended, 1);
1425+
Streamer.EmitULEB128IntValue(Reg);
1426+
}
14221427
return;
14231428
}
14241429
case MCCFIInstruction::OpGnuArgsSize:

test/MC/ELF/cfi-restore-extended.s

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-dwarfdump -debug-frame - | FileCheck %s
2+
3+
// Check that register numbers greater than 63 can be used in .cfi_restore directives
4+
f:
5+
.cfi_startproc
6+
nop
7+
// CHECK: DW_CFA_advance_loc: 1
8+
.cfi_restore %rbp
9+
// CHECK-NEXT: DW_CFA_restore: reg6
10+
nop
11+
// CHECK-NEXT: DW_CFA_advance_loc: 1
12+
.cfi_restore 89
13+
// CHECK-NEXT: DW_CFA_restore_extended: reg89
14+
// CHECK-NEXT: DW_CFA_nop:
15+
nop
16+
.cfi_endproc
17+

0 commit comments

Comments
 (0)