Skip to content

Commit a45dd3d

Browse files
committed
[X86] Support -mstack-protector-guard-symbol
Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D129346
1 parent 6437862 commit a45dd3d

File tree

12 files changed

+111
-2
lines changed

12 files changed

+111
-2
lines changed

clang/docs/ClangCommandLineReference.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,6 +3285,10 @@ Use the given offset for addressing the stack-protector guard
32853285

32863286
Use the given reg for addressing the stack-protector guard
32873287

3288+
.. option:: -mstack-protector-guard-symbol=<arg>
3289+
3290+
Use the given symbol for addressing the stack-protector guard
3291+
32883292
.. option:: -mstack-protector-guard=<arg>
32893293

32903294
Use the given guard (global, tls) for addressing the stack-protector guard

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,8 @@ X86 Support in Clang
548548
- Added the ``-m[no-]rdpru`` flag to enable/disable the RDPRU instruction
549549
provided by AMD Zen2 and later processors. Defined intrinsics for using
550550
this instruction (see rdpruintrin.h).
551+
- Support ``-mstack-protector-guard-symbol=[SymbolName]`` to use the given
552+
symbol for addressing the stack protector guard.
551553

552554
DWARF Support in Clang
553555
----------------------

clang/include/clang/Basic/CodeGenOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
389389
/// On AArch64 this can only be "sp_el0".
390390
std::string StackProtectorGuardReg;
391391

392+
/// Specify a symbol to be the guard value.
393+
std::string StackProtectorGuardSymbol;
394+
392395
/// Path to ignorelist file specifying which objects
393396
/// (files, functions) listed for instrumentation by sanitizer
394397
/// coverage pass should actually not be instrumented.

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3771,6 +3771,9 @@ def mstack_protector_guard_EQ : Joined<["-"], "mstack-protector-guard=">, Group<
37713771
def mstack_protector_guard_offset_EQ : Joined<["-"], "mstack-protector-guard-offset=">, Group<m_Group>, Flags<[CC1Option]>,
37723772
HelpText<"Use the given offset for addressing the stack-protector guard">,
37733773
MarshallingInfoInt<CodeGenOpts<"StackProtectorGuardOffset">, "INT_MAX", "int">;
3774+
def mstack_protector_guard_symbol_EQ : Joined<["-"], "mstack-protector-guard-symbol=">, Group<m_Group>, Flags<[CC1Option]>,
3775+
HelpText<"Use the given symbol for addressing the stack-protector guard">,
3776+
MarshallingInfoString<CodeGenOpts<"StackProtectorGuardSymbol">>;
37743777
def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg=">, Group<m_Group>, Flags<[CC1Option]>,
37753778
HelpText<"Use the given reg for addressing the stack-protector guard">,
37763779
MarshallingInfoString<CodeGenOpts<"StackProtectorGuardReg">>;

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,9 @@ void CodeGenModule::Release() {
900900
if (!getCodeGenOpts().StackProtectorGuardReg.empty())
901901
getModule().setStackProtectorGuardReg(
902902
getCodeGenOpts().StackProtectorGuardReg);
903+
if (!getCodeGenOpts().StackProtectorGuardSymbol.empty())
904+
getModule().setStackProtectorGuardSymbol(
905+
getCodeGenOpts().StackProtectorGuardSymbol);
903906
if (getCodeGenOpts().StackProtectorGuardOffset != INT_MAX)
904907
getModule().setStackProtectorGuardOffset(
905908
getCodeGenOpts().StackProtectorGuardOffset);

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,6 +3231,16 @@ static void RenderAnalyzerOptions(const ArgList &Args, ArgStringList &CmdArgs,
32313231
Args.AddAllArgValues(CmdArgs, options::OPT_Xanalyzer);
32323232
}
32333233

3234+
static bool isValidSymbolName(StringRef S) {
3235+
if (S.empty())
3236+
return false;
3237+
3238+
if (std::isdigit(S[0]))
3239+
return false;
3240+
3241+
return llvm::all_of(S, [](char C) { return std::isalnum(C) || C == '_'; });
3242+
}
3243+
32343244
static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
32353245
const ArgList &Args, ArgStringList &CmdArgs,
32363246
bool KernelOrKext) {
@@ -3362,6 +3372,16 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
33623372
}
33633373
A->render(Args, CmdArgs);
33643374
}
3375+
3376+
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_symbol_EQ)) {
3377+
StringRef Value = A->getValue();
3378+
if (!isValidSymbolName(Value)) {
3379+
D.Diag(diag::err_drv_argument_only_allowed_with)
3380+
<< A->getOption().getName() << "legal symbol name";
3381+
return;
3382+
}
3383+
A->render(Args, CmdArgs);
3384+
}
33653385
}
33663386

