Coverage Report

Created: 2019-02-21 13:17

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Object/ObjectFile.h
Line
Count
Source (jump to first uncovered line)
1
//===- ObjectFile.h - File format independent object file -------*- 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
// This file declares a file format independent ObjectFile class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_OBJECT_OBJECTFILE_H
14
#define LLVM_OBJECT_OBJECTFILE_H
15
16
#include "llvm/ADT/StringRef.h"
17
#include "llvm/ADT/Triple.h"
18
#include "llvm/ADT/iterator_range.h"
19
#include "llvm/BinaryFormat/Magic.h"
20
#include "llvm/MC/SubtargetFeature.h"
21
#include "llvm/Object/Binary.h"
22
#include "llvm/Object/Error.h"
23
#include "llvm/Object/SymbolicFile.h"
24
#include "llvm/Support/Casting.h"
25
#include "llvm/Support/Error.h"
26
#include "llvm/Support/FileSystem.h"
27
#include "llvm/Support/MemoryBuffer.h"
28
#include <cassert>
29
#include <cstdint>
30
#include <memory>
31
#include <system_error>
32
33
namespace llvm {
34
35
class ARMAttributeParser;
36
37
namespace object {
38
39
class COFFObjectFile;
40
class MachOObjectFile;
41
class ObjectFile;
42
class SectionRef;
43
class SymbolRef;
44
class symbol_iterator;
45
class WasmObjectFile;
46
47
using section_iterator = content_iterator<SectionRef>;
48
49
/// This is a value type class that represents a single relocation in the list
50
/// of relocations in the object file.
51
class RelocationRef {
52
  DataRefImpl RelocationPimpl;
53
  const ObjectFile *OwningObject = nullptr;
54
55
public:
56
93
  RelocationRef() = default;
57
  RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
58
59
  bool operator==(const RelocationRef &Other) const;
60
61
  void moveNext();
62
63
  uint64_t getOffset() const;
64
  symbol_iterator getSymbol() const;
65
  uint64_t getType() const;
66
67
  /// Get a string that represents the type of this relocation.
68
  ///
69
  /// This is for display purposes only.
70
  void getTypeName(SmallVectorImpl<char> &Result) const;
71
72
  DataRefImpl getRawDataRefImpl() const;
73
  const ObjectFile *getObject() const;
74
};
75
76
using relocation_iterator = content_iterator<RelocationRef>;
77
78
/// This is a value type class that represents a single section in the list of
79
/// sections in the object file.
80
class SectionRef {
81
  friend class SymbolRef;
82
83
  DataRefImpl SectionPimpl;
84
  const ObjectFile *OwningObject = nullptr;
85
86
public:
87
3.13k
  SectionRef() = default;
88
  SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
89
90
  bool operator==(const SectionRef &Other) const;
91
  bool operator!=(const SectionRef &Other) const;
92
  bool operator<(const SectionRef &Other) const;
93
94
  void moveNext();
95
96
  std::error_code getName(StringRef &Result) const;
97
  uint64_t getAddress() const;
98
  uint64_t getIndex() const;
99
  uint64_t getSize() const;
100
  std::error_code getContents(StringRef &Result) const;
101
102
  /// Get the alignment of this section as the actual value (not log 2).
103
  uint64_t getAlignment() const;
104
105
  bool isCompressed() const;
106
  /// Whether this section contains instructions.
107
  bool isText() const;
108
  /// Whether this section contains data, not instructions.
109
  bool isData() const;
110
  /// Whether this section contains BSS uninitialized data.
111
  bool isBSS() const;
112
  bool isVirtual() const;
113
  bool isBitcode() const;
114
  bool isStripped() const;
115
116
  /// Whether this section will be placed in the text segment, according to the
117
  /// Berkeley size format. This is true if the section is allocatable, and
118
  /// contains either code or readonly data.
119
  bool isBerkeleyText() const;
120
  /// Whether this section will be placed in the data segment, according to the
121
  /// Berkeley size format. This is true if the section is allocatable and
122
  /// contains data (e.g. PROGBITS), but is not text.
123
  bool isBerkeleyData() const;
124
125
  bool containsSymbol(SymbolRef S) const;
126
127
  relocation_iterator relocation_begin() const;
128
  relocation_iterator relocation_end() const;
129
4.83k
  iterator_range<relocation_iterator> relocations() const {
130
4.83k
    return make_range(relocation_begin(), relocation_end());
131
4.83k
  }
132
  section_iterator getRelocatedSection() const;
133
134
  DataRefImpl getRawDataRefImpl() const;
135
  const ObjectFile *getObject() const;
136
};
137
138
/// This is a value type class that represents a single symbol in the list of
139
/// symbols in the object file.
140
class SymbolRef : public BasicSymbolRef {
141
  friend class SectionRef;
142
143
public:
144
  enum Type {
145
    ST_Unknown, // Type not specified
146
    ST_Data,
147
    ST_Debug,
148
    ST_File,
149
    ST_Function,
150
    ST_Other
151
  };
152
153
  SymbolRef() = default;
154
  SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
155
  SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
156
    assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
157
  }
158
159
  Expected<StringRef> getName() const;
160
  /// Returns the symbol virtual address (i.e. address at which it will be
161
  /// mapped).
162
  Expected<uint64_t> getAddress() const;
163
164
  /// Return the value of the symbol depending on the object this can be an
165
  /// offset or a virtual address.
166
  uint64_t getValue() const;
167
168
  /// Get the alignment of this symbol as the actual value (not log 2).
169
  uint32_t getAlignment() const;
170
  uint64_t getCommonSize() const;
171
  Expected<SymbolRef::Type> getType() const;
172
173
  /// Get section this symbol is defined in reference to. Result is
174
  /// end_sections() if it is undefined or is an absolute symbol.
175
  Expected<section_iterator> getSection() const;
176
177
  const ObjectFile *getObject() const;
178
};
179
180
class symbol_iterator : public basic_symbol_iterator {
181
public:
182
10.4k
  symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
183
  symbol_iterator(const basic_symbol_iterator &B)
184
      : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
185
11.0k
                                        cast<ObjectFile>(B->getObject()))) {}
