diff options
Diffstat (limited to 'contrib/llvm-project/lld/ELF/OutputSections.cpp')
-rw-r--r-- | contrib/llvm-project/lld/ELF/OutputSections.cpp | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/contrib/llvm-project/lld/ELF/OutputSections.cpp b/contrib/llvm-project/lld/ELF/OutputSections.cpp index b609878be319..7e9e76b070ec 100644 --- a/contrib/llvm-project/lld/ELF/OutputSections.cpp +++ b/contrib/llvm-project/lld/ELF/OutputSections.cpp @@ -14,11 +14,11 @@ #include "Target.h" #include "lld/Common/Memory.h" #include "lld/Common/Strings.h" -#include "lld/Common/Threads.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/Compression.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/Parallel.h" #include "llvm/Support/SHA1.h" #include <regex> @@ -27,9 +27,9 @@ using namespace llvm::dwarf; using namespace llvm::object; using namespace llvm::support::endian; using namespace llvm::ELF; +using namespace lld; +using namespace lld::elf; -namespace lld { -namespace elf { uint8_t *Out::bufferStart; uint8_t Out::first; PhdrEntry *Out::tlsPhdr; @@ -39,7 +39,7 @@ OutputSection *Out::preinitArray; OutputSection *Out::initArray; OutputSection *Out::finiArray; -std::vector<OutputSection *> outputSections; +std::vector<OutputSection *> elf::outputSections; uint32_t OutputSection::getPhdrFlags() const { uint32_t ret = 0; @@ -225,7 +225,7 @@ static void sortByOrder(MutableArrayRef<InputSection *> in, in[i] = v[i].second; } -uint64_t getHeaderSize() { +uint64_t elf::getHeaderSize() { if (config->oFormatBinary) return 0; return Out::elfHeader->size + Out::programHeaders->size; @@ -242,6 +242,25 @@ void OutputSection::sort(llvm::function_ref<int(InputSectionBase *s)> order) { sortByOrder(isd->sections, order); } +static void nopInstrFill(uint8_t *buf, size_t size) { + if (size == 0) + return; + unsigned i = 0; + if (size == 0) + return; + std::vector<std::vector<uint8_t>> nopFiller = *target->nopInstrs; + unsigned num = size / nopFiller.back().size(); + for (unsigned c = 0; c < num; ++c) { + memcpy(buf + i, nopFiller.back().data(), nopFiller.back().size()); + i += nopFiller.back().size(); + } + unsigned remaining = size - i; + if (!remaining) + return; + assert(nopFiller[remaining - 1].size() == remaining); + memcpy(buf + i, nopFiller[remaining - 1].data(), remaining); +} + // Fill [Buf, Buf + Size) with Filler. // This is used for linker script "=fillexp" command. static void fill(uint8_t *buf, size_t size, @@ -330,7 +349,11 @@ template <class ELFT> void OutputSection::writeTo(uint8_t *buf) { end = buf + size; else end = buf + sections[i + 1]->outSecOff; - fill(start, end - start, filler); + if (isec->nopFiller) { + assert(target->nopInstrs); + nopInstrFill(start, end - start); + } else + fill(start, end - start, filler); } }); @@ -356,8 +379,7 @@ static void finalizeShtGroup(OutputSection *os, } void OutputSection::finalize() { - std::vector<InputSection *> v = getInputSections(this); - InputSection *first = v.empty() ? nullptr : v[0]; + InputSection *first = getFirstInputSection(this); if (flags & SHF_LINK_ORDER) { // We must preserve the link order dependency of sections with the @@ -456,7 +478,7 @@ void OutputSection::sortCtorsDtors() { // If an input string is in the form of "foo.N" where N is a number, // return N. Otherwise, returns 65536, which is one greater than the // lowest priority. -int getPriority(StringRef s) { +int elf::getPriority(StringRef s) { size_t pos = s.rfind('.'); if (pos == StringRef::npos) return 65536; @@ -466,7 +488,15 @@ int getPriority(StringRef s) { return v; } -std::vector<InputSection *> getInputSections(OutputSection *os) { +InputSection *elf::getFirstInputSection(const OutputSection *os) { + for (BaseCommand *base : os->sectionCommands) + if (auto *isd = dyn_cast<InputSectionDescription>(base)) + if (!isd->sections.empty()) + return isd->sections[0]; + return nullptr; +} + +std::vector<InputSection *> elf::getInputSections(const OutputSection *os) { std::vector<InputSection *> ret; for (BaseCommand *base : os->sectionCommands) if (auto *isd = dyn_cast<InputSectionDescription>(base)) @@ -507,6 +537,3 @@ template void OutputSection::maybeCompress<ELF32LE>(); template void OutputSection::maybeCompress<ELF32BE>(); template void OutputSection::maybeCompress<ELF64LE>(); template void OutputSection::maybeCompress<ELF64BE>(); - -} // namespace elf -} // namespace lld |