diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 85568a12531f9..c9b6318fe5212 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -1796,7 +1796,7 @@ void Writer::createGuardCFTables() { // Add the ehcont target table unless the user told us not to. if (config->guardCF & GuardCFLevel::EHCont) maybeAddRVATable(std::move(ehContTargets), "__guard_eh_cont_table", - "__guard_eh_cont_count", true); + "__guard_eh_cont_count"); // Set __guard_flags, which will be used in the load config to indicate that // /guard:cf was enabled. diff --git a/lld/test/COFF/guard-ehcont.s b/lld/test/COFF/guard-ehcont.s index f040a62f7e3dd..73807688feee6 100644 --- a/lld/test/COFF/guard-ehcont.s +++ b/lld/test/COFF/guard-ehcont.s @@ -10,7 +10,7 @@ # CHECK: GuardCFCheckFunction: 0x0 # CHECK: GuardCFCheckDispatch: 0x0 # CHECK: GuardCFFunctionTable: 0x14000{{.*}} -# CHECK: GuardCFFunctionCount: 4 +# CHECK: GuardCFFunctionCount: 1 # CHECK: GuardFlags [ (0x400500) # CHECK: CF_FUNCTION_TABLE_PRESENT (0x400) # CHECK: CF_INSTRUMENTED (0x100) @@ -19,25 +19,13 @@ # CHECK: GuardAddressTakenIatEntryTable: 0x0 # CHECK: GuardAddressTakenIatEntryCount: 0 # CHECK: GuardEHContinuationTable: 0x14000{{.*}} -# CHECK: GuardEHContinuationCount: 1 +# CHECK: GuardEHContinuationCount: 2 # CHECK: ] # CHECK: GuardEHContTable [ # CHECK-NEXT: 0x14000{{.*}} +# CHECK-NEXT: 0x14000{{.*}} # CHECK-NEXT: ] - -# This assembly is reduced from C code like: -# int main() -# { -# try { -# throw 3; -# } -# catch (int e) { -# return e != 3; -# } -# return 2; -# } - # We need @feat.00 to have 0x4000 to indicate /guard:ehcont. .def @feat.00; .scl 3; @@ -48,168 +36,50 @@ .def main; .scl 2; .type 32; .endef .globl main # -- Begin function main .p2align 4, 0x90 -main: # @main -.Lfunc_begin0: +main: .seh_proc main -.intel_syntax - .seh_handler __CxxFrameHandler3, @unwind, @except -# %bb.0: # %entry - push rbp - .seh_pushreg rbp - sub rsp, 64 - .seh_stackalloc 64 - lea rbp, [rsp + 64] - .seh_setframe rbp, 64 - .seh_endprologue - mov qword ptr [rbp - 16], -2 - mov dword ptr [rbp - 20], 0 - mov dword ptr [rbp - 24], 3 -.Ltmp0: - lea rdx, [rip + _TI1H] - lea rcx, [rbp - 24] - call _CxxThrowException -.Ltmp1: - jmp .LBB0_3 -.LBB0_2: # Block address taken - # %catchret.dest -$ehgcr_0_2: - mov eax, dword ptr [rbp - 20] - add rsp, 64 - pop rbp - ret -.LBB0_3: # %unreachable - int3 - .seh_handlerdata - .long ($cppxdata$main)@IMGREL - .text - .seh_endproc - .def "?catch$1@?0?main@4HA"; - .scl 3; - .type 32; - .endef - .p2align 4, 0x90 -"?catch$1@?0?main@4HA": -.seh_proc "?catch$1@?0?main@4HA" - .seh_handler __CxxFrameHandler3, @unwind, @except -.LBB0_1: # %catch - mov qword ptr [rsp + 16], rdx - push rbp - .seh_pushreg rbp - sub rsp, 32 - .seh_stackalloc 32 - lea rbp, [rdx + 64] - .seh_endprologue - mov eax, dword ptr [rbp - 4] - sub eax, 3 - setne al - movzx eax, al - mov dword ptr [rbp - 20], eax - lea rax, [rip + .LBB0_2] - add rsp, 32 - pop rbp - ret # CATCHRET - .def free; .scl 2; .type 32; .endef - .globl free -free: - ret - .def __CxxFrameHandler3; .scl 2; .type 32; .endef - .globl __CxxFrameHandler3 -__CxxFrameHandler3: - ret - .def _CxxThrowException; .scl 2; .type 32; .endef - .globl _CxxThrowException -_CxxThrowException: - ret -.Lfunc_end0: + .seh_handler __C_specific_handler, @unwind, @except .seh_handlerdata - .long ($cppxdata$main)@IMGREL + .long 2 + .long (seh_begin)@IMGREL + .long (seh_end)@IMGREL + .long 1 + .long (seh_except)@IMGREL + .long (seh2_begin)@IMGREL + .long (seh2_end)@IMGREL + .long 1 + .long (seh2_except)@IMGREL .text - .seh_endproc - .section .xdata,"dr" - .p2align 2 -$cppxdata$main: - .long 429065506 # MagicNumber - .long 2 # MaxState - .long ($stateUnwindMap$main)@IMGREL # UnwindMap - .long 1 # NumTryBlocks - .long ($tryMap$main)@IMGREL # TryBlockMap - .long 4 # IPMapEntries - .long ($ip2state$main)@IMGREL # IPToStateXData - .long 48 # UnwindHelp - .long 0 # ESTypeList - .long 1 # EHFlags -$stateUnwindMap$main: - .long -1 # ToState - .long 0 # Action - .long -1 # ToState - .long 0 # Action -$tryMap$main: - .long 0 # TryLow - .long 0 # TryHigh - .long 1 # CatchHigh - .long 1 # NumCatches - .long ($handlerMap$0$main)@IMGREL # HandlerArray -$handlerMap$0$main: - .long 0 # Adjectives - .long "??_R0H@8"@IMGREL # Type - .long 60 # CatchObjOffset - .long "?catch$1@?0?main@4HA"@IMGREL # Handler - .long 56 # ParentFrameOffset -$ip2state$main: - .long .Lfunc_begin0@IMGREL # IP - .long -1 # ToState - .long .Ltmp0@IMGREL+1 # IP - .long 0 # ToState - .long .Ltmp1@IMGREL+1 # IP - .long -1 # ToState - .long "?catch$1@?0?main@4HA"@IMGREL # IP - .long 1 # ToState - .text - # -- End function - .section .data,"dw",discard,"??_R0H@8" - .globl "??_R0H@8" # @"??_R0H@8" - .p2align 4 -"??_R0H@8": - .quad 0 - .quad 0 - .asciz ".H" - .zero 5 + seh_begin: + nop + int3 + nop + seh_end: + nop + seh_except: + nop - .section .xdata,"dr",discard,"_CT??_R0H@84" - .globl "_CT??_R0H@84" # @"_CT??_R0H@84" - .p2align 4 -"_CT??_R0H@84": - .long 1 # 0x1 - .long "??_R0H@8"@IMGREL - .long 0 # 0x0 - .long 4294967295 # 0xffffffff - .long 0 # 0x0 - .long 4 # 0x4 - .long 0 # 0x0 + seh2_begin: + nop + int3 + nop + seh2_end: + nop + seh2_except: + nop + + xor %eax, %eax + ret +.seh_endproc - .section .xdata,"dr",discard,_CTA1H - .globl _CTA1H # @_CTA1H - .p2align 3 -_CTA1H: - .long 1 # 0x1 - .long "_CT??_R0H@84"@IMGREL +__C_specific_handler: + ret - .section .xdata,"dr",discard,_TI1H - .globl _TI1H # @_TI1H - .p2align 3 -_TI1H: - .long 0 # 0x0 - .long 0 # 0x0 - .long 0 # 0x0 - .long _CTA1H@IMGREL +.section .gehcont$y,"dr" +.symidx seh_except +.symidx seh2_except - .section .gehcont$y,"dr" - .symidx $ehgcr_0_2 - .addrsig_sym _CxxThrowException - .addrsig_sym __CxxFrameHandler3 - .addrsig_sym "??_R0H@8" - .addrsig_sym __ImageBase - .section .rdata,"dr" +.section .rdata,"dr" .globl _load_config_used _load_config_used: .long 312 diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 0a5073d2d23fa..4caa1c7ff9077 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -940,36 +940,34 @@ void COFFDumper::printCOFFLoadConfig() { OS << " flags " << utohexstr(Flags); }; + // The stride gives the number of extra bytes in addition to the 4-byte + // RVA of each entry in the table. As of writing only a 1-byte extra flag + // has been defined. + uint32_t Stride = Tables.GuardFlags >> 28; + PrintExtraCB PrintExtra = Stride == 1 ? PrintGuardFlags : nullptr; + if (Tables.GuardFidTableVA) { ListScope LS(W, "GuardFidTable"); - if (uint32_t Size = - Tables.GuardFlags & - uint32_t(COFF::GuardFlags::CF_FUNCTION_TABLE_SIZE_MASK)) { - // The size mask gives the number of extra bytes in addition to the 4-byte - // RVA of each entry in the table. As of writing only a 1-byte extra flag - // has been defined. - Size = (Size >> 28) + 4; - printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, Size, - PrintGuardFlags); - } else { - printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 4); - } + printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, + 4 + Stride, PrintExtra); } if (Tables.GuardIatTableVA) { ListScope LS(W, "GuardIatTable"); - printRVATable(Tables.GuardIatTableVA, Tables.GuardIatTableCount, 4); + printRVATable(Tables.GuardIatTableVA, Tables.GuardIatTableCount, + 4 + Stride, PrintExtra); } if (Tables.GuardLJmpTableVA) { ListScope LS(W, "GuardLJmpTable"); - printRVATable(Tables.GuardLJmpTableVA, Tables.GuardLJmpTableCount, 4); + printRVATable(Tables.GuardLJmpTableVA, Tables.GuardLJmpTableCount, + 4 + Stride, PrintExtra); } if (Tables.GuardEHContTableVA) { ListScope LS(W, "GuardEHContTable"); - printRVATable(Tables.GuardEHContTableVA, Tables.GuardEHContTableCount, 5, - PrintGuardFlags); + printRVATable(Tables.GuardEHContTableVA, Tables.GuardEHContTableCount, + 4 + Stride, PrintExtra); } }