There were a few issues with the previous setup:
- The section sorting comparator used a declarative map of section names to determine the correct order, but it turns out we need to match on more than just names -- in particular, an upcoming diff will sort based on whether the S_ZERO_FILL flag is set. This diff changes the sorter to a more imperative but flexible form.
- We were sorting OutputSections stored in a MapVector, which left the MapVector in an inconsistent state -- the wrong keys map to the wrong values! In practice, we weren't doing key lookups (only container iteration) after the sort, so this was fine, but it was still a dubious state of affairs. This diff copies the OutputSections to a vector before sorting them.
- We were adding unneeded OutputSections to OutputSegments and then filtering them out later, which meant that we had to remember whether an OutputSegment was in a pre- or post-filtered state. This diff only adds the sections to the segments if they are needed.
In addition to those major changes, two minor ones worth noting:
- I renamed all OutputSection variable names to osec, to parallel isec. Previously we were using some inconsistent combination of osec, os, and section.
- I added a check (and a test) for InputSections with names that clashed with those of our synthetic OutputSections.
for future reference: the change from a pointer to an array was required so that these constants could be used in StringSwitch.