我无法回答问题 1。但是,我很难想象使用must这个词可能意味着该规则是可选的。
至于问题 2,您需要编译器/链接器的支持。您不能合理地期望使用 PE 编辑后链接工具来支持它。考虑以下代码:
try
Beep;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
编译器发出以下内容:
Project1.dpr.11: try
0041C3AA 33C0 xor eax,eax
0041C3AC 55 push ebp
0041C3AD 68C9C34100 push $0041c3c9 // exception handler is at $0041c3c9
0041C3B2 64FF30 push dword ptr fs:[eax]
0041C3B5 648920 mov fs:[eax],esp
Project1.dpr.12: Beep;
0041C3B8 6A00 push $00
0041C3BA E8E1CEFEFF call MessageBeep
0041C3BF 33C0 xor eax,eax
0041C3C1 5A pop edx
0041C3C2 59 pop ecx
0041C3C3 59 pop ecx
0041C3C4 648910 mov fs:[eax],edx
0041C3C7 EB59 jmp $0041c422
0041C3C9 E97291FEFF jmp @HandleOnException
0041C3CE 0100 add [eax],eax
0041C3D0 0000 add [eax],al
0041C3D2 E42F in al,$2f
0041C3D4 41 inc ecx
0041C3D5 00DA add dl,bl
0041C3D7 C3 ret
0041C3D8 41 inc ecx
0041C3D9 00A3D83E4200 add [ebx+$00423ed8],ah
Project1.dpr.15: Writeln(E.ClassName, ': ', E.Message);
........
现在,真正的异常处理程序是HandleOnException
在System.pas
. 但是,压入堆栈$0041c3c9
的地址是包含该try/except
块的代码的本地地址。这意味着为了创建 SafeSEH PE 部分,您需要找到try/except
代码中的每一个部分。虽然这显然是可行的,但我认为它并不容易处理。
我宁愿想象 x86 编译器的 SEH 异常处理程序只是_HandleXXX
在System.pas
. 在这种情况下,添加一个仅列出这些功能的 PE 部分作为链接后步骤将很容易。然而,由于每一个try/except
都有自己的本地异常处理程序,我现在相信只有编译器作者才能真正希望添加 SafeSEH PE 部分。
据我所知,没有要求SafeSEH
支持 x86 Windows 编译器的 QC 报告。我建议您记录 QC 报告和官方支持案例。
更新: @haimg 做得很好,因为我在失败的地方取得了成功并设法找到了 QC 报告:QC#106781。