forked from OSchip/llvm-project
Revert "Revert "[clang, llvm] Add __declspec(safebuffers), support it in CodeView""
This reverts commit cd20a18286
and adds a
"let Heading" to NoStackProtectorDocs.
This commit is contained in:
parent
e0bc76eb23
commit
8a868d8859
|
@ -2080,12 +2080,19 @@ def NotTailCalled : InheritableAttr {
|
|||
def : MutualExclusions<[AlwaysInline, NotTailCalled]>;
|
||||
|
||||
def NoStackProtector : InheritableAttr {
|
||||
let Spellings = [Clang<"no_stack_protector">];
|
||||
let Spellings = [Clang<"no_stack_protector">, Declspec<"safebuffers">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [NoStackProtectorDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def StrictGuardStackCheck : InheritableAttr {
|
||||
let Spellings = [Declspec<"strict_gs_check">];
|
||||
let Subjects = SubjectList<[Function]>;
|
||||
let Documentation = [StrictGuardStackCheckDocs];
|
||||
let SimpleHandler = 1;
|
||||
}
|
||||
|
||||
def NoThrow : InheritableAttr {
|
||||
let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
|
||||
let Subjects = SubjectList<[FunctionLike]>;
|
||||
|
|
|
@ -4452,8 +4452,10 @@ spelled "XYZ" in the `OpenMP 5.1 Standard`_).
|
|||
|
||||
def NoStackProtectorDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Heading = "no_stack_protector, safebuffers";
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((no_stack_protector))`` attribute which disables
|
||||
Clang supports the ``__attribute__((no_stack_protector))`` and Microsoft style
|
||||
``__declspec(safebuffers)`` attribute which disables
|
||||
the stack protector on the specified function. This attribute is useful for
|
||||
selectively disabling the stack protector on some functions when building with
|
||||
``-fstack-protector`` compiler option.
|
||||
|
@ -4472,6 +4474,27 @@ option.
|
|||
}];
|
||||
}
|
||||
|
||||
def StrictGuardStackCheckDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the Microsoft style ``__declspec((strict_gs_check))`` attribute
|
||||
which upgrades the stack protector check from ``-fstack-protector`` to
|
||||
``-fstack-protector-strong``.
|
||||
|
||||
For example, it upgrades the stack protector for the function ``foo`` to
|
||||
``-fstack-protector-strong`` but function ``bar`` will still be built with the
|
||||
stack protector with the ``-fstack-protector`` option.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
__declspec((strict_gs_check))
|
||||
int foo(int x); // stack protection will be upgraded for foo.
|
||||
|
||||
int bar(int y); // bar can be built with the standard stack protector checks.
|
||||
|
||||
}];
|
||||
}
|
||||
|
||||
def NotTailCalledDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
|
|
|
@ -1970,14 +1970,17 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
|
|||
if (!hasUnwindExceptions(LangOpts))
|
||||
B.addAttribute(llvm::Attribute::NoUnwind);
|
||||
|
||||
if (!D || !D->hasAttr<NoStackProtectorAttr>()) {
|
||||
if (LangOpts.getStackProtector() == LangOptions::SSPOn)
|
||||
B.addAttribute(llvm::Attribute::StackProtect);
|
||||
else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
|
||||
B.addAttribute(llvm::Attribute::StackProtectStrong);
|
||||
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
|
||||
B.addAttribute(llvm::Attribute::StackProtectReq);
|
||||
}
|
||||
if (D && D->hasAttr<NoStackProtectorAttr>())
|
||||
; // Do nothing.
|
||||
else if (D && D->hasAttr<StrictGuardStackCheckAttr>() &&
|
||||
LangOpts.getStackProtector() == LangOptions::SSPOn)
|
||||
B.addAttribute(llvm::Attribute::StackProtectStrong);
|
||||
else if (LangOpts.getStackProtector() == LangOptions::SSPOn)
|
||||
B.addAttribute(llvm::Attribute::StackProtect);
|
||||
else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
|
||||
B.addAttribute(llvm::Attribute::StackProtectStrong);
|
||||
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
|
||||
B.addAttribute(llvm::Attribute::StackProtectReq);
|
||||
|
||||
if (!D) {
|
||||
// If we don't have a declaration to control inlining, the function isn't
|
||||
|
|
|
@ -5,7 +5,7 @@ typedef int (__cdecl *tptr)(void);
|
|||
void (*__fastcall fastpfunc)(void);
|
||||
extern __declspec(dllimport) void __stdcall VarR4FromDec(void);
|
||||
__declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
|
||||
__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} */
|
||||
__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory);
|
||||
typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
|
||||
|
||||
void * __ptr64 PtrToPtr64(const void *p) {
|
||||
|
|
|
@ -772,6 +772,23 @@ enum CodeViewIdentifiers {
|
|||
DEBUG_HASHES_SECTION_MAGIC = 0x133C9C5
|
||||
};
|
||||
|
||||
// These flags show up in the @feat.00 symbol. They appear to be some kind of
|
||||
// compiler features bitfield read by link.exe.
|
||||
enum Feat00Flags : uint32_t {
|
||||
// Object is compatible with /safeseh.
|
||||
SafeSEH = 0x1,
|
||||
// Object was compiled with /GS.
|
||||
GuardStack = 0x100,
|
||||
// Object was compiled with /sdl.
|
||||
SDL = 0x200,
|
||||
// Object was compiled with /guard:cf.
|
||||
GuardCF = 0x800,
|
||||
// Object was compiled with /guard:ehcont.
|
||||
GuardEHCont = 0x4000,
|
||||
// Object was compiled with /kernel.
|
||||
Kernel = 0x40000000,
|
||||
};
|
||||
|
||||
inline bool isReservedSectionNumber(int32_t SectionNumber) {
|
||||
return SectionNumber <= 0;
|
||||
}
|
||||
|
|
|
@ -1498,8 +1498,16 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
|
|||
FPO |= FrameProcedureOptions::MarkedInline;
|
||||
if (GV.hasFnAttribute(Attribute::Naked))
|
||||
FPO |= FrameProcedureOptions::Naked;
|
||||
if (MFI.hasStackProtectorIndex())
|
||||
if (MFI.hasStackProtectorIndex()) {
|
||||
FPO |= FrameProcedureOptions::SecurityChecks;
|
||||
if (GV.hasFnAttribute(Attribute::StackProtectStrong) ||
|
||||
GV.hasFnAttribute(Attribute::StackProtectReq)) {
|
||||
FPO |= FrameProcedureOptions::StrictSecurityChecks;
|
||||
}
|
||||
} else if (!GV.hasStackProtectorFnAttr()) {
|
||||
// __declspec(safebuffers) disables stack guards.
|
||||
FPO |= FrameProcedureOptions::SafeBuffers;
|
||||
}
|
||||
FPO |= FrameProcedureOptions(uint32_t(CurFn->EncodedLocalFramePtrReg) << 14U);
|
||||
FPO |= FrameProcedureOptions(uint32_t(CurFn->EncodedParamFramePtrReg) << 16U);
|
||||
if (Asm->TM.getOptLevel() != CodeGenOpt::None &&
|
||||
|
|
|
@ -201,30 +201,32 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
|
|||
const Triple &TT = TM.getTargetTriple();
|
||||
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
// Emit an absolute @feat.00 symbol. This appears to be some kind of
|
||||
// compiler features bitfield read by link.exe.
|
||||
// Emit an absolute @feat.00 symbol
|
||||
MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
|
||||
OutStreamer->beginCOFFSymbolDef(S);
|
||||
OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
|
||||
OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
|
||||
OutStreamer->endCOFFSymbolDef();
|
||||
int64_t Feat00Flags = 0;
|
||||
int64_t Feat00Value = 0;
|
||||
|
||||
if (M.getModuleFlag("cfguard")) {
|
||||
Feat00Flags |= 0x800; // Object is CFG-aware.
|
||||
// Object is CFG-aware.
|
||||
Feat00Value |= COFF::Feat00Flags::GuardCF;
|
||||
}
|
||||
|
||||
if (M.getModuleFlag("ehcontguard")) {
|
||||
Feat00Flags |= 0x4000; // Object also has EHCont.
|
||||
// Object also has EHCont.
|
||||
Feat00Value |= COFF::Feat00Flags::GuardEHCont;
|
||||
}
|
||||
|
||||
if (M.getModuleFlag("ms-kernel")) {
|
||||
Feat00Flags |= 0x40000000; // Object is compiled with /kernel.
|
||||
// Object is compiled with /kernel.
|
||||
Feat00Value |= COFF::Feat00Flags::Kernel;
|
||||
}
|
||||
|
||||
OutStreamer->emitSymbolAttribute(S, MCSA_Global);
|
||||
OutStreamer->emitAssignment(
|
||||
S, MCConstantExpr::create(Feat00Flags, MMI->getContext()));
|
||||
S, MCConstantExpr::create(Feat00Value, MMI->getContext()));
|
||||
}
|
||||
|
||||
if (!TT.isOSBinFormatELF())
|
||||
|
|
|
@ -792,14 +792,13 @@ void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
|
|||
OutStreamer->switchSection(getObjFileLowering().getTextSection());
|
||||
|
||||
if (TT.isOSBinFormatCOFF()) {
|
||||
// Emit an absolute @feat.00 symbol. This appears to be some kind of
|
||||
// compiler features bitfield read by link.exe.
|
||||
// Emit an absolute @feat.00 symbol.
|
||||
MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
|
||||
OutStreamer->beginCOFFSymbolDef(S);
|
||||
OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
|
||||
OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
|
||||
OutStreamer->endCOFFSymbolDef();
|
||||
int64_t Feat00Flags = 0;
|
||||
int64_t Feat00Value = 0;
|
||||
|
||||
if (TT.getArch() == Triple::x86) {
|
||||
// According to the PE-COFF spec, the LSB of this value marks the object
|
||||
|
@ -807,24 +806,27 @@ void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
|
|||
// must be registered in .sxdata. Use of any unregistered handlers will
|
||||
// cause the process to terminate immediately. LLVM does not know how to
|
||||
// register any SEH handlers, so its object files should be safe.
|
||||
Feat00Flags |= 1;
|
||||
Feat00Value |= COFF::Feat00Flags::SafeSEH;
|
||||
}
|
||||
|
||||
if (M.getModuleFlag("cfguard")) {
|
||||
Feat00Flags |= 0x800; // Object is CFG-aware.
|
||||
// Object is CFG-aware.
|
||||
Feat00Value |= COFF::Feat00Flags::GuardCF;
|
||||
}
|
||||
|
||||
if (M.getModuleFlag("ehcontguard")) {
|
||||
Feat00Flags |= 0x4000; // Object also has EHCont.
|
||||
// Object also has EHCont.
|
||||
Feat00Value |= COFF::Feat00Flags::GuardEHCont;
|
||||
}
|
||||
|
||||
if (M.getModuleFlag("ms-kernel")) {
|
||||
Feat00Flags |= 0x40000000; // Object is compiled with /kernel.
|
||||
// Object is compiled with /kernel.
|
||||
Feat00Value |= COFF::Feat00Flags::Kernel;
|
||||
}
|
||||
|
||||
OutStreamer->emitSymbolAttribute(S, MCSA_Global);
|
||||
OutStreamer->emitAssignment(
|
||||
S, MCConstantExpr::create(Feat00Flags, MMI->getContext()));
|
||||
S, MCConstantExpr::create(Feat00Value, MMI->getContext()));
|
||||
}
|
||||
OutStreamer->emitSyntaxDirective();
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
; CHECK-LABEL: S_GPROC32_ID [size = 52] `use_alloca`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = VFRAME, param fp reg = EBP
|
||||
; CHECK: flags = has alloca | secure checks | opt speed
|
||||
; CHECK: flags = has alloca | secure checks | strict secure checks | opt speed
|
||||
; CHECK-LABEL: S_GPROC32_ID [size = 52] `call_setjmp`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = NONE, param fp reg = NONE
|
||||
|
@ -73,7 +73,7 @@
|
|||
; CHECK-LABEL: S_GPROC32_ID [size = 56] `use_inlineasm`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = NONE, param fp reg = NONE
|
||||
; CHECK: flags = has inline asm | opt speed
|
||||
; CHECK: flags = has inline asm | safe buffers | opt speed
|
||||
; CHECK-LABEL: S_GPROC32_ID [size = 48] `cpp_eh`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = EBP, param fp reg = EBP
|
||||
|
@ -81,11 +81,11 @@
|
|||
; CHECK-LABEL: S_GPROC32_ID [size = 52] `use_inline`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = NONE, param fp reg = NONE
|
||||
; CHECK: flags = opt speed
|
||||
; CHECK: flags = safe buffers | opt speed
|
||||
; CHECK-LABEL: S_LPROC32_ID [size = 56] `is_marked_inline`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = NONE, param fp reg = NONE
|
||||
; CHECK: flags = marked inline | opt speed
|
||||
; CHECK: flags = marked inline | safe buffers | opt speed
|
||||
; CHECK-LABEL: S_GPROC32_ID [size = 44] `seh`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = EBP, param fp reg = EBP
|
||||
|
@ -93,15 +93,15 @@
|
|||
; CHECK-LABEL: S_LPROC32_ID [size = 56] `?filt$0@0@seh@@`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = EBP, param fp reg = EBP
|
||||
; CHECK: flags = opt speed
|
||||
; CHECK: flags = safe buffers | opt speed
|
||||
; CHECK-LABEL: S_GPROC32_ID [size = 52] `use_naked`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = NONE, param fp reg = NONE
|
||||
; CHECK: flags = has inline asm | naked | opt speed
|
||||
; CHECK: flags = has inline asm | naked | safe buffers | opt speed
|
||||
; CHECK-LABEL: S_GPROC32_ID [size = 52] `stack_guard`
|
||||
; CHECK: S_FRAMEPROC [size = 32]
|
||||
; CHECK: local fp reg = VFRAME, param fp reg = EBP
|
||||
; CHECK: flags = secure checks | opt speed
|
||||
; CHECK: flags = secure checks | strict secure checks | opt speed
|
||||
|
||||
; ModuleID = 'frameproc-flags.cpp'
|
||||
source_filename = "frameproc-flags.cpp"
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
; X86-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X86-NEXT: .long 0 # Exception handler offset
|
||||
; X86-NEXT: .short 0 # Exception handler section
|
||||
; X86-NEXT: .long 0 # Flags (defines frame register)
|
||||
; X86-NEXT: .long 8192 # Flags (defines frame register)
|
||||
; X86-NEXT: .p2align 2
|
||||
; X86-NEXT: [[FPROC_END]]:
|
||||
; X86-NEXT: .short 2
|
||||
|
@ -130,7 +130,7 @@
|
|||
; X86-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X86-NEXT: .long 0 # Exception handler offset
|
||||
; X86-NEXT: .short 0 # Exception handler section
|
||||
; X86-NEXT: .long 0 # Flags (defines frame register)
|
||||
; X86-NEXT: .long 8192 # Flags (defines frame register)
|
||||
; X86-NEXT: .p2align 2
|
||||
; X86-NEXT: [[FPROC_END]]:
|
||||
; X86-NEXT: .short 2
|
||||
|
@ -169,7 +169,7 @@
|
|||
; X86-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X86-NEXT: .long 0 # Exception handler offset
|
||||
; X86-NEXT: .short 0 # Exception handler section
|
||||
; X86-NEXT: .long 0 # Flags (defines frame register)
|
||||
; X86-NEXT: .long 8192 # Flags (defines frame register)
|
||||
; X86-NEXT: .p2align 2
|
||||
; X86-NEXT: [[FPROC_END]]:
|
||||
; X86-NEXT: .short 2
|
||||
|
@ -403,7 +403,7 @@
|
|||
; X64-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X64-NEXT: .long 0 # Exception handler offset
|
||||
; X64-NEXT: .short 0 # Exception handler section
|
||||
; X64-NEXT: .long 81920 # Flags (defines frame register)
|
||||
; X64-NEXT: .long 90112 # Flags (defines frame register)
|
||||
; X64-NEXT: .p2align 2
|
||||
; X64-NEXT: [[FPROC_END]]:
|
||||
; X64-NEXT: .short 2
|
||||
|
@ -441,7 +441,7 @@
|
|||
; X64-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X64-NEXT: .long 0 # Exception handler offset
|
||||
; X64-NEXT: .short 0 # Exception handler section
|
||||
; X64-NEXT: .long 81920 # Flags (defines frame register)
|
||||
; X64-NEXT: .long 90112 # Flags (defines frame register)
|
||||
; X64-NEXT: .p2align 2
|
||||
; X64-NEXT: [[FPROC_END]]:
|
||||
; X64-NEXT: .short 2
|
||||
|
@ -479,7 +479,7 @@
|
|||
; X64-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X64-NEXT: .long 0 # Exception handler offset
|
||||
; X64-NEXT: .short 0 # Exception handler section
|
||||
; X64-NEXT: .long 81920 # Flags (defines frame register)
|
||||
; X64-NEXT: .long 90112 # Flags (defines frame register)
|
||||
; X64-NEXT: .p2align 2
|
||||
; X64-NEXT: [[FPROC_END]]:
|
||||
; X64-NEXT: .short 2
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
; X86-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X86-NEXT: .long 0 # Exception handler offset
|
||||
; X86-NEXT: .short 0 # Exception handler section
|
||||
; X86-NEXT: .long 0 # Flags (defines frame register)
|
||||
; X86-NEXT: .long 8192 # Flags (defines frame register)
|
||||
; X86-NEXT: .p2align 2
|
||||
; X86-NEXT: [[FPROC_END]]:
|
||||
; X86-NEXT: .short 2
|
||||
|
@ -201,7 +201,7 @@
|
|||
; X64-NEXT: .long 0 # Bytes of callee saved registers
|
||||
; X64-NEXT: .long 0 # Exception handler offset
|
||||
; X64-NEXT: .short 0 # Exception handler section
|
||||
; X64-NEXT: .long 81920 # Flags (defines frame register)
|
||||
; X64-NEXT: .long 90112 # Flags (defines frame register)
|
||||
; X64-NEXT: .p2align 2
|
||||
; X64-NEXT: [[FPROC_END]]:
|
||||
; X64-NEXT: .short 2
|
||||
|
|
|
@ -125,7 +125,8 @@
|
|||
; CODEVIEW-NEXT: BytesOfCalleeSavedRegisters: 0xC
|
||||
; CODEVIEW-NEXT: OffsetOfExceptionHandler: 0x0
|
||||
; CODEVIEW-NEXT: SectionIdOfExceptionHandler: 0x0
|
||||
; CODEVIEW-NEXT: Flags [ (0x14000)
|
||||
; CODEVIEW-NEXT: Flags [ (0x16000)
|
||||
; CODEVIEW-NEXT: SafeBuffers (0x2000)
|
||||
; CODEVIEW-NEXT: ]
|
||||
; CODEVIEW-NEXT: LocalFramePtrReg: VFRAME (0x7536)
|
||||
; CODEVIEW-NEXT: ParamFramePtrReg: VFRAME (0x7536)
|
||||
|
|
Loading…
Reference in New Issue