Coverage Report

Created: 2018-01-17 17:22

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/InputChunks.h
Line
Count
Source (jump to first uncovered line)
1
//===- InputChunks.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
// An input chunk represents an indivisible blocks of code or data from an input
11
// file.  i.e. a single wasm data segment or a single wasm function.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLD_WASM_INPUT_CHUNKS_H
16
#define LLD_WASM_INPUT_CHUNKS_H
17
18
#include "InputFiles.h"
19
#include "WriterUtils.h"
20
#include "lld/Common/ErrorHandler.h"
21
#include "llvm/Object/Wasm.h"
22
23
using llvm::object::WasmSegment;
24
using llvm::wasm::WasmFunction;
25
using llvm::wasm::WasmRelocation;
26
using llvm::wasm::WasmSignature;
27
using llvm::object::WasmSection;
28
29
namespace lld {
30
namespace wasm {
31
32
class ObjFile;
33
class OutputSegment;
34
35
class InputChunk {
36
public:
37
0
  uint32_t getSize() const { return data().size(); }
38
39
  void copyRelocations(const WasmSection &Section);
40
41
  void writeTo(uint8_t *SectionStart) const;
42
43
0
  void setOutputOffset(uint32_t Offset) {
44
0
    OutputOffset = Offset;
45
0
    calcRelocations();
46
0
  }
47
48
0
  uint32_t getOutputOffset() const { return OutputOffset; }
49
50
  virtual StringRef getComdat() const = 0;
51
52
  bool Discarded = false;
53
  std::vector<OutputRelocation> OutRelocations;
54
55
protected:
56
0
  InputChunk(const ObjFile *F) : File(F) {}
57
0
  virtual ~InputChunk() = default;
58
  void calcRelocations();
59
  virtual ArrayRef<uint8_t> data() const = 0;
60
  virtual uint32_t getInputSectionOffset() const = 0;
61
62
  std::vector<WasmRelocation> Relocations;
63
  int32_t OutputOffset = 0;
64
  const ObjFile *File;
65
};
66
67
// Represents a WebAssembly data segment which can be included as part of
68
// an output data segments.  Note that in WebAssembly, unlike ELF and other
69
// formats, used the term "data segment" to refer to the continous regions of
70
// memory that make on the data section. See:
71
// https://webassembly.github.io/spec/syntax/modules.html#syntax-data
72
//
73
// For example, by default, clang will produce a separate data section for
74
// each global variable.
75
class InputSegment : public InputChunk {
76
public:
77
  InputSegment(const WasmSegment &Seg, const ObjFile *F)
78
0
      : InputChunk(F), Segment(Seg) {}
79
80
  // Translate an offset in the input segment to an offset in the output
81
  // segment.
82
  uint32_t translateVA(uint32_t Address) const;
83
84
0
  const OutputSegment *getOutputSegment() const { return OutputSeg; }
85
86
0
  void setOutputSegment(const OutputSegment *Segment, uint32_t Offset) {
87
0
    OutputSeg = Segment;
88
0
    OutputSegmentOffset = Offset;
89
0
  }
90
91
0
  uint32_t getAlignment() const { return Segment.Data.Alignment; }
92
0
  uint32_t startVA() const { return Segment.Data.Offset.Value.Int32; }
93
0
  uint32_t endVA() const { return startVA() + getSize(); }
94
0
  StringRef getName() const { return Segment.Data.Name; }
95
0
  StringRef getComdat() const override { return Segment.Data.Comdat; }
96
97
  int32_t OutputSegmentOffset = 0;
98
99
protected:
100
0
  ArrayRef<uint8_t> data() const override { return Segment.Data.Content; }
101
0
  uint32_t getInputSectionOffset() const override {
102
0
    return Segment.SectionOffset;
103
0
  }
104
105
  const WasmSegment &Segment;
106
  const OutputSegment *OutputSeg = nullptr;
107
};
108
109
// Represents a single wasm function within and input file.  These are
110
// combined to create the final output CODE section.
111
class InputFunction : public InputChunk {
112
public:
113
  InputFunction(const WasmSignature &S, const WasmFunction *Func,
114
                const ObjFile *F)
115
0
      : InputChunk(F), Signature(S), Function(Func) {}
116
117
0
  virtual StringRef getName() const { return Function->Name; }
118
0
  StringRef getComdat() const override { return Function->Comdat; }
119
0
  uint32_t getOutputIndex() const { return OutputIndex.getValue(); }
120
0
  bool hasOutputIndex() const { return OutputIndex.hasValue(); }
121
  void setOutputIndex(uint32_t Index);
122
123
  const WasmSignature &Signature;
124
125
protected:
126
0
  ArrayRef<uint8_t> data() const override {
127
0
    return File->CodeSection->Content.slice(getInputSectionOffset(),
128
0
                                            Function->Size);
129
0
  }
130
0
  uint32_t getInputSectionOffset() const override {
131
0
    return Function->CodeSectionOffset;
132
0
  }
133
134
  const WasmFunction *Function;
135
  llvm::Optional<uint32_t> OutputIndex;
136
};
137
138
class SyntheticFunction : public InputFunction {
139
public:
140
  SyntheticFunction(const WasmSignature &S, ArrayRef<uint8_t> Body,
141
                    StringRef Name)
142
0
      : InputFunction(S, nullptr, nullptr), Name(Name), Body(Body) {}
143
144
0
  StringRef getName() const override { return Name; }
145
146
protected:
147
0
  ArrayRef<uint8_t> data() const override { return Body; }
148
149
  StringRef Name;
150
  ArrayRef<uint8_t> Body;
151
};
152
153
} // namespace wasm
154
} // namespace lld
155
156
#endif // LLD_WASM_INPUT_CHUNKS_H