Details
- Reviewers
jhenderson rnk ruiu - Commits
- rG184377da5c7c: [LLD] Implement /guard:[no]ehcont
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Event Timeline
Hi @rnk , I'm implementing EHCont guard in LLD referring to your longjmp patch. Currently the binary's EHCont table always be null. I guess it results from I haven't told lld where's the place it should put the EHCont table in the load config table.
But I didn't find any related code in longjmp patch. Could you point me where the code is? Or I misunderstood something?
The CRT is actually responsible for providing a struct defining the load configuration. You can see in the LLD gfids tests that they all have a blob like this:
.section .rdata,"dr" .globl _load_config_used _load_config_used: .long 256 .fill 124, 1, 0 .quad __guard_fids_table .quad __guard_fids_count .long __guard_flags .fill 128, 1, 0
To add ehcont tests, you will need to provide a similar load config that llvm-readobj can parse. Hopefully that answers your question.
Yes. It solves my problems. Thanks very much.
Now, the last question: I found it works with a given load configuration in the test (That's why I'm sure it's the right direction), but still doesn't work when using clang-cl or/and lld-link to build a cpp file. I guess it maybe related to the lld-link that doesn't use the latest CRT. Do you know how to fix this problem?
lld/test/COFF/pdb-natvis.test | ||
---|---|---|
17 ↗ | (On Diff #333000) | I have no idea how this been affected by this patch. |
- Remove lib dependency to make linux testing happy.
- Revert the change to pdb-natvis.test.
lld/test/COFF/pdb-natvis.test | ||
---|---|---|
17 ↗ | (On Diff #333000) | Since the change results in the build server fail, I suspect if it is my local problem. Reverted it to see if the build server happy. |
lld/COFF/DriverUtils.cpp | ||
---|---|---|
104–114 | This changed the behaviour of /guard:cf. Before this change, /guard:cf is equivalent to /guard:cf,longjmp by default, but after this change one must explicitly pass /guard:longjmp to`lld-link for it to generate the guard long jump table. This also does not match the behaviour of MSVC's link.exe. From my quick testing, /guard:cf, /guard:longjmp and /guard:cf,longjmp all do the same thing for it to enable both CFGuard and the long jump table. Only when you pass /guard:cf,nolongjmp is the jump table not present in the final image. |
lld/COFF/DriverUtils.cpp | ||
---|---|---|
104–114 | Thanks for raising the problem. I don't find any description about the longjmp option in official document. Unless there's explicit document about the relationship between /guard:cf, /guard:longjmp and /guard:cf,longjmp, I don't think we need to match the exact behavior with MSVC. The single /guard:cf has ambiguity since we are supporting ehcont. So I'm not sure if the current MSVC behavior is constant in future versions. |
lld/COFF/DriverUtils.cpp | ||
---|---|---|
104–114 | I just think that, long jump guard seems to be a rather cheap hardening measure when control flow guard is already in use. Not enabling it by default perhaps seems a bit odd, especially since this feels like an unintentional change. But fine with me either way (I don't really use MSVC or Clang with MSVC target, just noticed the difference when investigating this LLD feature.) |
lld/COFF/DriverUtils.cpp | ||
---|---|---|
104–114 | Thanks for the point. I'm not a MSVC/clang-cl user either. So I couldn't weight how cheap the long jump guard is. I designed it in the perspective of a junior user, to whom it's hard to understand the longjmp is on by default for some reason and need nolongjmp to disable it, while ehcont is on the contrary. |
lld/COFF/DriverUtils.cpp | ||
---|---|---|
104–114 | I agree, longjump protections should be implied by /guard:cf. The nolongjump flag exists merely as a backwards compatibility escape hatch. Users should generally not specify /guard:longjump. |
lld/COFF/DriverUtils.cpp | ||
---|---|---|
104–114 | Also, FWIW, even if the exact behaviour of Microsoft's tools isn't documented, such a detail like this would most probably not change randomly from one version to another. I also would prefer that we match link.exe's behaviour exactly on this point, instead of making up our own rules for how these flags interact. |
clang-format: please reformat the code