Page MenuHomePhabricator

lld/coff: Implement some support for the comdat selection field

Authored by thakis on Jan 28 2019, 6:17 AM.



LLD used to handle comdats as if the selection field was always set to IMAGE_COMDAT_SELECT_ANY. This means for obj files produced by cl /Gy, LLD would never report a duplicate symbol error.

This patch:

  • adds validation for the Selection field (should make no difference in practice for compiler-generated obj inputs)
  • rejects comdats that have different Selection fields in different obj files (likewise). This is a bit more strict but also more self-consistent thank link.exe (see comment in code)
  • implements handling for all the selection kinds

In practice, compilers only generate comdats with IMAGE_COMDAT_SELECT_NODUPLICATES (LLD now produces duplicate symbol errors for these), IMAGE_COMDAT_SELECT_ANY (no behavior change), and IMAGE_COMDAT_SELECT_LARGEST (for RTTI data, here LLD should no longer create broken executables when linking some TUs with RTTI enabled and some with it disabled – but see below).

The implementation of IMAGE_COMDAT_SELECT_LARGEST is incomplete: If one SELECT_LARGEST comdat replaces an earlier one, the comdat symbol is replaced correctly, but the old section stays loaded and if /opt:ref is disabled (via /opt:noref or /debug) it's still written to the output. That's not ideal, but better than the current treatment of just picking any one of those comdats. I hope to fix this better later.


Diff Detail


Event Timeline

thakis created this revision.Jan 28 2019, 6:17 AM
thakis marked an inline comment as done.
thakis added inline comments.
447 ↗(On Diff #183841)

This function is getting fairly long; probably want to move the whole contents of this if to its own function or something. But I thought I'd see if you have other comments first since moving the contents is easy to do.

ruiu added inline comments.Jan 29 2019, 11:09 AM
447 ↗(On Diff #183841)

I'm not too worried by the length of this function as long as each if ends with return. If each if ends with return, this function is virtually just a large switch, and a logic for each case is independent to another. That said I think it is perhaps better to move this function to a new function though.

461–464 ↗(On Diff #183841)

I'd invert the condition and call fatal early to reduce the indentation depth of the regular code path.

508 ↗(On Diff #183841)

Is it safe to fall through? Maybe you want to do continue to skip it.

thakis updated this revision to Diff 184161.Jan 29 2019, 1:14 PM
thakis marked 2 inline comments as done.


508 ↗(On Diff #183841)

At least for the warn() case I figured it's probably better to link in the comdat with the new Selection value.

ruiu accepted this revision.Jan 29 2019, 1:30 PM


This revision is now accepted and ready to land.Jan 29 2019, 1:30 PM
This revision was automatically updated to reflect the committed changes.