[WebAssembly] Move code and data section generation to finalizeContent. NFC.

Previously these sections were being generated during their
constructors.  This moves the work to finalizeContent, and also does
the same for the relocation sections because their contents depends
on the final layout too.

This change is part of a larger refactor to how we deal with synthetic
sections: https://reviews.llvm.org/D61811

Differential Revision: https://reviews.llvm.org/D61971

llvm-svn: 360941
This commit is contained in:
Sam Clegg 2019-05-16 21:36:06 +00:00
parent 1a53ff2a13
commit d029bf0f8c
3 changed files with 41 additions and 21 deletions

View File

@ -79,10 +79,7 @@ void OutputSection::createHeader(size_t BodySize) {
" total=" + Twine(getSize()));
}
CodeSection::CodeSection(ArrayRef<InputFunction *> 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 @@ void CodeSection::writeRelocations(raw_ostream &OS) const {
C->writeRelocations(OS);
}
DataSection::DataSection(ArrayRef<OutputSegment *> 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 @@ void DataSection::writeRelocations(raw_ostream &OS) const {
C->writeRelocations(OS);
}
CustomSection::CustomSection(std::string Name,
ArrayRef<InputSection *> 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 @@ void CustomSection::writeRelocations(raw_ostream &OS) const {
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);
}

View File

@ -40,7 +40,7 @@ public:
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 @@ public:
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 @@ protected:
class CodeSection : public OutputSection {
public:
explicit CodeSection(ArrayRef<InputFunction *> Functions);
size_t getSize() const override { return Header.size() + BodySize; }
explicit CodeSection(ArrayRef<InputFunction *> 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<InputFunction *> Functions;
@ -98,11 +104,14 @@ protected:
class DataSection : public OutputSection {
public:
explicit DataSection(ArrayRef<OutputSegment *> Segments);
explicit DataSection(ArrayRef<OutputSegment *> 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<OutputSegment *> Segments;
@ -119,20 +128,36 @@ protected:
// separately and are instead synthesized by the linker.
class CustomSection : public OutputSection {
public:
CustomSection(std::string Name, ArrayRef<InputSection *> InputSections);
CustomSection(std::string Name, ArrayRef<InputSection *> 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<InputSection *> 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

View File

@ -469,11 +469,7 @@ void Writer::createRelocSections() {
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<RelocSection>(Name, OSec, I));
}
}