summaryrefslogtreecommitdiff
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp73
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);
}