diff options
Diffstat (limited to 'lld/wasm')
-rw-r--r-- | lld/wasm/OutputSections.cpp | 16 | ||||
-rw-r--r-- | lld/wasm/OutputSections.h | 2 | ||||
-rw-r--r-- | lld/wasm/OutputSegment.h | 1 | ||||
-rw-r--r-- | lld/wasm/SyntheticSections.cpp | 6 | ||||
-rw-r--r-- | lld/wasm/SyntheticSections.h | 4 | ||||
-rw-r--r-- | lld/wasm/Writer.cpp | 9 |
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>(); |