mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[IR] make stack-protector-guard-* flags into module attrs
D88631 added initial support for: - -mstack-protector-guard= - -mstack-protector-guard-reg= - -mstack-protector-guard-offset= flags, and D100919 extended these to AArch64. Unfortunately, these flags aren't retained for LTO. Make them module attributes rather than TargetOptions. Link: https://github.com/ClangBuiltLinux/linux/issues/1378 Reviewed By: tejohnson Differential Revision: https://reviews.llvm.org/D102742
This commit is contained in:
parent
073c495f90
commit
753fcd644e
@ -106,10 +106,6 @@ bool getXCOFFTracebackTable();
|
||||
|
||||
std::string getBBSections();
|
||||
|
||||
std::string getStackProtectorGuard();
|
||||
int getStackProtectorGuardOffset();
|
||||
std::string getStackProtectorGuardReg();
|
||||
|
||||
unsigned getTLSSize();
|
||||
|
||||
bool getEmulatedTLS();
|
||||
@ -150,9 +146,6 @@ struct RegisterCodeGenFlags {
|
||||
|
||||
llvm::BasicBlockSection getBBSectionsMode(llvm::TargetOptions &Options);
|
||||
|
||||
llvm::StackProtectorGuards
|
||||
getStackProtectorGuardMode(llvm::TargetOptions &Options);
|
||||
|
||||
/// Common utility function tightly tied to the options listed here. Initializes
|
||||
/// a TargetOptions object with CodeGen flags and returns it.
|
||||
/// \p TheTriple is used to determine the default value for options if
|
||||
|
@ -895,6 +895,20 @@ public:
|
||||
FramePointerKind getFramePointer() const;
|
||||
void setFramePointer(FramePointerKind Kind);
|
||||
|
||||
/// Get/set what kind of stack protector guard to use.
|
||||
StringRef getStackProtectorGuard() const;
|
||||
void setStackProtectorGuard(StringRef Kind);
|
||||
|
||||
/// Get/set which register to use as the stack protector guard register. The
|
||||
/// empty string is equivalent to "global". Other values may be "tls" or
|
||||
/// "sysreg".
|
||||
StringRef getStackProtectorGuardReg() const;
|
||||
void setStackProtectorGuardReg(StringRef Reg);
|
||||
|
||||
/// Get/set what offset from the stack protector to use.
|
||||
int getStackProtectorGuardOffset() const;
|
||||
void setStackProtectorGuardOffset(int Offset);
|
||||
|
||||
/// @name Utility functions for querying and setting the build SDK version
|
||||
/// @{
|
||||
|
||||
|
@ -73,8 +73,6 @@ namespace llvm {
|
||||
None // Do not use Basic Block Sections.
|
||||
};
|
||||
|
||||
enum class StackProtectorGuards { None, TLS, Global, SysReg };
|
||||
|
||||
enum class EABI {
|
||||
Unknown,
|
||||
Default, // Default means not specified
|
||||
@ -328,16 +326,6 @@ namespace llvm {
|
||||
/// By default, it is set to false.
|
||||
unsigned DebugStrictDwarf : 1;
|
||||
|
||||
/// Stack protector guard offset to use.
|
||||
int StackProtectorGuardOffset = INT_MAX;
|
||||
|
||||
/// Stack protector guard mode to use, e.g. tls, global, sysreg.
|
||||
StackProtectorGuards StackProtectorGuard =
|
||||
StackProtectorGuards::None;
|
||||
|
||||
/// Stack protector guard reg to use, e.g. usually fs or gs in X86.
|
||||
std::string StackProtectorGuardReg = "None";
|
||||
|
||||
/// Name of the stack usage file (i.e., .su file) if user passes
|
||||
/// -fstack-usage. If empty, it can be implied that -fstack-usage is not
|
||||
/// passed on the command line.
|
||||
|
@ -79,9 +79,6 @@ CGOPT_EXP(bool, FunctionSections)
|
||||
CGOPT(bool, IgnoreXCOFFVisibility)
|
||||
CGOPT(bool, XCOFFTracebackTable)
|
||||
CGOPT(std::string, BBSections)
|
||||
CGOPT(std::string, StackProtectorGuard)
|
||||
CGOPT(int, StackProtectorGuardOffset)
|
||||
CGOPT(std::string, StackProtectorGuardReg)
|
||||
CGOPT(unsigned, TLSSize)
|
||||
CGOPT(bool, EmulatedTLS)
|
||||
CGOPT(bool, UniqueSectionNames)
|
||||
@ -366,21 +363,6 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
|
||||
cl::init("none"));
|
||||
CGBINDOPT(BBSections);
|
||||
|
||||
static cl::opt<std::string> StackProtectorGuard(
|
||||
"stack-protector-guard", cl::desc("Stack protector guard mode"),
|
||||
cl::init("none"));
|
||||
CGBINDOPT(StackProtectorGuard);
|
||||
|
||||
static cl::opt<std::string> StackProtectorGuardReg(
|
||||
"stack-protector-guard-reg", cl::desc("Stack protector guard register"),
|
||||
cl::init("none"));
|
||||
CGBINDOPT(StackProtectorGuardReg);
|
||||
|
||||
static cl::opt<int> StackProtectorGuardOffset(
|
||||
"stack-protector-guard-offset", cl::desc("Stack protector guard offset"),
|
||||
cl::init(INT_MAX));
|
||||
CGBINDOPT(StackProtectorGuardOffset);
|
||||
|
||||
static cl::opt<unsigned> TLSSize(
|
||||
"tls-size", cl::desc("Bit size of immediate TLS offsets"), cl::init(0));
|
||||
CGBINDOPT(TLSSize);
|
||||
@ -502,26 +484,6 @@ codegen::getBBSectionsMode(llvm::TargetOptions &Options) {
|
||||
}
|
||||
}
|
||||
|
||||
llvm::StackProtectorGuards
|
||||
codegen::getStackProtectorGuardMode(llvm::TargetOptions &Options) {
|
||||
if (getStackProtectorGuard() == "tls")
|
||||
return StackProtectorGuards::TLS;
|
||||
if (getStackProtectorGuard() == "global")
|
||||
return StackProtectorGuards::Global;
|
||||
if (getStackProtectorGuard() == "sysreg")
|
||||
return StackProtectorGuards::SysReg;
|
||||
if (getStackProtectorGuard() != "none") {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
|
||||
MemoryBuffer::getFile(getStackProtectorGuard());
|
||||
if (!MBOrErr)
|
||||
errs() << "error illegal stack protector guard mode: "
|
||||
<< MBOrErr.getError().message() << "\n";
|
||||
else
|
||||
Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
|
||||
}
|
||||
return StackProtectorGuards::None;
|
||||
}
|
||||
|
||||
// Common utility function tightly tied to the options listed here. Initializes
|
||||
// a TargetOptions object with CodeGen flags and returns it.
|
||||
TargetOptions
|
||||
@ -558,9 +520,6 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
|
||||
Options.BBSections = getBBSectionsMode(Options);
|
||||
Options.UniqueSectionNames = getUniqueSectionNames();
|
||||
Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
|
||||
Options.StackProtectorGuard = getStackProtectorGuardMode(Options);
|
||||
Options.StackProtectorGuardOffset = getStackProtectorGuardOffset();
|
||||
Options.StackProtectorGuardReg = getStackProtectorGuardReg();
|
||||
Options.TLSSize = getTLSSize();
|
||||
Options.EmulatedTLS = getEmulatedTLS();
|
||||
Options.ExplicitEmulatedTLS = EmulatedTLSView->getNumOccurrences() > 0;
|
||||
|
@ -380,9 +380,8 @@ static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
|
||||
IRBuilder<> &B,
|
||||
bool *SupportsSelectionDAGSP = nullptr) {
|
||||
Value *Guard = TLI->getIRStackGuard(B);
|
||||
auto GuardMode = TLI->getTargetMachine().Options.StackProtectorGuard;
|
||||
if ((GuardMode == llvm::StackProtectorGuards::TLS ||
|
||||
GuardMode == llvm::StackProtectorGuards::None) && Guard)
|
||||
StringRef GuardMode = M->getStackProtectorGuard();
|
||||
if ((GuardMode == "tls" || GuardMode.empty()) && Guard)
|
||||
return B.CreateLoad(B.getInt8PtrTy(), Guard, true, "StackGuard");
|
||||
|
||||
// Use SelectionDAG SSP handling, since there isn't an IR guard.
|
||||
|
@ -686,6 +686,41 @@ void Module::setFramePointer(FramePointerKind Kind) {
|
||||
addModuleFlag(ModFlagBehavior::Max, "frame-pointer", static_cast<int>(Kind));
|
||||
}
|
||||
|
||||
StringRef Module::getStackProtectorGuard() const {
|
||||
Metadata *MD = getModuleFlag("stack-protector-guard");
|
||||
if (auto *MDS = dyn_cast_or_null<MDString>(MD))
|
||||
return MDS->getString();
|
||||
return {};
|
||||
}
|
||||
|
||||
void Module::setStackProtectorGuard(StringRef Kind) {
|
||||
MDString *ID = MDString::get(getContext(), Kind);
|
||||
addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard", ID);
|
||||
}
|
||||
|
||||
StringRef Module::getStackProtectorGuardReg() const {
|
||||
Metadata *MD = getModuleFlag("stack-protector-guard-reg");
|
||||
if (auto *MDS = dyn_cast_or_null<MDString>(MD))
|
||||
return MDS->getString();
|
||||
return {};
|
||||
}
|
||||
|
||||
void Module::setStackProtectorGuardReg(StringRef Reg) {
|
||||
MDString *ID = MDString::get(getContext(), Reg);
|
||||
addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-reg", ID);
|
||||
}
|
||||
|
||||
int Module::getStackProtectorGuardOffset() const {
|
||||
Metadata *MD = getModuleFlag("stack-protector-guard-offset");
|
||||
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))
|
||||
return CI->getSExtValue();
|
||||
return INT_MAX;
|
||||
}
|
||||
|
||||
void Module::setStackProtectorGuardOffset(int Offset) {
|
||||
addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-offset", Offset);
|
||||
}
|
||||
|
||||
void Module::setSDKVersion(const VersionTuple &V) {
|
||||
SmallVector<unsigned, 3> Entries;
|
||||
Entries.push_back(V.getMajor());
|
||||
|
@ -1904,10 +1904,10 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
|
||||
}
|
||||
|
||||
Register Reg = MI.getOperand(0).getReg();
|
||||
TargetOptions Options = MI.getParent()->getParent()->getTarget().Options;
|
||||
if (Options.StackProtectorGuard == StackProtectorGuards::SysReg) {
|
||||
Module &M = *MBB.getParent()->getFunction().getParent();
|
||||
if (M.getStackProtectorGuard() == "sysreg") {
|
||||
const AArch64SysReg::SysReg *SrcReg =
|
||||
AArch64SysReg::lookupSysRegByName(Options.StackProtectorGuardReg);
|
||||
AArch64SysReg::lookupSysRegByName(M.getStackProtectorGuardReg());
|
||||
if (!SrcReg)
|
||||
report_fatal_error("Unknown SysReg for Stack Protector Guard Register");
|
||||
|
||||
@ -1915,7 +1915,7 @@ bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
|
||||
BuildMI(MBB, MI, DL, get(AArch64::MRS))
|
||||
.addDef(Reg, RegState::Renamable)
|
||||
.addImm(SrcReg->Encoding);
|
||||
int Offset = Options.StackProtectorGuardOffset;
|
||||
int Offset = M.getStackProtectorGuardOffset();
|
||||
if (Offset >= 0 && Offset <= 32760 && Offset % 8 == 0) {
|
||||
// ldr xN, [xN, #offset]
|
||||
BuildMI(MBB, MI, DL, get(AArch64::LDRXui))
|
||||
|
@ -2510,15 +2510,16 @@ Value *X86TargetLowering::getIRStackGuard(IRBuilder<> &IRB) const {
|
||||
return SegmentOffset(IRB, 0x10, getAddressSpace());
|
||||
} else {
|
||||
unsigned AddressSpace = getAddressSpace();
|
||||
Module *M = IRB.GetInsertBlock()->getParent()->getParent();
|
||||
// Specially, some users may customize the base reg and offset.
|
||||
int Offset = getTargetMachine().Options.StackProtectorGuardOffset;
|
||||
int Offset = M->getStackProtectorGuardOffset();
|
||||
// If we don't set -stack-protector-guard-offset value:
|
||||
// %fs:0x28, unless we're using a Kernel code model, in which case
|
||||
// it's %gs:0x28. gs:0x14 on i386.
|
||||
if (Offset == INT_MAX)
|
||||
Offset = (Subtarget.is64Bit()) ? 0x28 : 0x14;
|
||||
|
||||
const auto &GuardReg = getTargetMachine().Options.StackProtectorGuardReg;
|
||||
StringRef GuardReg = M->getStackProtectorGuardReg();
|
||||
if (GuardReg == "fs")
|
||||
AddressSpace = X86AS::FS;
|
||||
else if (GuardReg == "gs")
|
||||
@ -2548,12 +2549,11 @@ void X86TargetLowering::insertSSPDeclarations(Module &M) const {
|
||||
return;
|
||||
}
|
||||
|
||||
auto GuardMode = getTargetMachine().Options.StackProtectorGuard;
|
||||
StringRef GuardMode = M.getStackProtectorGuard();
|
||||
|
||||
// glibc, bionic, and Fuchsia have a special slot for the stack guard.
|
||||
if ((GuardMode == llvm::StackProtectorGuards::TLS ||
|
||||
GuardMode == llvm::StackProtectorGuards::None)
|
||||
&& hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
|
||||
if ((GuardMode == "tls" || GuardMode.empty()) &&
|
||||
hasStackGuardSlotTLS(Subtarget.getTargetTriple()))
|
||||
return;
|
||||
TargetLowering::insertSSPDeclarations(M);
|
||||
}
|
||||
|
@ -1,46 +1,39 @@
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=0 -verify-machineinstrs -o - | \
|
||||
; RUN: split-file %s %t
|
||||
; RUN: cat %t/main.ll %t/a.ll > %t/a2.ll
|
||||
; RUN: cat %t/main.ll %t/b.ll > %t/b2.ll
|
||||
; RUN: cat %t/main.ll %t/c.ll > %t/c2.ll
|
||||
; RUN: cat %t/main.ll %t/d.ll > %t/d2.ll
|
||||
; RUN: cat %t/main.ll %t/e.ll > %t/e2.ll
|
||||
; RUN: cat %t/main.ll %t/f.ll > %t/f2.ll
|
||||
; RUN: cat %t/main.ll %t/g.ll > %t/g2.ll
|
||||
; RUN: cat %t/main.ll %t/h.ll > %t/h2.ll
|
||||
; RUN: cat %t/main.ll %t/i.ll > %t/i2.ll
|
||||
; RUN: cat %t/main.ll %t/j.ll > %t/j2.ll
|
||||
; RUN: llc %t/a2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NO-OFFSET %s
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=8 -verify-machineinstrs -o - | \
|
||||
; RUN: llc %t/b2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-POSITIVE-OFFSET %s
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=-8 -verify-machineinstrs -o - | \
|
||||
; RUN: llc %t/c2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NEGATIVE-OFFSET %s
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=1 -verify-machineinstrs -o - | \
|
||||
; RUN: llc %t/d2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NPOT-OFFSET %s
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=-1 -verify-machineinstrs -o - | \
|
||||
; RUN: llc %t/e2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NPOT-NEG-OFFSET %s
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=257 -verify-machineinstrs -o - | \
|
||||
; RUN: llc %t/f2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-257-OFFSET %s
|
||||
; RUN: llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=-257 -verify-machineinstrs -o - | \
|
||||
; RUN: llc %t/g2.ll -verify-machineinstrs -o - | \
|
||||
; RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-MINUS-257-OFFSET %s
|
||||
|
||||
; XFAIL
|
||||
; RUN: not --crash llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=32761 -o - 2>&1 | \
|
||||
; RUN: not --crash llc %t/h2.ll -o - 2>&1 | \
|
||||
; RUN: FileCheck --check-prefix=CHECK-BAD-OFFSET %s
|
||||
; RUN: not --crash llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=-4096 -o - 2>&1 | \
|
||||
; RUN: not --crash llc %t/i2.ll -o - 2>&1 | \
|
||||
; RUN: FileCheck --check-prefix=CHECK-BAD-OFFSET %s
|
||||
; RUN: not --crash llc %s --stack-protector-guard=sysreg \
|
||||
; RUN: --stack-protector-guard-reg=sp_el0 \
|
||||
; RUN: --stack-protector-guard-offset=4097 -o - 2>&1 | \
|
||||
; RUN: not --crash llc %t/j2.ll -o - 2>&1 | \
|
||||
; RUN: FileCheck --check-prefix=CHECK-BAD-OFFSET %s
|
||||
|
||||
;--- main.ll
|
||||
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
; Verify that we `mrs` from `SP_EL0` twice, rather than load from
|
||||
@ -100,6 +93,31 @@ entry:
|
||||
|
||||
declare void @baz(i32*)
|
||||
|
||||
attributes #0 = { sspstrong }
|
||||
|
||||
; CHECK-BAD-OFFSET: LLVM ERROR: Unable to encode Stack Protector Guard Offset
|
||||
|
||||
attributes #0 = { sspstrong }
|
||||
!llvm.module.flags = !{!1, !2, !3}
|
||||
|
||||
!1 = !{i32 2, !"stack-protector-guard", !"sysreg"}
|
||||
!2 = !{i32 2, !"stack-protector-guard-reg", !"sp_el0"}
|
||||
|
||||
;--- a.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 0}
|
||||
;--- b.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 8}
|
||||
;--- c.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 -8}
|
||||
;--- d.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 1}
|
||||
;--- e.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 -1}
|
||||
;--- f.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 257}
|
||||
;--- g.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 -257}
|
||||
;--- h.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 32761}
|
||||
;--- i.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 -4096}
|
||||
;--- j.ll
|
||||
!3 = !{i32 2, !"stack-protector-guard-offset", i32 4097}
|
||||
|
@ -1,10 +1,18 @@
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %s | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -stack-protector-guard=tls -o - < %s | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -stack-protector-guard=global -o - < %s | FileCheck --check-prefix=CHECK-GLOBAL %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -stack-protector-guard-reg=fs -o - < %s | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -stack-protector-guard-reg=gs -o - < %s | FileCheck --check-prefix=CHECK-GS %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -stack-protector-guard-offset=20 -o - < %s | FileCheck --check-prefix=CHECK-OFFSET %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -stack-protector-guard-offset=-20 -o - < %s | FileCheck --check-prefix=CHECK-NEGATIVE-OFFSET %s
|
||||
; RUN: split-file %s %t
|
||||
; RUN: cat %t/main.ll %t/a.ll > %t/a2.ll
|
||||
; RUN: cat %t/main.ll %t/b.ll > %t/b2.ll
|
||||
; RUN: cat %t/main.ll %t/c.ll > %t/c2.ll
|
||||
; RUN: cat %t/main.ll %t/d.ll > %t/d2.ll
|
||||
; RUN: cat %t/main.ll %t/e.ll > %t/e2.ll
|
||||
; RUN: cat %t/main.ll %t/f.ll > %t/f2.ll
|
||||
; RUN: cat %t/main.ll %t/g.ll > %t/g2.ll
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/a2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/b2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/c2.ll | FileCheck --check-prefix=CHECK-GLOBAL %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/d2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/e2.ll | FileCheck --check-prefix=CHECK-GS %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/f2.ll | FileCheck --check-prefix=CHECK-OFFSET %s
|
||||
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/g2.ll | FileCheck --check-prefix=CHECK-NEGATIVE-OFFSET %s
|
||||
|
||||
; CHECK-TLS-FS-40: movq %fs:40, %rax
|
||||
; CHECK-TLS-FS-40: movq %fs:40, %rax
|
||||
@ -47,6 +55,8 @@
|
||||
; CHECK-GLOBAL-NEXT: .cfi_def_cfa_offset 32
|
||||
; CHECK-GLOBAL-NEXT: callq __stack_chk_fail
|
||||
|
||||
;--- main.ll
|
||||
|
||||
; ModuleID = 't.c'
|
||||
@.str = private unnamed_addr constant [14 x i8] c"stackoverflow\00", align 1
|
||||
@a = dso_local local_unnamed_addr global i8* null, align 8
|
||||
@ -75,3 +85,23 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noa
|
||||
attributes #0 = { nounwind sspreq uwtable writeonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
attributes #1 = { argmemonly nounwind willreturn }
|
||||
attributes #2 = { nounwind }
|
||||
|
||||
;--- a.ll
|
||||
;--- b.ll
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 2, !"stack-protector-guard", !"tls"}
|
||||
;--- c.ll
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 2, !"stack-protector-guard", !"global"}
|
||||
;--- d.ll
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 2, !"stack-protector-guard-reg", !"fs"}
|
||||
;--- e.ll
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 2, !"stack-protector-guard-reg", !"gs"}
|
||||
;--- f.ll
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 2, !"stack-protector-guard-offset", i32 20}
|
||||
;--- g.ll
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 2, !"stack-protector-guard-offset", i32 -20}
|
||||
|
77
test/Linker/stack-protector-guard-module-attrs.ll
Normal file
77
test/Linker/stack-protector-guard-module-attrs.ll
Normal file
@ -0,0 +1,77 @@
|
||||
; RUN: split-file %s %t
|
||||
; RUN: not llvm-link %t/a.ll %t/b.ll 2>&1 | FileCheck --check-prefix=CHECK-KIND %s
|
||||
; RUN: not llvm-link %t/c.ll %t/d.ll 2>&1 | FileCheck --check-prefix=CHECK-REG %s
|
||||
; RUN: not llvm-link %t/e.ll %t/f.ll 2>&1 | FileCheck --check-prefix=CHECK-OFFSET %s
|
||||
; RUN: llvm-link %t/g.ll %t/h.ll
|
||||
|
||||
; CHECK-KIND: error: linking module flags 'stack-protector-guard': IDs have conflicting values
|
||||
; CHECK-REG: error: linking module flags 'stack-protector-guard-reg': IDs have conflicting values
|
||||
; CHECK-OFFSET: error: linking module flags 'stack-protector-guard-offset': IDs have conflicting values
|
||||
|
||||
;--- a.ll
|
||||
; Test that different values of stack-protector-guard fail.
|
||||
define void @foo() sspstrong {
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"stack-protector-guard", !"sysreg"}
|
||||
;--- b.ll
|
||||
declare void @foo() sspstrong
|
||||
define void @bar() sspstrong {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"stack-protector-guard", !"global"}
|
||||
|
||||
;--- c.ll
|
||||
; Test that different values of stack-protector-guard-reg fail.
|
||||
define void @foo() sspstrong {
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"stack-protector-guard-reg", !"sp_el0"}
|
||||
;--- d.ll
|
||||
declare void @foo() sspstrong
|
||||
define void @bar() sspstrong {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"stack-protector-guard-reg", !"sp_el1"}
|
||||
|
||||
;--- e.ll
|
||||
; Test that different values of stack-protector-guard-offset fail.
|
||||
define void @foo() sspstrong {
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"stack-protector-guard-offset", i32 257}
|
||||
;--- f.ll
|
||||
declare void @foo() sspstrong
|
||||
define void @bar() sspstrong {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0}
|
||||
!0 = !{i32 1, !"stack-protector-guard-offset", i32 256}
|
||||
|
||||
;--- g.ll
|
||||
; Test that the same values for the three module attributes succeed.
|
||||
define void @foo() sspstrong {
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0, !1, !2}
|
||||
!0 = !{i32 1, !"stack-protector-guard", !"sysreg"}
|
||||
!1 = !{i32 1, !"stack-protector-guard-reg", !"sp_el0"}
|
||||
!2 = !{i32 1, !"stack-protector-guard-offset", i32 257}
|
||||
;--- h.ll
|
||||
declare void @foo() sspstrong
|
||||
define void @bar() sspstrong {
|
||||
call void @foo()
|
||||
ret void
|
||||
}
|
||||
!llvm.module.flags = !{!0, !1, !2}
|
||||
!0 = !{i32 1, !"stack-protector-guard", !"sysreg"}
|
||||
!1 = !{i32 1, !"stack-protector-guard-reg", !"sp_el0"}
|
||||
!2 = !{i32 1, !"stack-protector-guard-offset", i32 257}
|
Loading…
Reference in New Issue
Block a user