blob: 926101710cdf3ef3c204a19b0b10e3325ea96e52 [file] [log] [blame]
Sam Cleggc94d3932017-11-17 18:14:09 +00001//===- OutputSections.h -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_WASM_OUTPUT_SECTIONS_H
11#define LLD_WASM_OUTPUT_SECTIONS_H
12
13#include "InputSegment.h"
14#include "WriterUtils.h"
15#include "lld/Common/ErrorHandler.h"
16#include "llvm/ADT/DenseMap.h"
17
18using llvm::raw_ostream;
19using llvm::raw_string_ostream;
20
21namespace lld {
22
23namespace wasm {
24class OutputSection;
25}
26std::string toString(wasm::OutputSection *Section);
27
28namespace wasm {
29
30class OutputSegment;
31class ObjFile;
32
33class OutputSection {
34public:
35 OutputSection(uint32_t Type, std::string Name = "")
36 : Type(Type), Name(Name) {}
37
38 virtual ~OutputSection() = default;
39
40 void setOffset(size_t NewOffset) {
41 log("setOffset: " + toString(this) + " -> " + Twine(NewOffset));
42 Offset = NewOffset;
43 }
44
45 void createHeader(size_t BodySize);
46 virtual size_t getSize() const = 0;
47 virtual void writeTo(uint8_t *Buf) = 0;
48 virtual void finalizeContents() {}
49
50 std::string Header;
51 uint32_t Type;
52 std::string Name;
53
54 virtual uint32_t numRelocations() const { return 0; }
55 virtual void writeRelocations(raw_ostream &OS) const {}
56
57protected:
58 size_t Offset = 0;
59};
60
61class SyntheticSection : public OutputSection {
62public:
63 SyntheticSection(uint32_t Type, std::string Name = "")
64 : OutputSection(Type, Name), BodyOutputStream(Body) {
65 if (!Name.empty())
66 writeStr(BodyOutputStream, Name);
67 }
68
69 void writeTo(uint8_t *Buf) override {
70 assert(Offset);
71 log("writing " + toString(this));
72 memcpy(Buf + Offset, Header.data(), Header.size());
73 memcpy(Buf + Offset + Header.size(), Body.data(), Body.size());
74 }
75
76 size_t getSize() const override { return Header.size() + Body.size(); }
77
78 void finalizeContents() override {
79 BodyOutputStream.flush();
80 createHeader(Body.size());
81 }
82
83 raw_ostream &getStream() { return BodyOutputStream; }
84
85 std::string Body;
86
87protected:
88 raw_string_ostream BodyOutputStream;
89};
90
91// Some synthetic sections (e.g. "name" and "linking") have subsections.
92// Just like the synthetic sections themselves these need to be created before
93// they can be written out (since they are preceded by their length). This
94// class is used to create subsections and then write them into the stream
95// of the parent section.
96class SubSection : public SyntheticSection {
97public:
98 explicit SubSection(uint32_t Type) : SyntheticSection(Type) {}
99
100 void writeToStream(raw_ostream &OS) {
101 writeBytes(OS, Header.data(), Header.size());
102 writeBytes(OS, Body.data(), Body.size());
103 }
104};
105
106class CodeSection : public OutputSection {
107public:
Sam Clegg0fb6faa2017-12-08 01:09:21 +0000108 explicit CodeSection(uint32_t NumFunctions, ArrayRef<ObjFile *> Objs);
Sam Cleggc94d3932017-11-17 18:14:09 +0000109 size_t getSize() const override { return Header.size() + BodySize; }
110 void writeTo(uint8_t *Buf) override;
111 uint32_t numRelocations() const override;
112 void writeRelocations(raw_ostream &OS) const override;
113
114protected:
Sam Clegg0fb6faa2017-12-08 01:09:21 +0000115 ArrayRef<ObjFile *> InputObjects;
Sam Cleggc94d3932017-11-17 18:14:09 +0000116 std::string CodeSectionHeader;
117 size_t BodySize = 0;
118};
119
120class DataSection : public OutputSection {
121public:
Sam Clegg0fb6faa2017-12-08 01:09:21 +0000122 explicit DataSection(ArrayRef<OutputSegment *> Segments);
Sam Cleggc94d3932017-11-17 18:14:09 +0000123 size_t getSize() const override { return Header.size() + BodySize; }
124 void writeTo(uint8_t *Buf) override;
125 uint32_t numRelocations() const override { return Relocations.size(); }
126 void writeRelocations(raw_ostream &OS) const override;
127
128protected:
129 std::vector<OutputRelocation> Relocations;
Sam Clegg0fb6faa2017-12-08 01:09:21 +0000130 ArrayRef<OutputSegment *> Segments;
Sam Cleggc94d3932017-11-17 18:14:09 +0000131 std::string DataSectionHeader;
132 size_t BodySize = 0;
133};
134
135} // namespace wasm
136} // namespace lld
137
138#endif // LLD_WASM_OUTPUT_SECTIONS_H