Skip to content

Commit 1082e93

Browse files
committed
[LLD][COFF] Add more variety of CET flags
1 parent 7ba6255 commit 1082e93

File tree

11 files changed

+171
-4
lines changed

11 files changed

+171
-4
lines changed

lld/COFF/Config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,10 @@ struct Configuration {
307307
bool dynamicBase = true;
308308
bool allowBind = true;
309309
bool cetCompat = false;
310+
bool cetCompatStrict = false;
311+
bool cetCompatIpValidationRelaxed = false;
312+
bool cetCompatDynamicApisInProcOnly = false;
313+
bool hotpatchCompat = false;
310314
bool nxCompat = true;
311315
bool allowIsolation = true;
312316
bool terminalServerAware = true;

lld/COFF/Driver.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,6 +2145,13 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
21452145
config->integrityCheck =
21462146
args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false);
21472147
config->cetCompat = args.hasFlag(OPT_cetcompat, OPT_cetcompat_no, false);
2148+
config->cetCompatStrict = args.hasFlag(OPT_cetcompatstrict, OPT_cetcompatstrict_no, false);
2149+
config->cetCompatIpValidationRelaxed =
2150+
args.hasFlag(OPT_cetipvalidationrelaxed, OPT_cetipvalidationrelaxed_no, false);
2151+
config->cetCompatDynamicApisInProcOnly =
2152+
args.hasFlag(OPT_cetdynamicapisinproc, OPT_cetdynamicapisinproc_no, false);
2153+
config->hotpatchCompat =
2154+
args.hasFlag(OPT_hotpatchcompatible, OPT_hotpatchcompatible_no, false);
21482155
config->nxCompat = args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true);
21492156
for (auto *arg : args.filtered(OPT_swaprun))
21502157
parseSwaprun(arg->getValue());

lld/COFF/Options.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ defm appcontainer : B<"appcontainer",
196196
"Image can run outside an app container (default)">;
197197
defm cetcompat : B<"cetcompat", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack",
198198
"Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack (default)">;
199+
defm cetcompatstrict : B<"cetcompatstrict", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in strict mode",
200+
"Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in strict mode (default)">;
201+
defm cetipvalidationrelaxed : B<"cetipvalidationrelaxed", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation",
202+
"Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation (default)">;
203+
defm cetdynamicapisinproc : B<"cetdynamicapisinproc", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in such a way that dynamic APIs allowed in process",
204+
"Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with dynamic APIs allowed in process (default)">;
205+
defm hotpatchcompatible : B<"hotpatchcompatible", "Mark executable image as compatible with hotpatch",
206+
"Don't mark executable image as compatible with hotpatch (default)">;
199207
defm dynamicbase : B<"dynamicbase", "Enable ASLR (default unless /fixed)",
200208
"Disable ASLR (default when /fixed)">;
201209
defm fixed : B<"fixed", "Disable base relocations",

lld/COFF/Writer.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,9 @@ void Writer::createMiscChunks() {
12161216
// Create Debug Information Chunks
12171217
debugInfoSec = config->mingw ? buildidSec : rdataSec;
12181218
if (config->buildIDHash != BuildIDHash::None || config->debug ||
1219-
config->repro || config->cetCompat) {
1219+
config->repro || config->cetCompat || config->cetCompatStrict ||
1220+
config->cetCompatIpValidationRelaxed ||
1221+
config->cetCompatDynamicApisInProcOnly || config->hotpatchCompat) {
12201222
debugDirectory =
12211223
make<DebugDirectoryChunk>(ctx, debugRecords, config->repro);
12221224
debugDirectory->setAlignment(4);
@@ -1237,10 +1239,30 @@ void Writer::createMiscChunks() {
12371239
});
12381240
}
12391241

1242+
uint16_t ex_characteristics_flags = 0;
12401243
if (config->cetCompat) {
1244+
ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT;
1245+
}
1246+
if (config->cetCompatStrict) {
1247+
ex_characteristics_flags |=
1248+
IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE;
1249+
}
1250+
if (config->cetCompatIpValidationRelaxed) {
1251+
ex_characteristics_flags |=
1252+
IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE;
1253+
}
1254+
if (config->cetCompatDynamicApisInProcOnly) {
1255+
ex_characteristics_flags |=
1256+
IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY;
1257+
}
1258+
if (config->hotpatchCompat) {
1259+
ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE;
1260+
}
1261+
1262+
if (ex_characteristics_flags) {
12411263
debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS,
12421264
make<ExtendedDllCharacteristicsChunk>(
1243-
IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT));
1265+
ex_characteristics_flags));
12441266
}
12451267

12461268
// Align and add each chunk referenced by the debug data directory.

lld/test/COFF/options.test

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,46 @@ CETCOMPAT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT
6060
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPAT %s
6161
NONCETCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT
6262