186
187
14.6k
  const SymbolRef *operator->() const {
188
14.6k
    const BasicSymbolRef &P = basic_symbol_iterator::operator *();
189
14.6k
    return static_cast<const SymbolRef*>(&P);
190
14.6k
  }
191
192
51.0k
  const SymbolRef &operator*() const {
193
51.0k
    const BasicSymbolRef &P = basic_symbol_iterator::operator *();
194
51.0k
    return static_cast<const SymbolRef&>(P);
195
51.0k
  }
196
};
197
198
/// This class is the base class for all object file types. Concrete instances
199
/// of this object are created by createObjectFile, which figures out which type
200
/// to create.
201
class ObjectFile : public SymbolicFile {
202
  virtual void anchor();
203
204
protected:
205
  ObjectFile(unsigned int Type, MemoryBufferRef Source);
206
207
596k
  const uint8_t *base() const {
208
596k
    return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
209
596k
  }
210
211
  // These functions are for SymbolRef to call internally. The main goal of
212
  // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
213
  // entry in the memory mapped object file. SymbolPimpl cannot contain any
214
  // virtual functions because then it could not point into the memory mapped
215
  // file.
216
  //
217
  // Implementations assume that the DataRefImpl is valid and has not been
218
  // modified externally. It's UB otherwise.
219
  friend class SymbolRef;
220
221
  virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
222
  std::error_code printSymbolName(raw_ostream &OS,
223
                                  DataRefImpl Symb) const override;
224
  virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
225
  virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
226
  virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
227
  virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
228
  virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
229
  virtual Expected<section_iterator>
230
  getSymbolSection(DataRefImpl Symb) const = 0;
231
232
  // Same as above for SectionRef.
233
  friend class SectionRef;
234
235
  virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
236
  virtual std::error_code getSectionName(DataRefImpl Sec,
237
                                         StringRef &Res) const = 0;
238
  virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
239
  virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
240
  virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
241
  virtual std::error_code getSectionContents(DataRefImpl Sec,
242
                                             StringRef &Res) const = 0;
243
  virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
244
  virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
245
  virtual bool isSectionText(DataRefImpl Sec) const = 0;
246
  virtual bool isSectionData(DataRefImpl Sec) const = 0;
247
  virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
248
  // A section is 'virtual' if its contents aren't present in the object image.
249
  virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
250
  virtual bool isSectionBitcode(DataRefImpl Sec) const;
251
  virtual bool isSectionStripped(DataRefImpl Sec) const;
252
  virtual bool isBerkeleyText(DataRefImpl Sec) const;
253
  virtual bool isBerkeleyData(DataRefImpl Sec) const;
254
  virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
255
  virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
256
  virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
257
258
  // Same as above for RelocationRef.
259
  friend class RelocationRef;
260
  virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
261
  virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
262
  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
263
  virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
264
  virtual void getRelocationTypeName(DataRefImpl Rel,
265
                                     SmallVectorImpl<char> &Result) const = 0;
266
267
  uint64_t getSymbolValue(DataRefImpl Symb) const;
268
269
public:
270
  ObjectFile() = delete;
271
  ObjectFile(const ObjectFile &other) = delete;
272
273
292
  uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
274
292
    assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
275
292
    return getCommonSymbolSizeImpl(Symb);
276
292
  }
