This is an archive of the discontinued LLVM Phabricator instance.

[COFF] Allow debug info to relocate against discarded symbols
ClosedPublic

Authored by rnk on Jun 26 2017, 3:38 PM.

Details

Summary

In order to do this without switching on the symbol kind multiple times,
I created Defined::getChunkAndOffset and use that instead of
SymbolBody::getRVA in the inner relocation loop.

Now we get the symbol's chunk before switching over relocation types, so
we can test if it has been discarded outside the inner relocation type
switch. This also simplifies application of section relative
relocations. Previously we would switch on symbol kind to compute the
RVA, then the relocation type, and then the symbol kind again to get the
output section so we could subtract that from the symbol RVA. Now we
*always* have an OutputSection, so applying SECREL and SECTION
relocations isn't as much of a special case.

I'm still not quite happy with the cleanliness of this code. I'm not
sure what offsets and bases we should be using during the relocation
processing loop: VA, RVA, or OutputSectionOffset. I started work on the
FIXME to add a fake Chunk and OutputSection for absolute and __ImageBase
symbols so that we never need null checks for these pointers, but I
decided to send out this patch for comments before undertaking that
large effort.

Diff Detail

Repository
rL LLVM

Event Timeline

rnk created this revision.Jun 26 2017, 3:38 PM
rnk added reviewers: ruiu, pcc.Jun 26 2017, 3:38 PM
rnk added subscribers: llvm-commits, inglorion.

ptal

This was the last change I needed to produce a PDB for a program that links in the CRT.

Do they emit a S_DISCARDED for the symbol?

rnk added a comment.Jun 26 2017, 5:19 PM

Do they emit a S_DISCARDED for the symbol?

Nope. It's not nearly as bad as DWARF, though, which has tons of relocations against discarded sections.

rnk added a comment.Jun 26 2017, 5:23 PM
In D34650#791386, @rnk wrote:

Do they emit a S_DISCARDED for the symbol?

Nope. It's not nearly as bad as DWARF, though, which has tons of relocations against discarded sections.

It's worth pointing out that this only seems to be a problem for globals, not functions. Functions use associative comdats to drop debug info describing discarded functions. The only place I've seen these bad relocations is in these S_GDATA32 records for external globals. MSVC represents function declarations with LF_FUNC_ID type records, which are merged across TUs and don't contain relocations.

rnk updated this revision to Diff 104272.Jun 27 2017, 2:27 PM
  • clean up code, test fatal error emission
rnk added a comment.Jun 27 2017, 2:28 PM

Hopefully this version of the patch is cleaner. The error checking should be more streamlined, and we now have a test for the error case of a relocation against a discarded section.

ruiu added inline comments.Jun 27 2017, 3:02 PM
lld/COFF/Chunks.cpp
56–66 ↗(On Diff #104272)

Ah, this is much more elegant than I was thinking. Good job!

lld/COFF/MarkLive.cpp
57 ↗(On Diff #104272)

... a common error in debug sections?

rnk added inline comments.Jun 27 2017, 3:40 PM
lld/COFF/Chunks.cpp
56–66 ↗(On Diff #104272)

Thanks!

lld/COFF/MarkLive.cpp
57 ↗(On Diff #104272)

I guess this is a bad comment. It's more that I didn't want to duplicate the error message in two places when we can just continue here.

Concretely, we need this code because if we don't have it, we will fail the next assert, because isLive() is defined as:

return Live && !Discarded;
lld/test/COFF/reloc-discarded.s
28 ↗(On Diff #104272)

This is the invalid input test that shows how to get into this situation, FWIW.

rnk updated this revision to Diff 104323.Jun 27 2017, 5:28 PM
  • better comment
ruiu accepted this revision.Jun 27 2017, 5:40 PM

LGTM

This revision is now accepted and ready to land.Jun 27 2017, 5:40 PM
rnk updated this revision to Diff 104334.Jun 27 2017, 6:17 PM

The last patch didn't pass tests, and fixing the tests required some surgery.
PTAL

This revision was automatically updated to reflect the committed changes.