aboutsummaryrefslogtreecommitdiff
path: root/COFF/Writer.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 21:35:55 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 21:35:55 +0000
commit1e52e898a35b86ecd41b7040085e21d3a140a115 (patch)
tree97a1a3c25b38699a99c5f89badc2bf004cf1241d /COFF/Writer.cpp
parentf1e1c239e31b467e17f1648b1f524fc9ab5b431a (diff)
Vendor import of lld release_90 branch r369369:vendor/lld/lld-release_90-r369369
Notes
Notes: svn path=/vendor/lld/dist-release_90/; revision=351312 svn path=/vendor/lld/lld-release_90-r369369/; revision=351313; tag=vendor/lld/lld-release_90-r369369
Diffstat (limited to 'COFF/Writer.cpp')
-rw-r--r--COFF/Writer.cpp34
1 files changed, 30 insertions, 4 deletions
diff --git a/COFF/Writer.cpp b/COFF/Writer.cpp
index 36ef87de4263..cc75db0f519c 100644
--- a/COFF/Writer.cpp
+++ b/COFF/Writer.cpp
@@ -762,6 +762,28 @@ void Writer::locateImportTables() {
}
}
+// Return whether a SectionChunk's suffix (the dollar and any trailing
+// suffix) should be removed and sorted into the main suffixless
+// PartialSection.
+static bool shouldStripSectionSuffix(SectionChunk *sc, StringRef name) {
+ // On MinGW, comdat groups are formed by putting the comdat group name
+ // after the '$' in the section name. For .eh_frame$<symbol>, that must
+ // still be sorted before the .eh_frame trailer from crtend.o, thus just
+ // strip the section name trailer. For other sections, such as
+ // .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
+ // ".tls$"), they must be strictly sorted after .tls. And for the
+ // hypothetical case of comdat .CRT$XCU, we definitely need to keep the
+ // suffix for sorting. Thus, to play it safe, only strip the suffix for
+ // the standard sections.
+ if (!config->mingw)
+ return false;
+ if (!sc || !sc->isCOMDAT())
+ return false;
+ return name.startswith(".text$") || name.startswith(".data$") ||
+ name.startswith(".rdata$") || name.startswith(".pdata$") ||
+ name.startswith(".xdata$") || name.startswith(".eh_frame$");
+}
+
// Create output section objects and add them to OutputSections.
void Writer::createSections() {
// First, create the builtin sections.
@@ -807,10 +829,7 @@ void Writer::createSections() {
continue;
}
StringRef name = c->getSectionName();
- // On MinGW, comdat groups are formed by putting the comdat group name
- // after the '$' in the section name. Such a section name suffix shouldn't
- // imply separate alphabetical sorting of those section chunks though.
- if (config->mingw && sc && sc->isCOMDAT())
+ if (shouldStripSectionSuffix(sc, name))
name = name.split('$').first;
PartialSection *pSec = createPartialSection(name,
c->getOutputCharacteristics());
@@ -1076,6 +1095,13 @@ Optional<coff_symbol16> Writer::createSymbol(Defined *def) {
}
}
+ // Symbols that are runtime pseudo relocations don't point to the actual
+ // symbol data itself (as they are imported), but points to the IAT entry
+ // instead. Avoid emitting them to the symbol table, as they can confuse
+ // debuggers.
+ if (def->isRuntimePseudoReloc)
+ return None;
+
StringRef name = def->getName();
if (name.size() > COFF::NameSize) {
sym.Name.Offset.Zeroes = 0;