ObjectFile.h revision d111c7844ec26448764ced627e153f406d730c5f
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/DenseMapInfo.h"
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
34namespace llvm {
35
36class ARMAttributeParser;
37
38namespace object {
39
40class COFFObjectFile;
41class MachOObjectFile;
42class ObjectFile;
43class SectionRef;
44class SymbolRef;
45class symbol_iterator;
46class WasmObjectFile;
47
48using 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.
52class RelocationRef {
53  DataRefImpl RelocationPimpl;
54  const ObjectFile *OwningObject = nullptr;
55
56public:
57  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
77using 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.
81class SectionRef {
82  friend class SymbolRef;
83
84  DataRefImpl SectionPimpl;
85  const ObjectFile *OwningObject = nullptr;
86
87public:
88  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  Expected<StringRef> getContents() 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  /// Whether this section contains instructions.
108  bool isText() const;
109  /// Whether this section contains data, not instructions.
110  bool isData() const;
111  /// Whether this section contains BSS uninitialized data.
112  bool isBSS() const;
113  bool isVirtual() const;
114  bool isBitcode() const;
115  bool isStripped() const;
116
117  /// Whether this section will be placed in the text segment, according to the
118  /// Berkeley size format. This is true if the section is allocatable, and
119  /// contains either code or readonly data.
120  bool isBerkeleyText() const;
121  /// Whether this section will be placed in the data segment, according to the
122  /// Berkeley size format. This is true if the section is allocatable and
123  /// contains data (e.g. PROGBITS), but is not text.
124  bool isBerkeleyData() const;
125
126  bool containsSymbol(SymbolRef S) const;
127
128  relocation_iterator relocation_begin() const;
129  relocation_iterator relocation_end() const;
130  iterator_range<relocation_iterator> relocations() const {
131    return make_range(relocation_begin(), relocation_end());
132  }
133  section_iterator getRelocatedSection() const;
134
135  DataRefImpl getRawDataRefImpl() const;
136  const ObjectFile *getObject() const;
137};
138
139struct SectionedAddress {
140  // TODO: constructors could be removed when C++14 would be adopted.
141  SectionedAddress() {}
142  SectionedAddress(uint64_t Addr, uint64_t SectIdx)
143      : Address(Addr), SectionIndex(SectIdx) {}
144
145  const static uint64_t UndefSection = UINT64_MAX;
146
147  uint64_t Address = 0;
148  uint64_t SectionIndex = UndefSection;
149};
150
151inline bool operator<(const SectionedAddress &LHS,
152                      const SectionedAddress &RHS) {
153  return std::tie(LHS.SectionIndex, LHS.Address) <
154         std::tie(RHS.SectionIndex, RHS.Address);
155}
156
157inline bool operator==(const SectionedAddress &LHS,
158                       const SectionedAddress &RHS) {
159  return std::tie(LHS.SectionIndex, LHS.Address) ==
160         std::tie(RHS.SectionIndex, RHS.Address);
161}
162
163/// This is a value type class that represents a single symbol in the list of
164/// symbols in the object file.
165class SymbolRef : public BasicSymbolRef {
166  friend class SectionRef;
167
168public:
169  enum Type {
170    ST_Unknown, // Type not specified
171    ST_Data,
172    ST_Debug,
173    ST_File,
174    ST_Function,
175    ST_Other
176  };
177
178  SymbolRef() = default;
179  SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
180  SymbolRef(const BasicSymbolRef &B) : BasicSymbolRef(B) {
181    assert(isa<ObjectFile>(BasicSymbolRef::getObject()));
182  }
183
184  Expected<StringRef> getName() const;
185  /// Returns the symbol virtual address (i.e. address at which it will be
186  /// mapped).
187  Expected<uint64_t> getAddress() const;
188
189  /// Return the value of the symbol depending on the object this can be an
190  /// offset or a virtual address.
191  uint64_t getValue() const;
192
193  /// Get the alignment of this symbol as the actual value (not log 2).
194  uint32_t getAlignment() const;
195  uint64_t getCommonSize() const;
196  Expected<SymbolRef::Type> getType() const;
197
198  /// Get section this symbol is defined in reference to. Result is
199  /// end_sections() if it is undefined or is an absolute symbol.
200  Expected<section_iterator> getSection() const;
201
202  const ObjectFile *getObject() const;
203};
204
205class symbol_iterator : public basic_symbol_iterator {
206public:
207  symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
208  symbol_iterator(const basic_symbol_iterator &B)
209      : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
210                                        cast<ObjectFile>(B->getObject()))) {}
211
212  const SymbolRef *operator->() const {
213    const BasicSymbolRef &P = basic_symbol_iterator::operator *();
214    return static_cast<const SymbolRef*>(&P);
215  }
216
217  const SymbolRef &operator*() const {
218    const BasicSymbolRef &P = basic_symbol_iterator::operator *();
219    return static_cast<const SymbolRef&>(P);
220  }
221};
222
223/// This class is the base class for all object file types. Concrete instances
224/// of this object are created by createObjectFile, which figures out which type
225/// to create.
226class ObjectFile : public SymbolicFile {
227  virtual void anchor();
228
229protected:
230  ObjectFile(unsigned int Type, MemoryBufferRef Source);
231
232  const uint8_t *base() const {
233    return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
234  }
235
236  // These functions are for SymbolRef to call internally. The main goal of
237  // this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
238  // entry in the memory mapped object file. SymbolPimpl cannot contain any
239  // virtual functions because then it could not point into the memory mapped
240  // file.
241  //
242  // Implementations assume that the DataRefImpl is valid and has not been
243  // modified externally. It's UB otherwise.
244  friend class SymbolRef;
245
246  virtual Expected<StringRef> getSymbolName(DataRefImpl Symb) const = 0;
247  Error printSymbolName(raw_ostream &OS,
248                                  DataRefImpl Symb) const override;
249  virtual Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const = 0;
250  virtual uint64_t getSymbolValueImpl(DataRefImpl Symb) const = 0;
251  virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const;
252  virtual uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const = 0;
253  virtual Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const = 0;
254  virtual Expected<section_iterator>
255  getSymbolSection(DataRefImpl Symb) const = 0;
256
257  // Same as above for SectionRef.
258  friend class SectionRef;
259
260  virtual void moveSectionNext(DataRefImpl &Sec) const = 0;
261  virtual Expected<StringRef> getSectionName(DataRefImpl Sec) const = 0;
262  virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
263  virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0;
264  virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
265  virtual Expected<ArrayRef<uint8_t>>
266  getSectionContents(DataRefImpl Sec) const = 0;
267  virtual uint64_t getSectionAlignment(DataRefImpl Sec) const = 0;
268  virtual bool isSectionCompressed(DataRefImpl Sec) const = 0;
269  virtual bool isSectionText(DataRefImpl Sec) const = 0;
270  virtual bool isSectionData(DataRefImpl Sec) const = 0;
271  virtual bool isSectionBSS(DataRefImpl Sec) const = 0;
272  // A section is 'virtual' if its contents aren't present in the object image.
273  virtual bool isSectionVirtual(DataRefImpl Sec) const = 0;
274  virtual bool isSectionBitcode(DataRefImpl Sec) const;
275  virtual bool isSectionStripped(DataRefImpl Sec) const;
276  virtual bool isBerkeleyText(DataRefImpl Sec) const;
277  virtual bool isBerkeleyData(DataRefImpl Sec) const;
278  virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
279  virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
280  virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
281
282  // Same as above for RelocationRef.
283  friend class RelocationRef;
284  virtual void moveRelocationNext(DataRefImpl &Rel) const = 0;
285  virtual uint64_t getRelocationOffset(DataRefImpl Rel) const = 0;
286  virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
287  virtual uint64_t getRelocationType(DataRefImpl Rel) const = 0;
288  virtual void getRelocationTypeName(DataRefImpl Rel,
289                                     SmallVectorImpl<char> &Result) const = 0;
290
291  uint64_t getSymbolValue(DataRefImpl Symb) const;
292
293public:
294  ObjectFile() = delete;
295  ObjectFile(const ObjectFile &other) = delete;
296
297  uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
298    assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
299    return getCommonSymbolSizeImpl(Symb);
300  }
301
302  virtual std::vector<SectionRef> dynamic_relocation_sections() const {
303    return std::vector<SectionRef>();
304  }
305
306  using symbol_iterator_range = iterator_range<symbol_iterator>;
307  symbol_iterator_range symbols() const {
308    return symbol_iterator_range(symbol_begin(), symbol_end());
309  }
310
311  virtual section_iterator section_begin() const = 0;
312  virtual section_iterator section_end() const = 0;
313
314  using section_iterator_range = iterator_range<section_iterator>;
315  section_iterator_range sections() const {
316    return section_iterator_range(section_begin(), section_end());
317  }
318
319  /// The number of bytes used to represent an address in this object
320  ///        file format.
321  virtual uint8_t getBytesInAddress() const = 0;
322
323  virtual StringRef getFileFormatName() const = 0;
324  virtual Triple::ArchType getArch() const = 0;
325  virtual SubtargetFeatures getFeatures() const = 0;
326  virtual void setARMSubArch(Triple &TheTriple) const { }
327  virtual Expected<uint64_t> getStartAddress() const {
328    return errorCodeToError(object_error::parse_failed);
329  };
330
331  /// Create a triple from the data in this object file.
332  Triple makeTriple() const;
333
334  /// Maps a debug section name to a standard DWARF section name.
335  virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
336
337  /// True if this is a relocatable object (.o/.obj).
338  virtual bool isRelocatableObject() const = 0;
339
340  /// @returns Pointer to ObjectFile subclass to handle this type of object.
341  /// @param ObjectPath The path to the object file. ObjectPath.isObject must
342  ///        return true.
343  /// Create ObjectFile from path.
344  static Expected<OwningBinary<ObjectFile>>
345  createObjectFile(StringRef ObjectPath);
346
347  static Expected<std::unique_ptr<ObjectFile>>
348  createObjectFile(MemoryBufferRef Object, llvm::file_magic Type);
349  static Expected<std::unique_ptr<ObjectFile>>
350  createObjectFile(MemoryBufferRef Object) {
351    return createObjectFile(Object, llvm::file_magic::unknown);
352  }
353
354  static bool classof(const Binary *v) {
355    return v->isObject();
356  }
357
358  static Expected<std::unique_ptr<COFFObjectFile>>
359  createCOFFObjectFile(MemoryBufferRef Object);
360
361  static Expected<std::unique_ptr<ObjectFile>>
362  createXCOFFObjectFile(MemoryBufferRef Object, unsigned FileType);
363
364  static Expected<std::unique_ptr<ObjectFile>>
365  createELFObjectFile(MemoryBufferRef Object);
366
367  static Expected<std::unique_ptr<MachOObjectFile>>
368  createMachOObjectFile(MemoryBufferRef Object,
369                        uint32_t UniversalCputype = 0,
370                        uint32_t UniversalIndex = 0);
371
372  static Expected<std::unique_ptr<WasmObjectFile>>
373  createWasmObjectFile(MemoryBufferRef Object);
374};
375
376// Inline function definitions.
377inline SymbolRef::SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner)
378    : BasicSymbolRef(SymbolP, Owner) {}
379
380inline Expected<StringRef> SymbolRef::getName() const {
381  return getObject()->getSymbolName(getRawDataRefImpl());
382}
383
384inline Expected<uint64_t> SymbolRef::getAddress() const {
385  return getObject()->getSymbolAddress(getRawDataRefImpl());
386}
387
388inline uint64_t SymbolRef::getValue() const {
389  return getObject()->getSymbolValue(getRawDataRefImpl());
390}
391
392inline uint32_t SymbolRef::getAlignment() const {
393  return getObject()->getSymbolAlignment(getRawDataRefImpl());
394}
395
396inline uint64_t SymbolRef::getCommonSize() const {
397  return getObject()->getCommonSymbolSize(getRawDataRefImpl());
398}
399
400inline Expected<section_iterator> SymbolRef::getSection() const {
401  return getObject()->getSymbolSection(getRawDataRefImpl());
402}
403
404inline Expected<SymbolRef::Type> SymbolRef::getType() const {
405  return getObject()->getSymbolType(getRawDataRefImpl());
406}
407
408inline const ObjectFile *SymbolRef::getObject() const {
409  const SymbolicFile *O = BasicSymbolRef::getObject();
410  return cast<ObjectFile>(O);
411}
412
413/// SectionRef
414inline SectionRef::SectionRef(DataRefImpl SectionP,
415                              const ObjectFile *Owner)
416  : SectionPimpl(SectionP)
417  , OwningObject(Owner) {}
418
419inline bool SectionRef::operator==(const SectionRef &Other) const {
420  return OwningObject == Other.OwningObject &&
421         SectionPimpl == Other.SectionPimpl;
422}
423
424inline bool SectionRef::operator!=(const SectionRef &Other) const {
425  return !(*this == Other);
426}
427
428inline bool SectionRef::operator<(const SectionRef &Other) const {
429  assert(OwningObject == Other.OwningObject);
430  return SectionPimpl < Other.SectionPimpl;
431}
432
433inline void SectionRef::moveNext() {
434  return OwningObject->moveSectionNext(SectionPimpl);
435}
436
437inline std::error_code SectionRef::getName(StringRef &Result) const {
438  Expected<StringRef> NameOrErr = OwningObject->getSectionName(SectionPimpl);
439  if (!NameOrErr)
440    return errorToErrorCode(NameOrErr.takeError());
441  Result = *NameOrErr;
442  return std::error_code();
443}
444
445inline uint64_t SectionRef::getAddress() const {
446  return OwningObject->getSectionAddress(SectionPimpl);
447}
448
449inline uint64_t SectionRef::getIndex() const {
450  return OwningObject->getSectionIndex(SectionPimpl);
451}
452
453inline uint64_t SectionRef::getSize() const {
454  return OwningObject->getSectionSize(SectionPimpl);
455}
456
457inline Expected<StringRef> SectionRef::getContents() const {
458  Expected<ArrayRef<uint8_t>> Res =
459      OwningObject->getSectionContents(SectionPimpl);
460  if (!Res)
461    return Res.takeError();
462  return StringRef(reinterpret_cast<const char *>(Res->data()), Res->size());
463}
464
465inline uint64_t SectionRef::getAlignment() const {
466  return OwningObject->getSectionAlignment(SectionPimpl);
467}
468
469inline bool SectionRef::isCompressed() const {
470  return OwningObject->isSectionCompressed(SectionPimpl);
471}
472
473inline bool SectionRef::isText() const {
474  return OwningObject->isSectionText(SectionPimpl);
475}
476
477inline bool SectionRef::isData() const {
478  return OwningObject->isSectionData(SectionPimpl);
479}
480
481inline bool SectionRef::isBSS() const {
482  return OwningObject->isSectionBSS(SectionPimpl);
483}
484
485inline bool SectionRef::isVirtual() const {
486  return OwningObject->isSectionVirtual(SectionPimpl);
487}
488
489inline bool SectionRef::isBitcode() const {
490  return OwningObject->isSectionBitcode(SectionPimpl);
491}
492
493inline bool SectionRef::isStripped() const {
494  return OwningObject->isSectionStripped(SectionPimpl);
495}
496
497inline bool SectionRef::isBerkeleyText() const {
498  return OwningObject->isBerkeleyText(SectionPimpl);
499}
500
501inline bool SectionRef::isBerkeleyData() const {
502  return OwningObject->isBerkeleyData(SectionPimpl);
503}
504
505inline relocation_iterator SectionRef::relocation_begin() const {
506  return OwningObject->section_rel_begin(SectionPimpl);
507}
508
509inline relocation_iterator SectionRef::relocation_end() const {
510  return OwningObject->section_rel_end(SectionPimpl);
511}
512
513inline section_iterator SectionRef::getRelocatedSection() const {
514  return OwningObject->getRelocatedSection(SectionPimpl);
515}
516
517inline DataRefImpl SectionRef::getRawDataRefImpl() const {
518  return SectionPimpl;
519}
520
521inline const ObjectFile *SectionRef::getObject() const {
522  return OwningObject;
523}
524
525/// RelocationRef
526inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
527                              const ObjectFile *Owner)
528  : RelocationPimpl(RelocationP)
529  , OwningObject(Owner) {}
530
531inline bool RelocationRef::operator==(const RelocationRef &Other) const {
532  return RelocationPimpl == Other.RelocationPimpl;
533}
534
535inline void RelocationRef::moveNext() {
536  return OwningObject->moveRelocationNext(RelocationPimpl);
537}
538
539inline uint64_t RelocationRef::getOffset() const {
540  return OwningObject->getRelocationOffset(RelocationPimpl);
541}
542
543inline symbol_iterator RelocationRef::getSymbol() const {
544  return OwningObject->getRelocationSymbol(RelocationPimpl);
545}
546
547inline uint64_t RelocationRef::getType() const {
548  return OwningObject->getRelocationType(RelocationPimpl);
549}
550
551inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
552  return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
553}
554
555inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
556  return RelocationPimpl;
557}
558
559inline const ObjectFile *RelocationRef::getObject() const {
560  return OwningObject;
561}
562
563} // end namespace object
564
565template <> struct DenseMapInfo<object::SectionRef> {
566  static bool isEqual(const object::SectionRef &A,
567                      const object::SectionRef &B) {
568    return A == B;
569  }
570  static object::SectionRef getEmptyKey() {
571    return object::SectionRef({}, nullptr);
572  }
573  static object::SectionRef getTombstoneKey() {
574    object::DataRefImpl TS;
575    TS.p = (uintptr_t)-1;
576    return object::SectionRef(TS, nullptr);
577  }
578  static unsigned getHashValue(const object::SectionRef &Sec) {
579    object::DataRefImpl Raw = Sec.getRawDataRefImpl();
580    return hash_combine(Raw.p, Raw.d.a, Raw.d.b);
581  }
582};
583
584} // end namespace llvm
585
586#endif // LLVM_OBJECT_OBJECTFILE_H
587