aboutsummaryrefslogtreecommitdiff
path: root/lld/ELF/OutputSections.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /lld/ELF/OutputSections.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'lld/ELF/OutputSections.cpp')
-rw-r--r--lld/ELF/OutputSections.cpp61
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