[PATCH] D35473: [ELF] compareByFilePosition requires stable_sort

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 17 05:41:59 PDT 2017


peter.smith added a comment.

In https://reviews.llvm.org/D35473#811101, @smeenai wrote:

> I discovered this because the `.ARM.exidx` end sentinel was getting incorrectly reordered away from the end of the section, leading to unwinding failing in certain binaries. CC @peter.smith, in case you've run into any similar issues.
>
> Unfortunately, I'm not sure how to write a test case for this. I was using `-ffunction-sections` so I would end up with multiple `.ARM.exidx.*` sections, so there's a reasonable chance of the sentinel getting incorrectly reordered, but there's no guarantee, since it depends on the underlying `std::sort` implementation (which could potentially even be randomized). Any ideas?


I've not seen this myself, but I haven't done a lot of testing on this after the initial patch went in, which I think was stable_sort at the time. I agree it will be difficult to write a test that will trigger reliably on all platforms sort routine. I've no objections to the change, although it might be better to rewrite compareByFilePosition to be std::sort friendly. For example it is currently:

  static bool compareByFilePosition(InputSection *A, InputSection *B) {
    // Synthetic doesn't have link order dependecy, stable_sort will keep it last
    if (A->kind() == InputSectionBase::Synthetic ||
        B->kind() == InputSectionBase::Synthetic)
      return false;
    InputSection *LA = A->getLinkOrderDep();
    InputSection *LB = B->getLinkOrderDep();
    OutputSection *AOut = LA->getParent();
    OutputSection *BOut = LB->getParent();
    if (AOut != BOut)
      return AOut->SectionIndex < BOut->SectionIndex;
    return LA->OutSecOff < LB->OutSecOff;
  }

I think it could be rewritten as:

  static bool compareByFilePosition(InputSection *A, InputSection *B) {
    // Only Synthetic with a link order dependency is the ARMExidxSentinelSection
    // There is only one of these and it must be last.
    if (A->kind() == InputSectionBase::Synthetic)
      return false;
    if (B->kind() == InputSectionBase::Synthetic)
      return true;
    InputSection *LA = A->getLinkOrderDep();
    InputSection *LB = B->getLinkOrderDep();
    OutputSection *AOut = LA->getParent();
    OutputSection *BOut = LB->getParent();
    if (AOut != BOut)
      return AOut->SectionIndex < BOut->SectionIndex;
    return LA->OutSecOff < LB->OutSecOff;
  }


https://reviews.llvm.org/D35473





More information about the llvm-commits mailing list