This is an archive of the discontinued LLVM Phabricator instance.

[COFF] Simplify symbol table output section computation
ClosedPublic

Authored by smeenai on May 25 2018, 1:44 PM.

Details

Summary

Rather than using a loop to compare symbol RVAs to the starting RVAs of
sections to determine which section a symbol belongs to, just get the
output section of a symbol directly via its chunk, and bail if the
symbol doesn't have an output section, which avoids having to hardcode
logic for handling dead symbols, CodeView symbols, etc. This was
suggested by Reid Kleckner; thank you.

This also fixes writing out symbol tables in the presence of RVA table
input sections (e.g. .sxdata and .gfids). Such sections aren't written
to the output file directly, so their RVA is 0, and the loop would thus
fail to find an output section for them, resulting in a segfault. Extend
some existing tests to cover this case.

Fixes PR37584.

Event Timeline

smeenai created this revision.May 25 2018, 1:44 PM
smeenai added inline comments.May 25 2018, 1:46 PM
COFF/Writer.cpp
611–614

Does this need to be generalized to all RVA table sections, e.g. the control flow guard sections? We aren't using that right now, so it's not an immediate concern, but just wondering in general.

rnk added inline comments.May 25 2018, 3:12 PM
COFF/Writer.cpp
611–614

It does. I think these are all the cases where we pull out chunks and set them aside so they don't make it to the final output:

if (C->isCodeView())
  DebugChunks.push_back(C);
else if (Config->GuardCF != GuardCFLevel::Off && Name == ".gfids$y")
  GuardFidChunks.push_back(C);
else if (Config->GuardCF != GuardCFLevel::Off && Name == ".gljmp$y")
  GuardLJmpChunks.push_back(C);
else if (Name == ".sxdata")
  SXDataChunks.push_back(C);

They are still marked as "live" so we can figure out which debug info (or RVA tables) to toss and which to keep, but none of them will ever make it into the output.

smeenai added inline comments.May 25 2018, 3:43 PM
COFF/Writer.cpp
611–614

Okay. Sounds like we should be setting some property on SectionChunk to indicate that, to avoid having to duplicate all that logic in Writer? Something along the lines of WrittenToOutputDirectly (since the section's contents do get written to the output, just in a debug info/RVA table form)? Alternatively we could leave CodeView sections as is and mark the other ones as RVATableChunkInput or something along those lines, and then ignore those sections in the Writer (in addition to the existing ignoring of CodeView sections).

rnk added inline comments.May 25 2018, 5:22 PM
COFF/Writer.cpp
611–614

I think we'd actually want to set that in Writer::assignAddresses, since it would subsume the isLive check as well.

Actually, remind me why we can't just use Def->getChunk()->getOutputSection() (with some null checks) here? Why are we searching the output sections by RVA anyway? I think it's only a few cases. If there's no OutputSection, then we shouldn't write it to the symbol table.

smeenai added inline comments.May 29 2018, 11:08 AM
COFF/Writer.cpp
611–614

Good question. I did some archeology, and the search for output sections by RVA actually dates all the way back to https://reviews.llvm.org/D11023, which first introduced symbol tables. Let me try changing that and seeing if tests are happy.

smeenai updated this revision to Diff 148958.May 29 2018, 11:55 AM
smeenai retitled this revision from [COFF] Don't crash when emitting symbol table for SafeSEH input files to [COFF] Simplify symbol table output section computation.
smeenai edited the summary of this revision. (Show Details)

@rnk's suggestion

rnk accepted this revision.May 29 2018, 12:00 PM

lgtm

This revision is now accepted and ready to land.May 29 2018, 12:00 PM
This revision was automatically updated to reflect the committed changes.
pcc added inline comments.May 29 2018, 1:50 PM
COFF/Writer.cpp
638

Can we move this switch to the top of the function? Then the only code that needs to care about output sections will be in the default case of the switch.

smeenai added inline comments.May 29 2018, 1:52 PM
COFF/Writer.cpp
638

Good idea; I'll throw up a patch in a bit.