This is an archive of the discontinued LLVM Phabricator instance.

lld-link: align sections to 16 bytes if referenced from the gfids table
ClosedPublic

Authored by inglorion on Jun 27 2018, 5:20 PM.

Details

Summary

Control flow guard works best when targets it checks are 16-byte aligned.
Microsoft's link.exe helps ensure this by aligning code from sections
that are referenced from the gfids table to 16 bytes when linking with
-guard:cf, even if the original section specifies a smaller alignment.
This change implements that behavior in lld-link.

See https://crbug.com/857012 for more details.

Diff Detail

Repository
rLLD LLVM Linker

Event Timeline

inglorion created this revision.Jun 27 2018, 5:20 PM
pcc added a subscriber: pcc.Jun 27 2018, 5:24 PM
pcc added inline comments.
lld/COFF/Writer.cpp
1050 ↗(On Diff #153218)

I think this can be simplified: the alignment should always be a power of 2.

inglorion added inline comments.Jun 27 2018, 5:39 PM
lld/COFF/Writer.cpp
1050 ↗(On Diff #153218)

So just if (Alignment < 16) Alignment = 16 would do it?

pcc added inline comments.Jun 27 2018, 5:39 PM
lld/COFF/Writer.cpp
1050 ↗(On Diff #153218)

Yes.

inglorion updated this revision to Diff 153228.Jun 27 2018, 6:03 PM

simplified as suggested by @pcc (thanks!)

ruiu accepted this revision.Jun 27 2018, 9:43 PM

LGTM

lld/COFF/Writer.cpp
1049 ↗(On Diff #153228)

Please replace auto with the real type.

This revision is now accepted and ready to land.Jun 27 2018, 9:43 PM
hans added a comment.Jun 28 2018, 4:44 AM

Nice! I like how simple this turned out.

From the commit message:
PR857012 is the Chromium bug number. LLVM hasn't had that many bugs :-p
Maybe just change to "See also https://crbug.com/857012" for details or something like that.

lld/test/COFF/guardcf-align.s
11 ↗(On Diff #153228)

It would be good to have a comment about the intention of these checks, since it's not obvious from a quick read.

The regexes are a little tricky to read. Will there be more entries in the gfid than the one for foo? If not, could we just check that there's only one entry and that it's aligned?

Also it would be nice to check that it's really foo that's getting aligned. Maybe we could generate a map file (/lldmap:file) and check foo's alignment there?

Oh, and could we be getting lucky and foo is aligned because it's first in the segment or something? Maybe there should be more than one function that we check the alignment of just to be sure?

inglorion marked 2 inline comments as done.Jun 28 2018, 8:20 AM
inglorion added inline comments.
lld/test/COFF/guardcf-align.s
11 ↗(On Diff #153228)

I've added a comment to explain what we're looking for with the regexes.

The table actually contains multiple entries. We're checking that all of them end in 0 (which means they're 16-byte aligned). We could constrain the check to only foo (using the map, as you suggest), but really we want all of them to be aligned. foo is just a symbol in a section specifically crafted to cause alignment problems.

You're right that foo could end up being aligned by accident, but it's unlikely that all entries will be aligned by accident. In fact, they aren't, without the patch.

hans accepted this revision.Jun 28 2018, 8:24 AM
hans added inline comments.
lld/test/COFF/guardcf-align.s
11 ↗(On Diff #153228)

Okay, sounds good.

inglorion updated this revision to Diff 153328.Jun 28 2018, 8:24 AM
inglorion marked an inline comment as done.
inglorion edited the summary of this revision. (Show Details)
inglorion removed a subscriber: pcc.

improvements suggested by @ruiu and @hans (thanks!)

This revision was automatically updated to reflect the committed changes.