Skip to content

Commit ae83640

Browse files
committed
[SOL] Error when we overwrite data on the stack (llvm#106)
1 parent cf12f53 commit ae83640

File tree

4 files changed

+81
-20
lines changed

4 files changed

+81
-20
lines changed

llvm/lib/Target/SBF/SBFISelLowering.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -625,37 +625,39 @@ SDValue SBFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
625625
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
626626
SDValue DstAddr;
627627
MachinePointerInfo DstInfo;
628+
int FrameIndex;
629+
int64_t Offset;
628630
if (Subtarget->getHasDynamicFrames()) {
629631
// In the new call convention, arguments are stored in the callee frame
630632
// The positive offset signals that the variable does not occupy space
631633
// in the caller frame.
632-
int64_t Offset = static_cast<int64_t>(VA.getLocMemOffset() +
633-
PtrVT.getFixedSizeInBits() / 8);
634+
Offset = static_cast<int64_t>(VA.getLocMemOffset() +
635+
PtrVT.getFixedSizeInBits() / 8);
634636
if (!Subtarget->getEnableNewCallConvention())
635637
// In the old call convention, we place argument at the start of the
636638
// frame in a fixed stack offset.
637639
Offset = -Offset;
638640

639-
int FrameIndex = MF.getFrameInfo().CreateFixedObject(
641+
FrameIndex = MF.getFrameInfo().CreateFixedObject(
640642
VA.getLocVT().getFixedSizeInBits() / 8, Offset, false);
641-
SBFFuncInfo->storeFrameIndexArgument(FrameIndex);
642-
DstAddr = DAG.getFrameIndex(FrameIndex, PtrVT);
643-
DstInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex, Offset);
644643
} else {
645-
SDValue Const =
646-
DAG.getConstant(SBFRegisterInfo::FrameLength - VA.getLocMemOffset(),
647-
CLI.DL, MVT::i64);
648-
DstAddr = DAG.getNode(ISD::SUB, CLI.DL, PtrVT, FramePtr, Const);
649-
DstInfo = MachinePointerInfo();
644+
Offset = static_cast<int64_t>(VA.getLocMemOffset());
645+
FrameIndex = MF.getFrameInfo().CreateFixedObject(
646+
VA.getLocVT().getFixedSizeInBits() / 8, Offset, false);
650647
}
651648

649+
SBFFuncInfo->storeFrameIndexArgument(FrameIndex);
650+
DstAddr = DAG.getFrameIndex(FrameIndex, PtrVT);
651+
DstInfo = MachinePointerInfo::getFixedStack(MF, FrameIndex, Offset);
652652
Chain = DAG.getStore(Chain, CLI.DL, Arg, DstAddr, DstInfo);
653653
}
654654

655-
// Pass the current stack frame pointer via SBF::R5, gluing the
656-
// instruction to instructions passing the first 4 arguments in
657-
// registers below.
658-
Chain = DAG.getCopyToReg(Chain, CLI.DL, SBF::R5, FramePtr, InGlue);
655+
if (!Subtarget->getEnableNewCallConvention())
656+
// Pass the current stack frame pointer via SBF::R5, gluing the
657+
// instruction to instructions passing the first 4 arguments in
658+
// registers below.
659+
Chain = DAG.getCopyToReg(Chain, CLI.DL, SBF::R5, FramePtr, InGlue);
660+
659661
InGlue = Chain.getValue(1);
660662
}
661663

