Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/Core/DefinedAtom.h
Line
Count
Source (jump to first uncovered line)
1
//===- Core/DefinedAtom.h - An Atom with content --------------------------===//
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_CORE_DEFINED_ATOM_H
11
#define LLD_CORE_DEFINED_ATOM_H
12
13
#include "lld/Core/Atom.h"
14
#include "lld/Core/Reference.h"
15
#include "lld/Core/LLVM.h"
16
#include "llvm/Support/ErrorHandling.h"
17
18
namespace lld {
19
class File;
20
21
/// \brief The fundamental unit of linking.
22
///
23
/// A C function or global variable is an atom.  An atom has content and
24
/// attributes. The content of a function atom is the instructions that
25
/// implement the function.  The content of a global variable atom is its
26
/// initial bytes.
27
///
28
/// Here are some example attribute sets for common atoms. If a particular
29
/// attribute is not listed, the default values are:  definition=regular,
30
/// sectionChoice=basedOnContent, scope=translationUnit, merge=no,
31
/// deadStrip=normal, interposable=no
32
///
33
///  C function:  void foo() {} <br>
34
///    name=foo, type=code, perm=r_x, scope=global
35
///
36
///  C static function:  staic void func() {} <br>
37
///    name=func, type=code, perm=r_x
38
///
39
///  C global variable:  int count = 1; <br>
40
///    name=count, type=data, perm=rw_, scope=global
41
///
42
///  C tentative definition:  int bar; <br>
43
///    name=bar, type=zerofill, perm=rw_, scope=global,
44
///    merge=asTentative, interposable=yesAndRuntimeWeak
45
///
46
///  Uninitialized C static variable:  static int stuff; <br>
47
///    name=stuff, type=zerofill, perm=rw_
48
///
49
///  Weak C function:  __attribute__((weak)) void foo() {} <br>
50
///    name=foo, type=code, perm=r_x, scope=global, merge=asWeak
51
///
52
///  Hidden C function:  __attribute__((visibility("hidden"))) void foo() {}<br>
53
///    name=foo, type=code, perm=r_x, scope=linkageUnit
54
///
55
///  No-dead-strip function:  __attribute__((used)) void foo() {} <br>
56
///    name=foo, type=code, perm=r_x, scope=global, deadStrip=never
57
///
58
///  Non-inlined C++ inline method:  inline void Foo::doit() {} <br>
59
///    name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
60
///    mergeDupes=asWeak
61
///
62
///  Non-inlined C++ inline method whose address is taken:
63
///     inline void Foo::doit() {} <br>
64
///    name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
65
///    mergeDupes=asAddressedWeak
66
///
67
///  literal c-string:  "hello" <br>
68
///    name="" type=cstring, perm=r__, scope=linkageUnit
69
///
70
///  literal double:  1.234 <br>
71
///    name="" type=literal8, perm=r__, scope=linkageUnit
72
///
73
///  constant:  { 1,2,3 } <br>
74
///    name="" type=constant, perm=r__, scope=linkageUnit
75
///
76
///  Pointer to initializer function:  <br>
77
///    name="" type=initializer, perm=rw_l,
78
///    sectionChoice=customRequired
79
///
80
///  C function place in custom section:  __attribute__((section("__foo")))
81
///                                       void foo() {} <br>
82
///    name=foo, type=code, perm=r_x, scope=global,
83
///    sectionChoice=customRequired, customSectionName=__foo
84
///
85
class DefinedAtom : public Atom {
86
public:
87
  enum Interposable {
88
    interposeNo,            // linker can directly bind uses of this atom
89
    interposeYes,           // linker must indirect (through GOT) uses
90
    interposeYesAndRuntimeWeak // must indirect and mark symbol weak in final
91
                               // linked image
92
  };
93
94
  enum Merge {
95
    mergeNo,                // Another atom with same name is error
96
    mergeAsTentative,       // Is ANSI C tentative definition, can be coalesced
97
    mergeAsWeak,            // Is C++ inline definition that was not inlined,
98
                            // but address was not taken, so atom can be hidden
99
                            // by linker
100
    mergeAsWeakAndAddressUsed, // Is C++ definition inline definition whose
101
                               // address was taken.
102
    mergeSameNameAndSize,   // Another atom with different size is error
103
    mergeByLargestSection,  // Choose an atom whose section is the largest.
104
    mergeByContent,         // Merge with other constants with same content.
105
  };
106
107
  enum ContentType {
108
    typeUnknown,            // for use with definitionUndefined
109
    typeMachHeader,         // atom representing mach_header [Darwin]
110
    typeCode,               // executable code
111
    typeResolver,           // function which returns address of target
112
    typeBranchIsland,       // linker created for large binaries
113
    typeBranchShim,         // linker created to switch thumb mode
114
    typeStub,               // linker created for calling external function
115
    typeStubHelper,         // linker created for initial stub binding
116
    typeConstant,           // a read-only constant
117
    typeCString,            // a zero terminated UTF8 C string
118
    typeUTF16String,        // a zero terminated UTF16 string
119
    typeCFI,                // a FDE or CIE from dwarf unwind info
120
    typeLSDA,               // extra unwinding info
121
    typeLiteral4,           // a four-btye read-only constant
122
    typeLiteral8,           // an eight-btye read-only constant
123
    typeLiteral16,          // a sixteen-btye read-only constant
124
    typeData,               // read-write data
125
    typeDataFast,           // allow data to be quickly accessed
126
    typeZeroFill,           // zero-fill data
127
    typeZeroFillFast,       // allow zero-fill data to be quicky accessed
128
    typeConstData,          // read-only data after dynamic linker is done
129
    typeObjC1Class,         // ObjC1 class [Darwin]
130
    typeLazyPointer,        // pointer through which a stub jumps
131
    typeLazyDylibPointer,   // pointer through which a stub jumps [Darwin]
132
    typeNonLazyPointer,     // pointer to external symbol
133
    typeCFString,           // NS/CFString object [Darwin]
134
    typeGOT,                // pointer to external symbol
135
    typeInitializerPtr,     // pointer to initializer function
136
    typeTerminatorPtr,      // pointer to terminator function
137
    typeCStringPtr,         // pointer to UTF8 C string [Darwin]
138
    typeObjCClassPtr,       // pointer to ObjC class [Darwin]
139
    typeObjC2CategoryList,  // pointers to ObjC category [Darwin]
140
    typeObjCImageInfo,      // pointer to ObjC class [Darwin]
141
    typeObjCMethodList,     // pointer to ObjC method list [Darwin]
142
    typeDTraceDOF,          // runtime data for Dtrace [Darwin]
143
    typeInterposingTuples,  // tuples of interposing info for dyld [Darwin]
144
    typeTempLTO,            // temporary atom for bitcode reader
145
    typeCompactUnwindInfo,  // runtime data for unwinder [Darwin]
146
    typeProcessedUnwindInfo,// compressed compact unwind info [Darwin]
147
    typeThunkTLV,           // thunk used to access a TLV [Darwin]
148
    typeTLVInitialData,     // initial data for a TLV [Darwin]
149
    typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]
150
    typeTLVInitializerPtr,  // pointer to thread local initializer [Darwin]
151
    typeDSOHandle,          // atom representing DSO handle [Darwin]
152
    typeSectCreate,         // Created via the -sectcreate option [Darwin]
153
  };
154
155
  // Permission bits for atoms and segments. The order of these values are
156
  // important, because the layout pass may sort atoms by permission if other
157
  // attributes are the same.
158
  enum ContentPermissions {
159
    perm___  = 0,           // mapped as unaccessible
160
    permR__  = 8,           // mapped read-only
161
    permRW_  = 8 + 2,       // mapped readable and writable
162
    permRW_L = 8 + 2 + 1,   // initially mapped r/w, then made read-only
163
                            // loader writable
164
    permR_X  = 8 + 4,       // mapped readable and executable
165
    permRWX  = 8 + 2 + 4,   // mapped readable and writable and executable
166
    permUnknown = 16        // unknown or invalid permissions
167
  };
168
169
  enum SectionChoice {
170
    sectionBasedOnContent,  // linker infers final section based on content
171
    sectionCustomPreferred, // linker may place in specific section
172
    sectionCustomRequired   // linker must place in specific section
173
  };
174
175
  enum DeadStripKind {
176
    deadStripNormal,        // linker may dead strip this atom
177
    deadStripNever,         // linker must never dead strip this atom
178
    deadStripAlways         // linker must remove this atom if unused
179
  };
180
181
  enum DynamicExport {
182
    /// \brief The linker may or may not export this atom dynamically depending
183
    ///   on the output type and other context of the link.
184
    dynamicExportNormal,
185
    /// \brief The linker will always export this atom dynamically.
186
    dynamicExportAlways,
187
  };
188
189
  // Attributes describe a code model used by the atom.
190
  enum CodeModel {
191
    codeNA,           // no specific code model
192
    // MIPS code models
193
    codeMipsPIC,      // PIC function in a PIC / non-PIC mixed file
194
    codeMipsMicro,    // microMIPS instruction encoding
195
    codeMipsMicroPIC, // microMIPS instruction encoding + PIC
196
    codeMips16,       // MIPS-16 instruction encoding
197
    // ARM code models
198
    codeARMThumb,     // ARM Thumb instruction set
199
    codeARM_a,        // $a-like mapping symbol (for ARM code)
200
    codeARM_d,        // $d-like mapping symbol (for data)
201
    codeARM_t,        // $t-like mapping symbol (for Thumb code)
202
  };
203
204
  struct Alignment {
205
1.24k
    Alignment(int v, int m = 0) : value(v), modulus(m) {}
206
207
    uint16_t value;
208
    uint16_t modulus;
209
210
272
    bool operator==(const Alignment &rhs) const {
211
102
      return (value == rhs.value) && (modulus == rhs.modulus);
212
272
    }
213
  };
214
215
  /// \brief returns a value for the order of this Atom within its file.
216
  ///
217
  /// This is used by the linker to order the layout of Atoms so that the
218
  /// resulting image is stable and reproducible.
219
  virtual uint64_t ordinal() const = 0;
220
221
  /// \brief the number of bytes of space this atom's content will occupy in the
222
  /// final linked image.
223
  ///
224
  /// For a function atom, it is the number of bytes of code in the function.
225
  virtual uint64_t size() const = 0;
226
227
  /// \brief The size of the section from which the atom is instantiated.
228
  ///
229
  /// Merge::mergeByLargestSection is defined in terms of section size
230
  /// and not in terms of atom size, so we need this function separate
231
  /// from size().
232
267
  virtual uint64_t sectionSize() const { return 0; }
233
234
  /// \brief The visibility of this atom to other atoms.
235
  ///
236
  /// C static functions have scope scopeTranslationUnit.  Regular C functions
237
  /// have scope scopeGlobal.  Functions compiled with visibility=hidden have
238
  /// scope scopeLinkageUnit so they can be see by other atoms being linked but
239
  /// not by the OS loader.
240
  virtual Scope scope() const = 0;
241
242
  /// \brief Whether the linker should use direct or indirect access to this
243
  /// atom.
244
  virtual Interposable interposable() const = 0;
245
246
  /// \brief how the linker should handle if multiple atoms have the same name.
247
  virtual Merge merge() const = 0;
248
249
  /// \brief The type of this atom, such as code or data.
250
  virtual ContentType contentType() const = 0;
251
252
  /// \brief The alignment constraints on how this atom must be laid out in the
253
  /// final linked image (e.g. 16-byte aligned).
254
  virtual Alignment alignment() const = 0;
255
256
  /// \brief Whether this atom must be in a specially named section in the final
257
  /// linked image, or if the linker can infer the section based on the
258
  /// contentType().
259
  virtual SectionChoice sectionChoice() const = 0;
260
261
  /// \brief If sectionChoice() != sectionBasedOnContent, then this return the
262
  /// name of the section the atom should be placed into.
263
  virtual StringRef customSectionName() const = 0;
264
265
  /// \brief constraints on whether the linker may dead strip away this atom.
266
  virtual DeadStripKind deadStrip() const = 0;
267
268
  /// \brief Under which conditions should this atom be dynamically exported.
269
267
  virtual DynamicExport dynamicExport() const {
270
267
    return dynamicExportNormal;
271
267
  }
272
273
  /// \brief Code model used by the atom.
274
267
  virtual CodeModel codeModel() const { return codeNA; }
275
276
  /// \brief Returns the OS memory protections required for this atom's content
277
  /// at runtime.
278
  ///
279
  /// A function atom is R_X, a global variable is RW_, and a read-only constant
280
  /// is R__.
281
  virtual ContentPermissions permissions() const;
282
283
  /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's
284
  /// content.
285
  virtual ArrayRef<uint8_t> rawContent() const = 0;
286
287
  /// This class abstracts iterating over the sequence of References
288
  /// in an Atom.  Concrete instances of DefinedAtom must implement
289
  /// the derefIterator() and incrementIterator() methods.
290
  class reference_iterator {
291
  public:
292
    reference_iterator(const DefinedAtom &a, const void *it)
293
12.4k
      : _atom(a), _it(it) { }
294
295
6.12k
    const Reference *operator*() const {
296
6.12k
      return _atom.derefIterator(_it);
297
6.12k
    }
298
299
3
    const Reference *operator->() const {
300
3
      return _atom.derefIterator(_it);
301
3
    }
302
303
11.9k
    bool operator==(const reference_iterator &other) const {
304
11.9k
      return _it == other._it;
305
11.9k
    }
306
307
11.9k
    bool operator!=(const reference_iterator &other) const {
308
11.9k
      return !(*this == other);
309
11.9k
    }
310
311
5.74k
    reference_iterator &operator++() {
312
5.74k
      _atom.incrementIterator(_it);
313
5.74k
      return *this;
314
5.74k
    }
315
  private:
316
    const DefinedAtom &_atom;
317
    const void *_it;
318
  };
319
320
  /// \brief Returns an iterator to the beginning of this Atom's References.
321
  virtual reference_iterator begin() const = 0;
322
323
  /// \brief Returns an iterator to the end of this Atom's References.
324
  virtual reference_iterator end() const = 0;
325
326
  /// Adds a reference to this atom.
327
  virtual void addReference(Reference::KindNamespace ns,
328
                            Reference::KindArch arch,
329
                            Reference::KindValue kindValue, uint64_t off,
330
0
                            const Atom *target, Reference::Addend a) {
331
0
    llvm_unreachable("Subclass does not permit adding references");
332
0
  }
333
334
3.70k
  static bool classof(const Atom *a) {
335
3.70k
    return a->definition() == definitionRegular;
336
3.70k
  }
337
338
  /// Utility for deriving permissions from content type
339
  static ContentPermissions permissions(ContentType type);
340
341
  /// Utility function to check if the atom occupies file space
342
384
  bool occupiesDiskSpace() const {
343
384
    ContentType atomContentType = contentType();
344
384
    return !(atomContentType == DefinedAtom::typeZeroFill ||
345
378
             atomContentType == DefinedAtom::typeZeroFillFast ||
346
378
             atomContentType == DefinedAtom::typeTLVInitialZeroFill);
347
384
  }
348
349
  /// Utility function to check if relocations in this atom to other defined
350
  /// atoms can be implicitly generated, and so we don't need to explicitly
351
  /// emit those relocations.
352
0
  bool relocsToDefinedCanBeImplicit() const {
353
0
    ContentType atomContentType = contentType();
354
0
    return atomContentType == typeCFI;
355
0
  }
356
357
protected:
358
  // DefinedAtom is an abstract base class. Only subclasses can access
359
  // constructor.
360
1.18k
  DefinedAtom() : Atom(definitionRegular) { }
361
362
1.18k
  ~DefinedAtom() override = default;
363
364
  /// \brief Returns a pointer to the Reference object that the abstract
365
  /// iterator "points" to.
366
  virtual const Reference *derefIterator(const void *iter) const = 0;
367
368
  /// \brief Adjusts the abstract iterator to "point" to the next Reference
369
  /// object for this Atom.
370
  virtual void incrementIterator(const void *&iter) const = 0;
371
};
372
} // end namespace lld
373
374
#endif