Coverage Report

Created: 2019-05-19 14:56

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/OutputSections.h
Line
Count
Source (jump to first uncovered line)
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 = "")
32
1.25k
      : Type(Type), Name(Name) {}
33
1.25k
  virtual ~OutputSection() = default;
34
35
  StringRef getSectionName() const;
36
1.25k
  void setOffset(size_t NewOffset) {
37
1.25k
    log("setOffset: " + toString(*this) + ": " + Twine(NewOffset));
38
1.25k
    Offset = NewOffset;
39
1.25k
  }
40
  void createHeader(size_t BodySize);
41
  virtual size_t getSize() const = 0;
42
  virtual void writeTo(uint8_t *Buf) = 0;
43
  virtual void finalizeContents() = 0;
44
108
  virtual uint32_t numRelocations() const { return 0; }
45
0
  virtual void writeRelocations(raw_ostream &OS) const {}
46
47
  std::string Header;
48
  uint32_t Type;
49
  std::string Name;
50
51
protected:
52
  size_t Offset = 0;
53
};
54
55
class SyntheticSection : public OutputSection {
56
public:
57
  SyntheticSection(uint32_t Type, std::string Name = "")
58
1.08k
      : OutputSection(Type, Name), BodyOutputStream(Body) {
59
1.08k
    if (!Name.empty())
60
188
      writeStr(BodyOutputStream, Name, "section name");
61
1.08k
  }
62
63
1.00k
  void writeTo(uint8_t *Buf) override {
64
1.00k
    assert(Offset);
65
1.00k
    log("writing " + toString(*this));
66
1.00k
    memcpy(Buf + Offset, Header.data(), Header.size());
67
1.00k
    memcpy(Buf + Offset + Header.size(), Body.data(), Body.size());
68
1.00k
  }
69
70
2.16k
  size_t getSize() const override { return Header.size() + Body.size(); }
71
72
1.06k
  virtual void writeBody() {}
73
74
1.08k
  void finalizeContents() override {
75
1.08k
    writeBody();
76
1.08k
    BodyOutputStream.flush();
77
1.08k
    createHeader(Body.size());
78
1.08k
  }
79
80
1.06k
  raw_ostream &getStream() { return BodyOutputStream; }
81
82
  std::string Body;
83
84
protected:
85
  llvm::raw_string_ostream BodyOutputStream;
86
};
87
88
class CodeSection : public OutputSection {
89
public:
90
  explicit CodeSection(ArrayRef<InputFunction *> Functions)
91
126
      : OutputSection(llvm::wasm::WASM_SEC_CODE), Functions(Functions) {}
92
93
375
  size_t getSize() const override { assert(BodySize); return Header.size() + BodySize; }
94
  void writeTo(uint8_t *Buf) override;
95
  uint32_t numRelocations() const override;
96
  void writeRelocations(raw_ostream &OS) const override;
97
  void finalizeContents() override;
98
99
protected:
100
  ArrayRef<InputFunction *> Functions;
101
  std::string CodeSectionHeader;
102
  size_t BodySize = 0;
103
};
104
105
class DataSection : public OutputSection {
106
public:
107
  explicit DataSection(ArrayRef<OutputSegment *> Segments)
108
27
      : OutputSection(llvm::wasm::WASM_SEC_DATA), Segments(Segments) {}
109
110
81
  size_t getSize() const override { return Header.size() + BodySize; }
111
  void writeTo(uint8_t *Buf) override;
112
  uint32_t numRelocations() const override;
113
  void writeRelocations(raw_ostream &OS) const override;
114
  void finalizeContents() override;
115
116
protected:
117
  ArrayRef<OutputSegment *> Segments;
118
  std::string DataSectionHeader;
119
  size_t BodySize = 0;
120
};
121
122
// Represents a custom section in the output file.  Wasm custom sections are
123
// used for storing user-defined metadata.  Unlike the core sections types
124
// they are identified by their string name.
125
// The linker combines custom sections that have the same name by simply
126
// concatenating them.
127
// Note that some custom sections such as "name" and "linking" are handled
128
// separately and are instead synthesized by the linker.
129
class CustomSection : public OutputSection {
130
public:
131
  CustomSection(std::string Name, ArrayRef<InputSection *> InputSections)
132
      : OutputSection(llvm::wasm::WASM_SEC_CUSTOM, Name),
133
22
        InputSections(InputSections) {}
134
66
  size_t getSize() const override {
135
66
    return Header.size() + NameData.size() + PayloadSize;
136
66
  }
137
  void writeTo(uint8_t *Buf) override;
138
  uint32_t numRelocations() const override;
139
  void writeRelocations(raw_ostream &OS) const override;
140
  void finalizeContents() override;
141
142
protected:
143
  size_t PayloadSize = 0;
144
  ArrayRef<InputSection *> InputSections;
145
  std::string NameData;
146
};
147
148
class RelocSection : public SyntheticSection {
149
public:
150
  RelocSection(StringRef Name, OutputSection *Sec, uint32_t SectionIndex)
151
      : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, Name), Sec(Sec),
152
14
        SectionIndex(SectionIndex) {}
153
  void writeBody() override;
154
155
protected:
156
  OutputSection* Sec;
157
  uint32_t SectionIndex;
158
};
159
160
161
} // namespace wasm
162
} // namespace lld
163
164
#endif // LLD_WASM_OUTPUT_SECTIONS_H