From 1082e93e75464bed81343af095aad4e294e3b358 Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Sat, 26 Jul 2025 22:12:14 +0900 Subject: [PATCH 01/14] [LLD][COFF] Add more variety of CET flags --- lld/COFF/Config.h | 4 ++ lld/COFF/Driver.cpp | 7 ++++ lld/COFF/Options.td | 8 ++++ lld/COFF/Writer.cpp | 26 +++++++++++- lld/test/COFF/options.test | 40 +++++++++++++++++++ llvm/include/llvm/BinaryFormat/COFF.h | 17 +++++++- .../llvm-readobj/COFF/cetcompatstrict.test | 16 ++++++++ .../COFF/cetdynamicapisinproc.test | 16 ++++++++ .../COFF/cetipvalidationrelaxed.test | 16 ++++++++ .../llvm-readobj/COFF/hotpatchcompatible.test | 16 ++++++++ llvm/tools/llvm-readobj/COFFDumper.cpp | 9 ++++- 11 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test create mode 100644 llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test create mode 100644 llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test create mode 100644 llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h index 91b6e632fa7ed..95491c51bb7cd 100644 --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -307,6 +307,10 @@ struct Configuration { bool dynamicBase = true; bool allowBind = true; bool cetCompat = false; + bool cetCompatStrict = false; + bool cetCompatIpValidationRelaxed = false; + bool cetCompatDynamicApisInProcOnly = false; + bool hotpatchCompat = false; bool nxCompat = true; bool allowIsolation = true; bool terminalServerAware = true; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 83040b534be9c..8cdadb2068ccd 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2145,6 +2145,13 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->integrityCheck = args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); config->cetCompat = args.hasFlag(OPT_cetcompat, OPT_cetcompat_no, false); + config->cetCompatStrict = args.hasFlag(OPT_cetcompatstrict, OPT_cetcompatstrict_no, false); + config->cetCompatIpValidationRelaxed = + args.hasFlag(OPT_cetipvalidationrelaxed, OPT_cetipvalidationrelaxed_no, false); + config->cetCompatDynamicApisInProcOnly = + args.hasFlag(OPT_cetdynamicapisinproc, OPT_cetdynamicapisinproc_no, false); + config->hotpatchCompat = + args.hasFlag(OPT_hotpatchcompatible, OPT_hotpatchcompatible_no, false); config->nxCompat = args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); for (auto *arg : args.filtered(OPT_swaprun)) parseSwaprun(arg->getValue()); diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index 2a82fb5cd8845..da2e4706fa606 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -196,6 +196,14 @@ defm appcontainer : B<"appcontainer", "Image can run outside an app container (default)">; defm cetcompat : B<"cetcompat", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack", "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack (default)">; +defm cetcompatstrict : B<"cetcompatstrict", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in strict mode", + "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in strict mode (default)">; +defm cetipvalidationrelaxed : B<"cetipvalidationrelaxed", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation", + "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation (default)">; +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", + "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with dynamic APIs allowed in process (default)">; +defm hotpatchcompatible : B<"hotpatchcompatible", "Mark executable image as compatible with hotpatch", + "Don't mark executable image as compatible with hotpatch (default)">; defm dynamicbase : B<"dynamicbase", "Enable ASLR (default unless /fixed)", "Disable ASLR (default when /fixed)">; defm fixed : B<"fixed", "Disable base relocations", diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 076561807af47..5c72cca522feb 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1216,7 +1216,9 @@ void Writer::createMiscChunks() { // Create Debug Information Chunks debugInfoSec = config->mingw ? buildidSec : rdataSec; if (config->buildIDHash != BuildIDHash::None || config->debug || - config->repro || config->cetCompat) { + config->repro || config->cetCompat || config->cetCompatStrict || + config->cetCompatIpValidationRelaxed || + config->cetCompatDynamicApisInProcOnly || config->hotpatchCompat) { debugDirectory = make(ctx, debugRecords, config->repro); debugDirectory->setAlignment(4); @@ -1237,10 +1239,30 @@ void Writer::createMiscChunks() { }); } + uint16_t ex_characteristics_flags = 0; if (config->cetCompat) { + ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT; + } + if (config->cetCompatStrict) { + ex_characteristics_flags |= + IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE; + } + if (config->cetCompatIpValidationRelaxed) { + ex_characteristics_flags |= + IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE; + } + if (config->cetCompatDynamicApisInProcOnly) { + ex_characteristics_flags |= + IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY; + } + if (config->hotpatchCompat) { + ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE; + } + + if (ex_characteristics_flags) { debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS, make( - IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT)); + ex_characteristics_flags)); } // Align and add each chunk referenced by the debug data directory. diff --git a/lld/test/COFF/options.test b/lld/test/COFF/options.test index 0dd889042869a..d131169eada61 100644 --- a/lld/test/COFF/options.test +++ b/lld/test/COFF/options.test @@ -60,6 +60,46 @@ CETCOMPAT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT # RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPAT %s NONCETCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT +# RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPATSTRICT %s +CETCOMPATSTRICT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE + +# RUN: lld-link /out:%t.exe /entry:main %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTRICT %s +# RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict:no %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTRICT %s +NONCETCOMPATSTRICT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE + +# RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPATSTIPVALIDATIONRELAXED %s +CETCOMPATSTIPVALIDATIONRELAXED: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE + +# RUN: lld-link /out:%t.exe /entry:main %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTIPVALIDATIONRELAXED %s +# RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed:no %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTIPVALIDATIONRELAXED %s +NONCETCOMPATSTIPVALIDATIONRELAXED-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE + +# RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETDYNAMICAPISINPROC %s +CETDYNAMICAPISINPROC: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY + +# RUN: lld-link /out:%t.exe /entry:main %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s +# RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc:no %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s +NONCETDYNAMICAPISINPROC-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY + +# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=HOTPATCHCOMPATIBLE %s +HOTPATCHCOMPATIBLE: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE + +# RUN: lld-link /out:%t.exe /entry:main %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONHOTPATCHCOMPATIBLE %s +# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible:no %t.obj +# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONHOTPATCHCOMPATIBLE %s +NONHOTPATCHCOMPATIBLE-NOT: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE + # RUN: lld-link /out:%t.exe /entry:main /swaprun:CD %t.obj # RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s # RUN: lld-link /out:%t.exe /entry:main /swaprun:cd,net %t.obj diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h index f3b5d5e3f23c6..e06fc39b5de23 100644 --- a/llvm/include/llvm/BinaryFormat/COFF.h +++ b/llvm/include/llvm/BinaryFormat/COFF.h @@ -694,7 +694,22 @@ enum DLLCharacteristics : unsigned { enum ExtendedDLLCharacteristics : unsigned { /// Image is CET compatible - IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001 + IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001, + /// Image is CET compatible in strict mode + IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE = 0x0002, + /// Image is CET compatible in such a way that context IP validation is relaxed + IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = 0x0004, + /// Image is CET compatible in such a way that the use of + /// dynamic APIs is restricted to processes only + IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY = 0x0008, + /// Reserved for future use. Not used by MSVC link.exe + IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_1 = 0x0010, + /// Reserved for future use. Not used by MSVC link.exe + IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_2 = 0x0020, + /// Image is CFI compatible. + IMAGE_DLL_CHARACTERISTICS_EX_FORWARD_CFI_COMPAT = 0x0040, + /// Image is hotpatch compatible. + IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE = 0x0080, }; enum DebugType : unsigned { diff --git a/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test b/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test new file mode 100644 index 0000000000000..9807bfe5686ee --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test @@ -0,0 +1,16 @@ +# To regenerate has-cetstrict.exe +# $ echo int main() { return 0; } > has-cetstrict.c +# $ cl has-cetstrict.c /link /cetcompatstrict +RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetstrict.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x2) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 02000000 |....| +CHECK: ) +CHECK: } + diff --git a/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test b/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test new file mode 100644 index 0000000000000..18b3ec70177cb --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test @@ -0,0 +1,16 @@ +# To regenerate has-cetdynamicapisinproc.exe +# $ echo int main() { return 0; } > has-cetdynamicapisinproc.c +# $ cl has-cetdynamicapisinproc.c /link /cetdynamicapisinproc +RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetdynamicapisinproc.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x8) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 08000000 |....| +CHECK: ) +CHECK: } + diff --git a/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test b/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test new file mode 100644 index 0000000000000..25cf1db3464f7 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test @@ -0,0 +1,16 @@ +# To regenerate has-cetipvalidationrelaxed.exe +# $ echo int main() { return 0; } > has-cetipvalidationrelaxed.c +# $ cl has-cetipvalidationrelaxed.c /link /cetipvalidationrelaxed +RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetipvalidationrelaxed.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x4) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 04000000 |....| +CHECK: ) +CHECK: } + diff --git a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test new file mode 100644 index 0000000000000..87208d24f9fee --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test @@ -0,0 +1,16 @@ +# To regenerate has-hotpatchcompatible.exe +# $ echo int main() { return 0; } > has-hotpatchcompatible.c +# $ cl has-hotpatchcompatible.c /link /hotpatchcompatible +RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-hotpatchcompatible.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x80) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 80000000 |....| +CHECK: ) +CHECK: } + diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index dce8e60bda1ef..2f158e1bbe781 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -414,7 +414,14 @@ const EnumEntry PEDLLCharacteristics[] = { static const EnumEntry PEExtendedDLLCharacteristics[] = { - LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_1 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_RESERVED_2 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_FORWARD_CFI_COMPAT ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE ), }; static const EnumEntry From 884e21f4ffb9db1cb61183d11866674630942ee3 Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Sat, 26 Jul 2025 22:23:57 +0900 Subject: [PATCH 02/14] lint --- lld/COFF/Driver.cpp | 13 +++++++------ lld/COFF/Writer.cpp | 13 +++++++------ llvm/include/llvm/BinaryFormat/COFF.h | 6 ++++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 8cdadb2068ccd..0f064323db46a 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2145,13 +2145,14 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->integrityCheck = args.hasFlag(OPT_integritycheck, OPT_integritycheck_no, false); config->cetCompat = args.hasFlag(OPT_cetcompat, OPT_cetcompat_no, false); - config->cetCompatStrict = args.hasFlag(OPT_cetcompatstrict, OPT_cetcompatstrict_no, false); - config->cetCompatIpValidationRelaxed = - args.hasFlag(OPT_cetipvalidationrelaxed, OPT_cetipvalidationrelaxed_no, false); - config->cetCompatDynamicApisInProcOnly = - args.hasFlag(OPT_cetdynamicapisinproc, OPT_cetdynamicapisinproc_no, false); + config->cetCompatStrict = + args.hasFlag(OPT_cetcompatstrict, OPT_cetcompatstrict_no, false); + config->cetCompatIpValidationRelaxed = args.hasFlag( + OPT_cetipvalidationrelaxed, OPT_cetipvalidationrelaxed_no, false); + config->cetCompatDynamicApisInProcOnly = args.hasFlag( + OPT_cetdynamicapisinproc, OPT_cetdynamicapisinproc_no, false); config->hotpatchCompat = - args.hasFlag(OPT_hotpatchcompatible, OPT_hotpatchcompatible_no, false); + args.hasFlag(OPT_hotpatchcompatible, OPT_hotpatchcompatible_no, false); config->nxCompat = args.hasFlag(OPT_nxcompat, OPT_nxcompat_no, true); for (auto *arg : args.filtered(OPT_swaprun)) parseSwaprun(arg->getValue()); diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 5c72cca522feb..103dd7e392ee5 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1248,21 +1248,22 @@ void Writer::createMiscChunks() { IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE; } if (config->cetCompatIpValidationRelaxed) { - ex_characteristics_flags |= + ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE; } if (config->cetCompatDynamicApisInProcOnly) { - ex_characteristics_flags |= + ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY; } if (config->hotpatchCompat) { - ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE; + ex_characteristics_flags |= + IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE; } if (ex_characteristics_flags) { - debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS, - make( - ex_characteristics_flags)); + debugRecords.emplace_back( + COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS, + make(ex_characteristics_flags)); } // Align and add each chunk referenced by the debug data directory. diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h index e06fc39b5de23..64fe2160f9970 100644 --- a/llvm/include/llvm/BinaryFormat/COFF.h +++ b/llvm/include/llvm/BinaryFormat/COFF.h @@ -697,8 +697,10 @@ enum ExtendedDLLCharacteristics : unsigned { IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001, /// Image is CET compatible in strict mode IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE = 0x0002, - /// Image is CET compatible in such a way that context IP validation is relaxed - IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = 0x0004, + /// Image is CET compatible in such a way that context IP validation is + /// relaxed + IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE = + 0x0004, /// Image is CET compatible in such a way that the use of /// dynamic APIs is restricted to processes only IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY = 0x0008, From 9e6664e4bf8bd9ab916a6b8befa0c918189a9275 Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Sun, 27 Jul 2025 01:19:33 +0900 Subject: [PATCH 03/14] turn off linting for COFFDumper --- llvm/tools/llvm-readobj/COFFDumper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 2f158e1bbe781..96e0a634648e4 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -412,6 +412,7 @@ const EnumEntry PEDLLCharacteristics[] = { LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE), }; +// clang-format off static const EnumEntry PEExtendedDLLCharacteristics[] = { LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT ), @@ -423,6 +424,7 @@ static const EnumEntry LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_FORWARD_CFI_COMPAT ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE ), }; +// clang-format on static const EnumEntry ImageSectionCharacteristics[] = { From 539cc6fe3d2b51fd4982cca58ae3336e1a12049b Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Sun, 27 Jul 2025 02:51:52 +0900 Subject: [PATCH 04/14] fix test --- lld/test/COFF/cetcompat.test | 15 +++++++++++++++ lld/test/COFF/cetcompatstrict.test | 15 +++++++++++++++ lld/test/COFF/cetdynamicapisinproc.test | 15 +++++++++++++++ lld/test/COFF/cetipvalidationrelaxed.test | 15 +++++++++++++++ lld/test/COFF/hotpatchcompatible.test | 15 +++++++++++++++ .../tools/llvm-readobj/COFF/Inputs/has-cet.exe | Bin 94720 -> 0 bytes .../llvm-readobj/COFF/Inputs/hascetret42.yaml | 15 +++++++++++++++ .../test/tools/llvm-readobj/COFF/cetcompat.test | 7 +++---- .../llvm-readobj/COFF/cetcompatstrict.test | 7 +++---- .../llvm-readobj/COFF/cetdynamicapisinproc.test | 7 +++---- .../COFF/cetipvalidationrelaxed.test | 7 +++---- .../llvm-readobj/COFF/hotpatchcompatible.test | 7 +++---- 12 files changed, 105 insertions(+), 20 deletions(-) create mode 100644 lld/test/COFF/cetcompat.test create mode 100644 lld/test/COFF/cetcompatstrict.test create mode 100644 lld/test/COFF/cetdynamicapisinproc.test create mode 100644 lld/test/COFF/cetipvalidationrelaxed.test create mode 100644 lld/test/COFF/hotpatchcompatible.test delete mode 100644 llvm/test/tools/llvm-readobj/COFF/Inputs/has-cet.exe create mode 100644 llvm/test/tools/llvm-readobj/COFF/Inputs/hascetret42.yaml diff --git a/lld/test/COFF/cetcompat.test b/lld/test/COFF/cetcompat.test new file mode 100644 index 0000000000000..b2ca293771340 --- /dev/null +++ b/lld/test/COFF/cetcompat.test @@ -0,0 +1,15 @@ +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompat %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x1) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT (0x1) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 01000000 |....| +CHECK: ) +CHECK: } + diff --git a/lld/test/COFF/cetcompatstrict.test b/lld/test/COFF/cetcompatstrict.test new file mode 100644 index 0000000000000..31acf13010c24 --- /dev/null +++ b/lld/test/COFF/cetcompatstrict.test @@ -0,0 +1,15 @@ +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x2) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 02000000 |....| +CHECK: ) +CHECK: } + diff --git a/lld/test/COFF/cetdynamicapisinproc.test b/lld/test/COFF/cetdynamicapisinproc.test new file mode 100644 index 0000000000000..22edd22587bb7 --- /dev/null +++ b/lld/test/COFF/cetdynamicapisinproc.test @@ -0,0 +1,15 @@ +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x8) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 08000000 |....| +CHECK: ) +CHECK: } + diff --git a/lld/test/COFF/cetipvalidationrelaxed.test b/lld/test/COFF/cetipvalidationrelaxed.test new file mode 100644 index 0000000000000..e5a19f571f051 --- /dev/null +++ b/lld/test/COFF/cetipvalidationrelaxed.test @@ -0,0 +1,15 @@ +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x4) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 04000000 |....| +CHECK: ) +CHECK: } + diff --git a/lld/test/COFF/hotpatchcompatible.test b/lld/test/COFF/hotpatchcompatible.test new file mode 100644 index 0000000000000..f705584b26617 --- /dev/null +++ b/lld/test/COFF/hotpatchcompatible.test @@ -0,0 +1,15 @@ +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s + +CHECK: DebugEntry { +CHECK: Characteristics: 0x0 +CHECK: Type: ExtendedDLLCharacteristics (0x14) +CHECK: ExtendedCharacteristics [ (0x80) +CHECK: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) +CHECK: ] +CHECK: RawData ( +CHECK: 0000: 80000000 |....| +CHECK: ) +CHECK: } + diff --git a/llvm/test/tools/llvm-readobj/COFF/Inputs/has-cet.exe b/llvm/test/tools/llvm-readobj/COFF/Inputs/has-cet.exe deleted file mode 100644 index c77060d976d2ff57dd628bc97ce1261aba5ab399..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94720 zcmeFadwf*I`S`z^WRoRiIYC(nBC=x8XuL!tl60Z$!UoR5M&kvgUSko|YL&t+U=>Z= zM6)?=OIvO2r?&d({VukOfVT~iT)2Zb5Eazgo^`!MP)I=8@B5jvn*`LpzOUcw`{$1r zCue5P%ri63%slhlX14aq6}DWP&6dZLPTOp&dCNba`upGi^zwPwxV6JQ=1Sroa=bMtMUz(tpOzI*!(^Urp<3QIGf z?;cSW`$lBO>)Ge}vD0=}5WjwG&F-n{J$?6c>OFIJwaPd1_1k!ROQ!E0r{2?cpP}A0 zyU*j@Q!;J0SG@!3eaX%9ZW7qX_N1=HX1n3OeA_EKzjJN&TaRtLZD`K0QMTtvS!bo* za2)Sq753TXCE*;KEng)KylpG_DoEsCuC2Z?TPRbOR0~M^7%rXy(f{o6SRezwY1J;rYwLd@O!W{_sfOGyNc> z{&{S+`m-0^aDDiCo9(0rNCKwq2Rs=Z5mNtrOq;WHq|;_QW1 zM%739Y8ytrE5DS_ciklc|7Cug?Lj`)$!^*Zf_nyi3f7c!!Km-FV4xnng#_X@)asA$pFl=|IF` z{()kZJD#wc7tk7`JvEvfr&&3?4R@7#Y~)!?9;011t}gZIMz~Z5xfR!C#^VpUtW9fZ z9wBIKH2+5K6}+#Jw;GqL0IddO5iQ7!-A@=zX2!|$bt7*=1*p*t-I;Re-mdV7%0!Q@ zJ>k0H3cD@x(RtPYue7HQGM3hS)mAw!;$w67Ga$gG1=?F2Q;D0ur{U(eh6n;9dFLfk zBTUa3Dl(+9+q{|d)cdVW6`4)_uo|Z1QPgJairmPMFa3_$r)FKata*2&lzIEn2ze7KF{?a0jAu=^2*)NSS@>3EDYT&4 zUlO@2RK8Ao+CM^%UtFT+ZX=kl$BP<5@uCfSY(#0$yFFZD%qj|b+ZGiX)10|&A#Y-l zQ;)7IOYN!Lp*Qca@D%-iscpGntPnis^UhIdFKM^%-MY(sm&R7^V8n(t?T!@a_q#jh z&@Y8bD^J6eXGpQN?h5BM?T8eaYe5l{d_Uuy?QlQN_2`tJk~yt|^#b!jmT5|3j)L6= zlFfr8NL{)Xcu6jqogGVY8?;xvOQ; zG67fHeCkcN+h76o^n_Mw+_Y(>y?xU<0(#uBhV=ISx6r)*P^}(ymYV;z0y!2ADihU? z3Tn|FOi2E>=Ue5r%R4%u5ir0JIygs<|FzV27$A)wBp6d;*P2l>4K-*Bqnl@J+yIg$_%CIPWlt^<0L7Jw%5Lq~0i&&^a(BSk=x^+~Ej<5L zf8!@J=ie3y7(0xf%5Hyry1iy-m-cIaWc3Ze?N_~EgEqwBnh4MPVv9j;;bhOvAv{Z)`$n5IcZ`u}*2pEp5 zFSgtK(Jp%+=D3((s(>_|z-nPW0&)GYx96@?rLEK+Fm_Ar*}Ap0?+#g9STnSZvTllW zIv#}~ml+s{xgH^?t^LmkEh=-Cg!@T&hM8-Njcu^Ljaj^q949XR4&d$E^tN|A`p|7U zy<*q{rJnKa-)N6qXgDq*ceKmd>F^Vfg&K2ACFDQQ?g`7}&E3}NIF$q@D)~HtQ+CB1 zClL>LcSW>lmoGN9h*-=~$X^-EGG+;zdIe)zd>!{Q%k5;9-j?*HDtFYd-p=%Y!_t^XST)z`7t${ut-gPh^8jx&c@kplB~ z1X3TUz24%-o4O-~<|IEq{fOph^0?y1eEc;o*Aj#Z|fyEHh#1Y$;Fbqyx6%Fci^WrW;Oy3fZ&khL62m zXNZ{5y6|~=`khR>;hNYvJl2+Jr7gD7m^H#me8s;73$$@f)Mv9@0V|^B`u;x$jdqZs z{tbK&8N0MqJA!NMnSUYe@eRRfZ?SgYK1weLYPYp5(CQPx#@+_vON*1YNb*4W1CBRC zhzXIOX~XTI+%`Sh28Q1536;0ivcB4q1>q?nuj|@rtj_!EDXN`r*G~5r>y2#7fDjUvH^ za=U{3H`@K_w->C?V;6rCySQ&b?BXw4E>5>g{L|RQpR=!Ad{7d2?~h%4Sc2NPfY6SM z_r)$gME)auE0$+Ltj^g|SD5{-;*zeD{-yB|9s{o7veJ?O>$o`B*(Osh<;;xZifn=G zcuO31^0R+Xb=>`(126*Kb>UM6Nh~qNi+J_oMfti{cP=SdBWjz?r(5epX5?^~u@S2eegg9rjtfyBt8YlaNQ?m z`_kbe(?gM{D?*&Sne{4ogz==hvjMaAF%4?-h6TDX?U+WI0xSGf7Hmd_G{%2YZhuy>uuAT;P!1sgni?YgAbEaZ{8gq7WBTQHHpS6*(%wL zXAeHSSJ>a6vDLp?G+SwRDb2HnE;1?YUiEijZm)=(5r|JOAQvdU1!>g$6{7@#j|V%d zblUv^IVqRQsoYItkG#nc(?3_x=m_55q*{5Yx%1 z7q%OPQhJ=tQ04Pf@jUWN{OM`L7X)Iyy!LEd%I9YiDWBgCT*Cre1Xv4dQKr6Cvz(;0 z=+1%qGgY@sdnjiWk@~Z6o<@J8;83p)plp8!eWwkV3>%aw&{8+7T`SHTp5Y^q4m9@t zGBhS{_ei>I{C;it&;jN`YZAs(xCNMuPpa*g{iLxxaz$$Fy6qIY+gd z;yx*^xSpfh|4aCuWEHef@h7l0(zhNxnk<$+9B9+RqnNZ7&iO|5!<}gPYRlWR9NkUY z>GqV1A%(vI8O7S^Llg{Y=U%-r*-<}*MCec+R=H1 zpFKK%NZK2KCDakpq|tAFCao1E&^FU9r86zhH2Zn^teSl+9{^mBZtOGq%vo5zYD8l% ze3jPpO~{%^CPKFw6ZAa@7wD?4l8q-(9P}n4`-9XiS&t`c$nZI9C6Z4B0_upkLQoHX z-1m9%GbxP@E8;}Uocs?l-M9rNaj`SHEYGPm3oF68sLc%SaC&IOjRX>vVHyf)EwG-iU8moRHZ%<>@lR3PH zHx+juSFTMH~(>Vmbvv8B#g+bplLwZg5WPF~w2uM^fb%Io;G_sOehZB$;4wfFLh zU0S?Gc)XyIfUo!i33nE!iVZzada4qCK%ySI#hE-_c#K4byS!CqP?!nE?kd}k;W){U zYI9S}HB!BG!#!srjO7Ns(p^MK^zEtoOB>K{iz0)$tH)fQ!NsySxX&UVi%?~Ko3#F{ zkzBO1s4_(5oSu+RJ2q_!8ICW`m;Bv+W7`@ZEswr4wR}VHrS96wu29VNm;e>{#*2Dv zE(3BCvd2P{%ga2dNh~FaCuH1JTCW(xogrhN?4Z%pY{5=D!wg@wBV3@zP6$RjoWAou zY?wMeqWPLW^sO52(;i%}r#n-Vg6RU`v{!l?lu=>CSYbRcq+GI{axv-}uP+P3t05cpyAXk6&bOs2(42 z(9P74${i%qk&f+Vsu+DeEy(Z4y_#OoXw3q5~`E4dk20DsUfu1~xB zV{TymtL1N2ohU1`9bP*jRVaItq8oEAzd}t5Wv!^FOb3iln!B~8OPLFCKWa()l9A>- zz{IZ`iITSZ1h~4xNoK6g44wnX_}B}eD*n}Zq`)m=*7`Tb65W`14`PuX8#`BCblTyo z`er0oH}<3I*7ewOUnpMdQ|c>`mSW3wI>i*KfiVmj%YBv}OgHA}ND$_J;k6YFip -| z^y;d}r!m)J1yezbxo;z4woxn#;wcrry0jkqCk9Iy+Tyc*GIinogZ2O=YQp*G$SVOgdXB#cL%m1|ewGYx}4o%VHe!H?BL4cTUdOG2+I^PyK7)&QZxe0%3F;=ym z^nI<6PqTh>wvpjmLq@N^HJ^2KogUpx!Sxh8J93b~Bf|AOqSW6)|y3N7Nl7+W>~Fj9~KH_gz`tb*|~2ht$>Utc$bMaiML03c6>2#o)h_)ypV|WNq8t@i0*aW?PVG|%$H>CS=`aUw=1o0PapfuaV{SOW2frXjN0C+4gKGWMi&V`rJwV7Wq;^7kp%v0AqD!9fxmG02J2P6NsCJl3PFvl=> z>KziG-VNa~85o6W_h?|yrJ)%!SL)p?;{okfQm!f=f?M<`VLoW=!r);Pnq6#6DopptJc&$Y)0(NtrZnyMJAOh6E5UH$Vsbv%{K=W38WVoRaNi@} zyxYRZ>y_*Dm%7wq5<}zdzXE>TwUW=NA{-VXE@Eqmnb#DkrsU#D5;-36|2Zq?PkEU? zm*I=M*IG$`k)-?72v2uP_F)~4k$^yVKE1eum)fz+3bbY`7@x{SW1lGLm2FvclL01v z2|Rys#^_#W?80;rnI-Mh9-)1V{gi$~Xyws{(9!`z=;*8=v^Z-BEns>4F9>4SD(R>x zW5U$zWp8FcRU0S4R<0Fssj@o|pO#KG(Xq-MDq>GAB|;mR6XGG1yh%oqH4U$N@fk9sw)>65 z8XtwDd#9Fng{mFr0WNYJ3~{h>n;vtYLR76mvz9p{a4L5s$19)$C*EjFq|<*&PsIo2 zxW+zP0$W<){jTlI5U7jWeDOG3nrtJ1Z~lBZlUYIvoUCQar`;R=hm@Ejbpd)+_j)Vx zZzBC_Tk&mpiUjdhu-^ST@BT%G1*(q~wg3XX0={Q~Y`F1>|2dl%nLU)eN|L-gVIQh1 z;XI93g}RQMDs|_|N>06MXy*5Yz%vyh@(ZfvbsTY50fHbH2e`Y9@0U>J2?klAJZK@oDN?A zpIaS0Y!7>)hjYSi^T(hmgRvWn)lQWf>yPgJB8Ba*D<=?BAW{WUS4jmJi~Gf?!{QkY z$6A;_OQ+6iU*a}r48R(bf#tm4^`HnpXd0A1OxzKZLSIL-MzCWknsq51hKda}FDK6BPHib_v$No#7N_|69eW+zfN13$KRc zV{u4I^2zvd47TrQ#8$aNZu(G7*YZvcaX@5B*FK?)U+~bt9jG3UYDC zDAe&>L)<1W^MJgy-mS=&-u2;?%J+Z?Wr|(n*LpOa76ZXnbImXXYnlZMJcMFwZuu(U z2W6QMekU2y&@U9S@RXz=a)Pm)y>-TUc3W~jT|pP{Mld!Tt;z?GhUv~=Y`O`#C{cS5 zG{b~mc%T<`(2HW;bIqsWZ&;F50*fs^k3m2Ifkn024mCC$zbO@3X4hjhDdwj!taI5` zm7y}TxBA%bNRX|smU&wverxFaYs}2nH;4VO))T8KW2ZC=tqOhD2wi>dbb;)xGQol%)+e}-`6PNdcs-CEQHY9jjAh?kmX;-9>f(^$m_?2vS>D%1=FneyP5Yd zKBBLrPwmT;wdhx6ck+`x>{eMguBp@r9(uGkyQs6+B3);a1cBcyHF!5-=sS$KiQqVb z^sMns+C|puh0%FKJ{zuU2wCDs~BK>`i zySM+Iqf#AeGpo}$e5PV=9O$P&&c+Q zrL7jvkeHqoBK zHEQDy5k26j9*_AYe1`G>OuIv9{>V|Fym>dDZs`Qpx@|U}Kd$GPKZjSaJOiT#75|ak zO_QY0{d>3KjXV6fT8aVcd-!DR2s<$Aq>7_cK4jyzMO<336-KT>$PT8v!k2*63w7&b zD5G3LlJ>NH0qr<`fj1{IjI!+h>vAY>kG#hx%vj}ZU%QvXrI3_{f!1#dlR8#{Uv z=@veiFfcq{#|t>E@|sAmL(Jc^t%?vcL8bm3MgQWd=oREmFaK5?IX|?o`V`}haMG`$$yAyJ`GebH( zYngr6TA`aPPFt)-NM`0ck_1vktfp6SfUz18CaCN)2tTQNV;76G{P<(i6@lj@cCs{t zSZsyNL@Qm*+W4$#Di)tpwjkCbLWM*LuA_b^b&2{Kee5xcab^OZ8@j%Yc8NGct+gfQ zj}$vEf(tWOXu=8Vj0Qrh$*u;xjppkGycH$L_SZ)rO!~|tpxic^dvs6bOSXr5V>SO$ zvvnN=hc(tJ@C*tY!G-4Xfyi8Q;XtI`oHr1;$-I0ZqMN~iNS!%(AhOInr#}*FkS>oK zh$p~-sSyVSo(u{=H7Iyh)ROU9M8BF|@bWK}SWP0GW^)s~2+dLCMo5hTs}ob?19Y8f zrq7k`{7@x$U1zb4V26u4{tC5|*)ueHN3k4h*a_#V#~!uH?GCem@NJPaMMnm$n*m>( zw0mY8GVB^Y7Jh7}xTTCU-@HJID7{({j88hUxDsca)I!6RI*|%-%`tN(Da!hvwOw?1 zjm$*zQKq5c>Xsa;Y@`?uo7Vw_PU?N6AT!)vB_ssolcmXkdiw zo5-#k2SuuU;sJsO_Xv?Wr6UaeR1~qF9Gai7J7?u!R|t^Og)!y{3aV0g!QSAgvpn@( z_T_Bzr>jx9nC~HBS$psxIf-$p@GC_i)?XZ<&Dlbs=Sig(eacOLUI+E1S`i;u7 zp<&YP$~P(Pewj?{7HcIL5M>xix08f^5VxEkqQAo7Gk}4{TNo}+CxW@#qP=G=+86hK z80{UtG=DXQ23vb$TYv^Al~J^Bm|vTbX!jd|w!EWhI;QlrOkY_L5bnQ>LfM&z&Ac>L zW&T?}a8`jd!Ec@(pX-4ZE(I)FpFyPC;(MPS1ZQ499BDqp23hB4gT7DAe)p*F7GE9$ z$td^OScb_enYLFyxF6H~qUk~H@tsPI1o1-eu#;7MAwm#sLQ>gie#9yzd?J#{E$DSQ z^P(&_Y4>yYTQg&O%4Oa`t2=G7;E_bthMw8;C#gLjGqo^gt}_6Tc0WKtFfz)VE@Noy zOuNOv&h~vL9D``QvUW!AhQ&(O1g3X`_A@bnf0cdua+$!DyZs_PqfPikWYqChSC$D+ zFss;%P)o~oWqRy77Up%xo!5Di!&u~1qa$MKhkGY0Yot-Q)j&dd{@EH;zfXQQ0d z+Hr74^qnH@!8VNX4<=e>0`Z~}k#daJlh3O~JQKg&lGLxnPQ$j29&8VTA@3(krdM63+I~^7xrR@)eRjO)0y8q< zE1DD30$Yx5kJhYYVq<2pY6m2Vc4StRY6naemZC0k&9%H1_a&sXC83;K2}-r-z0?>9Pf*|CVA1-NjE4VdQUf4+xA_czjFKcn0$sSMME53_OdA-3 ziJ5*Fo6UVtq%X|~*39N(hd`O}Gee-7m6;0_l{;jUP)!P8bh}11NsYzLM~}r^Yb+QB zWtqII^d{DY&l(H*dTb7gRd$y-bAeAkMeVs2`C?nGksmTX3Z~ajubNzjk-2;u zVLf+FT`g+`T6E(SAyQg%R85K+cKq6H81Z+`ishXf%v~>@BnTov{WS6I{);@ z!L^Jd+gyj9`@Wp)^qNaN@o5=b6PneVWY#UD4a(cVIx3d>;(DH`Q$;0&slZ&ND$`_6OvAUp1F@pRGmBH-4V6#ocXGK$W)mlomg4!X z&5oaWfzAOTqtpEBnZRX+j%R3YRggBCH}HO5?N#08T*5|2GKa-SYkNe8Bk$NY7JJ{__n+e9v%w&BMBWOt=J*?WzY*a`*bJ03 z+rsWz!?Jrx&X1`uc{$Mi4dywOX>y*mv?!PXw$i>R*Vo#qm%qv?d`wTXD3<^60D6Gs zD}}$TAh5c2%!j-Zp;O+626Q2&CFQ&}JXw|hh2$3)iK>?sMM`{Cca`e0xduurqK}E< z;ENigGxZH~KN}{v9`h9$tc98y`4yi6MknOwG3mfby;5E6N(juh<^-&8nH;h6=vvKI z&|bMC?XJH^kij(rNF1XE_g(yTjNT+iCc$mE)LC18eyPj}_zplUlrGjuXc--B;A!Dm zK`$RR9hpAP9q8RnR`2SL>YaN~?~chZxOc~VQoXxO8c_SWxr+Wl6dRfoa=?LJHB_G+ z8Q$u*qoVUnK0A`{tGXj6Jd%E~reKlHv8q?#^s36VuWI?jVXRAA&EJSuXM7Iy2vPZR zSbl4Cgj~6p$U!5oGzhougsAClhgcT-!lwtzUzG_Chxgtu7%x^7{VR)ppg~8`Eu}ty7)QWS(SFmof z`i(*K304i3;V4#Zw6I^fEmtzuSHhuP35Ry2C;1%fLO6vA#VIIuPV$%6cwu`OjPlFh$qc?H(?|vT)I(io}t_ZjbMNiiF!3sgG z;kaUGmP|A-l@V}J3i($%2Hq-hMX?N3|s`c^xkjg~zF>oSMQoRxvJ)%FR z!#h)r6 zcn}wHp9jx+T+8(e;`p2Ue8h1+*XxMa5w9m+&lMFUEhMQ&&s`UcChd_`t+p0>>NMEN z)#C4JzShBJXA(5|majg@BE zq**>`R*JS{nw990ah?uy#{c1#8agM6!3w7#D>d#oaR^hc+AfO2A?8fFq*~A3lPPvD z!m&;4dxKFg>Uqt44}-x`vZ|6bea0@P9V72C|H$DMsY2K%+b4x^w^BNHTkNG_X&N|o=z;-{}=8L$U|YH zmmg`(8>c*Y_2`H8$UZ&(0~yV=(udZ(>K41Waf-*VrfPQES5g)g~(l#ngk#6j#-R@GRoBtf=Ru`WAaSLG9j- zMW3|>O5x!zE4`f6z0i{yF9(L~+N!RU%e!UqFr%#_P_)pKZu5J)mV6{unbsW6J-=>D z&l8`Yg;0$O^fX(b5oL-q)Z@(y!Gv%+Lfo#x_mMn4R7=!NDNbJL#!m!Uco0Gs(4sA* zj}?-=jDW|S>^-Ik^ONkylxki`H;yitOF>H;5r0V9a3IGX9@-EpDJgCZIc`t659H*8 zhe_Pi`heqhigV#acgq7MXqq5@>v9kn^yo+SNM~w#;pixa%VoVQy#T2qm+f(|l(p-Jjb zMk)3yT)@Se;V?G|@Lcd@b+iVZjvljYsFXOMoQrZIu>+2^?2-0J1GA19Ctd`#SXOGP z2=~G{_Qa<<;EqhO4I#MVa$x?MWk<8LCeiOueU*^In5(@Imxv2U8mxED7-Lw@efXhK zQ?oM6;=mYPBPJHb6a8EUA$5aw^U(vCkJ*de<4pVy`x5d8F1Cmu zmKvL4S-2YFY$4rx>{mjFV%L@|h+TW45OnS7c16#HiX&9qfnc3{hhjn?nbm3c^bD*Q z8ARErE-cAx>Nzj4TOn}d#O}_*wS2OL=$=}2b?K?$GpoL351*#3@M;9ktjdI5B-I)4~6|5R_2-L|?G&-Mre|jgTpS)#&gy ztFE+%tJywsWCsa&6H7~L;&pa^<008S7mxC{76fwF`<;RFN&>mBWb!Q8E0nkDgb1us z8!DPFLgk-D{tgalVB^QCuct>p&I^x;e(VanykA7<=Gfn(Zj)|~eMkayb8M3Y=;qkP z1VZI+WkyzyUtXlfb9Q`kx%PBmRPTaVjvl`xN6`6kairtabRVDo8)ANOl zJW{HxqM|v=-u2HN{5_^fs=En{pu_D5?RT0vSj6Wj>Y>^g*wWt3>nEKiuN@2O=Ko6^~4)r_A>u^ zhb%4ful)ma+OPd)-6BV{?~KSfl{-@9jeQTl%Czw`_WkKCn{COM#=d{b`(KTHvR1-x zSgb=NH~J1f?iNGSqMjL}my4E%TK78x{nrD=d94plv~Xa++}7(EbA}wvzb%NDHC~G4hg5FN8X&Hf# zF>wz}eaJhphnKJQChlsywRBEug7pQ|UHOJbzFzu>fN!O>Fiud)qQPjnFuV^EymZh05v;x-d`ZwKddr+hwe$&9TWs=MNnyx>M&K>nCiC8s6MEI>zZLl?>xBD~ zAh@bTvCdpTdFWq)zun;lcmZBWYg5-K%XD>(i^wpOn@2#xKk< zKYo`csihU3iGnm3zdT1Yx4xa~fXz}ipnz6=5#%J<~kB8K2ska+c`v$3&v+8YDXI8y^ z`a3XXimw*gsaPpXa0d{jwzV+uH68|OR^(^iZ+GL(dNmOK;lKZh4@b34Y zjJx|_kdz8VUFEXDx({aO@iLdg!_$sJmO#2adU)8Pm$(*2d@V{r>Ul^$Vmj65(eWbK zW5+*)8;loqL3VGvS=rL9I*hShG8^U2m>-g5@SQOikuUA~6Q7U1Go~NrwF5B642D@L zm&jGj*SQ9@UPjo^J=NcG-o?d1@VjP9F|5g5r4{zD;~611N@SO|itKcZyuMZ^Lwr`R zIUO`*H-hk0di;+zPHc$3G@S0T3Qp*514kBao|P}ri+a(EUNlUPO)@$KV}e9!vwEthp@!D~wM#rQ)&K z7M*UEQRbN;-~o@>&);I{3|M9dO?U3OOUExNFbmn3Rv3E>hh4OXpwz?leiy*%eZpV` zt0(UX=cLA)E6Bw>#tg;z&-k*U)Cj||4G}1s@Nuq{0OTyywg&muX5F#dnQGPNarc$u z&obut?Y}csZ|jwdS-Hk1FOiv9t{a(IR=#`xTfPt3t-f+id-Qp`n!A@R@{XNGBNl%L z8Wf68yZ~67HISpfZAYkca)LS!90>GQ*-=qO@9Hf}ho_p)CWK?MM^1yvjx6699_rm0 z8M6jeZaP)8232u7BFivCC)^_kV@85#55d z1A%Sy05&(Utt@q-IW7ZgQa>oONO(_SbP%*Ky?+g_gvOX=V?Aw2yDx#+g=K;d3YUIc zYvQ016$juoWbb}JV)IJ$_`9oXHJ=XG`wdh? z-n1audnD{XkZ%u9K9KL^fSxgw^IeQ0MCc6NSWg#!B*Hs7@V35u#tPbqkT@bCio#f6 zds%CKOJI8yMn^f)C>w6{V|(N`;-4fF1A^VfjLj?AeAw=SN%mH*XJ$tGel0T%bj=-L(Mq>;6=17#e;X;leeZ?e6 zyZ`qF!JG+J?YbOO8p__7cFzXA8D8ImQVnvohl!9ADUb?$sdJ-!xsfv^>`YBiNqQ&k zI3kqaaNNd>kX>ddgP-5&E0N@MhuDv!M{>31vsA95HHXYPJu~YpdTp)AQUuw`-4Od1 z*e_VaMdmwU5Sxh8>I)Q6f62n24Gh;xdGz2}23?Kv`@qK(LGJ~#~s zOXYb^D86W)Uojg2t;c6q5fs@p9&s425?^TEq&^ti$cb6s@f}2 z!+4CS`G^Jnj}l&Cg;z?r$qI`x#$2Yt{mTpdUTgWwrFKXymmw({nFAZ5mV*;M8&+G0 zClS_$P+)5f$^bw!q} z%PE&x2cLbcqnvNfAPri*9>0~kW7pK{vB*srsTV>+rhN>A%Jn+#{sH6t8l|cb4}y5D z&783r?%+9@&iIA0t<*S;Wkm;nDO0(|*oq`%Y#p-$?LCK(`O60Pjx)W^Z21@=OgWqwLISJP$Q*$v4?fq-h7jM(e`4wv`_NQ#32gR8#w#HU(#tBs$_JL z+k|^j+&BBvJC+~f2_YliKobKTH#A=Ii`Qx5I%Y>N(3E@ylR3Mmv05rY_1pws-LSkw z9iFbSWo(tAq~=2O%FX64FQq94_%*<<0e<82``uiWPkv9DqisgxUTTzK%T+qr#-5|2 z=Fw3hll__F{wn|Ke8~`Z-}ou7>bf2|$z3exhycg-w9K@LEwv7p?`%@S6O^+u8#w~t z0b247{$%;3e*Yd>ue1%4K_77RN`&t~!CNSmc-z9?)s5)hOvA1hx#w!uiq&w=fJLiq zk>TcoSJes<2<8cgRM_fEe~!SQ9C?RT4gqSOIVjzu!qIHEXG&$$s0_Ftb(O(R;ux8uN?5Ejyj$aF`3#7ksv&ogQV#dxE)_A&^H|?2$&R}3Q6tLwVzuNs?bmoUZAvHFMN+>9pK7Y8u=a(x;}prvsE~h@p)#^dyUZqq z<&EYCFH7qz=T<3q0`PklTJVR#@AX6P%0j0d@SNn;ntlpK#J900U=I$Sop~gnkm{eF z*?4w-X5-nBvf_hh==x6tsmxI3qne?TrO=w9@O;)3&7@`KD9o0cqvk}gporuEuVMa3 z2vUm}X7%`LAw$is!hLL&v~nCvKXRsZm*eFasaJ65_j2ZnC-*wmT2K#x@m&~wGy2Aq^onw3zb=$#yy zc@xCnC?u6L_iU^i&7YDj)oG~|GF1uReT-~6h)P3-xhQqwy|FUU~)qC$A zt?93PNdB5XwZ@YNd|*@gF`_SzBpH-QyVXPDReXgZ@W$yH={}C|y_j3$j z593d^=0pG?%(RGaS=`;s%aogZg}RPp!_hn2Si#oPMU(OrjbA;1OXT|3GHVo2a`r-9 z_xdCO;5^04Tn&dVaJZ4>MLB4&ObRpPOb;d89XrQZ?{(H$3}YWKV*<)Z(zvA-&}F>V zNO|+x4CG5fMpNlyq{!I};sk^gh&P97P1g5lk^6{lF5S@ zmv--(3y#l|jd`>AC-^6$3#h=C5oUK& z0zsrBJD1aLNP^(`MZ)0ccZlQW!)k#ZeI4#)0#N8A_}X^4&1Q|40`qeL14ANUnk_I( z1kA;Nq5B}ZC|h#aASk~EN_N~8oNoynhXtp`g7Zy*Gvv!~I)uZ?v}TrqGnoF!UAQ9v z0818k9}fs+siJiUanmx_s@-$oF5K?}OYXug1dg@&0Jz^L3_Vzu=eO>{Z5Q`6xeNCn z1VqOacXutI3UpnJKd_mb_z}wVQg`8w$$Dia&+Q66?hZvGS-6hTy zFN3gosarjlL z^7kK!*ZJb%Iu7dbqADe&m<5k9#G;_@mz9`1KAHH|{Dj7(-QSiD@Owrvhv0=PDfuow z0u$Vm2 zdG}=Q*y`7J#9TjO)CTC5Ii6lgixIEc;hv==kpe}(MIWTdLRLORFB3HtOEdN-Z!?=W zir%ks>{OWtFKy)O8omlU14=V`@1uMiad4cTDSzpp@}sQs_}bl(DX)5*9hdB#KSEl+ z_RgOlX1O%sXE1;A%9zxANJ$43MU7xi6f;1hFCYk zN0a$l)4h_?XAg%FKYvKreDy`)7Q~ntDG}wTco&lnx;XWsjvyepBa$1gzkZwKwzu=J zP^E@c&&`v~HNkkcMfNc!lt0c)c4e)m=JT+O94zFpLCtvwR0r^~h);RpGnV~m0)LkP z(`w3762PW2JV)}huUu1x-Ci_tDe4-Z{B1#A8ri}^K~8tDAM23iq}&Ucc*8M)NFVjU#iCwHza zoV}bkX@9dQ!U=HIrOWhZejB%d5K4 zLHz5eQ*JS+Em`dZl3XZJ^DpydYH3(rY~%Okw3-@-_uzXC2KX6>zY$~r)ws=O+`=;q zZ~2|h=)7X^zL*tJ*_^(c3C_J|48E`eY__kOv2iw=w>Mna6P-Px7^;vOZcHE1X67)g zj-Kee5np6ww!w@}KY!2W8$pnT-X@D6f#!|;fjpe7UeT0TDXTO4C7H~{kT~TB zaizrGB&Ju7y^wI^94p(DY9b=H2D3RUB&50bkV_k>N_4B8sI2vD1^HY{K(RXAM=DpFb^V!)vi|S&?`)MaIKP zcA_Vc!<%xzZKHX;>PQ!3fKEp5VgsrEqf`+&L*(^*ZB@a7Sgw-Kd{ws|dq~P?Oa6mi zX{)#d=(5r(v+HEVPh6sW)&fS*>1RW{`y76B>#j45U=b&Pns*~~trhbmyq2}%*`Cdf zN~w)t$9&WDdEC0??OF6qU)AmQa1~%uQDePdHNparDa+ws=!!UH${ug%MP?K@SO}YE z%i>rC%|^duxpX9_$TWzZ)%_7enGniYf2?#T_cnGX&;<&AjAB+Udu#fF zhqf2&IL$Zk?bQdJ?d~sg@VzgW+0B+knFi6>4JyOjGXQ@8z@*M<7B8EB z*Eatv{I(uFl%w5yzU&dPM@n^I=rMkLQoWxnty1r2ODlMXV$YVA$vgi2G?!~13FY?5 zf=9d_^!pE@zv&E?uMZwX-98sX<6)@IvZ&CRyyf0Y= zY4=mQwBc@?thO*aL*9?Wr^~Mr4BSWM*H*Epw&~?B$xoH!_*=MhJ)sWKyr+%r|V)qz^TjN|BSZTZ#}IG+NdXt=*6Z}^}d$Qj}+9?rE2pOx)>Iy|0(#uS#8e0}*h zgT}!HD-eE`c!IfaAptBdu@<&!(Hk>W$B;!1FCD{okh+u|LKeRI{%rO;=Z4Gqm8yeF ztglVhk_y zRt>NCM#`|}7P}!3%!HUV6S7$WqD5a+S-(iCJB$o#&g({I4H%g< z0k0uzgsG&~f@qm!-HBK3$=~4J_@XRKi>c4b9M&C3{B|HLV90pAmZf>7tWW;z2#+vF zKZiRE8??B?eE5vGv$7S@hMjnh_fTJ!x}ZB-(=w?JDJ8sX9Y!Ub+^Erk5791)GYnHtB!Xj9fP0^QNKIbCk% zzVuGhWqF>+I96FrtFs0L#4e%P`~rxe{O?sXA^PH6`kqK7&5hNf3OnlG(K0(E;B|P5 zKP-~_@85-&J`^lJ3{|Jq+7-LGFp?jKz8&LV@35tdji&o zsc*?EH+6};@=~+q9C(CPS>I8WerH+@ED^(<~ zVJU~aG%he$tAXYPT9{uUd@Ug!F0um$v}d~*|44oye#yR+o0;S{+SU}4Gg!WnrQp|o zyv|tXFK_d%)9&9&vhl!ukEynAk)K{#+-Dc?_T-Za_Ts)AiRL7Kmx<;|G&lLvOf*lT zdCB`TQPng@>P}Mo^5s*0>UIeiNVp(1Pr^!Q?Y66S|>1QBB-JWRsFQksP2&n_*Mt6kAu1Gm%MLwgvVD~kCo?{#2^-&hh1 zMSN@_L8D8S3_N*5hVNTRub9AnA$pvzawqQBR3j}R`7;EX@ z%eO}lX-mIvJn+-K78Z?l3Xg~Esrj_(P)_PvdF84OAIeMBNz9Q7$}2xLOV&nXlk6iic%%=a;1jLYgkH1B$JiM#BFk#2y z*{EW1i&(dmqX1BH{2_`jpta%;AwSF_N}w&!rp|oj6M-#hgZcQIf=H!>?RSgl5Vwc} zD*K~C%3?Q^mRXGz3EJ|8pxNe2SXQNl-zSqebNE05JIxK8+7=OoKm~@eSGZw7j%$|D zi>;Q=hiMnx;XHK&i@U}-y~+k0XnsF@iBYpqAf7>@w^#e2$V2}HvWOsx#i+SSX*bM2 z{Rc&lfK@+ko_t$o8I|UC>v4Q2yj}f%B;E~6CzAG+J|u6PpTU{T3b{~Q{1^NENbY_^ z5cYL`B#ZuAYq>u{S}Wp?nMT=#BIaDlUnQr$PR92qU~B~eD8RukWO6=fW%9vezPQQi zSfu_a*OJqpVufG|IUqlXdf|Y}$#Bv|V^QlA4-@aXf(B->!7MhI#qs&YSp(!X?Se$y zbSw;}9vTGy4`w%tvD9Pi&PVUb3(=!Un9&F3r)gGPl%4>krnyzpQ!RbzlIz;**9z6rUCneOUUKs_FO6=Bm zqEj=Ye`JWod#Q4FQW~Wq-*6%3O^Ur?j^w|?|SnyW&r0!8KVdIZ8)Bott@G==v z^F+i2>nkc`DsvIiC{d8+?|qndLb2tecs}Mi$Rp_mq-*AkKgjy1 z+4_vAEUM=gMMegymhTaFqngf4f3t+ZdGzx0`I)0EVRFMZ%v7Y@>nlGAlf zU_h366FJ2KRoiK9{=HSP)Ooxrivv)9ovDfDzwluPeI;Llt4;uXMSXr_k8)3#!$F=c z=5VTH^&AAma8}l7O88s}`^xC$O4h37*c%`>=1&-SVpG*^C8wE9M8(Ni5Uhs8gNreg z;LZvrv8+S9ykK%eNCd!^A4~IdIdLr~3V9!28^0}#*#5SAJzB3FT#yOJy#x59uydVcgw zMqvdI{gl`ji+z86C|p<>UN5Hg=L8M@J*Je&PFndmu|%i-z~M#Q%hT zmvj$BQO(c>hg)m0i|~^KJU2z*e?+<3FbBIFX+0fTl=eAn8|4ud*FC0K*Pb+Fxag)> z!|VY_WM{K)7KBBe0ZLpHzS*|pbrK@RBJ^rlf1!ukir;f|tn75}qFL`ogxt^!v9{^!Mu|?AebcZ9m|>iVe-9F{llx^izlZSie%|3SWDZLN&2sLjIBz> z3y;nF!>xaZ4LKJT|4URzwSIlFnC~4$^i}>abF_^dQaP=-OFjCywm1g{I)Vx7!a6EA z=p*FE73WZ|@Q43g5yIBbW%#-T9zJXo#+L^I+^IJa2OAk}-C;10 zhYRdMWDFEL#eh$Bqlq64V9mZq?xeByC{1;rp;l#GxfPvn)E^UydyXx-@5Qlr;X=QL zrkxntO8|9=3P^)kDZn+&{xj}CT#}gK{wL#yJKGBTJ-lX*@!*)tC z`k6>3`Fp4f&}N`?Mn^a_Q4b$oH35z3a+Gyfl=XXa!S8AWOhk7T_oQb?7v=hkd7WF3 zxw!((_($>JiK7=$xZ_HMXkROSg-Bh0s-2IqY8`dBS+OmRzIivwENX(sQMR7ENPDOo zYEe515%4{wAhIGpm$!1guC|}>`B?e{-?zTD6FhhhjPLJ|4Yn-03zpNR0jLkwS6267 z<+!5mY^}cuoXGg2SP5{&}md9&|A)ByulC)}qXm&tA+yEC!oxs>^0ooBP}vEit3TY5j$`j{v* z-Kh@!sh4}npQ?xHBjzfL#XNr)?+w&sFnH&`$-s`)^S{eLU$6$Z+#!cM z^q)iZiTCOYn!Iuh1(QA7Z1Vv>sR$b_cDI3ri--k6QCKKYYbN*`kpLbP3rodvj}sOBEok$Q2l=pO(BVhA1;h34pHd6JCluwi^jtgxPgQC_<5@a*M;hp=6CVJ`%AW2cf=!lS;S%Lb`p#$9y z5nb`h@!l@QV}N=L;=#lKZ=e-F=HKLj7$FszhvlME43u<<4>&?n(Uu_<)S1mfWD2co z3ySF=>E*+$mD^}OkAteleTDwb2DwFyXvE(Uny8-^5$KbpG;Tua?}|fE4}}fc*X(;b zPzc)36+5`l_P&AAW61uZiEb!(?MU&YMIZ!jBTZ=@^C!_zOI+JmikpOpmWWok7;Re2 zn9cLh8tHk&Dh6j+(d@_h*cT(t0FK07?D*q!$d{jO%3J8qjXK)`P&thfdwei2$_nXq zUlry>i$&hz)lQrTGvyF^&>A(e*uNa_)?d<1Xbh{t%xDs(h7avUQs3gWYlk=4{~YPs zetT17Ri_UZhA_l1<38bB_^)lrh>E@7J#1gdFt%f${I=(oHxP|>8O{6WO~PXAaGp!a z<8|d($C2?T@tr{Z+UIDf#1hkJo5MLgAadx664)lm9BQ)>2ry4fZK&ua?S7yn85d%Z%lG5K!O*yn|jx+{YIcCaPrSpC{v zqEWja5We1+n#{6Ku|{6OUcXm{$}CC{0%s>>uQc5}jPEbI=pPm5kTu>_>^}xGimFH) zh7oc->mKWU-(mUWq5r%x342Ctzj#)=VcAr zat$DYE5R$Lne<;Brc&QYuY2AGyL!&@Ta$PL+d%8SxYh4nY^kl=e5>EGEAV?t$OIE7 z=!?Gv%5+pReib$&Ld034YOo|6 zTyVubr-yAKCd}L({lq2BYijpno?t6`4OZwcafMqp^Z?&7dimLu?VhK0$LBgcL=5cd z)Y(oTFdnzsVuZJbpBW-Q*NoA>jAYa5Bw-#?ND~tzdTsF?bKCx%SVVn+W~IYZ?jO=? zE4n+pPZST+kNdm0wphLCeVUv$bu+QCN^Zou4ePb_l6S@SK|8c=Y_D=_7Q%5~sznl; zJ(_6T#&@r@&^0JBQl3t@z`qHn8Pq*03-Tlig25B=rBS&+e&&$(mmp{CB$AmA6vgns z)6xs?rFz;PM~e3R_%1uKBY}o@Y!fYVEt-fvS?ssOnwQ?)_OTttMpr5Hx(VozhK2YX z!qbyA0Pk#LyKwn_Drd`k#ol<;#ch}Vv#`qGf*Mm@C);{QbX&r!A}3lf%kr7f0a7P# zw0-ytUY?xj5=!$fvLU0J$Bs0d8Z@WBE>Et{G1ClYg`0McA&P3keiyMf0@^xGi^PH@ zfZMX}R!l!}P?t`ZkH(9~Yw{7&)Vn4XbtXAE&ObySjWO|-{@G$3hi#nV)9pB(yFs2V zqhI?MwGS)orszsu!*y8j@ElK82lWcWeiB0HzjSr_b(7mPR!8+HkGNbNQBaQAJ3f6$ zD^+~l#g7UILjm3W99pd}#3C>{9}f;rCmL%hxZ$#Na()Fi4dQ@IT{SxA3XC7o6*ezR z^EXN6_T`vRlr^K}CH1SMiA9+XDuAT+=tiLGxGJU^IC)Y3@cd?&r-%F&QKZn+0xGQ@ z5!M??VMRmgYT;*VM1RNUk+gK|so1xI`|p_gLP7V-|Gi3Df5g_^(KIwu^`58d70}(l zN6GOKJl7^VGvR&uwk*c04p?+S2i07jH{Mg1(?DzT)_SJTykLFm{2%(Ih~`}p&AXvu zf}-i4v`qWN`kvZwXc~3dIiu-W>~3=rl@{a84=>?+6cEvBR2X}*VKzS*k>5lf%c{w% z_5obe;nj4FX6bmhkoRh1sIP80$G@9x)5|1Jk@Q1a()jE-(mjLM#YMXGCa2gicQ@~$ zGTO?Xq~{vVJ<^(IKrUFGVoHrAco$r@rNs?)cHk3`P@;JuDNHl#TylQ;r)L3=KU$ab z*;%GpGqjz_=6j&mC`2XbZCM0!H-3U^VI>N%#J^kuPWXs3k=FOO;0h+Au%d7@QL-F) z!e(S(o6%%+70~+BwZqp`^pBlDL$}0#T8bDCH&U1%u=&N-PlT}}%uR&(9AUz&pHjc- zY+u4t=t(CiZGwNuullt`2u6E>*IVI%@29S|U|==C$k6P&-(L=^X$XR%j4fDcXp=bz z3tp&g6T4>j4hxROfMs5%ALp6bZk)wM|HybM7iN@U!N#1E^f?w??VS|4an(2xd9Wk0 zQAF-;UKgcv#J-7}pvA5cir(6b@N%*-MZ(-<6r0S*#k40+(>nt?YD14k6@kLDAj|VU$+NF)~L^gC!j+dR= z*`9j=^Alk`Y$lu3v=*DxN^q?E>e|T;Txf)&0?0h|5*})pq=Fs2;{9{Qd(V^^22Jh{ zVq4psOtuq`BSp3$q4Q_c3E7-VAYy5A3KC|Pwc<523P6UY4d9Y8(>6{Tnxydr%N8~? z(NLd3&w4I8r`Ugb9|{92ed`HZ(i?0!+aY&!#(0;x&GXt=PO9s=8L;Qk$_g59n0lb$ zJ=KREwj6!4Z;TP+PNgkwBcug2Glil4yb?VD6c-0~qA5XBj0|v+iBuSSSLP)g3BDn9 zz9?HT$_BkP`gEc208L^gaDZ(SMnE(JDE?qf5;vL##~|BH>EBlWd6<7tojbZ`dKhWG zAY@H*Fe8og=*xX=qfj>PaJ`-rtCPCvnB!paBPTrLY@3f#i~AaC!9N?tm8}+9cU0>j z=3Wn%FLy`SI?Ohvl6oKS0X>8iEd}w|-Hp|d7Zwntd2pz(MHw(xptYP+L2kFbhupa! z`Oi9*NnC$1>+;5|tF5gJbNITGHq6{Rm!=hf!0y-Tf8Q8 z)j1zP2&A}yOrSuDEbg@!nrUp?!mAgj1HiNH!dfy)A5J@X&BcpcEc)=PVb)9VvEw^D zmL82b`+`o6^S10SNAKKRI}1HQQux>z9yw`Y>+~38um>s^J3AY*J!qR$Q3qhN{+V4^ z`PU9YSo69H|C;eQ1j$_5rtWq^_VG1@TT zU>DLWae7G%q}FHHbq@8{}hGEBYkCWZ(S!`+Db8Tb)H4hjt{5?QaaInnI|4l6ZIRU zM8qQ?92!qdl72OIDinmiyNjy(a4iO?Bz-_Nel^&#b8KXiMZXHWajx}Rzf5p!N&16J*Ue-6c1LxTYpV?(ih$al9$tIp>Oic{<} zvPficu)(aKC} z%su#hj~{Yf0+FLTiP??K#ZLQ+5y7`oM40DZC1^|)iil#|kL(To4~c9IfoDMBZ%2{p zk>CMbAHg;KPT_YBe*HJdVh3)KMb&smIUK?me22>sm) zxNid+-`WguFQJRWmiF%ZaY0R~JZXbd8TGW^+A^Yi@5!vHk$X;FS%s@>z1~IGy;sj( z*n8zf;1asNGCXi0sD7;(t$FW}zyE{}+V*L*UWD;|k-}V?*S{ZX2F|E=L2-_w@NfKcu$z!kmh|*9^S|Q7YFAf%OQx=T!aMy*%MT7lE(B2jZ*|zNaY3 zYjXgOY^&UJ>g2XVNWjNi_!AakR(?rLy|0NkSjSN4U zXqYSovDKK6H$_=1tqozYOTuD9c6%RJq|og9a#sw9)tI&|!g*}CE@<+|nGf#o7*g?; zl1TqHkv`3qQQSxrS1bg~Vs+H2$Z@P+_pg{Z}gNJ)Ic;QMCZ;UYJ2SOjUq zdC?h5brbuYXinVv9YyRpI0Gv@CO!YL=OFJ>Ig`9)&p|ueH;^J0njLJ>m_keKliXOa z2kFRsd1C=aRGwC9dkcJR*NTOH&(_%yxh`AoG3dChWsiY7W&OXo$G`{EDJaa>afYvh zvVwBiV{#@~u%~6Oft)tRU%?if8q`Bf%H2kssJj=lyk(z2!HeEbSJ3Q|)6TTEtPY5P8$IY{Ridt)N{fGoAPAErgd1rdHiO9->F*|P|H6^qP0@e6p= z+=bdKo#+#dZf~tW71eqimye0pk++v)3SVTwxV!sj%^we zEI56+?jCXUg=y^-tn~ET&$i3*vW*n1YjxvIjr(12S_!L++N>x|&F!D&O_ zwa@AdV89!|2Gq;eh(Z;dz9GE25Z^n?XPc2YKMT&^v?vS4A?GK=x&fO9@LY&R5M(5@ zF|#ej$p@f|u_KaxPzL1U{>7QinokP=6Lmc# zXflUEy=j6Ju{N`vMBfSDoMn)nsbJ;mHaQ)w;X4azPJ^GbwV=`!`%l8G;q%GjXc5ay zVQYjYWC>{lApBVJHQEelg0{`6&CS>%J`$%}2GQEjgx7OKp4dDFdfyW3tc7AZB61JF zUrelQmoS;A>xl;EhMtu6wU|UrY~g@1HkRps)9iRE1g#JF#J>hYfU%uqK{I5zs^)V? z4A_NDU8?&dpQCfd`I4mOd%egFI(man7}WYzLKbe=V&EN8nKN|60lf>}2RUW5U_BuA z9iZSwbncT7-```rN4P$$0?Ca51Q`het#`p51I`wpeM!acIgg+i+n|O)$4#O@vC$FY z@ufbw;CwP}mrWl~Z?+!6T+K}Hy9_qt)%~25up(2n{vJ&6I!0H8TQP0yXsXtDA$&U1#A3BR3z8-1*EGF*ryMW zd()B~s|j9I9CDhE6`c3ff6&w4>gJE~d+w(GQU3wHZ?;?i0eWY8cdxmR!!Joc%zfR% z=oY)sRUxjHdNo+|ftC0(xPr1lW^4V3qdR?cy7HpwZZPo}ilRLw@isS>8*u(K{C2Jfzrf<=0kY~JkY0#Dl?c$lE*$KqdPRS@BAXx!!I0G^Gz zJPCvw3M}4kjk^pE(57*h(E(hnuG@66NU2{1zLFBEGhzla0MrBu4SGcmo>3&>=~_2X zTp00^9N{)~*ole@BXlx^UFZ#d!q$DwQ}kH|>x5ViHbJCgv39i-MMvAtqh*o4Bg$a?7B*d%X5YabNT9%G z&n+Y^{q_-U>6*ld>vnWa^2N0mUAK|f?dckCz>~kX)uo`uH9Lr&-`@1613kk5mi+c4 zW9-O87$5u@(gB(wTz8;rABZl$U-PRN(n%`FGrGuw#A%MU6nRizkFDd_JV1xrKvA~G zDD{KFhUSv(TWr3GOqTiC);vt}1A5f!+S_sjpk4wopyFbioh=kfKYZu@v}%i@E1EXa zTisGOt`c+tejo|9K2d8RdTXtWr3p z9=BVgy(2@8W_npIo~{QYLyly2z(y(r2nY}PI`b5E96J(YIkc$YibIEn&;;jO+ep+2 zTE)I}P7l5B_^oXX8X@VM^;VOAg{}AHs)8Dq|D4;DMcs?Fz*v_YBi;=kZ*i^24~`DU z^L@bX*$8y>TQ}4ZuO%cui$i3r1gNg zQRjxe)7hQPR+DE`e6-u;>PXikmiWrZen%qWcTcf)!P79&fU1LdHio&l>a*L!g6iUm z7i1z`DA0;JxW0i2#^VEeR;6u6Yci)05 zBm}>Y_(}|%mc`|?VtI#R?sub)WawJ_tv>f+GXqNLX4E{<9r=W6o`^_i%-LW_#ax@` z;kb8lw#VZZ9z3pQfUM@tyG1oUQP3c3rKsn-$liwaq9}a;O8+EEPxTDodiEu3b$^IR zk^6ZlZ1=k##a~&sL%5Q4`+={t;!@oX!w)mLAWKmf7eGCg_%2N6WNV`No>8s>t;d^v zQ=odWSifkZvS15cG#WYPNzJ}<$R7<|7)gS`!>(eQA4ZdskNN?6pF_^_BJqV5yvdGa z(VvRs=E;w&2wlAiCPTDu6SVBjzSl5Mvsgc-+-Qe#Ib|7(w;P&$Yl(yWV69GoS)P(k zru<@C^23L!@$oy#yd}Twh}OKnpt;S84^cgQ{Y><0vQay==YsQw$f7R(ktn2R6zyxB z>F*agq$)~3;aFm%wP$|=3KSJ`tRbsgk~#mB&K_0#q7J9*n)kU1@0`CQt%!|Y*%P@K zgk9O`!Qo4%{DvHfC}{G`?Aut;HoHsGhIKCE+&bb->Snx6TnWFNzp(O-sHk<#=?%+& zwqEkRB|oPg>a5*8$_uKScW*$THrZn=R_uL73Ue_&;HZhPj-L3`n3dk|3hQXd3B@H& z1rO`!2Sq|bg)yS}K+ZQ21vPk^Uu2T~q81;Y$f&?k00(mZ0=sQp0YS&l>W$AHS6cK3 zFawaeAJTsYLqJ6sKIDRq!(4F+-MK!jJ-+#H0LGqUHA!ZDI&_E`l{5(j$cEA};|TsN zIY2a zw-Sc2REzjJ9(o%X>#X4c`N8p7X*D=i6W0Z~er`Eag>SCW=>F7gbPg_p6p^0R>;VoSGRWT9%me~U4RZi{g zmR7}q>6ZR~$pzd)qY>V-W*WmZooOM{SD1dp^bpe;rWctSVq|*5n3|Z*W7>g^fQDPe z_%Wt0F@2Be9;QDty~woZ92q}=>1d{5Oz&bkk7+v7Jf=@FeVyqCO!qLYW_p(CRi=h} zWxjoxj$~?L8p$+A3fX#-Oo-ye}F{=DR?6S|6wgOY0ghYYu3&EJjvcQ8$TMutmRD{0AB z{~XVAjP%djCMmvWDDu_P{cjZ0xm#Rr&s*cw9G4iA8{zDXspllu)Qa!VvQOfyV!v90(St#BS=t$c-ywfr|S#)bspwzP`>5o2cSK4DA) z0=aU=TKbiYWh=v?f-%jm$yK$&-?a)~-HQKnD_qkG+Zb#2<6=9BJ&@>*u+?iAIn(J{0zpL{IeNjHY{9TtMD5bYvucdvDW{TGuGr^#kd2fSHoB< zkM37lUQIqm#{D_Gg|R>5j8^=OjE6A4lChS)jj@sWhTmj{vDi=hVOLXjO@(O zBawe*Vpeu$N_@5!FDE@NHDzIXVuJ9{xKt5idg3yUt}`YirY2@5>O$e6C_3Hv@j6`} zT!+G=4}Np+lOdO6Bxc5;yo3S~j@r)0TWydW@O&o~0 zRYv z&k0le*V?tbA&DB)#V$!pPcc#(%1WVD5!)gp`J_1CR4QL<{@nX+2@#tXmmaq;G2!2Y z+B)1n3YGF}k?Vg*u0{H{gwy2TO3u!q5k6sgdR!VFjg<71>=g7I4<=?Bla^!}wRWNL zk|4W6VdjE$U|0Vrfp7-qJ%*40^r^jBW^=HPueT_)I z1;;O$AGa(ng}YIQ|M*bq#n5-oM89GTOU#PTOvz~J9(2YD)NM>mjmye%;u_y}_MS0b*G;IjZ%nS!6H zy90jmC#tXexA_5ZVpT>Rik8m{eiJ55dc;IJ1x+zQ2!*eOB z!?|P0r_FW9vlpK{%dzVQ8!GNfcrsHm5EC-!|{AaXD*3P%);KbpF?E3(dy$r{#HD5g~WwS zH?qD%qxfcw&_fJeC~3kJv>9qQBuApu2K?|t`_TE|N9zNUZCm_E=5$Ypk{?mh zKM;@FlE$NSDK1exev~emW5|!@+nxAF{xl~e|55l6HZz{cI2x4V+|B+onBD_Q>CeHB z@}_%C>7?Oj#4iKCp7>?rM`g{!kII_QbPXu^7vM+fti_Mwqn+vo;r9yT*FdRUZ{kP! zY{rkmeU2ZM>o9)A{}Dgp&w&7G4oUmONIuEG%lnwiw2fsGj5=6g|vD z-CYu*Us(eFR8jvH{!AU!-`Qo@WIowU@hwErK36c!W4e}UA=Ag0KFzd*=@zDCO!qLY zV)`@F8m4EM+L)eaYG-XObeNAU|PbojHwF?xsq`e(`u$QOl?fQV|F|{y_WtzdXkm&}d z8=00c-NLk#X&KXUrj<;qm{v2bVQORA#MDqH%V}h)r60uD#59^|EYn=3g-lDBe!_GI z(@Lf_Og+zYeoSZNr0b%Vr0Zs4oVy2WyP3&3x=EQSx*2iVI`9(WmcyL8L{hpX2$w~k z2%9diOI2^+)88{t`mS!`Ykib6|6nP8W?Ixu~e&2?@iOi*yMmzzsDwlWvAC2lE!hM?XSzCNLH99{f!ZI2k^W6?)1P&>85DsK_#20+38s#&5wgoh+mw zL&)@K{?p=zWRM@FPqQv9B>8IjwfM<=DP)Tug`0x(soay0@&eE(V3MI3Jv>puRKh7- zPoi`$%%BTFXCNMp1=BDqpnBZ}IV=SYgFoF_nSPE)mC}*Y1d!!ui7(5O13AbBA zg@3~#(**oo?o=Q0p?^a$T2dJLXLR^bNEzCqv*^a5jA{6rg@2k$#9ay0&4PUYe@7B9 z{>Q%no%ZiPdH?BS!3^nt`nMJ{l-B=l4WEy>jrPw)_rLbfIfXU4mVa$9r})gR`@C%1_AhpP`PI(yie0<+?A^D&^1#8b4}Ej^+o~f+kA3(3 z4?k8P|LMffzx?`J&B;@z&-{M&4_ocIy7Pbj^|!sg;ljmBjhCCQT)lQ3Uw7BJv~hKF z_h{?c&a1t*PY1oBW2eqte7kn@yRCbVp1p4GZS2#xpMU=W0|N#P9x^m=*zlk`?i?|4 z)aWt6W5 zng%()E3M&q-UUfxnU*p&Tx5Tyb`D>{xQ40m5{F}2%GA)v{!B}mYI>nc#x+a>F3a%$ zrthIy2#wC!m=&dgYFZynXY_CJN#B&}6pyq;cRC5^-{PlYo)V8Tq#~UMMOjkB3{EQt zrFX~wBk9pxBMWI$X{pA}IRrU!__y-XY>Y}w^FNy7Bm*a++zCKhiX=Nt2LF~Gr9m^& zbj;$M<7*}Q_xQ_^GsRCrxwI5or1o#|r3Nt*rO@J1>9yQj>-GLq- z;h*!T{50)VAj+PNd1w~on2Ee)9to(;vVSPkKc`1=~ zZJbsIx8A9ix>6%Z)a4>vYyIl2B}_m%)MA(5o-M%N+r>Ej zPpG9WMF`RYJL_MmgqjXe%bVyw%Zq$7@VqZU9Ma?lLUJUdf9eHfOV;j>mglYYl6o)7 z&zzY!DJ3=0oRN}czH3H=(5o5XPipYE%)}YOS_d7i3;f9czfsb)5#N<*#!!0+7sHtJhvbqOYx@i`7*jpSgG1m0p?u-kW@1gM- zw`IJAu_xm)#(0ZHI3w#5>2t^ADw*%ixSFvKV;kcRjGGwi8GE*q@~4mOk@I8Rk+G)V z@5ETs?{{V#z~Q?v4rc7j*ut2;&`U0cu^;1P#$s5H!|+YcnjlRjLR6` z&bX3sZ^qS(jf`!K`!H@|+?TPZmy}OG#(s?b83!=#&p4Rz0LB)^0~yCK9>h4A@nFWe zjE68TWIUAdM#h1ROBoMmT+aAT##M|*GOl4fim{#XXvVtsvc6*&8yM3EOUW4-k7XRh zcpPIB;}FKtj1|VQj8(=Nj7^O57@HYyU_6m=3F9!vWsJiaS2CW&xSH`~#x}+gjGGuw zVeIKG>pzvTALB^I0gUfr9L#tcV+&*YS|zy{#&yYK|W#@LOqX18n0xQY4g7<>9id3Z7QW9-d1fU$vbFyqdQEsVP` zj$z!DaWdoXjB^?HV!VOzP{t*ULl~DaRv1?@p2)bG@nXhy#xB}~s)MYb8)F0Gwv3I8 z+c6Ge?8Vr`*qd=Q+qL+NbshQs z4wc~zjN36bGWKE|q=gTX;Z0h2#?e}M#<5!XkurRS7M^jQ7M}42Eqt&HU!w6Dmumd+ zl3%Xz8CPk1ljPTEe8zSShe^J!ldQj&MPh@7BPBL!I9lQ$#%?PlHZktbIGVAv(&?ZF zSSSLLE{mMDzrn(mqj+c?$dSHHQaRJ4)i*h^Gf67LkzS2l5?1Eqk`Y2uvSRAMmElO= zL5}uUkfVJRo>D>4=^SxA`VSJ2uWo)(zTFF zL5;}Ko-=Y;j{3-aQiTq#N}Md^-G4HhFlyZMlO-dlg8zUg9OMe=6Iy#BA3kZ zX&)51#TrH=Fa%;B*#pKBR3SN17sXi}^mJIpiVvY3#p{>ql~4jPRsq zB1w==NJ@%Qq56<6Ylhh8Lzvn}pl*UrTmMiy3DkugnKY`$Ka|g}=-vY~~bkv@RKf{4Z3l;&p zwsh2<0%29w;-{lVgthe-wXZ-}WHmmuGpetaKee|&AT2z#JHlH2)c&YET6k)QBtNbG z)E)yNO)dQ_NSpYYJg9vJqO|;YBX>$~rXxLSuT(xQJ!-d9KdpNpy*}A_&0Jq<&s6?7 zjHz8yewutqhfMcR%b(hLAWEmLH>tf7*5pU+p7PV`N9{ilp|$laJqJ`j-Uflt4+?xQ z{zd|2JNgHbTT8p4=OhrZw0cpvK(r#Q9=Sp;E%-qp_ZCdgmveY}&H~X&wR%ad@+8N7 zqvww5p_MyL)HBLaPtwFXw+p#XHOe7JdQNGdm)6edc_pkp7xdf`*7B$4m+nhzIneX$ z+AAlZQ@LB>Q$OI0)5QI6;Zy(M%+G3-9`zS=Uo<(zi+WB* zi;|A|5$F3T`;(RwWxql#PPRbVzfg*@g*|}!kYpzCosnAYmiw9}?$cckIm`YiLN}fB zm;K2^$MYihIkc3I>>HF@42PHf$ppuJp>c=$EA4rc{X+{sUDV&Xf1vQuPVI!`Hv>Mm zwr}}dxAbGq&%s2|*QSaR$#&NA{L6MW!69$wcHc0PJCXHtE{80COFgx6MYDuuxgs6UjV#v;M>%D=BAv=X z?X4wWS+2>Ba%<(%?w9OuCpeWe4ReT=Cs*bl=4d}M|0qX4pyl7vA5#7;?M>!C(b3<@ z{9DRPwm53NX8d*T-?CtppmJz;R+b~mQBEoU2uC}V`9wSTGM^~EyEHyiJNxH+s0Ywm zsLW@kqy5NyTAnAFPne_r>HIU(-ZSaBKOe;YpHCraQ$6lN@F{>O=J>AFXA`a?Nq@ zW&DYbengYAHm*{9x)Zm?*Lo2-&m?(h{jVlJt-qD|O>xvy<~P&Pj%0YVfbWYmm@v33umY4jkSJX)6);-KqW@GE|IhC7CV%d zMk({F*`u8CPmHS=f5^CoaS3BP0IV( zcEx1ozs})v89%|ekg?V;Z)E&2^S3a5m$8NI0NQ-9jQLjPYj(=Ej4PS1*=Y*7e4fm& zX8s$DZH&KR+{E}j#-9D8ybmz;WBerJ0LI%H2Q%Kw*uwY|#xab4V4Tdjig7MuZN6N{ zxSaVL86RW3f$P_f@fPMEVO+-e7si#0e`H+E_#k5&<4+kkF|J_j=`ZE+9b-SnZ!!*G z{66Dg#=kMPFn)@04C5Nc$&9~XoXhwy<3h$K8E<5Kg7Fr{zcMake4KG5<9&={_<8Kd zxSIKij5WKaW*4W%x5*6W1oVa`2oy-hH)_C>5MBmJp*G4^R;#N7A{X9^JAE=joOvW zzk~V7%+F(`NSFo#ze7jpO_#v2*W(BgCccQW3>{N;?3nctsr z8S@u1j%B_-<4WdBEt*bO&G>QVZ{+Yp7~7bi#<+=b0pkF!Pbg#0fwI1jF!p19h=!TJ zmT@`f7sNP#`7bjLW-PUL*oVV7hxsv#XECn!kok9FoXq@Z8Rs&d$+(d5bBwipES(u| zWPUMYZQsIZ##@-bim{FJ@4~o@`Lnh7%=cwn$^3g5S2Nzo*v9xV#!ZZ0W$YOs>$^qc zbNXEw`!PR;v97HQ-;Hqq^QBe+c3i$+Ut?Ux_#?)ZjNf5g&3F=H8{-VdQa?*OqotGU-8igUo$&%_d7W_r zTRpV(b|PD+G@QcL9StvHtBQsfv-L#7snGU2r=JQlw5!-T{g!qv!$0U~hf*&?tzQdIdKlV$?Tq7b&u+!7`M1WWUFOc= z<-3yPBlByy-x4o$+&_tv9qmTqH0%X;PA}bY|0G|tK5FS_ILVXhBj5FG$v?x#OR|5{bE@56X@_#=Q~LDWN+`j`<3=U&6+Lk>y)1+FKO>+d0r*ftnbqP9th2~)^AHY+CqoCq}^+= zG5d{(o)c{mI7h2lQ{DUJM&4R zT8St;Nwfu%J)PcS(aNJeKXjT9?P-u4Y3KOQ@lg6_LGJ$)Uiv$apVF?Um`IQu)-SK9ZNq7>3eJA6xdq}_n}6WPPGVEF`TSc@-lvZFi_ z(;Ga}Nu1^AA0*CpjGxl(-;zH^V`6V^g;(E-n_BTb9qeXpV$41+4vxH#hZE~>^|iOc zEy?LR{64_by z^si~btt%h`#J2DSZV5k2xbIu>s~q@+=gA##U>Sa|1B>LE)|U&4KR4QHSI)Hb*6_N& zTH*Ru*x-oFheNN{JkHLf5`5|i|J}arC|{8SzdF6XZNG>G4s36}uX1GGcn79*C`~Or z5?34iv}Q07mP4|s&Vt2I(?N0A4X=DTm(t1jZtG&AvCnMFCR(!e>4yZ38ktWt+VjP= zM9Uwz`6$u64fk7#+82HCIMI>K2=E#3RWs{*@hFCl6?`RHpz%iGL)UC@Pn-XOZ6ND z;d}G@L`xoU`+#Uh!ahMuKX`O2;qm}~asTZD)(X1e=xITNhEDvD_@D;&- zRzVHNj|m#>+9as4YtKrGw*j9RBwBtcUeKCdj|!?={;r^Ce}a~jGzgl}sjKLZOVh>* zn)lH>L3Jlr3mSdpbwM+(?G?2251XL&FWVoaeDYQe6Et?vbU{nL$`Uj~c~(&SmNG$& zH-8c|NVy?tO7E{JzG<~t(2TrzLG7sz3tAesS>m<_1TFvUoS;F|y$?~m=pO?mjhH5= zX>*34LG@2aJn&;d^CG?z)DUw?P~D8K-%$M6abqOy5F@DW+gw32Ry;3gN!RUyR=xa_ zp!SZ}1P#jSahT%cITAGb##}*T2dogZX8cQ%nsx}9cjwQ7R&~5C{eSK8Eyb^TK19%x z33CO_JN}@c8TY>+=!PTP1hwCJT+os=O@c<(w67BRFYO^{klPSJ4MpPwHMvg_v?h0s zp!Up0EmY8|&`3c`{O1aq;kroB=$~>0HNE|)ps^Xx3R*J!EkV&g2wMK^ zEv==ak|)|9rSe2~?k;FXae$x(-55cG7KaO3b$EuLx*-cB zUY#MR>6=x8#&#|i)Oh!cf|eA$EojZQ&m}#zSI|sJMDrR)tiE5gn5hk zSLuZAg4T=;5Y#Yuw4k@l&rojR)*CVPjY!dd7<$jqRW_ez4u__sEeHv_ za4hs5W%OI;?!6e=e&@;Y$rJa4c6@7J>^DVMLSG%$+qh)GjnHqt{He@3tv1v*Xu{vs zg*xT^RPRGB z9?H(&8>iP?I2T%Xq5JLaA8e=WZ&RL8^hSB;^!>2R3^OPl(!cpjH`iC$`l)NiphtcS zO?zYX$J_2PDAUe)OsSmOS$TiQYp?t?v8yup+~rR;C-qYPzJ58l=A*{YLVL!(nY9-} zKR!6FUAs&-W%GRl|5%^VOZj8l1Iu3dt+x{E;k9|^Ku<-MqpLFa{zZnyF&@g)1uN=1 zFY2U>Tab77Bc+}4>(joqM}oR2ca*F*7#8e?u{z! zsH~~-h~3k%o6_WY$M|9GhAZPv4mrKIOE=|(X<0Wme=$HQSX=Yy`inP0pJ^Yp|Ha|` zl+NDEEw-#Hq3JREJa-(rUD-J0?klyveU!30?wDihHe4AMoY3F;Z4V{yPiwC&^Ls02 zjt{yLHN{_f+PiPHabqW?-D$U{EbRv?HxoC#J3Fek5p-Qhg&-vQV4N^uwbVvH8cWzT= zd1SVmojFXI`QC%qNAw(^-2Hmow?mQ!DM17GbgZ1{r;Psk-u7Q47?n3&2CnrU>81Rz zeEp}h9`CNa@bdjH^$DyEU36o$&)IlY=@LKvc!w8Ek~y>T3`Ev-`L^ew;F1=~kSz!j|Bx_$95YKfiv2lC*T$rB|K|Rmw_= z?ID)2%7B=6{_5~ch_Zc5n>oMi8LR9+SXWbfp}X>)&%iY^4v$i{ZyP)#d)ioK<|BpA z3>?{3u}?kSUU#oI-^YPU(_?>r(qGqKDLLA3*m?x@%klCa7SKmIxOvWq3mHC2f76!E zt5y$DZZGPyJ3VNG5}jkE;ZsTI_2XlsN);vh>4*DPE*+ytQp?MCLO?l~XawgU`4JD8;asq-#t#zzw}-6_1VG7Pd^5%8Ri|N)ch9qbXDj2&`opB zb%;0gS33T9r#^Ss0Oi{zL-*s#pP>(bGj-LJ#C}Sj_wyoh=ejEi=^uUehA3lGkK2EHzQ2-Ry8gq54~{RJuyW2ZOCT>etU4R zav*(8<+P=KialBXd+4;@%IRm8=Nyc^96EV=-mz6l*F%^5w&=FT5o46a1k&(UaQ zO04JFO>I@B&&;RK>>N2>X&+?nVE-^!iSO~l+6fa?Wpwt~``g8jQ+~Z|+w4asj8rxq z|H$RZgQJz6PYoWoCU~F{^klaVg&oH$H}6g>{yFpxrCV*^qVNAgJN;$x+9&4>Qmg}q z&5t_aqwE>wF}VJ%`p}W%hZfo=Oj7Qj+_?G0zXmI3Vy6_Wo;pAowtV8L2|j}qmua0n zjRPZX@_Er=N}q3{&VBcGq_X4t6$?UF4pKV5v*XIV4~@z%OTUdb z&b>pi41DLp*@8jJ)3wbP6Czbbf3I!D_OB)>Wt;B0k@8ZA^6s1S3*K5ZL^<-Oe);Z0 z6P222rah76gOr!6a~_Q!TuquWeDJG%KR4Sz3x=`<;I3wxOZQgf;U!_u1c9S(*J)l=8wrWyof8 z%BxM+L+|jcZ?id~k8&a>f5p`I?^3+}h`$+>a+fmvuj5~NoHQ#>_N-qsBsox7@#cxb z`nKbg#>|SqkylL0f78zxYkK2fvuba9-DP!ov)bvZ%R4<^YgUa-`MsO+o7GQGl)Pt% zZ&n|eFy)oRFkr8KVU7KpRnOil>=kXB)i#fZH|?*zsg|F2`MB+&n`)iQ_6PGmxT!Au z-2UzzPux_`L_had_w1W$_U|qS#@%yM&FcR1@+ZdKRBsm!w8jPhZ>sAaX*&JG?>E$g zy-I#|Ie0@ok-u$e><2g0b*pdh*YM;Gb>z^pnV&7Yp?;K^llR`d8)~ob%=mvp?LPPV z8$$=)P_xU^*MI7LL*2JCY+ic9b+!GAu0^w}ud9E2?ec8eSJ%}iPTueS@tfDx3G1%i zJHUEf?YaK}{J*X~65(^?>6q)Py=k}0dKLa9!^VC(;JR8Q{Dgi>h!6^YwENf zwomf!x~3lXsGedOb4@*-muebqyr#a{_xK%C+g(!ww!XIGk%p`4{TrTMZ98#Q?UAv! zd&b_Y>W#WbhxgigRsAY{QS9Fvuc~uS22DS^=Bk?3y=s$7+EsPRy5zRzd#inwOHqJF=@rPDN@E9zChm)2KYX;RfO^$*^Cwn;ta7gX$WtVtc$jEU6FCiR^Q zi}l;yYf@h-a%n7ozDb=@`mX)=N1D`aPnPc(nBAoMJraliO==g9++Dh9P3kXSee~dS zM=NWwqC|d#Cq5by>aWzS2Cu>ax1RW!RG+ ze|1^ieZI!C@B5ck>)6j0zw_c{wero}{K$2eRiAw?bo5+)S^egkM&RZ<_boM_yKU{5olMfd6H+-HMmeaywsEGxFQd!&leUZm|trV;dUP z{bMFBzI?J#jjPNbu<1yn+AX!BYidQK8ruC0uZRyD)eV_5j*Ne;Q7x}395?w1@RReq zCg(S*-50uye)WMy^-ACAi_XV2s&7mQd3f60jcP)l_H!yHG^)RruPd89qER(1a9MV> zU!(f;2X`cY+@(?V=o%B7@7}0h4;(Zyq4ARXhi_Hc+&?amK7WJMWS@ZgKSZKOeZH zp1OO*_UGa+sZt+$Nxiw|i?jVFUsCJz7cK3^UQ(yJZ<*aZ_>$_|bn0B&UYFFpdpe%% zs|SvD!T(F@i;=%9SbyQ7I@W#o=9=Fxs*yu~{%T_NMKyhE|3}LXUQ|!6-}H;}O);Vn0)fVi)vEroRNpqE~+nl zdujjIu@}{YOZT5TKI5W#?f8Pkrb!posK4F~8aVEv`e^U(`zHlnRHx6mf54~4i)t6) z5I?cQku_}*zH_PSa_xfJcI#Uc*8g=uZS(e-9YarDQ1|7$^ThG*FQ|XK`_P-u9Jrv) z8r1K2?3WkRE+HRw4*Bqc+PCt-VE?x+sPU`)hW32^g8H~;(y_k9;0Nb-4$i-z{uO@U z$lRO@s-^9(7m8CZs7-@koqzbg3u;B~kZV2fzMxL(T=U-YNf*?QcHA@f%(x5c)n1GK zoHzV}y3;UZ%ISU=)X(Z_W0v_{P&XV2a=Fdtf*RXq&)`az3u^N4*S=ia*q}~5a`Uyj z>KfGN@}`#euW3+Aq61yLz6TweA9d|OgW7S-y^mk{szEgkae3eElLpnj;=+?X-)>M} z>2zk0`IQFsEw{3{nNKySol6Tll@>OrQHNg(zPhqO9W^k&EIO+}9q97IijR{U)cPm$ zGWy=%pnkOMiB&JpXi%T@kHG&1b#838=RQ{&)ZcczkUM*1gF3iVNne-24QlSSKKY;b zZcxw8vg9rIZBUPwFZ7<=zCrC|biw}yHKTXMO1I1PYGm2!@fXk6tJ!60$ls^x)i0+E zTX?CuUhS3t`uiT=)~j=BdS36lw_Y9e=OojVFY49P+Zz_H_^@7m_Mz@^+cwv$uXL=r z&E=JP^`+Mz%bW3Zy?SEEhJw;{^=c=-{EmM4_3GLmdfc{dS-rYEYeJDndcEp$=k@5~ zgnHFyV9xy8=hmwSzQ6Itw(0e1$Twac=3DAj|H&hZJE-+)$I4OoU$4Gb{%4VOXuUcj z=)ON<`qirgESql&>JGke^(xK>`083)VEavj{ia=gz5mBo|GZ>ZH@tLq@ul;2wPWm> zSsrKX>a&y9Z!w;*tK(i7H9PF6T@CqZ$Fv6y*wqKj)<-s%+ttdK`=3Aixn2GA{IJa7 zTkYy*L$X)?Cc7G2uyxakm+k7zb}nPpXYA^!#GH@ceax<|HB9jAvljSV*`QY+va9

|fi|p$4x9g8aEwHPPHjr{TQbJOkW-h{4)A|mXn!Oe{S z2se4n=lg=~YWMqlfBHm_U9BCo?0Q0gUG;QplW#KG)iDoFAMNjl@WR>EJRBtI=4mHA z2AoD=$6m7Vjv(nN{!06WI+5va)Bn}p`9Q~2l?nXLq)8|Lnn|0|Nt@CEi$;VpgeVdJ zrT;M1Qin9PS*$uOlagXdhcsowAIr29jaqvmRyG0$CX-1r|0mRpSP`@0;)4ckg$<``!0m=Dp6n$$UR7t0{$k zGJgF>gyl#t4PlsJ?ehJ>;=XsqFoq+iE?gpJ&$S{E_*) zoVA)~?pLpqKWDWwn}Nqho@0Fd!4g4T%Wp6qJ$k;!7tWN;+m^dr%8yOrY}$C^B|{nc z%+JtwZC!4>>PJ6~-|t)Da$URqI;C8EmdAW6RyVgSZ(Y4onr}G6CdS5@wriwZ(+t}> z<5>3@HZiuIVOx#OgUtcWcGrnXb1zcN^hT0rJ*}UuV~~%h#I=`XU1QWYGTqi`Sb3~6}9jbbMrtLDZ**0<9)L7Sx zP1aC;fyt$heVf>n$6_o*vcjyM7i27IjF;k9Y}3El@3*LSChQ8IF3@XHhdJz{&1+Ul zv^e@TZI&XdDyp-(EORVs&MMYAsVGtv-eOfzZ&MY`rM}w5=JUx)+CFDKU*40u!uKIt zrhV4+xQnHp^XU`Ei4UJ&z?wk>=6;S7TC5gjbwhqwt-QWimDd$Byavt;)<#+kM65 z7FE7~s{IFf5jTx|nf8U2xdm$OssgvwWroLUDNxpPRFTEUKB;@U7;Vp`ZQ8G+ZKGY< zZYibR5>-<-)vnb#M-@Ipk_)I=H z>a^d69UFaiP-osgn@@kZoS(yNnDS}1GH+-9>S<++JjL&PzqY@Ncc>8YIZsQ8RdUc} zDYmNOyR2@5omTg3^~)2ke@60gnXSyaM&>8-pOyI>`@iujWs2FqXj&N~w}@r+3i88y zf*kplT59>anwKr}l`@|izs-upRg+)U*sF%vlzh5TEwgM_ z_8eYiO44R_o4z@D`JwtPbJgOm530rWo77@Uv&#GJx90sW!|zh^3;#RqzUnu?`uU>I zs8RaLFe~GH)M<598u`z;te$zy9L|sToml82Mdq&(FuqyfkCtDdC)FQwzIF)I#RWLSnwK zxiV|o(7ki96{&@F*o=8Kb&jY!`?y@bPjh+sZ3A*t_o?!X`TZ+iNh{>V^89{F4d=10 zMVw2|VcZs)<7%0&7H09=$P4m;b5u3wsA~MFu4DY?S=GF{5|_nM#N3?A+=O*ip6ZLs z-@2@;N-gm&P>UFs1((e`Qj)V}i!yW4a=w>w0jhG^xjpaq!@Okus7QV+3azTJ%cApj z9^+olSTp{2*?njB>Cj%*+(Mqs_qo!hD(fp%WoJ2$J&V(GeMKH=hcr?*_*q|dpHeUB zvJaqtW!mT2#`Oo({WNlVT+6Jgtg~>|bHG1Q*L(JJojXZmY?bqi)O^N%{t;s)8h%)? zcTuM14)Ro&t6o;9$}OK(McFwSYub#Jo%@0FYD-k@^LHv|*C#l)e^S|7dX%mHQ_9}M z?<^r}uC^HKqD}v7p6{ow-_;Aa9tX`j8)@6Tww9=p&iu8tlDT156+bHVF@~FFjN!(! z$FNoEsFG`!opGsPTo|7tTxXUs$GaA*W!`G$x`Vl1rHnH^rQOXVzs2D*Se(skadaW(^hkobgZ~nslJpxwcKr8R)5&K%yP&&KWERH z^Vclnp^TZ&HdWGGblS)F4fA`l$S3kX$~}DZ}4VwWw}Et}XtDmwy5G&`Iyc;w;gy;sYA#E zr}N9E?DZAO-Z^z&A@h;b6Zue}O4_YPj?9+-Hy=~#t4Mx)EH>Xkmvr_ZGYsD(-v+{4SZO0!k7L$gQoe$6AACpEL0&uiMHEw&Y!jhb6D z=WQ|f@713VYTloprS*K4+F?$o?Z^N?nrW=L~H^AXKcnlEVDKV-Ihq2?8uO`6we?$o?Z z^N{8}nqkf3nkO}%)cmcc(&J+cBLBGOT)n5Q^JaHjCyNTRmhZJ~t9R|`V1a9Ou9ctI zU%jWZlZB}DFYT}Ms`IB=Ta49vF{+$cH{QIPCE{9k+|agix2zQ)n%Y?~wW90B^*eTV zHL>8Y`th9RuAQs5`dHJB_GqrVOFbdB^}BX`Y>)5CJsswnuN_@1S*Lz3dp>BckG-km z?{{?2;{JklyVtaB+jHG@ZJllwQO8Mjyl_)T`_>Nc&NlDb?rT}FjuioLL^`8xEo8ab zSKR$m!~d?WEWzzt*Rg%qX7wrR*S+4=d1afdzSov-XRnmLYL|D<&bB6_Iqt9CzqWb9 z+Vz*!t?%iNbd@y`u9NcXS!RB1XQ!;x{vPpV+UK`g)=I?BSn!s=3k%k_ZM~`O zEPJJ8jj=fVnLFC2#rlkWD?7X!eLFggu~qTHmeZ^ECPl|RbA{fNd^)`@Z$ds9tNA`? z5v<>_jm3~}Ru4&kBseR*UP8ZHsYeRd@7n6s``60-=Jq+wTX*bkJ3S8k6=KHNYle)w zh@#D`@N29pp>COqsASFtmVKa(rDC0#fy!%{z6|a?g)MsV2L?y4jQjDay3D2we@p=-)9sa7)6e-xgfOD)l>7 z-Q2~37n^r@+g7)4?NsGOd9`KN>HX^6Qpeg3R*c`(Al&9>`&$+>Ae zKDf1W$JTA)?Pl4tvFr4>Y?9igBeJ5ldQv`_4ajHOxOe87A6SkSte;xNgU=7kF?u{C zqO8_vL~|pHmvhB7^yW4*&V!aKckbEUF72(_vweG8C)t!UN2X)>@7f_#M;3?vzFN&<;$}i^R-aJDccAf3*GaKmM^U_|(N;e9O%L`yl(}nCY9;SB62pt9^Yp^GV8V|C;SO zUvYbV{rYp&{>lsWnI63ILUMmD5C1al%$5@n^CUEZ#@xUTncUGJaD75FFeGS}Bv>!Zc_Y9;<_`>oXb zr{vsgZN<9$?E8qE_UIKTIaEY zN@{%seg~2I$6(h&zGvsy5%_&X>^XSFBECPzz6Rcnh&>Do9IQo;eGY8Yy6`rw3#%4$ z4WW!YSGcT(Hqh(g7DVb1?$LTTd=dri>eA&n1rNIcQr( z+|cc?5_ufm3C}~u(YL@`5vk`k_yw)^!Oc#kPEn>6K7dG>0Q{!bPrw(nJ_#>5&y1}L ze&&3op5xeq@G(SU{y1Fx22-zr+qCY54>~L{GzKky`W|y!_34M~&V9k6p+(qOa#~h>DAeKe`>>fQWBC_yQ-m_1Gt&_Y%_| z;q@-ohs3@UCXn0EN8r9oc`pS00K6YD;scLq{W$!0txrN%ogOc^SL;3SIYfLDzWFk< z-HV_XIfY$#LA_GP(d%Ij89^6b@mACScfxLPd};y~|$KSth({y6Mk$#Xo)hu{h16uR)M zs~A7@h!{2ttUR{Ir!oR z@(leYc!!%Y-awwiyEZar==Z@y3pt8D0)Maxx6m{2)0>Gc`axLS$~#-=W$->k@?3cP zHME7@4_9r$XY@7jB_x0@-11?wFT!rE3orHXnKJb-g2)`K*{akL#PI=(Itm}!X7*)N z*hVa{3%|w>aW1#4 zes~O#c8|k8zW3k4vBE4OWrT0M#nfwIht_@Y8;JDx1iau@-7hHXJV`ym77@w_?-U(- z5Bx47^`C@WKd#3G`VsNxAS~N!)+ua4q#ifC9WnfeM-d-&3SUG{qQ3+$yq)<&eAdI! zeOz;~3!C>7bMzKie+SRrd2TNJ9FoI+7|uIjwrhtULZmG(yyH%D+z-H~5V23fn?7mw z*AE{=#C{Y$qxA_mugC1y^yl;P-2Q>ja4bFuzlQkH)9~{L&Hf&Sb)RKkU~h!Z&(Rn3 zT6i28K^H!Dn7*Sw4zK?L`_Om7I}nNIeek}!nakLPm-UfX&Ex>Qk0PjKk*zbegU*a7TbU%E{SMd}5BDfb3 z-~8}C#E3b(=9qb2-2xv)PEtMtZ+zH{VHdpgxY?E)K7`~bGYUJuX8P6z@BKP?i#-7C z|H!$K_eq5=M6M&kM-V6WEX*M;bXS_|JJNvO3fsQL^&Pz(-i?T#eefYf@^%!~pTHl= z2sa{PZ-H%yluyI*Z*%WN8F_c$!-&{D@L@#G+Zp&9BtV(xVeKPkJ;E1}IQExd#dpkO z?J$Ofu*YHb7;_uF27VSvqX*z`kPN#0yWGzp_U0hM|7dQ&m+1}-j@(v zDDSF>E|hmdL>J2Y8KMj2od(f`ztFn8!(e~Zv@=uwS8j*SjmS7QAM_&%=|x(R0Fp+2$Ns-< zf5r%8Xv@MF1#5#1L3gk<=n1w5eZih!Z?G?z31)-2pc=3bI0swN=};z=4dp^=&_3uKbPYBRx(7Xj zzCr(B?_gkXWH3FL8O#pm2Gx*#$T{R1Y8-M8d4_yL{-NHXz|hE0dMGoL9m)->lT`kW;i>X8&+X^*co<(8^i9fC+rLR!@c1^cqE(-XTsTV zF03Npr7-*u` zt@OK{o_EvtzJc(-D19HJ_u~Ui^r@9zjSP;`pD}tgPM;>|)g=A0(K82qtEG1h^sk8? zw$jITdf81sd+2E&eGSvwQTjVZkH_ir1ihX#`t6|Swe-D#-Z#$DCx`8-q>LM!h@e*CQVY zhJz!)(O^0_Miz_*ZPZjtElt$W9_|kJg!{tb@Mw4}JRY71Pljy~N2E5=5NV3EM%p9Y zk)B9jBpexyj77#H6OqY?E$WEYMjN6{(bi~tv^&}p?Tdz^qtUVGcyuB<8MVb6vD#Qe ztSQzSYmarudSZRCaBMU-78{RE#3p05xFcR0Z-_U=TjTBV?s!kUFCLDM#>e90@rn3k z+?H@8Y7-5KrbKI^J<*-$N%SSciP6MZVmvXCm`vD`j%01JA=#8{O|~bylRe44WH>pR z97~QTCz6v%Tgs8DO*N#NQmv`>RClT;)t3sVMpI*{@zg|WlDiJBkA%$@a0F@t4S}XW zYoI;Q9q0-4kvF4(vA}p>A}|@S^*j1&`y2Y3`djjT$9HH7!L#Qd# z8fp)9hk8PNp>Sw4G!_~UO@t;xwn4{W?O?-T6It0l*ge=Y*f$s^H^<1!33Ad#KGu?p z%FaC~q9f6CG!xB6b5Rwu z$DA=&tTE<}d1AhpKh_%y#71K2SSFT@yh6@k~4$ z&&5^3o^U2yiN=IG;Ys)s{zPvgkQhm%6PZLdkxQtgJ?Tukl8s4s(v$Qh{mI^BAUTpu zCo{=xGM7{-d&-$|r5aQ2lqcm&`BS~AKx!nFPGwTrR4%2Q++&f8Dqs&d1Fk@0z#Z@e zd;x!;Hy}?#s@NsxqgLZA!v_z4+e>jWz{cn|asKJkXPj3$%ba has-cet.c -# $ cl has-cet.c /link /cetcompat -RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cet.exe | FileCheck %s +RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompat %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s CHECK: DebugEntry { CHECK: Characteristics: 0x0 diff --git a/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test b/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test index 9807bfe5686ee..c60980d8490e4 100644 --- a/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test +++ b/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test @@ -1,7 +1,6 @@ -# To regenerate has-cetstrict.exe -# $ echo int main() { return 0; } > has-cetstrict.c -# $ cl has-cetstrict.c /link /cetcompatstrict -RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetstrict.exe | FileCheck %s +RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s CHECK: DebugEntry { CHECK: Characteristics: 0x0 diff --git a/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test b/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test index 18b3ec70177cb..355833fa5808a 100644 --- a/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test +++ b/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test @@ -1,7 +1,6 @@ -# To regenerate has-cetdynamicapisinproc.exe -# $ echo int main() { return 0; } > has-cetdynamicapisinproc.c -# $ cl has-cetdynamicapisinproc.c /link /cetdynamicapisinproc -RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetdynamicapisinproc.exe | FileCheck %s +RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s CHECK: DebugEntry { CHECK: Characteristics: 0x0 diff --git a/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test b/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test index 25cf1db3464f7..02bf679f89f50 100644 --- a/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test +++ b/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test @@ -1,7 +1,6 @@ -# To regenerate has-cetipvalidationrelaxed.exe -# $ echo int main() { return 0; } > has-cetipvalidationrelaxed.c -# $ cl has-cetipvalidationrelaxed.c /link /cetipvalidationrelaxed -RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-cetipvalidationrelaxed.exe | FileCheck %s +RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s CHECK: DebugEntry { CHECK: Characteristics: 0x0 diff --git a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test index 87208d24f9fee..a18bd784348fc 100644 --- a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test +++ b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test @@ -1,7 +1,6 @@ -# To regenerate has-hotpatchcompatible.exe -# $ echo int main() { return 0; } > has-hotpatchcompatible.c -# $ cl has-hotpatchcompatible.c /link /hotpatchcompatible -RUN: llvm-readobj --coff-debug-directory %p/Inputs/has-hotpatchcompatible.exe | FileCheck %s +RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s CHECK: DebugEntry { CHECK: Characteristics: 0x0 From 6723a3e552c81ee49936fe6d62aae9046a54956b Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Mon, 28 Jul 2025 21:59:42 +0900 Subject: [PATCH 05/14] reorder options --- lld/COFF/Options.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td index da2e4706fa606..d02121ab4c5ff 100644 --- a/lld/COFF/Options.td +++ b/lld/COFF/Options.td @@ -198,12 +198,10 @@ defm cetcompat : B<"cetcompat", "Mark executable image as compatible with Contro "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack (default)">; defm cetcompatstrict : B<"cetcompatstrict", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in strict mode", "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack in strict mode (default)">; -defm cetipvalidationrelaxed : B<"cetipvalidationrelaxed", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation", - "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation (default)">; 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", "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with dynamic APIs allowed in process (default)">; -defm hotpatchcompatible : B<"hotpatchcompatible", "Mark executable image as compatible with hotpatch", - "Don't mark executable image as compatible with hotpatch (default)">; +defm cetipvalidationrelaxed : B<"cetipvalidationrelaxed", "Mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation", + "Don't mark executable image as compatible with Control-flow Enforcement Technology (CET) Shadow Stack with relaxed context IP validation (default)">; defm dynamicbase : B<"dynamicbase", "Enable ASLR (default unless /fixed)", "Disable ASLR (default when /fixed)">; defm fixed : B<"fixed", "Disable base relocations", @@ -211,6 +209,8 @@ defm fixed : B<"fixed", "Disable base relocations", defm highentropyva : B<"highentropyva", "Enable 64-bit ASLR (default on 64-bit)", "Disable 64-bit ASLR">; +defm hotpatchcompatible : B<"hotpatchcompatible", "Mark executable image as compatible with hotpatch", + "Don't mark executable image as compatible with hotpatch (default)">; defm incremental : B<"incremental", "Keep original import library if contents are unchanged", "Overwrite import library even if contents are unchanged">; From c6e514777643a4d911dd4370e546a9673ee7e36e Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Mon, 28 Jul 2025 22:14:36 +0900 Subject: [PATCH 06/14] Check that hotpatchable image requires at lest 6 bytes of func pad --- lld/COFF/Driver.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 0f064323db46a..6fa7232477c82 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2198,6 +2198,12 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->incremental = false; } + // MS link.exe compatibility, at least 6 bytes of function padding is + // required if hotpatchable + if (config->hotpatchCompat && config->functionPadMin >= 6) { + Fatal(ctx) << "/hotpatchcompatible: requires at least 6 bytes of /functionpadmin"; + } + if (errCount(ctx)) return; From c2c6aee37539e0e9fab5981819f33fb286c8c9aa Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Mon, 28 Jul 2025 22:50:40 +0900 Subject: [PATCH 07/14] remove redundant braces --- lld/COFF/Writer.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 103dd7e392ee5..0ab1b1bd35fa0 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1240,25 +1240,20 @@ void Writer::createMiscChunks() { } uint16_t ex_characteristics_flags = 0; - if (config->cetCompat) { + if (config->cetCompat) ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT; - } - if (config->cetCompatStrict) { + if (config->cetCompatStrict) ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE; - } - if (config->cetCompatIpValidationRelaxed) { + if (config->cetCompatIpValidationRelaxed) ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE; - } - if (config->cetCompatDynamicApisInProcOnly) { + if (config->cetCompatDynamicApisInProcOnly) ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY; - } - if (config->hotpatchCompat) { + if (config->hotpatchCompat) ex_characteristics_flags |= IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE; - } if (ex_characteristics_flags) { debugRecords.emplace_back( From cefc30e07b42577cb41fd067e6f6477114980302 Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Mon, 28 Jul 2025 23:33:07 +0900 Subject: [PATCH 08/14] add test for /hotpatchcompatible func pad requirement --- lld/COFF/Driver.cpp | 12 ++++---- lld/test/COFF/hotpatchcompatible.test | 44 +++++++++++++++++++-------- lld/test/COFF/options.test | 2 +- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 6fa7232477c82..a3d73bb167092 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2198,12 +2198,6 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { config->incremental = false; } - // MS link.exe compatibility, at least 6 bytes of function padding is - // required if hotpatchable - if (config->hotpatchCompat && config->functionPadMin >= 6) { - Fatal(ctx) << "/hotpatchcompatible: requires at least 6 bytes of /functionpadmin"; - } - if (errCount(ctx)) return; @@ -2312,6 +2306,12 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { for (auto *arg : args.filtered(OPT_functionpadmin, OPT_functionpadmin_opt)) parseFunctionPadMin(arg); + // MS link.exe compatibility, at least 6 bytes of function padding is + // required if hotpatchable + if (config->hotpatchCompat && config->functionPadMin < 6) + Err(ctx) + << "/hotpatchcompatible: requires at least 6 bytes of /functionpadmin"; + // Handle /dependentloadflag for (auto *arg : args.filtered(OPT_dependentloadflag, OPT_dependentloadflag_opt)) diff --git a/lld/test/COFF/hotpatchcompatible.test b/lld/test/COFF/hotpatchcompatible.test index f705584b26617..b1ab362aea328 100644 --- a/lld/test/COFF/hotpatchcompatible.test +++ b/lld/test/COFF/hotpatchcompatible.test @@ -1,15 +1,33 @@ RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x80) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 80000000 |....| -CHECK: ) -CHECK: } +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECK1 %s +CHECK1: DebugEntry { +CHECK1: Characteristics: 0x0 +CHECK1: Type: ExtendedDLLCharacteristics (0x14) +CHECK1: ExtendedCharacteristics [ (0x80) +CHECK1: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) +CHECK1: ] +CHECK1: RawData ( +CHECK1: 0000: 80000000 |....| +CHECK1: ) +CHECK1: } + +// ---- more than 6 bytes is accepted +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:10 %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECK2 %s + +CHECK2: DebugEntry { +CHECK2: Characteristics: 0x0 +CHECK2: Type: ExtendedDLLCharacteristics (0x14) +CHECK2: ExtendedCharacteristics [ (0x80) +CHECK2: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) +CHECK2: ] +CHECK2: RawData ( +CHECK2: 0000: 80000000 |....| +CHECK2: ) +CHECK2: } + +// ---- hotpach compatible image requires at least 6 bytes function padding +RUN: not lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:5 %t.obj +CHECK3: lld-link: error: /hotpatchcompatible: requires at least 6 bytes of /functionpadmin diff --git a/lld/test/COFF/options.test b/lld/test/COFF/options.test index d131169eada61..3e59ca0f90a86 100644 --- a/lld/test/COFF/options.test +++ b/lld/test/COFF/options.test @@ -90,7 +90,7 @@ CETDYNAMICAPISINPROC: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PRO # RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s NONCETDYNAMICAPISINPROC-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY -# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj +# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj # RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=HOTPATCHCOMPATIBLE %s HOTPATCHCOMPATIBLE: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE From 16cc0026989f82993261233fe9138373b49ae09a Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Mon, 28 Jul 2025 08:03:19 -0700 Subject: [PATCH 09/14] fix test --- llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test index a18bd784348fc..d397fbdcc60ae 100644 --- a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test +++ b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test @@ -1,5 +1,5 @@ RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s CHECK: DebugEntry { From 2a68b44f5b73597aee5a4e66029dbe1fee9f1355 Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Wed, 30 Jul 2025 12:08:24 +0900 Subject: [PATCH 10/14] Revert changes in llvm-readobj --- .../llvm-readobj/COFF/Inputs/hascetret42.yaml | 15 --------------- llvm/test/tools/llvm-readobj/COFF/cetcompat.test | 15 --------------- .../tools/llvm-readobj/COFF/cetcompatstrict.test | 15 --------------- .../llvm-readobj/COFF/cetdynamicapisinproc.test | 15 --------------- .../llvm-readobj/COFF/cetipvalidationrelaxed.test | 15 --------------- .../llvm-readobj/COFF/hotpatchcompatible.test | 15 --------------- 6 files changed, 90 deletions(-) delete mode 100644 llvm/test/tools/llvm-readobj/COFF/Inputs/hascetret42.yaml delete mode 100644 llvm/test/tools/llvm-readobj/COFF/cetcompat.test delete mode 100644 llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test delete mode 100644 llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test delete mode 100644 llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test delete mode 100644 llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test diff --git a/llvm/test/tools/llvm-readobj/COFF/Inputs/hascetret42.yaml b/llvm/test/tools/llvm-readobj/COFF/Inputs/hascetret42.yaml deleted file mode 100644 index 0e827b3eb2dce..0000000000000 --- a/llvm/test/tools/llvm-readobj/COFF/Inputs/hascetret42.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- !COFF -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [] -sections: - - Name: .text - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] - SectionData: B82A000000C3 # mov eax, 42; ret -symbols: - - Name: main - Value: 0 - SectionNumber: 1 - SimpleType: IMAGE_SYM_TYPE_NULL - ComplexType: IMAGE_SYM_DTYPE_FUNCTION - StorageClass: IMAGE_SYM_CLASS_EXTERNAL diff --git a/llvm/test/tools/llvm-readobj/COFF/cetcompat.test b/llvm/test/tools/llvm-readobj/COFF/cetcompat.test deleted file mode 100644 index 0e629a374a8e4..0000000000000 --- a/llvm/test/tools/llvm-readobj/COFF/cetcompat.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetcompat %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x1) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT (0x1) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 01000000 |....| -CHECK: ) -CHECK: } - diff --git a/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test b/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test deleted file mode 100644 index c60980d8490e4..0000000000000 --- a/llvm/test/tools/llvm-readobj/COFF/cetcompatstrict.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x2) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 02000000 |....| -CHECK: ) -CHECK: } - diff --git a/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test b/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test deleted file mode 100644 index 355833fa5808a..0000000000000 --- a/llvm/test/tools/llvm-readobj/COFF/cetdynamicapisinproc.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x8) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 08000000 |....| -CHECK: ) -CHECK: } - diff --git a/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test b/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test deleted file mode 100644 index 02bf679f89f50..0000000000000 --- a/llvm/test/tools/llvm-readobj/COFF/cetipvalidationrelaxed.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x4) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 04000000 |....| -CHECK: ) -CHECK: } - diff --git a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test b/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test deleted file mode 100644 index d397fbdcc60ae..0000000000000 --- a/llvm/test/tools/llvm-readobj/COFF/hotpatchcompatible.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/hascetret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x80) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 80000000 |....| -CHECK: ) -CHECK: } - From dc065e865f56600b67aa5282df2ffd670d5c697e Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Wed, 30 Jul 2025 18:13:52 +0900 Subject: [PATCH 11/14] squash tests into the one and cover [:no] tests --- lld/test/COFF/cetcompatstrict.test | 15 --- lld/test/COFF/cetdynamicapisinproc.test | 15 --- lld/test/COFF/cetipvalidationrelaxed.test | 15 --- lld/test/COFF/exdllcharacteristics.test | 138 ++++++++++++++++++++++ lld/test/COFF/hotpatchcompatible.test | 33 ------ 5 files changed, 138 insertions(+), 78 deletions(-) delete mode 100644 lld/test/COFF/cetcompatstrict.test delete mode 100644 lld/test/COFF/cetdynamicapisinproc.test delete mode 100644 lld/test/COFF/cetipvalidationrelaxed.test create mode 100644 lld/test/COFF/exdllcharacteristics.test delete mode 100644 lld/test/COFF/hotpatchcompatible.test diff --git a/lld/test/COFF/cetcompatstrict.test b/lld/test/COFF/cetcompatstrict.test deleted file mode 100644 index 31acf13010c24..0000000000000 --- a/lld/test/COFF/cetcompatstrict.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x2) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 02000000 |....| -CHECK: ) -CHECK: } - diff --git a/lld/test/COFF/cetdynamicapisinproc.test b/lld/test/COFF/cetdynamicapisinproc.test deleted file mode 100644 index 22edd22587bb7..0000000000000 --- a/lld/test/COFF/cetdynamicapisinproc.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x8) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 08000000 |....| -CHECK: ) -CHECK: } - diff --git a/lld/test/COFF/cetipvalidationrelaxed.test b/lld/test/COFF/cetipvalidationrelaxed.test deleted file mode 100644 index e5a19f571f051..0000000000000 --- a/lld/test/COFF/cetipvalidationrelaxed.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck %s - -CHECK: DebugEntry { -CHECK: Characteristics: 0x0 -CHECK: Type: ExtendedDLLCharacteristics (0x14) -CHECK: ExtendedCharacteristics [ (0x4) -CHECK: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4) -CHECK: ] -CHECK: RawData ( -CHECK: 0000: 04000000 |....| -CHECK: ) -CHECK: } - diff --git a/lld/test/COFF/exdllcharacteristics.test b/lld/test/COFF/exdllcharacteristics.test new file mode 100644 index 0000000000000..7880fce505088 --- /dev/null +++ b/lld/test/COFF/exdllcharacteristics.test @@ -0,0 +1,138 @@ +// ---- /cetcompat (image is CET compatible) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompat %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKCETCOMPAT %s + +CHECKCETCOMPAT: DebugEntry { +CHECKCETCOMPAT: Characteristics: 0x0 +CHECKCETCOMPAT: Type: ExtendedDLLCharacteristics (0x14) +CHECKCETCOMPAT: ExtendedCharacteristics [ (0x1) +CHECKCETCOMPAT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT (0x1) +CHECKCETCOMPAT: ] +CHECKCETCOMPAT: RawData ( +CHECKCETCOMPAT: 0000: 01000000 |....| +CHECKCETCOMPAT: ) +CHECKCETCOMPAT: } + +// ---- /cetcompat:no (image is not CET compatible) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompat:no %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKNOCETCOMPAT %s + +CHECKNOCETCOMPAT-NOT: Type: ExtendedDLLCharacteristics (0x14) +CHECKNOCETCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT (0x1) + +// ---- /cetcompatstrict (CET in strict mode) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKCETCOMPATSTRICT %s + +CHECKCETCOMPATSTRICT: DebugEntry { +CHECKCETCOMPATSTRICT: Characteristics: 0x0 +CHECKCETCOMPATSTRICT: Type: ExtendedDLLCharacteristics (0x14) +CHECKCETCOMPATSTRICT: ExtendedCharacteristics [ (0x2) +CHECKCETCOMPATSTRICT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2) +CHECKCETCOMPATSTRICT: ] +CHECKCETCOMPATSTRICT: RawData ( +CHECKCETCOMPATSTRICT: 0000: 02000000 |....| +CHECKCETCOMPATSTRICT: ) +CHECKCETCOMPATSTRICT: } + +// ---- /cetcompatstrict:no (image is not CET strict mode) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict:no %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKNOCETSTRICT %s + +CHECKNOCETSTRICT-NOT: Type: ExtendedDLLCharacteristics (0x14) +CHECKNOCETSTRICT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE (0x2) + +// ---- /cetdynamicapisinproc +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKCETDYNAPI %s + +CHECKCETDYNAPI: DebugEntry { +CHECKCETDYNAPI: Characteristics: 0x0 +CHECKCETDYNAPI: Type: ExtendedDLLCharacteristics (0x14) +CHECKCETDYNAPI: ExtendedCharacteristics [ (0x8) +CHECKCETDYNAPI: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) +CHECKCETDYNAPI: ] +CHECKCETDYNAPI: RawData ( +CHECKCETDYNAPI: 0000: 08000000 |....| +CHECKCETDYNAPI: ) +CHECKCETDYNAPI: } + +// ---- /cetdynamicapisinproc:no (image is not CET dynamic apis allowed in proc) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc:no %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKNOCETDYNAPI %s + +CHECKNOCETDYNAPI-NOT: Type: ExtendedDLLCharacteristics (0x14) +CHECKNOCETDYNAPI-NOT: Type: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) + +// ---- /cetipvalidationrelaxed +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKCETIPRELAXED %s + +CHECKCETIPRELAXED: DebugEntry { +CHECKCETIPRELAXED: Characteristics: 0x0 +CHECKCETIPRELAXED: Type: ExtendedDLLCharacteristics (0x14) +CHECKCETIPRELAXED: ExtendedCharacteristics [ (0x4) +CHECKCETIPRELAXED: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4) +CHECKCETIPRELAXED: ] +CHECKCETIPRELAXED: RawData ( +CHECKCETIPRELAXED: 0000: 04000000 |....| +CHECKCETIPRELAXED: ) +CHECKCETIPRELAXED: } + +// ---- /cetipvalidationrelaxed:no (image is not CET in IP validation relaxed mode) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed:no %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKNOCETIPRELAXED %s + +CHECKNOCETIPRELAXED-NOT: Type: ExtendedDLLCharacteristics (0x14) +CHECKNOCETIPRELAXED-NOT: Type: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE (0x4) + +// ---- /hotpatchcompatible requires /functionpadmin:6 +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKHOTPATCHABLE %s + +CHECKHOTPATCHABLE: DebugEntry { +CHECKHOTPATCHABLE: Characteristics: 0x0 +CHECKHOTPATCHABLE: Type: ExtendedDLLCharacteristics (0x14) +CHECKHOTPATCHABLE: ExtendedCharacteristics [ (0x80) +CHECKHOTPATCHABLE: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) +CHECKHOTPATCHABLE: ] +CHECKHOTPATCHABLE: RawData ( +CHECKHOTPATCHABLE: 0000: 80000000 |....| +CHECKHOTPATCHABLE: ) +CHECKHOTPATCHABLE: } + +// ---- /hotpatchcompatible:no (image is not hotpatch compatible) +RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible:no %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKNOHOTPATCHABLE %s + +CHECKNOHOTPATCHABLE-NOT: Type: ExtendedDLLCharacteristics (0x14) +CHECKNOHOTPATCHABLE-NOT: Type: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) + +// ---- /hotpatchcompatible more than 6 bytes is accepted +RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:10 %t.obj +RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKHOTPATCHABLE2 %s + +CHECKHOTPATCHABLE2: DebugEntry { +CHECKHOTPATCHABLE2: Characteristics: 0x0 +CHECKHOTPATCHABLE2: Type: ExtendedDLLCharacteristics (0x14) +CHECKHOTPATCHABLE2: ExtendedCharacteristics [ (0x80) +CHECKHOTPATCHABLE2: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) +CHECKHOTPATCHABLE2: ] +CHECKHOTPATCHABLE2: RawData ( +CHECKHOTPATCHABLE2: 0000: 80000000 |....| +CHECKHOTPATCHABLE2: ) +CHECKHOTPATCHABLE2: } + +// ---- /hotpatchcompatible requires at least 6 bytes function padding +RUN: env LLD_IN_TEST=1 not lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:5 %t.obj 2>&1 | FileCheck -check-prefix=CHECKHOTPATCHNOT %s +CHECKHOTPATCHNOT: lld-link: error: /hotpatchcompatible: requires at least 6 bytes of /functionpadmin diff --git a/lld/test/COFF/hotpatchcompatible.test b/lld/test/COFF/hotpatchcompatible.test deleted file mode 100644 index b1ab362aea328..0000000000000 --- a/lld/test/COFF/hotpatchcompatible.test +++ /dev/null @@ -1,33 +0,0 @@ -RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj -RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECK1 %s - -CHECK1: DebugEntry { -CHECK1: Characteristics: 0x0 -CHECK1: Type: ExtendedDLLCharacteristics (0x14) -CHECK1: ExtendedCharacteristics [ (0x80) -CHECK1: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) -CHECK1: ] -CHECK1: RawData ( -CHECK1: 0000: 80000000 |....| -CHECK1: ) -CHECK1: } - -// ---- more than 6 bytes is accepted -RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:10 %t.obj -RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECK2 %s - -CHECK2: DebugEntry { -CHECK2: Characteristics: 0x0 -CHECK2: Type: ExtendedDLLCharacteristics (0x14) -CHECK2: ExtendedCharacteristics [ (0x80) -CHECK2: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE (0x80) -CHECK2: ] -CHECK2: RawData ( -CHECK2: 0000: 80000000 |....| -CHECK2: ) -CHECK2: } - -// ---- hotpach compatible image requires at least 6 bytes function padding -RUN: not lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:5 %t.obj -CHECK3: lld-link: error: /hotpatchcompatible: requires at least 6 bytes of /functionpadmin From c508db0c35293e6ab30093ed3f15a040073af17f Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Wed, 30 Jul 2025 18:18:07 +0900 Subject: [PATCH 12/14] fix comment --- lld/test/COFF/exdllcharacteristics.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/test/COFF/exdllcharacteristics.test b/lld/test/COFF/exdllcharacteristics.test index 7880fce505088..1ceb0ffdcef06 100644 --- a/lld/test/COFF/exdllcharacteristics.test +++ b/lld/test/COFF/exdllcharacteristics.test @@ -70,7 +70,7 @@ RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKN CHECKNOCETDYNAPI-NOT: Type: ExtendedDLLCharacteristics (0x14) CHECKNOCETDYNAPI-NOT: Type: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY (0x8) -// ---- /cetipvalidationrelaxed +// ---- /cetipvalidationrelaxed (image is not CET in context ip validation relaxed mode) RUN: yaml2obj %p/Inputs/ret42.yaml -o %t.obj RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CHECKCETIPRELAXED %s From fb91ee6f3dbfa011c1db9c3dda95376a28bfeb5b Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Wed, 30 Jul 2025 18:30:33 +0900 Subject: [PATCH 13/14] add test covers `/hotpatchcompatible` without `/functionpadmin` --- lld/test/COFF/exdllcharacteristics.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lld/test/COFF/exdllcharacteristics.test b/lld/test/COFF/exdllcharacteristics.test index 1ceb0ffdcef06..ef5a90ca9d519 100644 --- a/lld/test/COFF/exdllcharacteristics.test +++ b/lld/test/COFF/exdllcharacteristics.test @@ -136,3 +136,7 @@ CHECKHOTPATCHABLE2: } // ---- /hotpatchcompatible requires at least 6 bytes function padding RUN: env LLD_IN_TEST=1 not lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:5 %t.obj 2>&1 | FileCheck -check-prefix=CHECKHOTPATCHNOT %s CHECKHOTPATCHNOT: lld-link: error: /hotpatchcompatible: requires at least 6 bytes of /functionpadmin + +// ---- /hotpatchcompatible requires at least 6 bytes function padding -- without /functionpadmin should raise an error +RUN: env LLD_IN_TEST=1 not lld-link /out:%t.exe /entry:main /hotpatchcompatible %t.obj 2>&1 | FileCheck -check-prefix=CHECKHOTPATCHNOT2 %s +CHECKHOTPATCHNOT2: lld-link: error: /hotpatchcompatible: requires at least 6 bytes of /functionpadmin From 120c8ed7e502054d89cade8535db5ea6cd1c5df3 Mon Sep 17 00:00:00 2001 From: kkent030315 Date: Wed, 30 Jul 2025 18:39:56 +0900 Subject: [PATCH 14/14] remove dup tests from options.test --- lld/test/COFF/options.test | 50 -------------------------------------- 1 file changed, 50 deletions(-) diff --git a/lld/test/COFF/options.test b/lld/test/COFF/options.test index 3e59ca0f90a86..c21ae9685a85c 100644 --- a/lld/test/COFF/options.test +++ b/lld/test/COFF/options.test @@ -50,56 +50,6 @@ NXCOMPAT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT # RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s NONXCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT -# RUN: lld-link /out:%t.exe /entry:main /cetcompat %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPAT %s -CETCOMPAT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT - -# RUN: lld-link /out:%t.exe /entry:main %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPAT %s -# RUN: lld-link /out:%t.exe /entry:main /cetcompat:no %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPAT %s -NONCETCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT - -# RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPATSTRICT %s -CETCOMPATSTRICT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE - -# RUN: lld-link /out:%t.exe /entry:main %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTRICT %s -# RUN: lld-link /out:%t.exe /entry:main /cetcompatstrict:no %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTRICT %s -NONCETCOMPATSTRICT-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT_STRICT_MODE - -# RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETCOMPATSTIPVALIDATIONRELAXED %s -CETCOMPATSTIPVALIDATIONRELAXED: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE - -# RUN: lld-link /out:%t.exe /entry:main %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTIPVALIDATIONRELAXED %s -# RUN: lld-link /out:%t.exe /entry:main /cetipvalidationrelaxed:no %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETCOMPATSTIPVALIDATIONRELAXED %s -NONCETCOMPATSTIPVALIDATIONRELAXED-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_SET_CONTEXT_IP_VALIDATION_RELAXED_MODE - -# RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=CETDYNAMICAPISINPROC %s -CETDYNAMICAPISINPROC: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY - -# RUN: lld-link /out:%t.exe /entry:main %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s -# RUN: lld-link /out:%t.exe /entry:main /cetdynamicapisinproc:no %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONCETDYNAMICAPISINPROC %s -NONCETDYNAMICAPISINPROC-NOT: IMAGE_DLL_CHARACTERISTICS_EX_CET_DYNAMIC_APIS_ALLOW_IN_PROC_ONLY - -# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible /functionpadmin:6 %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=HOTPATCHCOMPATIBLE %s -HOTPATCHCOMPATIBLE: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE - -# RUN: lld-link /out:%t.exe /entry:main %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONHOTPATCHCOMPATIBLE %s -# RUN: lld-link /out:%t.exe /entry:main /hotpatchcompatible:no %t.obj -# RUN: llvm-readobj --coff-debug-directory %t.exe | FileCheck -check-prefix=NONHOTPATCHCOMPATIBLE %s -NONHOTPATCHCOMPATIBLE-NOT: IMAGE_DLL_CHARACTERISTICS_EX_HOTPATCH_COMPATIBLE - # RUN: lld-link /out:%t.exe /entry:main /swaprun:CD %t.obj # RUN: llvm-readobj --file-headers %t.exe | FileCheck -check-prefix=SWAPCD %s # RUN: lld-link /out:%t.exe /entry:main /swaprun:cd,net %t.obj