diff --git a/lld/wasm/OutputSections.h b/lld/wasm/OutputSections.h --- a/lld/wasm/OutputSections.h +++ b/lld/wasm/OutputSections.h @@ -40,7 +40,7 @@ void createHeader(size_t BodySize); virtual size_t getSize() const = 0; virtual void writeTo(uint8_t *Buf) = 0; - virtual void finalizeContents() {} + virtual void finalizeContents() = 0; virtual uint32_t numRelocations() const { return 0; } virtual void writeRelocations(raw_ostream &OS) const {} @@ -69,7 +69,10 @@ size_t getSize() const override { return Header.size() + Body.size(); } + virtual void writeBody() {} + void finalizeContents() override { + writeBody(); BodyOutputStream.flush(); createHeader(Body.size()); } @@ -84,11 +87,14 @@ class CodeSection : public OutputSection { public: - explicit CodeSection(ArrayRef Functions); - size_t getSize() const override { return Header.size() + BodySize; } + explicit CodeSection(ArrayRef Functions) + : OutputSection(llvm::wasm::WASM_SEC_CODE), Functions(Functions) {} + + size_t getSize() const override { assert(BodySize); return Header.size() + BodySize; } void writeTo(uint8_t *Buf) override; uint32_t numRelocations() const override; void writeRelocations(raw_ostream &OS) const override; + void finalizeContents() override; protected: ArrayRef Functions; @@ -98,11 +104,14 @@ class DataSection : public OutputSection { public: - explicit DataSection(ArrayRef Segments); + explicit DataSection(ArrayRef Segments) + : OutputSection(llvm::wasm::WASM_SEC_DATA), Segments(Segments) {} + size_t getSize() const override { return Header.size() + BodySize; } void writeTo(uint8_t *Buf) override; uint32_t numRelocations() const override; void writeRelocations(raw_ostream &OS) const override; + void finalizeContents() override; protected: ArrayRef Segments; @@ -119,20 +128,36 @@ // separately and are instead synthesized by the linker. class CustomSection : public OutputSection { public: - CustomSection(std::string Name, ArrayRef InputSections); + CustomSection(std::string Name, ArrayRef InputSections) + : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, Name), + InputSections(InputSections) {} size_t getSize() const override { return Header.size() + NameData.size() + PayloadSize; } void writeTo(uint8_t *Buf) override; uint32_t numRelocations() const override; void writeRelocations(raw_ostream &OS) const override; + void finalizeContents() override; protected: - size_t PayloadSize; + size_t PayloadSize = 0; ArrayRef InputSections; std::string NameData; }; +class RelocSection : public SyntheticSection { +public: + RelocSection(StringRef Name, OutputSection *Sec, uint32_t SectionIndex) + : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, Name), Sec(Sec), + SectionIndex(SectionIndex) {} + void writeBody() override; + +protected: + OutputSection* Sec; + uint32_t SectionIndex; +}; + + } // namespace wasm } // namespace lld diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp --- a/lld/wasm/OutputSections.cpp +++ b/lld/wasm/OutputSections.cpp @@ -79,10 +79,7 @@ " total=" + Twine(getSize())); } -CodeSection::CodeSection(ArrayRef Functions) - : OutputSection(WASM_SEC_CODE), Functions(Functions) { - assert(Functions.size() > 0); - +void CodeSection::finalizeContents() { raw_string_ostream OS(CodeSectionHeader); writeUleb128(OS, Functions.size(), "function count"); OS.flush(); @@ -128,8 +125,7 @@ C->writeRelocations(OS); } -DataSection::DataSection(ArrayRef Segments) - : OutputSection(WASM_SEC_DATA), Segments(Segments) { +void DataSection::finalizeContents() { raw_string_ostream OS(DataSectionHeader); writeUleb128(OS, Segments.size(), "data segment count"); @@ -202,10 +198,7 @@ C->writeRelocations(OS); } -CustomSection::CustomSection(std::string Name, - ArrayRef InputSections) - : OutputSection(WASM_SEC_CUSTOM, Name), PayloadSize(0), - InputSections(InputSections) { +void CustomSection::finalizeContents() { raw_string_ostream OS(NameData); encodeULEB128(Name.size(), OS); OS << Name; @@ -248,3 +241,9 @@ for (const InputSection *S : InputSections) S->writeRelocations(OS); } + +void RelocSection::writeBody() { + writeUleb128(BodyOutputStream, SectionIndex, "reloc section"); + writeUleb128(BodyOutputStream, Sec->numRelocations(), "reloc count"); + Sec->writeRelocations(BodyOutputStream); +} diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -469,12 +469,9 @@ llvm_unreachable( "relocations only supported for code, data, or custom sections"); - SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name); - raw_ostream &OS = Section->getStream(); - writeUleb128(OS, I, "reloc section"); - writeUleb128(OS, Count, "reloc count"); - OSec->writeRelocations(OS); + OutputSections.push_back(make(Name, OSec, I)); } + } static uint32_t getWasmFlags(const Symbol *Sym) {