| //===- OutputSections.h -----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Linker |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLD_WASM_OUTPUT_SECTIONS_H |
| #define LLD_WASM_OUTPUT_SECTIONS_H |
| |
| #include "InputChunks.h" |
| #include "WriterUtils.h" |
| #include "lld/Common/ErrorHandler.h" |
| #include "llvm/ADT/DenseMap.h" |
| |
| using llvm::raw_ostream; |
| using llvm::raw_string_ostream; |
| |
| namespace lld { |
| |
| namespace wasm { |
| class OutputSection; |
| } |
| std::string toString(const wasm::OutputSection &Section); |
| |
| namespace wasm { |
| |
| class OutputSegment; |
| |
| class OutputSection { |
| public: |
| OutputSection(uint32_t Type, std::string Name = "") |
| : Type(Type), Name(Name) {} |
| virtual ~OutputSection() = default; |
| |
| StringRef getSectionName() const; |
| void setOffset(size_t NewOffset) { |
| log("setOffset: " + toString(*this) + ": " + Twine(NewOffset)); |
| Offset = NewOffset; |
| } |
| void createHeader(size_t BodySize); |
| virtual size_t getSize() const = 0; |
| virtual void writeTo(uint8_t *Buf) = 0; |
| virtual void finalizeContents() {} |
| virtual uint32_t numRelocations() const { return 0; } |
| virtual void writeRelocations(raw_ostream &OS) const {} |
| |
| std::string Header; |
| uint32_t Type; |
| std::string Name; |
| |
| protected: |
| size_t Offset = 0; |
| }; |
| |
| class SyntheticSection : public OutputSection { |
| public: |
| SyntheticSection(uint32_t Type, std::string Name = "") |
| : OutputSection(Type, Name), BodyOutputStream(Body) { |
| if (!Name.empty()) |
| writeStr(BodyOutputStream, Name, "section name"); |
| } |
| |
| void writeTo(uint8_t *Buf) override { |
| assert(Offset); |
| log("writing " + toString(*this)); |
| memcpy(Buf + Offset, Header.data(), Header.size()); |
| memcpy(Buf + Offset + Header.size(), Body.data(), Body.size()); |
| } |
| |
| size_t getSize() const override { return Header.size() + Body.size(); } |
| |
| void finalizeContents() override { |
| BodyOutputStream.flush(); |
| createHeader(Body.size()); |
| } |
| |
| raw_ostream &getStream() { return BodyOutputStream; } |
| |
| std::string Body; |
| |
| protected: |
| raw_string_ostream BodyOutputStream; |
| }; |
| |
| class CodeSection : public OutputSection { |
| public: |
| explicit CodeSection(ArrayRef<InputFunction *> Functions); |
| 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; |
| |
| protected: |
| ArrayRef<InputFunction *> Functions; |
| std::string CodeSectionHeader; |
| size_t BodySize = 0; |
| }; |
| |
| class DataSection : public OutputSection { |
| public: |
| explicit DataSection(ArrayRef<OutputSegment *> 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; |
| |
| protected: |
| ArrayRef<OutputSegment *> Segments; |
| std::string DataSectionHeader; |
| size_t BodySize = 0; |
| }; |
| |
| // Represents a custom section in the output file. Wasm custom sections are |
| // used for storing user-defined metadata. Unlike the core sections types |
| // they are identified by their string name. |
| // The linker combines custom sections that have the same name by simply |
| // concatenating them. |
| // Note that some custom sections such as "name" and "linking" are handled |
| // separately and are instead synthesized by the linker. |
| class CustomSection : public OutputSection { |
| public: |
| CustomSection(std::string Name, ArrayRef<InputSection *> 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; |
| |
| protected: |
| size_t PayloadSize; |
| ArrayRef<InputSection *> InputSections; |
| std::string NameData; |
| }; |
| |
| } // namespace wasm |
| } // namespace lld |
| |
| #endif // LLD_WASM_OUTPUT_SECTIONS_H |