diff options
author | Jordan Rupprecht <rupprecht@google.com> | 2018-08-02 18:13:40 +0000 |
---|---|---|
committer | Jordan Rupprecht <rupprecht@google.com> | 2018-08-02 18:13:40 +0000 |
commit | 326ba173f34d8ee1a40e2d2af6dfa20e9b1b0114 (patch) | |
tree | 0e34bc81f265d4b648710ebd94244c56f67f1af2 /lld/ELF/InputSection.cpp | |
parent | 3db6f536dac0d47a75ca3aaa4e45f79ff64a5029 (diff) |
[LLD] Update split stack support to handle more generic prologues. Improve error handling. Add test file for better code-coverage. Update tests to be more complete.
Submitting patch on behalf of saugustine.
Differential Revision: https://reviews.llvm.org/D49926
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r-- | lld/ELF/InputSection.cpp | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 600a0bef151..597e8227217 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -838,6 +838,11 @@ static void switchMorestackCallsToMorestackNonSplit( // __morestack inside that function should be switched to // __morestack_non_split. Symbol *MoreStackNonSplit = Symtab->find("__morestack_non_split"); + if (!MoreStackNonSplit) { + error("Mixing split-stack objects requires a definition of " + "__morestack_non_split"); + return; + } // Sort both collections to compare addresses efficiently. llvm::sort(MorestackCalls.begin(), MorestackCalls.end(), @@ -862,8 +867,8 @@ static void switchMorestackCallsToMorestackNonSplit( } } -static bool enclosingPrologueAdjusted(uint64_t Offset, - const DenseSet<Defined *> &Prologues) { +static bool enclosingPrologueAttempted(uint64_t Offset, + const DenseSet<Defined *> &Prologues) { for (Defined *F : Prologues) if (F->Value <= Offset && Offset < F->Value + F->Size) return true; @@ -879,7 +884,7 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf, uint8_t *End) { if (!getFile<ELFT>()->SplitStack) return; - DenseSet<Defined *> AdjustedPrologues; + DenseSet<Defined *> Prologues; std::vector<Relocation *> MorestackCalls; for (Relocation &Rel : Relocations) { @@ -902,21 +907,26 @@ void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *Buf, if (D->Type != STT_FUNC) continue; - if (enclosingPrologueAdjusted(Rel.Offset, AdjustedPrologues)) + // If the callee's-file was compiled with split stack, nothing to do. + auto *IS = cast_or_null<InputSection>(D->Section); + if (!IS || IS->getFile<ELFT>()->SplitStack) + continue; + + if (enclosingPrologueAttempted(Rel.Offset, Prologues)) continue; if (Defined *F = getEnclosingFunction<ELFT>(Rel.Offset)) { - if (Target->adjustPrologueForCrossSplitStack(Buf + F->Value, End)) { - AdjustedPrologues.insert(F); + Prologues.insert(F); + if (Target->adjustPrologueForCrossSplitStack(Buf + getOffset(F->Value), + End)) continue; - } + if (!getFile<ELFT>()->SomeNoSplitStack) + error(lld::toString(this) + ": " + F->getName() + + " (with -fsplit-stack) calls " + D->getName() + + " (without -fsplit-stack), but couldn't adjust its prologue"); } - if (!getFile<ELFT>()->SomeNoSplitStack) - error("function call at " + getErrorLocation(Buf + Rel.Offset) + - "crosses a split-stack boundary, but unable " + - "to adjust the enclosing function's prologue"); } - switchMorestackCallsToMorestackNonSplit(AdjustedPrologues, MorestackCalls); + switchMorestackCallsToMorestackNonSplit(Prologues, MorestackCalls); } template <class ELFT> void InputSection::writeTo(uint8_t *Buf) { |