summaryrefslogtreecommitdiffstats
path: root/lld/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'lld/wasm')
-rw-r--r--lld/wasm/OutputSections.cpp16
-rw-r--r--lld/wasm/OutputSections.h2
-rw-r--r--lld/wasm/OutputSegment.h1
-rw-r--r--lld/wasm/SyntheticSections.cpp6
-rw-r--r--lld/wasm/SyntheticSections.h4
-rw-r--r--lld/wasm/Writer.cpp9
6 files changed, 32 insertions, 6 deletions
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index 469a51a0f06..0403f1d76f5 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -128,8 +128,11 @@ void CodeSection::writeRelocations(raw_ostream &os) const {
void DataSection::finalizeContents() {
raw_string_ostream os(dataSectionHeader);
+ unsigned segmentCount =
+ std::count_if(segments.begin(), segments.end(),
+ [](OutputSegment *segment) { return !segment->isBss; });
- writeUleb128(os, segments.size(), "data segment count");
+ writeUleb128(os, segmentCount, "data segment count");
os.flush();
bodySize = dataSectionHeader.size();
@@ -137,6 +140,8 @@ void DataSection::finalizeContents() {
"Currenly only a single data segment is supported in PIC mode");
for (OutputSegment *segment : segments) {
+ if (segment->isBss)
+ continue;
raw_string_ostream os(segment->header);
writeUleb128(os, segment->initFlags, "init flags");
if (segment->initFlags & WASM_SEGMENT_HAS_MEMINDEX)
@@ -181,6 +186,8 @@ void DataSection::writeTo(uint8_t *buf) {
memcpy(buf, dataSectionHeader.data(), dataSectionHeader.size());
for (const OutputSegment *segment : segments) {
+ if (segment->isBss)
+ continue;
// Write data segment header
uint8_t *segStart = buf + segment->sectionOffset;
memcpy(segStart, segment->header.data(), segment->header.size());
@@ -205,6 +212,13 @@ void DataSection::writeRelocations(raw_ostream &os) const {
c->writeRelocations(os);
}
+bool DataSection::isNeeded() const {
+ for (const OutputSegment *seg : segments)
+ if (!seg->isBss)
+ return true;
+ return false;
+}
+
void CustomSection::finalizeContents() {
raw_string_ostream os(nameData);
encodeULEB128(name.size(), os);
diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h
index 6b1c2a2eba2..1fcb5723df9 100644
--- a/lld/wasm/OutputSections.h
+++ b/lld/wasm/OutputSections.h
@@ -82,7 +82,7 @@ public:
void writeTo(uint8_t *buf) override;
uint32_t getNumRelocations() const override;
void writeRelocations(raw_ostream &os) const override;
- bool isNeeded() const override { return segments.size() > 0; }
+ bool isNeeded() const override;
void finalizeContents() override;
protected:
diff --git a/lld/wasm/OutputSegment.h b/lld/wasm/OutputSegment.h
index 663a9b82282..06f675c379d 100644
--- a/lld/wasm/OutputSegment.h
+++ b/lld/wasm/OutputSegment.h
@@ -32,6 +32,7 @@ public:
}
StringRef name;
+ bool isBss = false;
uint32_t index = 0;
uint32_t initFlags = 0;
uint32_t sectionOffset = 0;
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index 30c1096e16c..ba04543211c 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -365,6 +365,12 @@ void ElemSection::writeBody() {
}
}
+DataCountSection::DataCountSection(ArrayRef<OutputSegment *> segments)
+ : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT),
+ numSegments(std::count_if(
+ segments.begin(), segments.end(),
+ [](OutputSegment *const segment) { return !segment->isBss; })) {}
+
void DataCountSection::writeBody() {
writeUleb128(bodyOutputStream, numSegments, "data count");
}
diff --git a/lld/wasm/SyntheticSections.h b/lld/wasm/SyntheticSections.h
index 1557ce79d2d..23f9711dec1 100644
--- a/lld/wasm/SyntheticSections.h
+++ b/lld/wasm/SyntheticSections.h
@@ -250,9 +250,7 @@ protected:
class DataCountSection : public SyntheticSection {
public:
- DataCountSection(uint32_t numSegments)
- : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT),
- numSegments(numSegments) {}
+ DataCountSection(ArrayRef<OutputSegment *> segments);
bool isNeeded() const override;
void writeBody() override;
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 479b44b53fb..fe596257bea 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -669,6 +669,13 @@ void Writer::createOutputSegments() {
s = make<OutputSegment>(name);
if (config->sharedMemory || name == ".tdata")
s->initFlags = WASM_SEGMENT_IS_PASSIVE;
+ // Exported memories are guaranteed to be zero-initialized, so no need
+ // to emit data segments for bss sections.
+ // TODO: consider initializing bss sections with memory.fill
+ // instructions when memory is imported and bulk-memory is available.
+ if (!config->importMemory && !config->relocatable &&
+ name.startswith(".bss"))
+ s->isBss = true;
segments.push_back(s);
}
s->addInputSegment(segment);
@@ -961,7 +968,7 @@ void Writer::createSyntheticSections() {
out.exportSec = make<ExportSection>();
out.startSec = make<StartSection>(segments.size());
out.elemSec = make<ElemSection>();
- out.dataCountSec = make<DataCountSection>(segments.size());
+ out.dataCountSec = make<DataCountSection>(segments);
out.linkingSec = make<LinkingSection>(initFunctions, segments);
out.nameSec = make<NameSection>();
out.producersSec = make<ProducersSection>();
OpenPOWER on IntegriCloud