33673387
static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args,

clang/test/Driver/stack-protector-guard.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// RUN: FileCheck -check-prefix=CHECK-FS %s
1414
// RUN: %clang -### -target x86_64-unknown-unknown -mstack-protector-guard-reg=gs %s 2>&1 | \
1515
// RUN: FileCheck -check-prefix=CHECK-GS %s
16+
// RUN: %clang -### -target x86_64-unknown-unknown -mstack-protector-guard-symbol=sym %s 2>&1 | \
17+
// RUN: FileCheck -check-prefix=CHECK-SYM %s
1618

1719
// Invalid arch
1820
// RUN: not %clang -target powerpc64le-linux-gnu -mstack-protector-guard=tls %s 2>&1 | \
@@ -32,10 +34,16 @@
3234
// RUN: FileCheck -check-prefix=INVALID-REG %s
3335
// RUN: not %clang -target x86_64-unknown-unknown -c -mstack-protector-guard-reg=ds %s 2>&1 | \
3436
// RUN: FileCheck -check-prefix=INVALID-REG %s
37+
// RUN: not %clang -target x86_64-unknown-unknown -c -mstack-protector-guard-symbol=2s %s 2>&1 | \
38+
// RUN: FileCheck -check-prefix=INVALID-SYM %s
39+
// RUN: not %clang -target x86_64-unknown-unknown -c -mstack-protector-guard-symbol= %s 2>&1 | \
40+
// RUN: FileCheck -check-prefix=INVALID-SYM %s
3541

3642
// CHECK-FS: "-cc1" {{.*}}"-mstack-protector-guard-reg=fs"
3743
// CHECK-GS: "-cc1" {{.*}}"-mstack-protector-guard-reg=gs"
3844
// INVALID-REG: error: invalid value {{.*}} in 'mstack-protector-guard-reg=', expected one of: fs gs
45+
// CHECK-SYM: "-cc1" {{.*}}"-mstack-protector-guard-symbol=sym"
46+
// INVALID-SYM: error: invalid argument 'mstack-protector-guard-symbol=' only allowed with 'legal symbol name'
3947

4048
// RUN: not %clang -target arm-eabi-c -mstack-protector-guard=tls %s 2>&1 | \
4149
// RUN: FileCheck -check-prefix=MISSING-OFFSET %s

llvm/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ Changes to the DAG infrastructure
221221
---------------------------------
222222

223223

224+
Changes to the Metadata Info
225+
---------------------------------
226+
227+
* Add Module Flags Metadata ``stack-protector-guard-symbol`` which specify a
228+
symbol for addressing the stack-protector guard.
229+
224230
Changes to the Debug Info
225231
---------------------------------
226232

llvm/include/llvm/IR/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,10 @@ class LLVM_EXTERNAL_VISIBILITY Module {
911911
StringRef getStackProtectorGuardReg() const;
912912
void setStackProtectorGuardReg(StringRef Reg);
913913

914+
/// Get/set a symbol to use as the stack protector guard.
915+
StringRef getStackProtectorGuardSymbol() const;
916+
void setStackProtectorGuardSymbol(StringRef Symbol);
917+
914918
/// Get/set what offset from the stack protector to use.
915919
int getStackProtectorGuardOffset() const;
916920
void setStackProtectorGuardOffset(int Offset);

llvm/lib/IR/Module.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,18 @@ void Module::setStackProtectorGuardReg(StringRef Reg) {
714714
addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-reg", ID);
715715
}
716716

717+
StringRef Module::getStackProtectorGuardSymbol() const {
718+
Metadata *MD = getModuleFlag("stack-protector-guard-symbol");
719+
if (auto *MDS = dyn_cast_or_null<MDString>(MD))
720+
return MDS->getString();
721+
return {};
722+
}
723+
724+
void Module::setStackProtectorGuardSymbol(StringRef Symbol) {
725+
MDString *ID = MDString::get(getContext(), Symbol);
726+
addModuleFlag(ModFlagBehavior::Error, "stack-protector-guard-symbol", ID);
727+
}
728+
717729
int Module::getStackProtectorGuardOffset() const {
718730
Metadata *MD = getModuleFlag("stack-protector-guard-offset");
719731
if (auto *CI = mdconst::dyn_extract_or_null<ConstantInt>(MD))

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,6 +2845,21 @@ Value *X86TargetLowering::getIRStackGuard(IRBuilderBase &IRB) const {
28452845
AddressSpace = X86AS::FS;
28462846
else if (GuardReg == "gs")
28472847
AddressSpace = X86AS::GS;
2848+
2849+
// Use symbol guard if user specify.
2850+
StringRef GuardSymb = M->getStackProtectorGuardSymbol();
2851+
if (!GuardSymb.empty()) {
2852+
GlobalVariable *GV = M->getGlobalVariable(GuardSymb);
2853+
if (!GV) {
2854+
Type *Ty = Subtarget.is64Bit() ? Type::getInt64Ty(M->getContext())
2855+
: Type::getInt32Ty(M->getContext());
2856+
GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
2857+
nullptr, GuardSymb, nullptr,
2858+
GlobalValue::NotThreadLocal, AddressSpace);
2859+
}
2860+
return GV;
2861+
}
2862+
28482863
return SegmentOffset(IRB, Offset, AddressSpace);
28492864
}
28502865
}

