xref: /openbsd-src/gnu/llvm/lld/wasm/OutputSections.h (revision dfe94b169149f14cc1aee2cf6dad58a8d9a1860c)
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 &section);
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