Skip to content

Commit 4608868

Browse files
committedJun 22, 2019
AArch64: Prefer FP-relative debug locations in HWASANified functions.
To help produce better diagnostics for stack use-after-return, we'd like to be able to determine the addresses of each HWASANified function's local variables given a small amount of information recorded on entry to the function. Currently we require all HWASANified functions to use frame pointers and record (PC, FP) on function entry. This works better than recording SP because FP cannot change during the function, unlike SP which can change e.g. due to dynamic alloca. However, most variables currently end up using SP-relative locations in their debug info. This prevents us from recomputing the address of most variables because the distance between SP and FP isn't recorded in the debug info. To address this, make the AArch64 backend prefer FP-relative debug locations when producing debug info for HWASANified functions. Differential Revision: https://reviews.llvm.org/D63300 llvm-svn: 364117
1 parent 21f0f71 commit 4608868

File tree

4 files changed

+59
-11
lines changed

4 files changed

+59
-11
lines changed
 

‎llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,7 +1497,11 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
14971497
int AArch64FrameLowering::getFrameIndexReference(const MachineFunction &MF,
14981498
int FI,
14991499
unsigned &FrameReg) const {
1500-
return resolveFrameIndexReference(MF, FI, FrameReg);
1500+
return resolveFrameIndexReference(
1501+
MF, FI, FrameReg,
1502+
/*PreferFP=*/
1503+
MF.getFunction().hasFnAttribute(Attribute::SanitizeHWAddress),
1504+
/*ForSimm=*/false);
15011505
}
15021506

15031507
int AArch64FrameLowering::getNonLocalFrameIndexReference(
@@ -1530,7 +1534,8 @@ int AArch64FrameLowering::getSEHFrameIndexOffset(const MachineFunction &MF,
15301534

15311535
int AArch64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF,
15321536
int FI, unsigned &FrameReg,
1533-
bool PreferFP) const {
1537+
bool PreferFP,
1538+
bool ForSimm) const {
15341539
const auto &MFI = MF.getFrameInfo();
15351540
const auto *RegInfo = static_cast<const AArch64RegisterInfo *>(
15361541
MF.getSubtarget().getRegisterInfo());
@@ -1561,11 +1566,11 @@ int AArch64FrameLowering::resolveFrameIndexReference(const MachineFunction &MF,
15611566
assert(hasFP(MF) && "Re-aligned stack must have frame pointer");
15621567
UseFP = true;
15631568
} else if (hasFP(MF) && !RegInfo->needsStackRealignment(MF)) {
1564-
// If the FPOffset is negative, we have to keep in mind that the
1565-
// available offset range for negative offsets is smaller than for
1566-
// positive ones. If an offset is
1567-
// available via the FP and the SP, use whichever is closest.
1568-
bool FPOffsetFits = FPOffset >= -256;
1569+
// If the FPOffset is negative and we're producing a signed immediate, we
1570+
// have to keep in mind that the available offset range for negative
1571+
// offsets is smaller than for positive ones. If an offset is available
1572+
// via the FP and the SP, use whichever is closest.
1573+
bool FPOffsetFits = !ForSimm || FPOffset >= -256;
15691574
PreferFP |= Offset > -FPOffset;
15701575

15711576
if (MFI.hasVarSizedObjects()) {

‎llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class AArch64FrameLowering : public TargetFrameLowering {
4040
int getFrameIndexReference(const MachineFunction &MF, int FI,
4141
unsigned &FrameReg) const override;
4242
int resolveFrameIndexReference(const MachineFunction &MF, int FI,
43-
unsigned &FrameReg,
44-
bool PreferFP = false) const;
43+
unsigned &FrameReg, bool PreferFP,
44+
bool ForSimm) const;
4545
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
4646
MachineBasicBlock::iterator MI,
4747
const std::vector<CalleeSavedInfo> &CSI,

‎llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
453453
if (MI.isDebugValue() || MI.getOpcode() == TargetOpcode::STACKMAP ||
454454
MI.getOpcode() == TargetOpcode::PATCHPOINT) {
455455
Offset = TFI->resolveFrameIndexReference(MF, FrameIndex, FrameReg,
456-
/*PreferFP=*/true);
456+
/*PreferFP=*/true,
457+
/*ForSimm=*/false);
457458
Offset += MI.getOperand(FIOperandNum + 1).getImm();
458459
MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);
459460
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
@@ -468,7 +469,8 @@ void AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
468469
}
469470

470471
// Modify MI as necessary to handle as much of 'Offset' as possible
471-
Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
472+
Offset = TFI->resolveFrameIndexReference(
473+
MF, FrameIndex, FrameReg, /*PreferFP=*/false, /*ForSimm=*/true);
472474

473475
if (rewriteAArch64FrameIndex(MI, FIOperandNum, FrameReg, Offset, TII))
474476
return;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: llc -o - %s -filetype=obj -frame-pointer=all | llvm-dwarfdump - | FileCheck %s
2+
3+
target triple="aarch64--"
4+
5+
define void @f() sanitize_hwaddress !dbg !6 {
6+
entry:
7+
%x = call i8* @g(i32 0)
8+
%a = alloca [128 x i8]
9+
%b = alloca [128 x i8]
10+
; CHECK: DW_AT_location (DW_OP_fbreg
11+
call void @llvm.dbg.declare(metadata [128 x i8]* %a, metadata !12, metadata !DIExpression()), !dbg !14
12+
; CHECK: DW_AT_location (DW_OP_fbreg
13+
call void @llvm.dbg.declare(metadata [128 x i8]* %b, metadata !13, metadata !DIExpression()), !dbg !14
14+
ret void, !dbg !15
15+
}
16+
17+
declare i8* @g(i32)
18+
19+
declare void @llvm.dbg.declare(metadata, metadata, metadata)
20+
21+
!llvm.dbg.cu = !{!0}
22+
!llvm.module.flags = !{!3, !4}
23+
!llvm.ident = !{!5}
24+
25+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
26+
!1 = !DIFile(filename: "x.c", directory: "/")
27+
!2 = !{}
28+
!3 = !{i32 2, !"Dwarf Version", i32 4}
29+
!4 = !{i32 2, !"Debug Info Version", i32 3}
30+
!5 = !{!"clang"}
31+
!6 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !7, isLocal: false, isDefinition: true, scopeLine: 1, flags:
32+
DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2)
33+
!7 = !DISubroutineType(types: !8)
34+
!8 = !{null, !9}
35+
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
36+
!10 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !11)
37+
!11 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
38+
!12 = !DILocalVariable(name: "a", scope: !6, file: !1, line: 1, type: !9)
39+
!13 = !DILocalVariable(name: "b", scope: !6, file: !1, line: 1, type: !9)
40+
!14 = !DILocation(line: 1, column: 29, scope: !6)
41+
!15 = !DILocation(line: 1, column: 37, scope: !6)

0 commit comments

Comments
 (0)
Please sign in to comment.