llvm/test/CodeGen/X86/stack-protector-3.ll

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
; RUN: cat %t/main.ll %t/e.ll > %t/e2.ll
77
; RUN: cat %t/main.ll %t/f.ll > %t/f2.ll
88
; RUN: cat %t/main.ll %t/g.ll > %t/g2.ll
9+
; RUN: cat %t/main.ll %t/h.ll > %t/h2.ll
10+
; RUN: cat %t/existedGV.ll %t/main.ll %t/h.ll > %t/i2.ll
911
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/a2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
1012
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/b2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
1113
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/c2.ll | FileCheck --check-prefix=CHECK-GLOBAL %s
1214
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/d2.ll | FileCheck --check-prefix=CHECK-TLS-FS-40 %s
1315
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/e2.ll | FileCheck --check-prefix=CHECK-GS %s
1416
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/f2.ll | FileCheck --check-prefix=CHECK-OFFSET %s
1517
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/g2.ll | FileCheck --check-prefix=CHECK-NEGATIVE-OFFSET %s
16-
17-
;--- main.ll
18+
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/h2.ll | FileCheck --check-prefix=CHECK-SYM %s
19+
; RUN: llc -mtriple=x86_64-pc-linux-gnu -o - < %t/i2.ll | FileCheck --check-prefix=CHECK-SYMGV %s
1820

1921
; CHECK-TLS-FS-40: movq %fs:40, %rax
2022
; CHECK-TLS-FS-40: movq %fs:40, %rax
@@ -57,7 +59,31 @@
5759
; CHECK-GLOBAL-NEXT: .cfi_def_cfa_offset 32
5860
; CHECK-GLOBAL-NEXT: callq __stack_chk_fail
5961

62+
; CHECK-SYM: movq __woof@GOTPCREL(%rip), %rax
63+
; CHECK-SYM-NEXT: movq %fs:(%rax), %rcx
64+
; CHECK-SYM-NEXT: movq %rcx, 16(%rsp)
65+
; CHECK-SYM: movq %fs:(%rax), %rax
66+
; CHECK-SYM-NEXT: cmpq 16(%rsp), %rax
67+
; CHECK-SYM-NEXT: jne .LBB0_2
68+
; CHECK-SYM: .LBB0_2:
69+
; CHECK-SYM-NEXT: .cfi_def_cfa_offset 32
70+
; CHECK-SYM-NEXT: callq __stack_chk_fai
71+
72+
; CHECK-SYMGV: movq __woof(%rip), %rax
73+
; CHECK-SYMGV-NEXT: movq %rax, 16(%rsp)
74+
; CHECK-SYMGV: cmpq 16(%rsp), %rax
75+
; CHECK-SYMGV-NEXT: jne .LBB0_2
76+
; CHECK-SYMGV: .LBB0_2:
77+
; CHECK-SYMGV-NEXT: .cfi_def_cfa_offset 32
78+
; CHECK-SYMGV-NEXT: callq __stack_chk_fail
79+
6080
; ModuleID = 't.c'
81+
;--- existedGV.ll
82+
83+
@__woof = dso_local local_unnamed_addr global ptr null, align 8
84+
85+
;--- main.ll
86+
6187
@.str = private unnamed_addr constant [14 x i8] c"stackoverflow\00", align 1
6288
@a = dso_local local_unnamed_addr global ptr null, align 8
6389

@@ -104,3 +130,6 @@ attributes #2 = { nounwind }
104130
;--- g.ll
105131
!llvm.module.flags = !{!1}
106132
!1 = !{i32 2, !"stack-protector-guard-offset", i32 -20}
133+
;--- h.ll
134+
!llvm.module.flags = !{!1}
135+
!1 = !{i32 2, !"stack-protector-guard-symbol", !"__woof"}

0 commit comments

Comments
 (0)