Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/LinkerScript.h
Line
Count
Source
1
//===- LinkerScript.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_ELF_LINKER_SCRIPT_H
10
#define LLD_ELF_LINKER_SCRIPT_H
11
12
#include "Config.h"
13
#include "Writer.h"
14
#include "lld/Common/LLVM.h"
15
#include "lld/Common/Strings.h"
16
#include "llvm/ADT/ArrayRef.h"
17
#include "llvm/ADT/DenseMap.h"
18
#include "llvm/ADT/DenseSet.h"
19
#include "llvm/ADT/MapVector.h"
20
#include "llvm/ADT/StringRef.h"
21
#include "llvm/Support/MemoryBuffer.h"
22
#include <cstddef>
23
#include <cstdint>
24
#include <functional>
25
#include <memory>
26
#include <vector>
27
28
namespace lld {
29
namespace elf {
30
31
class Defined;
32
class InputSection;
33
class InputSectionBase;
34
class OutputSection;
35
class SectionBase;
36
class Symbol;
37
class ThunkSection;
38
39
// This represents an r-value in the linker script.
40
struct ExprValue {
41
  ExprValue(SectionBase *sec, bool forceAbsolute, uint64_t val,
42
            const Twine &loc)
43
12.1k
      : sec(sec), forceAbsolute(forceAbsolute), val(val), loc(loc.str()) {}
44
45
10.7k
  ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
Unexecuted instantiation: lld::elf::ExprValue::ExprValue(unsigned long long)
lld::elf::ExprValue::ExprValue(unsigned long long)
Line
Count
Source
45
10.7k
  ExprValue(uint64_t val) : ExprValue(nullptr, false, val, "") {}
46
47
1.90k
  bool isAbsolute() const { return forceAbsolute || 
sec == nullptr1.85k
; }
48
  uint64_t getValue() const;
49
  uint64_t getSecAddr() const;
50
  uint64_t getSectionOffset() const;
51
52
  // If a value is relative to a section, it has a non-null Sec.
53
  SectionBase *sec;
54
55
  // True if this expression is enclosed in ABSOLUTE().
56
  // This flag affects the return value of getValue().
57
  bool forceAbsolute;
58
59
  uint64_t val;
60
  uint64_t alignment = 1;
61
62
  // Original source location. Used for error messages.
63
  std::string loc;
64
};
65
66
// This represents an expression in the linker script.
67
// ScriptParser::readExpr reads an expression and returns an Expr.
68
// Later, we evaluate the expression by calling the function.
69
using Expr = std::function<ExprValue()>;
70
71
// This enum is used to implement linker script SECTIONS command.
72
// https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
73
enum SectionsCommandKind {
74
  AssignmentKind, // . = expr or <sym> = expr
75
  OutputSectionKind,
76
  InputSectionKind,
77
  ByteKind    // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
78
};
79
80
struct BaseCommand {
81
766k
  BaseCommand(int k) : kind(k) {}
82
  int kind;
83
};
84
85
// This represents ". = <expr>" or "<symbol> = <expr>".
86
struct SymbolAssignment : BaseCommand {
87
  SymbolAssignment(StringRef name, Expr e, std::string loc)
88
649
      : BaseCommand(AssignmentKind), name(name), expression(e), location(loc) {}
89
90
1.44M
  static bool classof(const BaseCommand *c) {
91
1.44M
    return c->kind == AssignmentKind;
92
1.44M
  }
93
94
  // The LHS of an expression. Name is either a symbol name or ".".
95
  StringRef name;
96
  Defined *sym = nullptr;
97
98
  // The RHS of an expression.
99
  Expr expression;
100
101
  // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
102
  bool provide = false;
103
  bool hidden = false;
104
105
  // Holds file name and line number for error reporting.
106
  std::string location;
107
108
  // A string representation of this command. We use this for -Map.
109
  std::string commandString;
110
111
  // Address of this assignment command.
112
  unsigned addr;
113
114
  // Size of this assignment command. This is usually 0, but if
115
  // you move '.' this may be greater than 0.
116
  unsigned size;
117
};
118
119
// Linker scripts allow additional constraints to be put on ouput sections.
120
// If an output section is marked as ONLY_IF_RO, the section is created
121
// only if its input sections are read-only. Likewise, an output section
122
// with ONLY_IF_RW is created if all input sections are RW.
123
enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
124
125
// This struct is used to represent the location and size of regions of
126
// target memory. Instances of the struct are created by parsing the
127
// MEMORY command.
128
struct MemoryRegion {
129
  MemoryRegion(StringRef name, uint64_t origin, uint64_t length, uint32_t flags,
130
               uint32_t negFlags)
131
      : name(name), origin(origin), length(length), flags(flags),
132
74
        negFlags(negFlags) {}
133
134
  std::string name;
135
  uint64_t origin;
136
  uint64_t length;
137
  uint32_t flags;
138
  uint32_t negFlags;
139
  uint64_t curPos = 0;
140
};
141
142
// This struct represents one section match pattern in SECTIONS() command.
143
// It can optionally have negative match pattern for EXCLUDED_FILE command.
144
// Also it may be surrounded with SORT() command, so contains sorting rules.
145
struct SectionPattern {
146
  SectionPattern(StringMatcher &&pat1, StringMatcher &&pat2)
147
      : excludedFilePat(pat1), sectionPat(pat2),
148
        sortOuter(SortSectionPolicy::Default),
149
823
        sortInner(SortSectionPolicy::Default) {}
150
151
  StringMatcher excludedFilePat;
152
  StringMatcher sectionPat;
153
  SortSectionPolicy sortOuter;
154
  SortSectionPolicy sortInner;
155
};
156
157
struct InputSectionDescription : BaseCommand {
158
  InputSectionDescription(StringRef filePattern)
159
378k
      : BaseCommand(InputSectionKind), filePat(filePattern) {}
160
161
1.50M
  static bool classof(const BaseCommand *c) {
162
1.50M
    return c->kind == InputSectionKind;
163
1.50M
  }
164
165
  StringMatcher filePat;
166
167
  // Input sections that matches at least one of SectionPatterns
168
  // will be associated with this InputSectionDescription.
169
  std::vector<SectionPattern> sectionPatterns;
170
171
  std::vector<InputSection *> sections;
172
173
  // Temporary record of synthetic ThunkSection instances and the pass that
174
  // they were created in. This is used to insert newly created ThunkSections
175
  // into Sections at the end of a createThunks() pass.
176
  std::vector<std::pair<ThunkSection *, uint32_t>> thunkSections;
177
};
178
179
// Represents BYTE(), SHORT(), LONG(), or QUAD().
180
struct ByteCommand : BaseCommand {
181
  ByteCommand(Expr e, unsigned size, std::string commandString)
182
      : BaseCommand(ByteKind), commandString(commandString), expression(e),
183
47
        size(size) {}
184
185
1.05M
  static bool classof(const BaseCommand *c) { return c->kind == ByteKind; }
186
187
  // Keeps string representing the command. Used for -Map" is perhaps better.
188
  std::string commandString;
189
190
  Expr expression;
191
192
  // This is just an offset of this assignment command in the output section.
193
  unsigned offset;
194
195
  // Size of this data command.
196
  unsigned size;
197
};
198
199
struct PhdrsCommand {
200
  StringRef name;
201
  unsigned type = llvm::ELF::PT_NULL;
202
  bool hasFilehdr = false;
203
  bool hasPhdrs = false;
204
  llvm::Optional<unsigned> flags;
205
  Expr lmaExpr = nullptr;
206
};
207
208
class LinkerScript final {
209
  // Temporary state used in processSectionCommands() and assignAddresses()
210
  // that must be reinitialized for each call to the above functions, and must
211
  // not be used outside of the scope of a call to the above functions.
212
  struct AddressState {
213
    AddressState();
214
    uint64_t threadBssOffset = 0;
215
    OutputSection *outSec = nullptr;
216
    MemoryRegion *memRegion = nullptr;
217
    MemoryRegion *lmaRegion = nullptr;
218
    uint64_t lmaOffset = 0;
219
  };
220
221
  llvm::DenseMap<StringRef, OutputSection *> nameToOutputSection;
222
223
  void addSymbol(SymbolAssignment *cmd);
224
  void assignSymbol(SymbolAssignment *cmd, bool inSec);
225
  void setDot(Expr e, const Twine &loc, bool inSec);
226
  void expandOutputSection(uint64_t size);
227
  void expandMemoryRegions(uint64_t size);
228
229
  std::vector<InputSection *>
230
  computeInputSections(const InputSectionDescription *);
231
232
  std::vector<InputSection *> createInputSectionList(OutputSection &cmd);
233
234
  std::vector<size_t> getPhdrIndices(OutputSection *sec);
235
236
  MemoryRegion *findMemoryRegion(OutputSection *sec);
237
238
  void switchTo(OutputSection *sec);
239
  uint64_t advance(uint64_t size, unsigned align);
240
  void output(InputSection *sec);
241
242
  void assignOffsets(OutputSection *sec);
243
244
  // Ctx captures the local AddressState and makes it accessible
245
  // deliberately. This is needed as there are some cases where we cannot just
246
  // thread the current state through to a lambda function created by the
247
  // script parser.
248
  // This should remain a plain pointer as its lifetime is smaller than
249
  // LinkerScript.
250
  AddressState *ctx = nullptr;
251
252
  OutputSection *aether;
253
254
  uint64_t dot;
255
256
public:
257
  OutputSection *createOutputSection(StringRef name, StringRef location);
258
  OutputSection *getOrCreateOutputSection(StringRef name);
259
260
2.54k
  bool hasPhdrsCommands() { return !phdrsCommands.empty(); }
261
8.35k
  uint64_t getDot() { return dot; }
262
  void discard(ArrayRef<InputSection *> v);
263
264
  ExprValue getSymbolValue(StringRef name, const Twine &loc);
265
266
  void addOrphanSections();
267
  void adjustSectionsBeforeSorting();
268
  void adjustSectionsAfterSorting();
269
270
  std::vector<PhdrEntry *> createPhdrs();
271
  bool needsInterpSection();
272
273
  bool shouldKeep(InputSectionBase *s);
274
  void assignAddresses();
275
  void allocateHeaders(std::vector<PhdrEntry *> &phdrs);
276
  void processSectionCommands();
277
  void declareSymbols();
278
279
  // Used to handle INSERT AFTER statements.
280
  void processInsertCommands();
281
282
  // SECTIONS command list.
283
  std::vector<BaseCommand *> sectionCommands;
284
285
  // PHDRS command list.
286
  std::vector<PhdrsCommand> phdrsCommands;
287
288
  bool hasSectionsCommand = false;
289
  bool errorOnMissingSection = false;
290
291
  // List of section patterns specified with KEEP commands. They will
292
  // be kept even if they are unused and --gc-sections is specified.
293
  std::vector<InputSectionDescription *> keptSections;
294
295
  // A map from memory region name to a memory region descriptor.
296
  llvm::MapVector<llvm::StringRef, MemoryRegion *> memoryRegions;
297
298
  // A list of symbols referenced by the script.
299
  std::vector<llvm::StringRef> referencedSymbols;
300
301
  // Used to implement INSERT [AFTER|BEFORE]. Contains commands that need
302
  // to be inserted into SECTIONS commands list.
303
  llvm::DenseMap<StringRef, std::vector<BaseCommand *>> insertAfterCommands;
304
  llvm::DenseMap<StringRef, std::vector<BaseCommand *>> insertBeforeCommands;
305
};
306
307
extern LinkerScript *script;
308
309
} // end namespace elf
310
} // end namespace lld
311
312
#endif // LLD_ELF_LINKER_SCRIPT_H