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.

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

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.


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


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.



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.