63+
# RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj
64+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPATSTRICT %s
65+
CETCOMPATSTRICT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE
66+
67+
# RUN: lld-link /out:%t.exe /entry:main %t.obj
68+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTRICT %s
69+
# RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict:no %t.obj
70+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTRICT %s
71+
NONCETCOMPATSTRICT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE
72+
73+
# RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj
74+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPATSTIPVALIDATIONRELAXED %s
75+
CETCOMPATSTIPVALIDATIONRELAXED: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE
76+
77+
# RUN: lld-link /out:%t.exe /entry:main %t.obj
78+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTIPVALIDATIONRELAXED %s
79+
# RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed:no %t.obj
80+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTIPVALIDATIONRELAXED %s
81+
NONCETCOMPATSTIPVALIDATIONRELAXED-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE
82+
83+
# RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj
84+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETDYNAMICAPISINPROC %s
85+
CETDYNAMICAPISINPROC: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY
86+
87+
# RUN: lld-link /out:%t.exe /entry:main %t.obj
88+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s
89+
# RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc:no %t.obj
90+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s
91+
NONCETDYNAMICAPISINPROC-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY
92+
93+
# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj
94+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=HOTPATCHCOMPATIBLE %s
95+
HOTPATCHCOMPATIBLE: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE
96+
97+
# RUN: lld-link /out:%t.exe /entry:main %t.obj
98+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONHOTPATCHCOMPATIBLE %s
99+
# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible:no %t.obj
100+
# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONHOTPATCHCOMPATIBLE %s
101+
NONHOTPATCHCOMPATIBLE-NOT: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE
102+
63103
# RUN: lld-link /out:%t.exe /entry:main /swaprun:CD %t.obj
64104
# RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s
65105
# RUN: lld-link /out:%t.exe /entry:main /swaprun:cd,net %t.obj

llvm/include/llvm/BinaryFormat/COFF.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,22 @@ enum DLLCharacteristics : unsigned {
694694

695695
enum ExtendedDLLCharacteristics : unsigned {
696696
/// Image is CET compatible
697-
IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001
697+
IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001,
698+
/// Image is CET compatible in strict mode
699+
IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE = 0x0002,
700+
/// Image is CET compatible in such a way that context IP validation is relaxed
701+
IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = 0x0004,
702+
/// Image is CET compatible in such a way that the use of
703+
/// dynamic APIs is restricted to processes only
704+
IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY = 0x0008,
705+
/// Reserved for future use. Not used by MSVC link.exe
706+
IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_1 = 0x0010,
707+
/// Reserved for future use. Not used by MSVC link.exe
708+
IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_2 = 0x0020,
709+
/// Image is CFI compatible.
710+
IMAGE_DLL_CHARACTERISTICS_EX_FORWARD_CFI_COMPAT = 0x0040,
711+
/// Image is hotpatch compatible.
712+
IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE = 0x0080,
698713
};
699714

700715
enum DebugType : unsigned {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# To regenerate has-cetstrict.exe
2+
# $ echo int main() { return 0; } > has-cetstrict.c
3+
# $ cl has-cetstrict.c /link /cetcompatstrict
4+
RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetstrict.exe | FileCheck %s
5+
6+
CHECK: DebugEntry {
7+
CHECK: Characteristics: 0x0
8+
CHECK: Type: ExtendedDLLCharacteristics (0x14)
9+
CHECK: ExtendedCharacteristics [ (0x2)
10+
CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2)
11+
CHECK: ]
12+
CHECK: RawData (
13+
CHECK: 0000: 02000000 |....|
14+
CHECK: )
15+
CHECK: }
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# To regenerate has-cetdynamicapisinproc.exe
2+
# $ echo int main() { return 0; } > has-cetdynamicapisinproc.c
3+
# $ cl has-cetdynamicapisinproc.c /link /cetdynamicapisinproc
4+
RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetdynamicapisinproc.exe | FileCheck %s
5+
6+
CHECK: DebugEntry {
7+
CHECK: Characteristics: 0x0
8+
CHECK: Type: ExtendedDLLCharacteristics (0x14)
9+
CHECK: ExtendedCharacteristics [ (0x8)
10+
CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8)
11+
CHECK: ]
12+
CHECK: RawData (
13+
CHECK: 0000: 08000000 |....|
14+
CHECK: )
15+
CHECK: }
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# To regenerate has-cetipvalidationrelaxed.exe
2+
# $ echo int main() { return 0; } > has-cetipvalidationrelaxed.c
3+
# $ cl has-cetipvalidationrelaxed.c /link /cetipvalidationrelaxed
4+
RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetipvalidationrelaxed.exe | FileCheck %s
5+
6+
CHECK: DebugEntry {
7+
CHECK: Characteristics: 0x0
8+
CHECK: Type: ExtendedDLLCharacteristics (0x14)
9+
CHECK: ExtendedCharacteristics [ (0x4)
10+
CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4)
11+
CHECK: ]
12+
CHECK: RawData (
13+
CHECK: 0000: 04000000 |....|
14+
CHECK: )
15+
CHECK: }
16+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# To regenerate has-hotpatchcompatible.exe
2+
# $ echo int main() { return 0; } > has-hotpatchcompatible.c
3+
# $ cl has-hotpatchcompatible.c /link /hotpatchcompatible
4+
RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-hotpatchcompatible.exe | FileCheck %s
5+
6+
CHECK: DebugEntry {
7+
CHECK: Characteristics: 0x0
8+
CHECK: Type: ExtendedDLLCharacteristics (0x14)
9+
CHECK: ExtendedCharacteristics [ (0x80)
10+
CHECK: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80)
11+
CHECK: ]
12+
CHECK: RawData (
13+
CHECK: 0000: 80000000 |....|
14+
CHECK: )
15+
CHECK: }
16+

0 commit comments

Comments
 (0)