Line data Source code
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 120 : 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 338 : 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 4127 : iterator_range<relocation_iterator> relocations() const {
119 16506 : return make_range(relocation_begin(), relocation_end());
120 : }
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 62 : 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 17365 : symbol_iterator(SymbolRef Sym) : basic_symbol_iterator(Sym) {}
172 9066 : symbol_iterator(const basic_symbol_iterator &B)
173 36264 : : basic_symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
174 18132 : cast<ObjectFile>(B->getObject()))) {}
175 :
176 : const SymbolRef *operator->() const {
177 : const BasicSymbolRef &P = basic_symbol_iterator::operator *();
178 : return static_cast<const SymbolRef*>(&P);
179 : }
180 :
181 : const SymbolRef &operator*() const {
182 : const BasicSymbolRef &P = basic_symbol_iterator::operator *();
183 : return static_cast<const SymbolRef&>(P);
184 : }
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 6453 : class ObjectFile : public SymbolicFile {
191 : virtual void anchor();
192 :
193 : protected:
194 : ObjectFile(unsigned int Type, MemoryBufferRef Source);
195 :
196 : const uint8_t *base() const {
197 : return reinterpret_cast<const uint8_t *>(Data.getBufferStart());
198 : }
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 : uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
261 : assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
262 838 : return getCommonSymbolSizeImpl(Symb);
263 : }
264 :
265 0 : virtual std::vector<SectionRef> dynamic_relocation_sections() const {
266 0 : return std::vector<SectionRef>();
267 : }
268 :
269 : using symbol_iterator_range = iterator_range<symbol_iterator>;
270 3367 : symbol_iterator_range symbols() const {
271 3367 : return symbol_iterator_range(symbol_begin(), symbol_end());
272 : }
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 10132 : section_iterator_range sections() const {
279 10132 : return section_iterator_range(section_begin(), section_end());
280 : }
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 : };
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 : }
301 :
302 : /// Maps a debug section name to a standard DWARF section name.
303 15228 : 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 : createObjectFile(MemoryBufferRef Object) {
319 1483 : return createObjectFile(Object, llvm::file_magic::unknown);
320 : }
321 :
322 : static bool classof(const Binary *v) {
323 2551 : return v->isObject();
324 : }
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 43283 : : BasicSymbolRef(SymbolP, Owner) {}
344 :
345 : inline Expected<StringRef> SymbolRef::getName() const {
346 13254152 : return getObject()->getSymbolName(getRawDataRefImpl());
347 : }
348 :
349 : inline Expected<uint64_t> SymbolRef::getAddress() const {
350 13254669 : return getObject()->getSymbolAddress(getRawDataRefImpl());
351 : }
352 :
353 2340 : inline uint64_t SymbolRef::getValue() const {
354 2340 : return getObject()->getSymbolValue(getRawDataRefImpl());
355 : }
356 :
357 : inline uint32_t SymbolRef::getAlignment() const {
358 181 : return getObject()->getSymbolAlignment(getRawDataRefImpl());
359 : }
360 :
361 : inline uint64_t SymbolRef::getCommonSize() const {
362 178 : return getObject()->getCommonSymbolSize(getRawDataRefImpl());
363 : }
364 :
365 : inline Expected<section_iterator> SymbolRef::getSection() const {
366 22721 : return getObject()->getSymbolSection(getRawDataRefImpl());
367 : }
368 :
369 : inline Expected<SymbolRef::Type> SymbolRef::getType() const {
370 13182213 : return getObject()->getSymbolType(getRawDataRefImpl());
371 : }
372 :
373 : inline const ObjectFile *SymbolRef::getObject() const {
374 39704131 : const SymbolicFile *O = BasicSymbolRef::getObject();
375 : return cast<ObjectFile>(O);
376 : }
377 :
378 : /// SectionRef
379 : inline SectionRef::SectionRef(DataRefImpl SectionP,
380 49868 : const ObjectFile *Owner)
381 : : SectionPimpl(SectionP)
382 27059 : , OwningObject(Owner) {}
383 :
384 : inline bool SectionRef::operator==(const SectionRef &Other) const {
385 32860 : return SectionPimpl == Other.SectionPimpl;
386 : }
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 113239 : return SectionPimpl < Other.SectionPimpl;
394 : }
395 :
396 : inline void SectionRef::moveNext() {
397 169556 : return OwningObject->moveSectionNext(SectionPimpl);
398 : }
399 :
400 0 : inline std::error_code SectionRef::getName(StringRef &Result) const {
401 89511 : return OwningObject->getSectionName(SectionPimpl, Result);
402 : }
403 :
404 0 : inline uint64_t SectionRef::getAddress() const {
405 23714 : return OwningObject->getSectionAddress(SectionPimpl);
406 : }
407 :
408 0 : inline uint64_t SectionRef::getIndex() const {
409 4196 : return OwningObject->getSectionIndex(SectionPimpl);
410 : }
411 :
412 0 : inline uint64_t SectionRef::getSize() const {
413 2824077 : return OwningObject->getSectionSize(SectionPimpl);
414 : }
415 :
416 0 : inline std::error_code SectionRef::getContents(StringRef &Result) const {
417 28169 : return OwningObject->getSectionContents(SectionPimpl, Result);
418 : }
419 :
420 0 : inline uint64_t SectionRef::getAlignment() const {
421 1751 : return OwningObject->getSectionAlignment(SectionPimpl);
422 : }
423 :
424 0 : inline bool SectionRef::isCompressed() const {
425 21674 : return OwningObject->isSectionCompressed(SectionPimpl);
426 : }
427 :
428 0 : inline bool SectionRef::isText() const {
429 15202 : return OwningObject->isSectionText(SectionPimpl);
430 : }
431 :
432 0 : inline bool SectionRef::isData() const {
433 3320 : return OwningObject->isSectionData(SectionPimpl);
434 : }
435 :
436 0 : inline bool SectionRef::isBSS() const {
437 27584 : return OwningObject->isSectionBSS(SectionPimpl);
438 : }
439 :
440 0 : inline bool SectionRef::isVirtual() const {
441 29938 : return OwningObject->isSectionVirtual(SectionPimpl);
442 : }
443 :
444 0 : inline bool SectionRef::isBitcode() const {
445 67105 : return OwningObject->isSectionBitcode(SectionPimpl);
446 : }
447 :
448 0 : inline bool SectionRef::isStripped() const {
449 22029 : return OwningObject->isSectionStripped(SectionPimpl);
450 : }
451 :
452 0 : inline relocation_iterator SectionRef::relocation_begin() const {
453 6280 : return OwningObject->section_rel_begin(SectionPimpl);
454 : }
455 :
456 0 : inline relocation_iterator SectionRef::relocation_end() const {
457 6280 : return OwningObject->section_rel_end(SectionPimpl);
458 : }
459 :
460 0 : inline section_iterator SectionRef::getRelocatedSection() const {
461 42419 : return OwningObject->getRelocatedSection(SectionPimpl);
462 : }
463 :
464 0 : inline DataRefImpl SectionRef::getRawDataRefImpl() const {
465 21786 : return SectionPimpl;
466 : }
467 :
468 0 : inline const ObjectFile *SectionRef::getObject() const {
469 0 : return OwningObject;
470 : }
471 :
472 : /// RelocationRef
473 : inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
474 17356 : const ObjectFile *Owner)
475 : : RelocationPimpl(RelocationP)
476 17356 : , OwningObject(Owner) {}
477 :
478 : inline bool RelocationRef::operator==(const RelocationRef &Other) const {
479 0 : return RelocationPimpl == Other.RelocationPimpl;
480 : }
481 :
482 : inline void RelocationRef::moveNext() {
483 22181 : return OwningObject->moveRelocationNext(RelocationPimpl);
484 : }
485 :
486 0 : inline uint64_t RelocationRef::getOffset() const {
487 22974 : return OwningObject->getRelocationOffset(RelocationPimpl);
488 : }
489 :
490 0 : inline symbol_iterator RelocationRef::getSymbol() const {
491 15694 : return OwningObject->getRelocationSymbol(RelocationPimpl);
492 : }
493 :
494 0 : inline uint64_t RelocationRef::getType() const {
495 14967 : return OwningObject->getRelocationType(RelocationPimpl);
496 : }
497 :
498 0 : inline void RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const {
499 973 : return OwningObject->getRelocationTypeName(RelocationPimpl, Result);
500 : }
501 :
502 0 : inline DataRefImpl RelocationRef::getRawDataRefImpl() const {
503 18493 : return RelocationPimpl;
504 : }
505 :
506 0 : inline const ObjectFile *RelocationRef::getObject() const {
507 0 : return OwningObject;
508 : }
509 :
510 : } // end namespace object
511 :
512 : } // end namespace llvm
513 :
514 : #endif // LLVM_OBJECT_OBJECTFILE_H
|