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) { 37 log("setOffset: " + toString(*this) + ": " + Twine(newOffset)); 38 offset = newOffset; 39 } 40 void createHeader(size_t bodySize); isNeeded()41 virtual bool isNeeded() const { return true; } 42 virtual size_t getSize() const = 0; getOffset()43 virtual size_t getOffset() { return offset; } 44 virtual void writeTo(uint8_t *buf) = 0; 45 virtual void finalizeContents() = 0; getNumRelocations()46 virtual uint32_t getNumRelocations() const { return 0; } writeRelocations(raw_ostream & os)47 virtual void writeRelocations(raw_ostream &os) const {} 48 49 std::string header; 50 uint32_t type; 51 uint32_t sectionIndex = UINT32_MAX; 52 std::string name; 53 OutputSectionSymbol *sectionSym = nullptr; 54 55 protected: 56 size_t offset = 0; 57 }; 58 59 class CodeSection : public OutputSection { 60 public: CodeSection(ArrayRef<InputFunction * > functions)61 explicit CodeSection(ArrayRef<InputFunction *> functions) 62 : OutputSection(llvm::wasm::WASM_SEC_CODE), functions(functions) {} 63 classof(const OutputSection * sec)64 static bool classof(const OutputSection *sec) { 65 return sec->type == llvm::wasm::WASM_SEC_CODE; 66 } 67 getSize()68 size_t getSize() const override { return header.size() + bodySize; } 69 void writeTo(uint8_t *buf) override; 70 uint32_t getNumRelocations() const override; 71 void writeRelocations(raw_ostream &os) const override; isNeeded()72 bool isNeeded() const override { return functions.size() > 0; } 73 void finalizeContents() override; 74 75 ArrayRef<InputFunction *> functions; 76 77 protected: 78 std::string codeSectionHeader; 79 size_t bodySize = 0; 80 }; 81 82 class DataSection : public OutputSection { 83 public: DataSection(ArrayRef<OutputSegment * > segments)84 explicit DataSection(ArrayRef<OutputSegment *> segments) 85 : OutputSection(llvm::wasm::WASM_SEC_DATA), segments(segments) {} 86 classof(const OutputSection * sec)87 static bool classof(const OutputSection *sec) { 88 return sec->type == llvm::wasm::WASM_SEC_DATA; 89 } 90 getSize()91 size_t getSize() const override { return header.size() + bodySize; } 92 void writeTo(uint8_t *buf) override; 93 uint32_t getNumRelocations() const override; 94 void writeRelocations(raw_ostream &os) const override; 95 bool isNeeded() const override; 96 void finalizeContents() override; 97 98 ArrayRef<OutputSegment *> segments; 99 100 protected: 101 std::string dataSectionHeader; 102 size_t bodySize = 0; 103 }; 104 105 // Represents a custom section in the output file. Wasm custom sections are 106 // used for storing user-defined metadata. Unlike the core sections types 107 // they are identified by their string name. 108 // The linker combines custom sections that have the same name by simply 109 // concatenating them. 110 // Note that some custom sections such as "name" and "linking" are handled 111 // separately and are instead synthesized by the linker. 112 class CustomSection : public OutputSection { 113 public: CustomSection(std::string name,ArrayRef<InputSection * > inputSections)114 CustomSection(std::string name, ArrayRef<InputSection *> inputSections) 115 : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, name), 116 inputSections(inputSections) {} 117 classof(const OutputSection * sec)118 static bool classof(const OutputSection *sec) { 119 return sec->type == llvm::wasm::WASM_SEC_CUSTOM; 120 } 121 getSize()122 size_t getSize() const override { 123 return header.size() + nameData.size() + payloadSize; 124 } 125 void writeTo(uint8_t *buf) override; 126 uint32_t getNumRelocations() const override; 127 void writeRelocations(raw_ostream &os) const override; 128 void finalizeContents() override; 129 130 protected: 131 size_t payloadSize = 0; 132 ArrayRef<InputSection *> inputSections; 133 std::string nameData; 134 }; 135 136 } // namespace wasm 137 } // namespace lld 138 139 #endif // LLD_WASM_OUTPUT_SECTIONS_H 140