aboutsummaryrefslogtreecommitdiff
path: root/lld
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-05-22 16:12:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-05-22 16:12:18 +0000
commitec2b0f99f245da9ce98e41cf4cc2b6b2a02726f6 (patch)
tree774f987ba7db709a137b63ff7fb53b89b681f188 /lld
parent4c8711804d577470fbe78eed165ac2de66b5653b (diff)
downloadsrc-vendor/llvm-project/llvmorg-10.0.1-rc1-0-gf79cd71e145.tar.gz
src-vendor/llvm-project/llvmorg-10.0.1-rc1-0-gf79cd71e145.zip
Vendor import of llvm-project branch release/10.xvendor/llvm-project/llvmorg-10.0.1-rc1-0-gf79cd71e145
llvmorg-10.0.1-rc1-0-gf79cd71e145.
Diffstat (limited to 'lld')
-rw-r--r--lld/COFF/MarkLive.cpp6
-rw-r--r--lld/ELF/Driver.cpp13
-rw-r--r--lld/ELF/InputSection.cpp3
-rw-r--r--lld/ELF/InputSection.h4
-rw-r--r--lld/ELF/OutputSections.cpp8
-rw-r--r--lld/ELF/Writer.cpp27
6 files changed, 44 insertions, 17 deletions
diff --git a/lld/COFF/MarkLive.cpp b/lld/COFF/MarkLive.cpp
index 6d34cb864e3c..0afa615a1933 100644
--- a/lld/COFF/MarkLive.cpp
+++ b/lld/COFF/MarkLive.cpp
@@ -28,10 +28,12 @@ void markLive(ArrayRef<Chunk *> chunks) {
// as we push, so sections never appear twice in the list.
SmallVector<SectionChunk *, 256> worklist;
- // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
+ // COMDAT section chunks are dead by default. Add non-COMDAT chunks. Do not
+ // traverse DWARF sections. They are live, but they should not keep other
+ // sections alive.
for (Chunk *c : chunks)
if (auto *sc = dyn_cast<SectionChunk>(c))
- if (sc->live)
+ if (sc->live && !sc->isDWARF())
worklist.push_back(sc);
auto enqueue = [&](SectionChunk *c) {
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 25330832339c..6de9698bb2c8 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1906,8 +1906,17 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// We do not want to emit debug sections if --strip-all
// or -strip-debug are given.
- return config->strip != StripPolicy::None &&
- (s->name.startswith(".debug") || s->name.startswith(".zdebug"));
+ if (config->strip == StripPolicy::None)
+ return false;
+
+ if (isDebugSection(*s))
+ return true;
+ if (auto *isec = dyn_cast<InputSection>(s))
+ if (InputSectionBase *rel = isec->getRelocatedSection())
+ if (isDebugSection(*rel))
+ return true;
+
+ return false;
});
// Now that the number of partitions is fixed, save a pointer to the main
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 147c51ab285e..d34abf641ed3 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -441,8 +441,7 @@ void InputSection::copyRelocations(uint8_t *buf, ArrayRef<RelTy> rels) {
// See the comment in maybeReportUndefined for PPC64 .toc .
auto *d = dyn_cast<Defined>(&sym);
if (!d) {
- if (!sec->name.startswith(".debug") &&
- !sec->name.startswith(".zdebug") && sec->name != ".eh_frame" &&
+ if (!isDebugSection(*sec) && sec->name != ".eh_frame" &&
sec->name != ".gcc_except_table" && sec->name != ".toc") {
uint32_t secIdx = cast<Undefined>(sym).discardedSecIdx;
Elf_Shdr_Impl<ELFT> sec =
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 3c42af7db7b4..fe2c3c516a96 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -357,6 +357,10 @@ private:
template <class ELFT> void copyShtGroup(uint8_t *buf);
};
+inline bool isDebugSection(const InputSectionBase &sec) {
+ return sec.name.startswith(".debug") || sec.name.startswith(".zdebug");
+}
+
// The list of all input sections.
extern std::vector<InputSectionBase *> inputSections;
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 6142cb0783ce..b609878be319 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -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));
@@ -367,8 +366,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) {
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index ac332de2a057..713c54dee509 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1523,17 +1523,30 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
// but sort must consider them all at once.
std::vector<InputSection **> scriptSections;
std::vector<InputSection *> sections;
+ bool started = false, stopped = false;
for (BaseCommand *base : sec->sectionCommands) {
if (auto *isd = dyn_cast<InputSectionDescription>(base)) {
for (InputSection *&isec : isd->sections) {
- scriptSections.push_back(&isec);
- sections.push_back(isec);
-
- InputSection *link = isec->getLinkOrderDep();
- if (!link->getParent())
- error(toString(isec) + ": sh_link points to discarded section " +
- toString(link));
+ if (!(isec->flags & SHF_LINK_ORDER)) {
+ if (started)
+ stopped = true;
+ } else if (stopped) {
+ error(toString(isec) + ": SHF_LINK_ORDER sections in " + sec->name +
+ " are not contiguous");
+ } else {
+ started = true;
+
+ scriptSections.push_back(&isec);
+ sections.push_back(isec);
+
+ InputSection *link = isec->getLinkOrderDep();
+ if (!link->getParent())
+ error(toString(isec) + ": sh_link points to discarded section " +
+ toString(link));
+ }
}
+ } else if (started) {
+ stopped = true;
}
}