diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h --- a/llvm/include/llvm/BinaryFormat/COFF.h +++ b/llvm/include/llvm/BinaryFormat/COFF.h @@ -704,6 +704,49 @@ IMPORT_NAME_UNDECORATE = 3 }; +enum class GuardFlags : uint32_t { + /// Module performs control flow integrity checks using system-supplied + /// support. + CF_INSTRUMENTED = 0x100, + /// Module performs control flow and write integrity checks. + CFW_INSTRUMENTED = 0x200, + /// Module contains valid control flow target metadata. + CF_FUNCTION_TABLE_PRESENT = 0x400, + /// Module does not make use of the /GS security cookie. + SECURITY_COOKIE_UNUSED = 0x800, + /// Module supports read only delay load IAT. + PROTECT_DELAYLOAD_IAT = 0x1000, + /// Delayload import table in its own .didat section (with nothing else in it) + /// that can be freely reprotected. + DELAYLOAD_IAT_IN_ITS_OWN_SECTION = 0x2000, + /// Module contains suppressed export information. This also infers that the + /// address taken IAT table is also present in the load config. + CF_EXPORT_SUPPRESSION_INFO_PRESENT = 0x4000, + /// Module enables suppression of exports. + CF_ENABLE_EXPORT_SUPPRESSION = 0x8000, + /// Module contains longjmp target information. + CF_LONGJUMP_TABLE_PRESENT = 0x10000, + /// Mask for the subfield that contains the stride of Control Flow Guard + /// function table entries (that is, the additional count of bytes per table + /// entry). + CF_FUNCTION_TABLE_SIZE_MASK = 0xF0000000, + CF_FUNCTION_TABLE_SIZE_5BYTES = 0x10000000, + CF_FUNCTION_TABLE_SIZE_6BYTES = 0x20000000, + CF_FUNCTION_TABLE_SIZE_7BYTES = 0x30000000, + CF_FUNCTION_TABLE_SIZE_8BYTES = 0x40000000, + CF_FUNCTION_TABLE_SIZE_9BYTES = 0x50000000, + CF_FUNCTION_TABLE_SIZE_10BYTES = 0x60000000, + CF_FUNCTION_TABLE_SIZE_11BYTES = 0x70000000, + CF_FUNCTION_TABLE_SIZE_12BYTES = 0x80000000, + CF_FUNCTION_TABLE_SIZE_13BYTES = 0x90000000, + CF_FUNCTION_TABLE_SIZE_14BYTES = 0xA0000000, + CF_FUNCTION_TABLE_SIZE_15BYTES = 0xB0000000, + CF_FUNCTION_TABLE_SIZE_16BYTES = 0xC0000000, + CF_FUNCTION_TABLE_SIZE_17BYTES = 0xD0000000, + CF_FUNCTION_TABLE_SIZE_18BYTES = 0xE0000000, + CF_FUNCTION_TABLE_SIZE_19BYTES = 0xF0000000, +}; + struct ImportHeader { uint16_t Sig1; ///< Must be IMAGE_FILE_MACHINE_UNKNOWN (0). uint16_t Sig2; ///< Must be 0xFFFF. diff --git a/llvm/test/tools/llvm-readobj/COFF/load-config.test b/llvm/test/tools/llvm-readobj/COFF/load-config.test --- a/llvm/test/tools/llvm-readobj/COFF/load-config.test +++ b/llvm/test/tools/llvm-readobj/COFF/load-config.test @@ -30,7 +30,13 @@ X86: GuardCFCheckDispatch: 0x0 X86: GuardCFFunctionTable: 0x100020A4 X86: GuardCFFunctionCount: 11 -X86: GuardFlags: 0x13500 +X86: GuardFlags [ (0x13500) +X86: CF_FUNCTION_TABLE_PRESENT (0x400) +X86: CF_INSTRUMENTED (0x100) +X86: CF_LONGJUMP_TABLE_PRESENT (0x10000) +X86: DELAYLOAD_IAT_IN_ITS_OWN_SECTION (0x2000) +X86: PROTECT_DELAYLOAD_IAT (0x1000) +X86: ] X86: ] X86: SEHTable [ X86: 0x10001BE0 @@ -75,7 +81,13 @@ X64: GuardCFCheckDispatch: 0x180002108 X64: GuardCFFunctionTable: 0x180002158 X64: GuardCFFunctionCount: 9 -X64: GuardFlags: 0x13500 +X64: GuardFlags [ (0x13500) +X64: CF_FUNCTION_TABLE_PRESENT (0x400) +X64: CF_INSTRUMENTED (0x100) +X64: CF_LONGJUMP_TABLE_PRESENT (0x10000) +X64: DELAYLOAD_IAT_IN_ITS_OWN_SECTION (0x2000) +X64: PROTECT_DELAYLOAD_IAT (0x1000) +X64: ] X64: ] X64-NOT: SEHTable X64: GuardFidTable [ diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -577,6 +577,50 @@ LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256), }; +const EnumEntry PELoadConfigGuardFlags[] = { + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_INSTRUMENTED), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CFW_INSTRUMENTED), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_FUNCTION_TABLE_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, SECURITY_COOKIE_UNUSED), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, PROTECT_DELAYLOAD_IAT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + DELAYLOAD_IAT_IN_ITS_OWN_SECTION), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_EXPORT_SUPPRESSION_INFO_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_ENABLE_EXPORT_SUPPRESSION), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_LONGJUMP_TABLE_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_5BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_6BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_7BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_8BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_9BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_10BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_11BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_12BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_13BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_14BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_15BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_16BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_17BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_18BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_19BYTES), +}; + template static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, COFFSymbolRef Symbol, @@ -880,7 +924,9 @@ W.printHex("GuardCFCheckDispatch", Conf->GuardCFCheckDispatch); W.printHex("GuardCFFunctionTable", Conf->GuardCFFunctionTable); W.printNumber("GuardCFFunctionCount", Conf->GuardCFFunctionCount); - W.printHex("GuardFlags", Conf->GuardFlags); + W.printFlags("GuardFlags", Conf->GuardFlags, + makeArrayRef(PELoadConfigGuardFlags), + (uint32_t)COFF::GuardFlags::CF_FUNCTION_TABLE_SIZE_MASK); Tables.GuardFidTableVA = Conf->GuardCFFunctionTable; Tables.GuardFidTableCount = Conf->GuardCFFunctionCount;