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