diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 25d5fe886bd5406bc1276c2fed3a6b53cde5ca0e..15ea8ae17ae2d494e4dc277e4d4f93863eede037 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1718,31 +1718,37 @@ Defined *SharedFileExtended::findSectionSymbol(uint64_t offset) const { bool isDebug = false; /*if (offset == 0x7738) // debug hint isDebug = true;*/ - auto predRange = [=](Symbol *sym) { - if (!sym || sym->isUndefined() || !sym->isSection()) - return false; - const Defined *d = cast(sym); + llvm::SmallVector candidates; + for (auto *sym : this->allSymbols) { + if (!sym || !sym->isSection()) + continue; + assert(sym->isDefined()); + Defined *d = cast(sym); uint64_t low = d->section->address; uint64_t high = low + d->section->size; if (isDebug) lld::outs() << "offset: 0x" + utohexstr(offset) + " sect name: " + d->section->name + "low 0x" + - utohexstr(low) + " high: 0x" + - utohexstr(high) + "\n"; - return (offset >= low) && (offset < high); - }; - - auto i = this->allSymbols.begin(); - auto e = this->allSymbols.end(); - auto ret = std::find_if(i, e, predRange); - if (ret == e) // item was not found + utohexstr(low) + " high: 0x" + utohexstr(high) + "\n"; + bool isGood = (offset >= low) && (offset < high); + if (!isGood) + continue; + candidates.push_back(d); + } + if (candidates.empty()) // no suitable items found return nullptr; - auto d = cast(*ret); + if (candidates.size() > 1) + llvm::sort(candidates, [=](Defined *d1, Defined *d2) { + auto a1 = d1->section->address; + auto a2 = d2->section->address; + return (offset - a1 < offset - a2); + }); + + auto d = *candidates.begin(); if (isDebug) traceSymbol(*d, "found section sym: "); - return d; }