• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) {
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