diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/ELF/OutputSections.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r-- | lld/ELF/OutputSections.cpp | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 6142cb0783ce..7e9e76b070ec 100644 --- a/lld/ELF/OutputSections.cpp +++ b/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; @@ -114,8 +114,7 @@ void OutputSection::commitSection(InputSection *isec) { flags = isec->flags; } else { // Otherwise, check if new type or flags are compatible with existing ones. - unsigned mask = SHF_TLS | SHF_LINK_ORDER; - if ((flags & mask) != (isec->flags & mask)) + if ((flags ^ isec->flags) & SHF_TLS) error("incompatible section flags for " + name + "\n>>> " + toString(isec) + ": 0x" + utohexstr(isec->flags) + "\n>>> output section " + name + ": 0x" + utohexstr(flags)); @@ -226,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; @@ -243,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, @@ -331,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); } }); @@ -357,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 @@ -367,8 +388,9 @@ void OutputSection::finalize() { // all InputSections in the OutputSection have the same dependency. if (auto *ex = dyn_cast<ARMExidxSyntheticSection>(first)) link = ex->getLinkOrderDep()->getParent()->sectionIndex; - else if (auto *d = first->getLinkOrderDep()) - link = d->getParent()->sectionIndex; + else if (first->flags & SHF_LINK_ORDER) + if (auto *d = first->getLinkOrderDep()) + link = d->getParent()->sectionIndex; } if (type == SHT_GROUP) { @@ -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 |