diff options
Diffstat (limited to 'lld/ELF/InputSection.cpp')
| -rw-r--r-- | lld/ELF/InputSection.cpp | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 943cf18e6cf0..4b047f75ad69 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -27,7 +27,6 @@ #include <algorithm> #include <mutex> #include <set> -#include <unordered_set> #include <vector> using namespace llvm; @@ -84,22 +83,7 @@ InputSectionBase::InputSectionBase(InputFile *file, uint64_t flags, if (!zlib::isAvailable()) error(toString(file) + ": contains a compressed section, " + "but zlib is not available"); - switch (config->ekind) { - case ELF32LEKind: - parseCompressedHeader<ELF32LE>(); - break; - case ELF32BEKind: - parseCompressedHeader<ELF32BE>(); - break; - case ELF64LEKind: - parseCompressedHeader<ELF64LE>(); - break; - case ELF64BEKind: - parseCompressedHeader<ELF64BE>(); - break; - default: - llvm_unreachable("unknown ELFT"); - } + invokeELFT(parseCompressedHeader); } } @@ -366,7 +350,7 @@ template <class ELFT> void InputSection::copyShtGroup(uint8_t *buf) { // different in the output. We also need to handle combined or discarded // members. ArrayRef<InputSectionBase *> sections = file->getSections(); - std::unordered_set<uint32_t> seen; + DenseSet<uint32_t> seen; for (uint32_t idx : from.slice(1)) { OutputSection *osec = sections[idx]->getOutputSection(); if (osec && seen.insert(osec->sectionIndex).second) @@ -1041,6 +1025,14 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) { } target.relocate(bufLoc, rel, targetVA); break; + case R_AARCH64_PAGE_PC: + if (i + 1 < size && aarch64relaxer.tryRelaxAdrpAdd( + rel, relocations[i + 1], secAddr, buf)) { + ++i; + continue; + } + target.relocate(bufLoc, rel, targetVA); + break; case R_PPC64_RELAX_GOT_PC: { // The R_PPC64_PCREL_OPT relocation must appear immediately after // R_PPC64_GOT_PCREL34 in the relocations table at the same offset. @@ -1127,7 +1119,8 @@ void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) { // For each function-defining prologue, find any calls to __morestack, // and replace them with calls to __morestack_non_split. static void switchMorestackCallsToMorestackNonSplit( - DenseSet<Defined *> &prologues, std::vector<Relocation *> &morestackCalls) { + DenseSet<Defined *> &prologues, + SmallVector<Relocation *, 0> &morestackCalls) { // If the target adjusted a function's prologue, all calls to // __morestack inside that function should be switched to @@ -1177,7 +1170,7 @@ template <class ELFT> void InputSectionBase::adjustSplitStackFunctionPrologues(uint8_t *buf, uint8_t *end) { DenseSet<Defined *> prologues; - std::vector<Relocation *> morestackCalls; + SmallVector<Relocation *, 0> morestackCalls; for (Relocation &rel : relocations) { // Ignore calls into the split-stack api. @@ -1359,16 +1352,12 @@ void EhInputSection::split(ArrayRef<RelTy> rels) { } static size_t findNull(StringRef s, size_t entSize) { - // Optimize the common case. - if (entSize == 1) - return s.find(0); - for (unsigned i = 0, n = s.size(); i != n; i += entSize) { const char *b = s.begin() + i; if (std::all_of(b, b + entSize, [](char c) { return c == 0; })) return i; } - return StringRef::npos; + llvm_unreachable(""); } SyntheticSection *MergeInputSection::getParent() const { @@ -1377,20 +1366,24 @@ SyntheticSection *MergeInputSection::getParent() const { // Split SHF_STRINGS section. Such section is a sequence of // null-terminated strings. -void MergeInputSection::splitStrings(ArrayRef<uint8_t> data, size_t entSize) { - size_t off = 0; +void MergeInputSection::splitStrings(StringRef s, size_t entSize) { const bool live = !(flags & SHF_ALLOC) || !config->gcSections; - StringRef s = toStringRef(data); - - while (!s.empty()) { - size_t end = findNull(s, entSize); - if (end == StringRef::npos) - fatal(toString(this) + ": string is not null terminated"); - size_t size = end + entSize; - - pieces.emplace_back(off, xxHash64(s.substr(0, size)), live); - s = s.substr(size); - off += size; + const char *p = s.data(), *end = s.data() + s.size(); + if (!std::all_of(end - entSize, end, [](char c) { return c == 0; })) + fatal(toString(this) + ": string is not null terminated"); + if (entSize == 1) { + // Optimize the common case. + do { + size_t size = strlen(p) + 1; + pieces.emplace_back(p - s.begin(), xxHash64(StringRef(p, size)), live); + p += size; + } while (p != end); + } else { + do { + size_t size = findNull(StringRef(p, end - p), entSize) + entSize; + pieces.emplace_back(p - s.begin(), xxHash64(StringRef(p, size)), live); + p += size; + } while (p != end); } } @@ -1402,7 +1395,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> data, assert((size % entSize) == 0); const bool live = !(flags & SHF_ALLOC) || !config->gcSections; - pieces.assign(size / entSize, SectionPiece(0, 0, false)); + pieces.resize_for_overwrite(size / entSize); for (size_t i = 0, j = 0; i != size; i += entSize, j++) pieces[j] = {i, (uint32_t)xxHash64(data.slice(i, entSize)), live}; } @@ -1429,7 +1422,7 @@ void MergeInputSection::splitIntoPieces() { assert(pieces.empty()); if (flags & SHF_STRINGS) - splitStrings(data(), entsize); + splitStrings(toStringRef(data()), entsize); else splitNonStrings(data(), entsize); } |