277
278
0
  virtual std::vector<SectionRef> dynamic_relocation_sections() const {
279
0
    return std::vector<SectionRef>();
280
0
  }
281
282
  using symbol_iterator_range = iterator_range<symbol_iterator>;
283
3.39k
  symbol_iterator_range symbols() const {
284
3.39k
    return symbol_iterator_range(symbol_begin(), symbol_end());
285
3.39k
  }
286
287
  virtual section_iterator section_begin() const = 0;
288
  virtual section_iterator section_end() const = 0;
289
290
  using section_iterator_range = iterator_range<section_iterator>;
291
10.5k
  section_iterator_range sections() const {
292
10.5k
    return section_iterator_range(section_begin(), section_end());
293
10.5k
  }
294
295
  /// The number of bytes used to represent an address in this object
296
  ///        file format.
297
  virtual uint8_t getBytesInAddress() const = 0;
298
299
  virtual StringRef getFileFormatName() const = 0;
300
  virtual Triple::ArchType getArch() const = 0;
301
  virtual SubtargetFeatures getFeatures() const = 0;
302
10
  virtual void setARMSubArch(Triple &TheTriple) const { }
303
0
  virtual Expected<uint64_t> getStartAddress() const {
304
0
    return errorCodeToError(object_error::parse_failed);
305
0
  };
306
307
  /// Create a triple from the data in this object file.
308
  Triple makeTriple() const;
309
310
  virtual std::error_code
311
0
    getBuildAttributes(ARMAttributeParser &Attributes) const {
312
0
      return std::error_code();
313
0
    }
314
315
  /// Maps a debug section name to a standard DWARF section name.
316
8.55k
  virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
317
318
  /// True if this is a relocatable object (.o/.obj).
319
  virtual bool isRelocatableObject() const = 0;
320
321
  /// @returns Pointer to ObjectFile subclass to handle this type of object.
322
  /// @param ObjectPath The path to the object file. ObjectPath.isObject must
323
  ///        return true.
324
  /// Create ObjectFile from path.
325
  static Expected<OwningBinary<ObjectFile>>
326
  createObjectFile(StringRef ObjectPath);
327
328
  static Expected<std::unique_ptr<ObjectFile>>
329
  createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
330
  static Expected<std::unique_ptr<ObjectFile>>
