1 //===- OutputSections.h -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLD_WASM_OUTPUT_SECTIONS_H 10 #define LLD_WASM_OUTPUT_SECTIONS_H 11 12 #include "InputChunks.h" 13 #include "WriterUtils.h" 14 #include "lld/Common/ErrorHandler.h" 15 #include "lld/Common/LLVM.h" 16 #include "llvm/ADT/DenseMap.h" 17 18 namespace lld { 19 20 namespace wasm { 21 class OutputSection; 22 } 23 std::string toString(const wasm::OutputSection §ion); 24 25 namespace wasm { 26 27 class OutputSegment; 28 29 class OutputSection { 30 public: 31 OutputSection(uint32_t type, std::string name = "") type(type)32 : type(type), name(name) {} 33 virtual ~OutputSection() = default; 34 35 StringRef getSectionName() const; setOffset(size_t newOffset)36 void setOffset(size_t newOffset) { offset = newOffset; } 37 void createHeader(size_t bodySize); isNeeded()38 virtual bool isNeeded() const { return true; } 39 virtual size_t getSize() const = 0; getOffset()40 virtual size_t getOffset() { return offset; } 41 virtual void writeTo(uint8_t *buf) = 0; 42 virtual void finalizeContents() = 0; getNumRelocations()43 virtual uint32_t getNumRelocations() const { return 0; } writeRelocations(raw_ostream & os)44 virtual void writeRelocations(raw_ostream &os) const {} 45 46 std::string header; 47 uint32_t type; 48 uint32_t sectionIndex = UINT32_MAX; 49 std::string name; 50 OutputSectionSymbol *sectionSym = nullptr; 51 52 protected: 53 size_t offset = 0; 54 }; 55 56 class CodeSection : public OutputSection { 57 public: CodeSection(ArrayRef<InputFunction * > functions)58 explicit CodeSection(ArrayRef<InputFunction *> functions) 59 : OutputSection(llvm::wasm::WASM_SEC_CODE), functions(functions) {} 60 classof(const OutputSection * sec)61 static bool classof(const OutputSection *sec) { 62 return sec->type == llvm::wasm::WASM_SEC_CODE; 63 } 64 getSize()65 size_t getSize() const override { return header.size() + bodySize; } 66 void writeTo(uint8_t *buf) override; 67 uint32_t getNumRelocations() const override; 68 void writeRelocations(raw_ostream &os) const override; isNeeded()69 bool isNeeded() const override { return functions.size() > 0; } 70 void finalizeContents() override; 71 72 ArrayRef<InputFunction *> functions; 73 74 protected: 75 std::string codeSectionHeader; 76 size_t bodySize = 0; 77 }; 78 79 class DataSection : public OutputSection { 80 public: DataSection(ArrayRef<OutputSegment * > segments)81 explicit DataSection(ArrayRef<OutputSegment *> segments) 82 : OutputSection(llvm::wasm::WASM_SEC_DATA), segments(segments) {} 83 classof(const OutputSection * sec)84 static bool classof(const OutputSection *sec) { 85 return sec->type == llvm::wasm::WASM_SEC_DATA; 86 } 87 getSize()88 size_t getSize() const override { return header.size() + bodySize; } 89 void writeTo(uint8_t *buf) override; 90 uint32_t getNumRelocations() const override; 91 void writeRelocations(raw_ostream &os) const override; 92 bool isNeeded() const override; 93 void finalizeContents() override; 94 95 ArrayRef<OutputSegment *> segments; 96 97 protected: 98 std::string dataSectionHeader; 99 size_t bodySize = 0; 100 }; 101 102 // Represents a custom section in the output file. Wasm custom sections are 103 // used for storing user-defined metadata. Unlike the core sections types 104 // they are identified by their string name. 105 // The linker combines custom sections that have the same name by simply 106 // concatenating them. 107 // Note that some custom sections such as "name" and "linking" are handled 108 // separately and are instead synthesized by the linker. 109 class CustomSection : public OutputSection { 110 public: CustomSection(std::string name,ArrayRef<InputChunk * > inputSections)111 CustomSection(std::string name, ArrayRef<InputChunk *> inputSections) 112 : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, name), 113 inputSections(inputSections) {} 114 classof(const OutputSection * sec)115 static bool classof(const OutputSection *sec) { 116 return sec->type == llvm::wasm::WASM_SEC_CUSTOM; 117 } 118 getSize()119 size_t getSize() const override { 120 return header.size() + nameData.size() + payloadSize; 121 } 122 void writeTo(uint8_t *buf) override; 123 uint32_t getNumRelocations() const override; 124 void writeRelocations(raw_ostream &os) const override; 125 void finalizeContents() override; 126 127 protected: 128 void finalizeInputSections(); 129 size_t payloadSize = 0; 130 std::vector<InputChunk *> inputSections; 131 std::string nameData; 132 }; 133 134 } // namespace wasm 135 } // namespace lld 136 137 #endif // LLD_WASM_OUTPUT_SECTIONS_H 138