Coverage Report

Created: 2018-11-16 02:38

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