llvm/lib/Target/SBF/SBFRegisterInfo.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL)
4747
{
4848
static Function *OldMF = nullptr;
4949
int MaxOffset = -1 * SBFRegisterInfo::FrameLength;
50-
if (Offset <= MaxOffset) {
50+
if (Offset < MaxOffset) {
5151

5252
if (&(MF.getFunction()) == OldMF) {
5353
return;
@@ -156,8 +156,21 @@ int SBFRegisterInfo::resolveInternalFrameIndex(
156156
const MachineFrameInfo &MFI = MF.getFrameInfo();
157157
const SBFFunctionInfo *SBFFuncInfo = MF.getInfo<SBFFunctionInfo>();
158158
int Offset = MFI.getObjectOffset(FI);
159-
if (MF.getSubtarget<SBFSubtarget>().getEnableNewCallConvention() &&
159+
160+
if (!MF.getSubtarget<SBFSubtarget>().getHasDynamicFrames() &&
160161
SBFFuncInfo->containsFrameIndex(FI)) {
162+
Offset = SBFRegisterInfo::FrameLength - Offset;
163+
if (static_cast<uint64_t>(Offset) < MFI.getStackSize()) {
164+
dbgs() << "Error: A function call in method "
165+
<< MF.getFunction().getName()
166+
<< " overwrites values in the frame. Please, decrease stack usage "
167+
<< "or remove parameters from the call.\n\n";
168+
report_fatal_error(
169+
"The function call may cause undefined behavior during execution.");
170+
}
171+
Offset = -Offset;
172+
} else if (MF.getSubtarget<SBFSubtarget>().getEnableNewCallConvention() &&
173+
SBFFuncInfo->containsFrameIndex(FI)) {
161174
uint64_t StackSize = MFI.getStackSize();
162175
Offset = -static_cast<int>(StackSize) - Offset;
163176
} else if (Imm.has_value()) {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; RUN: not --crash llc < %s -march=sbf 2>&1 | FileCheck %s
2+
3+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
4+
define i32 @func(i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3, i32 noundef %4, i32 noundef %5) #0 {
5+
ret i32 %2
6+
}
7+
8+
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
9+
define i32 @func1(i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3) #0 {
10+
%5 = alloca i32, align 4
11+
%6 = alloca i32, align 4
12+
%7 = alloca i32, align 4
13+
%8 = alloca i32, align 4
14+
%9 = alloca [4070 x i8], align 1
15+
store i32 %0, ptr %5, align 4
16+
store i32 %1, ptr %6, align 4
17+
store i32 %2, ptr %7, align 4
18+
store i32 %3, ptr %8, align 4
19+
%10 = load i32, ptr %5, align 4
20+
%11 = load i32, ptr %6, align 4
21+
%12 = load i32, ptr %7, align 4
22+
%13 = load i32, ptr %8, align 4
23+
%14 = getelementptr inbounds [4070 x i8], ptr %9, i64 0, i64 5
24+
%15 = load i8, ptr %14, align 1
25+
%16 = sext i8 %15 to i32
26+
%17 = getelementptr inbounds [4070 x i8], ptr %9, i64 0, i64 9
27+
%18 = load i8, ptr %17, align 1
28+
%19 = sext i8 %18 to i32
29+
%20 = call i32 @func(i32 noundef %10, i32 noundef %11, i32 noundef %12, i32 noundef %13, i32 noundef %16, i32 noundef %19)
30+
ret i32 %20
31+
32+
; CHECK: A function call in method func1 overwrites values in the frame.
33+
; CHECK: Please, decrease stack usage or remove parameters from the call.
34+
; CHECK: The function call may cause undefined behavior during execution.
35+
}
36+
37+
38+
attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz" }
39+
40+
!llvm.module.flags = !{!0, !1, !2, !3, !4}
41+
42+
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 14, i32 4]}
43+
!1 = !{i32 1, !"wchar_size", i32 4}
44+
!2 = !{i32 8, !"PIC Level", i32 2}
45+
!3 = !{i32 7, !"uwtable", i32 1}
46+
!4 = !{i32 7, !"frame-pointer", i32 1}

llvm/test/CodeGen/SBF/warn-stack.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
2424
; CHECK: Error: warn_stack.c
2525
; CHECK: please minimize large stack variables
2626
define void @warn() local_unnamed_addr #0 !dbg !20 {
27-
%1 = alloca [512 x i8], align 1
28-
%2 = getelementptr inbounds [512 x i8], [512 x i8]* %1, i64 0, i64 0, !dbg !26
27+
%1 = alloca [4124 x i8], align 1
28+
%2 = getelementptr inbounds [4124 x i8], [4124 x i8]* %1, i64 0, i64 0, !dbg !26
2929
call void @llvm.lifetime.start.p0i8(i64 512, i8* nonnull %2) #4, !dbg !26
30-
tail call void @llvm.dbg.declare(metadata [512 x i8]* %1, metadata !22, metadata !16), !dbg !27
30+
tail call void @llvm.dbg.declare(metadata [4124 x i8]* %1, metadata !22, metadata !16), !dbg !27
3131
call void @doit(i8* nonnull %2) #4, !dbg !28
3232
call void @llvm.lifetime.end.p0i8(i64 512, i8* nonnull %2) #4, !dbg !29
3333
ret void, !dbg !29

0 commit comments

Comments
 (0)