331
1.53k
  createObjectFile(MemoryBufferRef Object) {
332
1.53k
    return createObjectFile(Object, llvm::file_magic::unknown);
333
1.53k
  }
334
335
8.61k
  static bool classof(const Binary *v) {
336
8.61k
    return v->isObject();
337
8.61k
  }
338
339
  static Expected<std::unique_ptr<COFFObjectFile>>
340
  createCOFFObjectFile(MemoryBufferRef Object);
341
342
  static Expected<std::unique_ptr<ObjectFile>>
343
  createELFObjectFile(MemoryBufferRef Object);
344
345
  static Expected<std::unique_ptr<MachOObjectFile>>
346
  createMachOObjectFile(MemoryBufferRef Object,
347
                        uint32_t UniversalCputype = 0,
348
                        uint32_t UniversalIndex = 0);
349
350
  static Expected<std::unique_ptr<WasmObjectFile>>
351
  createWasmObjectFile(MemoryBufferRef Object);
352
};
353
354
// Inline function definitions.
355
inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
356
43.9k
    : BasicSymbolRef(SymbolP, Owner) {}
357
358
inline Expected<StringRef> SymbolRef::getName() const {
359
  return getObject()->getSymbolName(getRawDataRefImpl());
360
}
361
362
inline Expected<uint64_t> SymbolRef::getAddress() const {
363
  return getObject()->getSymbolAddress(getRawDataRefImpl());
364
}
365
366
inline uint64_t SymbolRef::getValue() const {
367
  return getObject()->getSymbolValue(getRawDataRefImpl());
368
}
369
370
inline uint32_t SymbolRef::getAlignment() const {
371
  return getObject()->getSymbolAlignment(getRawDataRefImpl());
372
}
373
374
inline uint64_t SymbolRef::getCommonSize() const {
375
  return getObject()->getCommonSymbolSize(getRawDataRefImpl());
376
}
377
378
26.6k
inline Expected<section_iterator> SymbolRef::getSection() const {
379
26.6k
  return getObject()->getSymbolSection(getRawDataRefImpl());
380
26.6k
}
381
382
inline Expected<SymbolRef::Type> SymbolRef::getType() const {
383
  return getObject()->getSymbolType(getRawDataRefImpl());
384
}
385
386
116k
inline const ObjectFile *SymbolRef::getObject() const {
387
116k
  const SymbolicFile *O = BasicSymbolRef::getObject();
388
116k
  return cast<ObjectFile>(O);
389
116k
}
390
391
/// SectionRef
392
inline SectionRef::SectionRef(DataRefImpl SectionP,
393
                              const ObjectFile *Owner)
394
  : SectionPimpl(SectionP)
395
140k
  , OwningObject(Owner) {}
396
397
244k
inline bool SectionRef::operator==(const SectionRef &Other) const {
398
244k
  return SectionPimpl == Other.SectionPimpl;
399
244k
}
400
401
inline bool SectionRef::operator!=(const SectionRef &Other) const {
402
  return SectionPimpl != Other.SectionPimpl;
403
}
404
405
inline bool SectionRef::operator<(const SectionRef &Other) const {
406
  return SectionPimpl < Other.SectionPimpl;
407
}
408
409
154k
inline void SectionRef::moveNext() {
410
154k
  return OwningObject->moveSectionNext(SectionPimpl);
411
154k
}
412
413
81.1k
inline std::error_code SectionRef::getName(StringRef &Result) const {
414
81.1k
  return OwningObject->getSectionName(SectionPimpl, Result);
415
81.1k
}
416
417
31.7k
inline uint64_t SectionRef::getAddress() const {
418
31.7k
  return OwningObject->getSectionAddress(SectionPimpl);
419
31.7k
}
420
421
inline uint64_t SectionRef::getIndex() const {
422
  return OwningObject->getSectionIndex(SectionPimpl);
423
}
424
425
356k
inline uint64_t SectionRef::getSize() const {
426
356k
  return OwningObject->getSectionSize(SectionPimpl);
427
356k
}
428
429
24.4k
inline std::error_code SectionRef::getContents(StringRef &Result) const {
430
24.4k
  return OwningObject->getSectionContents(SectionPimpl, Result);
431
24.4k
}
432
433
inline uint64_t SectionRef::getAlignment() const {
434
  return OwningObject->getSectionAlignment(SectionPimpl);
435
}
436
437
inline bool SectionRef::isCompressed() const {
438
  return OwningObject->isSectionCompressed(SectionPimpl);
439
}
440
441
inline bool SectionRef::isText() const {
442
  return OwningObject->isSectionText(SectionPimpl);
443
}
444
445
4.86k
inline bool SectionRef::isData() const {
446
4.86k
  return OwningObject->isSectionData(SectionPimpl);
447
4.86k
}
448
449
24.6k
inline bool SectionRef::isBSS() const {
450
24.6k
  return OwningObject->isSectionBSS(SectionPimpl);
451
24.6k
}
452
453
inline bool SectionRef::isVirtual() const {
454
  return OwningObject->isSectionVirtual(SectionPimpl);
455
}
456
457
67.2k
inline bool SectionRef::isBitcode() const {
458
67.2k
  return OwningObject->isSectionBitcode(SectionPimpl);
459
67.2k
}
460
461
inline bool SectionRef::isStripped() const {
462
  return OwningObject->isSectionStripped(SectionPimpl);
463
}
464
465
inline bool SectionRef::isBerkeleyText() const {
466
  return OwningObject->isBerkeleyText(SectionPimpl);
467
}
468
469
inline bool SectionRef::isBerkeleyData() const {
470
  return OwningObject->isBerkeleyData(SectionPimpl);
471
}
472
473
7.46k
inline relocation_iterator SectionRef::relocation_begin() const {
474
7.46k
  return OwningObject->section_rel_begin(SectionPimpl);
475
7.46k
}
476
477
7.46k
inline relocation_iterator SectionRef::relocation_end() const {
478
7.46k
  return OwningObject->section_rel_end(SectionPimpl);
479
7.46k
}
480
481
inline section_iterator SectionRef::getRelocatedSection() const {
482
  return OwningObject->getRelocatedSection(SectionPimpl);
483
}
484
485
26.3k
inline DataRefImpl SectionRef::getRawDataRefImpl() const {
486
26.3k
  return SectionPimpl;
487
26.3k
}
488
489
inline const ObjectFile *SectionRef::getObject() const {
490
  return OwningObject;
491
}
492
493
/// RelocationRef
494
inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
495
                              const ObjectFile *Owner)
496
  : RelocationPimpl(RelocationP)
497
19.2k
  , OwningObject(Owner) {}
498
499
24.0k
inline bool RelocationRef::operator==(const RelocationRef &Other) const {
500
24.0k
  return RelocationPimpl == Other.RelocationPimpl;
501
24.0k
}
502
503
15.3k
inline void RelocationRef::moveNext() {
504
15.3k
  return OwningObject->moveRelocationNext(RelocationPimpl);
505
15.3k
}
506
507
24.2k
inline uint64_t RelocationRef::getOffset() const {
508
24.2k
  return OwningObject->getRelocationOffset(RelocationPimpl);
509
24.2k
}
510
511
9.99k
inline symbol_iterator RelocationRef::getSymbol() const {
512
9.99k
  return OwningObject->getRelocationSymbol(RelocationPimpl);
513
9.99k
}
514
515
6.49k
inline uint64_t RelocationRef::getType() const {
516
6.49k
  return OwningObject->getRelocationType(RelocationPimpl);
517
6.49k
}
518
519
inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
520
  return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
521
}
522
523
12.3k
inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
524
12.3k
  return RelocationPimpl;
525
12.3k
}
526
527
inline const ObjectFile *RelocationRef::getObject() const {
528
  return OwningObject;
529
}
530
531
} // end namespace object
532
533
} // end namespace llvm
534
535
#endif // LLVM_OBJECT_OBJECTFILE_H