paulkirth created this revision. Herald added a subscriber: hiraditya. paulkirth updated this revision to Diff 409705. paulkirth added a comment. paulkirth updated this revision to Diff 409797. tstellar added a subscriber: serge-sans-paille. paulkirth edited the summary of this revision. paulkirth added reviewers: phosek, mcgrathr, tstellar. Herald added a project: All. paulkirth published this revision for review. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits.
Fix ARM test breakage paulkirth added a comment. Actually fix the ARM test Current stack size diagnostics ignore the size of the unsafe stack. This patch attaches the size of the static portion of the unsafe stack to the function as metadata, which can be used by the backend to emit diagnostics regarding stack usage. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D119996 Files: clang/test/Frontend/stack-usage-safestack.c llvm/include/llvm/CodeGen/MachineFrameInfo.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/MachineFunction.cpp llvm/lib/CodeGen/PrologEpilogInserter.cpp llvm/lib/CodeGen/SafeStack.cpp llvm/test/Transforms/SafeStack/ARM/debug.ll
Index: llvm/test/Transforms/SafeStack/ARM/debug.ll =================================================================== --- llvm/test/Transforms/SafeStack/ARM/debug.ll +++ llvm/test/Transforms/SafeStack/ARM/debug.ll @@ -10,8 +10,8 @@ ; void Capture(char*x); ; void f() { char c[16]; Capture(c); } -; CHECK: !35 = !DILocation(line: 3, column: 11, scope: !17, inlinedAt: !36) -; CHECK: !36 = distinct !DILocation(line: 6, scope: !27) +; CHECK: !36 = !DILocation(line: 3, column: 11, scope: !17, inlinedAt: !37) +; CHECK: !37 = distinct !DILocation(line: 6, scope: !27) @addr = common local_unnamed_addr global i8*** null, align 4, !dbg !0 Index: llvm/lib/CodeGen/SafeStack.cpp =================================================================== --- llvm/lib/CodeGen/SafeStack.cpp +++ llvm/lib/CodeGen/SafeStack.cpp @@ -49,6 +49,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" @@ -645,6 +646,13 @@ // FIXME: no need to update BasePointer in leaf functions. unsigned FrameSize = alignTo(SSL.getFrameSize(), StackAlignment); + MDBuilder MDB(F.getContext()); + SmallVector<Metadata *, 2> Data; + Data.push_back(MDB.createString("unsafe-stack-size")); + Data.push_back(MDB.createConstant(ConstantInt::get(Int32Ty, FrameSize))); + MDNode *MD = MDTuple::get(F.getContext(), Data); + F.setMetadata(LLVMContext::MD_annotation, MD); + // Update shadow stack pointer in the function epilogue. IRB.SetInsertPoint(BasePointer->getNextNode()); Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp =================================================================== --- llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -285,6 +285,9 @@ assert(!Failed && "Invalid warn-stack-size fn attr value"); (void)Failed; } + if (MF.getFunction().hasFnAttribute(Attribute::SafeStack)) { + StackSize += MFI.getUnsafeStackSize(); + } if (StackSize > Threshold) { DiagnosticInfoStackSize DiagStackSize(F, StackSize, Threshold, DS_Warning); F.getContext().diagnose(DiagStackSize); Index: llvm/lib/CodeGen/MachineFunction.cpp =================================================================== --- llvm/lib/CodeGen/MachineFunction.cpp +++ llvm/lib/CodeGen/MachineFunction.cpp @@ -109,6 +109,27 @@ llvm_unreachable("Invalid machine function property"); } +void setUnsafeStackSize(const Function &F, MachineFrameInfo &FrameInfo) { + if (!F.hasFnAttribute(Attribute::SafeStack)) + return; + + auto *Existing = + dyn_cast_or_null<MDTuple>(F.getMetadata(LLVMContext::MD_annotation)); + + if (!Existing || Existing->getNumOperands() != 2) + return; + + auto *MetadataName = "unsafe-stack-size"; + if (auto &N = Existing->getOperand(0)) { + if (cast<MDString>(N.get())->getString() == MetadataName) { + if (auto &Op = Existing->getOperand(1)) { + auto Val = mdconst::extract<ConstantInt>(Op)->getZExtValue(); + FrameInfo.setUnsafeStackSize(Val); + } + } + } +} + // Pin the vtable to this file. void MachineFunction::Delegate::anchor() {} @@ -177,6 +198,8 @@ /*ForcedRealign=*/CanRealignSP && F.hasFnAttribute(Attribute::StackAlignment)); + setUnsafeStackSize(F, *FrameInfo); + if (F.hasFnAttribute(Attribute::StackAlignment)) FrameInfo->ensureMaxAlignment(*F.getFnStackAlign()); Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1208,7 +1208,8 @@ return; const MachineFrameInfo &FrameInfo = MF.getFrameInfo(); - uint64_t StackSize = FrameInfo.getStackSize(); + uint64_t StackSize = + FrameInfo.getStackSize() + FrameInfo.getUnsafeStackSize(); if (StackUsageStream == nullptr) { std::error_code EC; Index: llvm/include/llvm/CodeGen/MachineFrameInfo.h =================================================================== --- llvm/include/llvm/CodeGen/MachineFrameInfo.h +++ llvm/include/llvm/CodeGen/MachineFrameInfo.h @@ -335,6 +335,9 @@ /// Not null, if shrink-wrapping found a better place for the epilogue. MachineBasicBlock *Restore = nullptr; + /// Size of the UnsafeStack Frame + uint64_t UnsafeStackSize = 0; + public: explicit MachineFrameInfo(unsigned StackAlignment, bool StackRealignable, bool ForcedRealign) @@ -773,6 +776,9 @@ MachineBasicBlock *getRestorePoint() const { return Restore; } void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; } + uint64_t getUnsafeStackSize() const { return UnsafeStackSize; } + void setUnsafeStackSize(uint64_t Size) { UnsafeStackSize = Size; } + /// Return a set of physical registers that are pristine. /// /// Pristine registers hold a value that is useless to the current function, Index: clang/test/Frontend/stack-usage-safestack.c =================================================================== --- /dev/null +++ clang/test/Frontend/stack-usage-safestack.c @@ -0,0 +1,20 @@ +/// Check that stack frame size warnings behave the same when safe stack is enabled + +// RUN: %clang_cc1 %s -fwarn-stack-size=48 -S -o - -triple=i386-apple-darwin 2>&1 | FileCheck --check-prefix=REGULAR %s +// RUN: %clang_cc1 %s -fwarn-stack-size=1060 -S -o - -triple=i386-apple-darwin 2>&1 | FileCheck --check-prefix=IGNORE %s + +// RUN: %clang_cc1 %s -fsanitize=safe-stack -fwarn-stack-size=48 -S -o - -triple=i386-apple-darwin 2>&1 | FileCheck --check-prefix=SAFESTACK %s +// RUN: %clang_cc1 %s -fsanitize=safe-stack -fwarn-stack-size=1060 -S -o - -triple=i386-apple-darwin 2>&1 | FileCheck --check-prefix=IGNORE %s + +extern void init(int *buf, int size); +extern int use_buf(int *buf, int size); + +// REGULAR: warning: stack frame size ([[#]]) exceeds limit ([[#]]) in 'stackSizeWarning' +// SAFESTACK: warning: stack frame size ([[#]]) exceeds limit ([[#]]) in 'stackSizeWarning' +// IGNORE-NOT: stack frame size ([[#]]) exceeds limit ([[#]]) in 'stackSizeWarning' +void stackSizeWarning() { + int buf[256]; + init(buf, sizeof(buf)); + if (buf[0] < 42) + use_buf(buf, sizeof(buf)); +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits