1 | //===- ELFObjectFile.h - ELF object file implementation ---------*- 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 the ELFObjectFile template class. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_OBJECT_ELFOBJECTFILE_H |
14 | #define LLVM_OBJECT_ELFOBJECTFILE_H |
15 | |
16 | #include "llvm/ADT/ArrayRef.h" |
17 | #include "llvm/ADT/STLExtras.h" |
18 | #include "llvm/ADT/SmallVector.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include "llvm/ADT/Triple.h" |
21 | #include "llvm/ADT/iterator_range.h" |
22 | #include "llvm/BinaryFormat/ELF.h" |
23 | #include "llvm/MC/SubtargetFeature.h" |
24 | #include "llvm/Object/Binary.h" |
25 | #include "llvm/Object/ELF.h" |
26 | #include "llvm/Object/ELFTypes.h" |
27 | #include "llvm/Object/Error.h" |
28 | #include "llvm/Object/ObjectFile.h" |
29 | #include "llvm/Object/SymbolicFile.h" |
30 | #include "llvm/Support/ARMAttributeParser.h" |
31 | #include "llvm/Support/Casting.h" |
32 | #include "llvm/Support/ELFAttributes.h" |
33 | #include "llvm/Support/Endian.h" |
34 | #include "llvm/Support/Error.h" |
35 | #include "llvm/Support/ErrorHandling.h" |
36 | #include "llvm/Support/MemoryBuffer.h" |
37 | #include <cassert> |
38 | #include <cstdint> |
39 | #include <system_error> |
40 | |
41 | namespace llvm { |
42 | namespace object { |
43 | |
44 | constexpr int NumElfSymbolTypes = 16; |
45 | extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes]; |
46 | |
47 | class elf_symbol_iterator; |
48 | |
49 | class ELFObjectFileBase : public ObjectFile { |
50 | friend class ELFRelocationRef; |
51 | friend class ELFSectionRef; |
52 | friend class ELFSymbolRef; |
53 | |
54 | SubtargetFeatures getMIPSFeatures() const; |
55 | SubtargetFeatures getARMFeatures() const; |
56 | SubtargetFeatures getRISCVFeatures() const; |
57 | |
58 | StringRef getAMDGPUCPUName() const; |
59 | |
60 | protected: |
61 | ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); |
62 | |
63 | virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; |
64 | virtual uint8_t getSymbolBinding(DataRefImpl Symb) const = 0; |
65 | virtual uint8_t getSymbolOther(DataRefImpl Symb) const = 0; |
66 | virtual uint8_t getSymbolELFType(DataRefImpl Symb) const = 0; |
67 | |
68 | virtual uint32_t getSectionType(DataRefImpl Sec) const = 0; |
69 | virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0; |
70 | virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0; |
71 | |
72 | virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; |
73 | virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0; |
74 | |
75 | public: |
76 | using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>; |
77 | |
78 | virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0; |
79 | |
80 | /// Returns platform-specific object flags, if any. |
81 | virtual unsigned getPlatformFlags() const = 0; |
82 | |
83 | elf_symbol_iterator_range symbols() const; |
84 | |
85 | static bool classof(const Binary *v) { return v->isELF(); } |
86 | |
87 | SubtargetFeatures getFeatures() const override; |
88 | |
89 | Optional<StringRef> tryGetCPUName() const override; |
90 | |
91 | void setARMSubArch(Triple &TheTriple) const override; |
92 | |
93 | virtual uint16_t getEType() const = 0; |
94 | |
95 | virtual uint16_t getEMachine() const = 0; |
96 | |
97 | std::vector<std::pair<Optional<DataRefImpl>, uint64_t>> |
98 | getPltAddresses() const; |
99 | }; |
100 | |
101 | class ELFSectionRef : public SectionRef { |
102 | public: |
103 | ELFSectionRef(const SectionRef &B) : SectionRef(B) { |
104 | assert(isa<ELFObjectFileBase>(SectionRef::getObject())); |
105 | } |
106 | |
107 | const ELFObjectFileBase *getObject() const { |
108 | return cast<ELFObjectFileBase>(SectionRef::getObject()); |
109 | } |
110 | |
111 | uint32_t getType() const { |
112 | return getObject()->getSectionType(getRawDataRefImpl()); |
113 | } |
114 | |
115 | uint64_t getFlags() const { |
116 | return getObject()->getSectionFlags(getRawDataRefImpl()); |
117 | } |
118 | |
119 | uint64_t getOffset() const { |
120 | return getObject()->getSectionOffset(getRawDataRefImpl()); |
121 | } |
122 | }; |
123 | |
124 | class elf_section_iterator : public section_iterator { |
125 | public: |
126 | elf_section_iterator(const section_iterator &B) : section_iterator(B) { |
127 | assert(isa<ELFObjectFileBase>(B->getObject())); |
128 | } |
129 | |
130 | const ELFSectionRef *operator->() const { |
131 | return static_cast<const ELFSectionRef *>(section_iterator::operator->()); |
132 | } |
133 | |
134 | const ELFSectionRef &operator*() const { |
135 | return static_cast<const ELFSectionRef &>(section_iterator::operator*()); |
136 | } |
137 | }; |
138 | |
139 | class ELFSymbolRef : public SymbolRef { |
140 | public: |
141 | ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) { |
142 | assert(isa<ELFObjectFileBase>(SymbolRef::getObject())); |
143 | } |
144 | |
145 | const ELFObjectFileBase *getObject() const { |
146 | return cast<ELFObjectFileBase>(BasicSymbolRef::getObject()); |
147 | } |
148 | |
149 | uint64_t getSize() const { |
150 | return getObject()->getSymbolSize(getRawDataRefImpl()); |
151 | } |
152 | |
153 | uint8_t getBinding() const { |
154 | return getObject()->getSymbolBinding(getRawDataRefImpl()); |
155 | } |
156 | |
157 | uint8_t getOther() const { |
158 | return getObject()->getSymbolOther(getRawDataRefImpl()); |
159 | } |
160 | |
161 | uint8_t getELFType() const { |
162 | return getObject()->getSymbolELFType(getRawDataRefImpl()); |
163 | } |
164 | |
165 | StringRef getELFTypeName() const { |
166 | uint8_t Type = getELFType(); |
167 | for (auto &EE : ElfSymbolTypes) { |
168 | if (EE.Value == Type) { |
169 | return EE.AltName; |
170 | } |
171 | } |
172 | return "" ; |
173 | } |
174 | }; |
175 | |
176 | class elf_symbol_iterator : public symbol_iterator { |
177 | public: |
178 | elf_symbol_iterator(const basic_symbol_iterator &B) |
179 | : symbol_iterator(SymbolRef(B->getRawDataRefImpl(), |
180 | cast<ELFObjectFileBase>(B->getObject()))) {} |
181 | |
182 | const ELFSymbolRef *operator->() const { |
183 | return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->()); |
184 | } |
185 | |
186 | const ELFSymbolRef &operator*() const { |
187 | return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*()); |
188 | } |
189 | }; |
190 | |
191 | class ELFRelocationRef : public RelocationRef { |
192 | public: |
193 | ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) { |
194 | assert(isa<ELFObjectFileBase>(RelocationRef::getObject())); |
195 | } |
196 | |
197 | const ELFObjectFileBase *getObject() const { |
198 | return cast<ELFObjectFileBase>(RelocationRef::getObject()); |
199 | } |
200 | |
201 | Expected<int64_t> getAddend() const { |
202 | return getObject()->getRelocationAddend(getRawDataRefImpl()); |
203 | } |
204 | }; |
205 | |
206 | class elf_relocation_iterator : public relocation_iterator { |
207 | public: |
208 | elf_relocation_iterator(const relocation_iterator &B) |
209 | : relocation_iterator(RelocationRef( |
210 | B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {} |
211 | |
212 | const ELFRelocationRef *operator->() const { |
213 | return static_cast<const ELFRelocationRef *>( |
214 | relocation_iterator::operator->()); |
215 | } |
216 | |
217 | const ELFRelocationRef &operator*() const { |
218 | return static_cast<const ELFRelocationRef &>( |
219 | relocation_iterator::operator*()); |
220 | } |
221 | }; |
222 | |
223 | inline ELFObjectFileBase::elf_symbol_iterator_range |
224 | ELFObjectFileBase::symbols() const { |
225 | return elf_symbol_iterator_range(symbol_begin(), symbol_end()); |
226 | } |
227 | |
228 | template <class ELFT> class ELFObjectFile : public ELFObjectFileBase { |
229 | uint16_t getEMachine() const override; |
230 | uint16_t getEType() const override; |
231 | uint64_t getSymbolSize(DataRefImpl Sym) const override; |
232 | |
233 | public: |
234 | LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) |
235 | |
236 | SectionRef toSectionRef(const Elf_Shdr *Sec) const { |
237 | return SectionRef(toDRI(Sec), this); |
238 | } |
239 | |
240 | ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const { |
241 | return ELFSymbolRef({toDRI(SymTable, SymbolNum), this}); |
242 | } |
243 | |
244 | bool IsContentValid() const { return ContentValid; } |
245 | |
246 | private: |
247 | ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF, |
248 | const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec, |
249 | const Elf_Shdr *DotSymtabShndxSec); |
250 | |
251 | bool ContentValid = false; |
252 | |
253 | protected: |
254 | ELFFile<ELFT> EF; |
255 | |
256 | const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section. |
257 | const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section. |
258 | const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section. |
259 | |
260 | Error initContent() override; |
261 | |
262 | void moveSymbolNext(DataRefImpl &Symb) const override; |
263 | Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; |
264 | Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; |
265 | uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; |
266 | uint32_t getSymbolAlignment(DataRefImpl Symb) const override; |
267 | uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; |
268 | Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override; |
269 | uint8_t getSymbolBinding(DataRefImpl Symb) const override; |
270 | uint8_t getSymbolOther(DataRefImpl Symb) const override; |
271 | uint8_t getSymbolELFType(DataRefImpl Symb) const override; |
272 | Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; |
273 | Expected<section_iterator> getSymbolSection(const Elf_Sym *Symb, |
274 | const Elf_Shdr *SymTab) const; |
275 | Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; |
276 | |
277 | void moveSectionNext(DataRefImpl &Sec) const override; |
278 | Expected<StringRef> getSectionName(DataRefImpl Sec) const override; |
279 | uint64_t getSectionAddress(DataRefImpl Sec) const override; |
280 | uint64_t getSectionIndex(DataRefImpl Sec) const override; |
281 | uint64_t getSectionSize(DataRefImpl Sec) const override; |
282 | Expected<ArrayRef<uint8_t>> |
283 | getSectionContents(DataRefImpl Sec) const override; |
284 | uint64_t getSectionAlignment(DataRefImpl Sec) const override; |
285 | bool isSectionCompressed(DataRefImpl Sec) const override; |
286 | bool isSectionText(DataRefImpl Sec) const override; |
287 | bool isSectionData(DataRefImpl Sec) const override; |
288 | bool isSectionBSS(DataRefImpl Sec) const override; |
289 | bool isSectionVirtual(DataRefImpl Sec) const override; |
290 | bool isBerkeleyText(DataRefImpl Sec) const override; |
291 | bool isBerkeleyData(DataRefImpl Sec) const override; |
292 | bool isDebugSection(StringRef SectionName) const override; |
293 | relocation_iterator section_rel_begin(DataRefImpl Sec) const override; |
294 | relocation_iterator section_rel_end(DataRefImpl Sec) const override; |
295 | std::vector<SectionRef> dynamic_relocation_sections() const override; |
296 | Expected<section_iterator> |
297 | getRelocatedSection(DataRefImpl Sec) const override; |
298 | |
299 | void moveRelocationNext(DataRefImpl &Rel) const override; |
300 | uint64_t getRelocationOffset(DataRefImpl Rel) const override; |
301 | symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; |
302 | uint64_t getRelocationType(DataRefImpl Rel) const override; |
303 | void getRelocationTypeName(DataRefImpl Rel, |
304 | SmallVectorImpl<char> &Result) const override; |
305 | |
306 | uint32_t getSectionType(DataRefImpl Sec) const override; |
307 | uint64_t getSectionFlags(DataRefImpl Sec) const override; |
308 | uint64_t getSectionOffset(DataRefImpl Sec) const override; |
309 | StringRef getRelocationTypeName(uint32_t Type) const; |
310 | |
311 | DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const { |
312 | DataRefImpl DRI; |
313 | if (!SymTable) { |
314 | DRI.d.a = 0; |
315 | DRI.d.b = 0; |
316 | return DRI; |
317 | } |
318 | assert(SymTable->sh_type == ELF::SHT_SYMTAB || |
319 | SymTable->sh_type == ELF::SHT_DYNSYM); |
320 | |
321 | auto SectionsOrErr = EF.sections(); |
322 | if (!SectionsOrErr) { |
323 | DRI.d.a = 0; |
324 | DRI.d.b = 0; |
325 | return DRI; |
326 | } |
327 | uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin()); |
328 | unsigned SymTableIndex = |
329 | (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr); |
330 | |
331 | DRI.d.a = SymTableIndex; |
332 | DRI.d.b = SymbolNum; |
333 | return DRI; |
334 | } |
335 | |
336 | const Elf_Shdr *toELFShdrIter(DataRefImpl Sec) const { |
337 | return reinterpret_cast<const Elf_Shdr *>(Sec.p); |
338 | } |
339 | |
340 | DataRefImpl toDRI(const Elf_Shdr *Sec) const { |
341 | DataRefImpl DRI; |
342 | DRI.p = reinterpret_cast<uintptr_t>(Sec); |
343 | return DRI; |
344 | } |
345 | |
346 | DataRefImpl toDRI(const Elf_Dyn *Dyn) const { |
347 | DataRefImpl DRI; |
348 | DRI.p = reinterpret_cast<uintptr_t>(Dyn); |
349 | return DRI; |
350 | } |
351 | |
352 | bool isExportedToOtherDSO(const Elf_Sym *ESym) const { |
353 | unsigned char Binding = ESym->getBinding(); |
354 | unsigned char Visibility = ESym->getVisibility(); |
355 | |
356 | // A symbol is exported if its binding is either GLOBAL or WEAK, and its |
357 | // visibility is either DEFAULT or PROTECTED. All other symbols are not |
358 | // exported. |
359 | return ( |
360 | (Binding == ELF::STB_GLOBAL || Binding == ELF::STB_WEAK || |
361 | Binding == ELF::STB_GNU_UNIQUE) && |
362 | (Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED)); |
363 | } |
364 | |
365 | Error getBuildAttributes(ELFAttributeParser &Attributes) const override { |
366 | auto SectionsOrErr = EF.sections(); |
367 | if (!SectionsOrErr) |
368 | return SectionsOrErr.takeError(); |
369 | |
370 | for (const Elf_Shdr &Sec : *SectionsOrErr) { |
371 | if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES || |
372 | Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) { |
373 | auto ErrorOrContents = EF.getSectionContents(Sec); |
374 | if (!ErrorOrContents) |
375 | return ErrorOrContents.takeError(); |
376 | |
377 | auto Contents = ErrorOrContents.get(); |
378 | if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1) |
379 | return Error::success(); |
380 | |
381 | if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness)) |
382 | return E; |
383 | break; |
384 | } |
385 | } |
386 | return Error::success(); |
387 | } |
388 | |
389 | // This flag is used for classof, to distinguish ELFObjectFile from |
390 | // its subclass. If more subclasses will be created, this flag will |
391 | // have to become an enum. |
392 | bool isDyldELFObject; |
393 | |
394 | public: |
395 | ELFObjectFile(ELFObjectFile<ELFT> &&Other); |
396 | static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object, |
397 | bool InitContent = true); |
398 | |
399 | const Elf_Rel *getRel(DataRefImpl Rel) const; |
400 | const Elf_Rela *getRela(DataRefImpl Rela) const; |
401 | |
402 | Expected<const Elf_Sym *> getSymbol(DataRefImpl Sym) const { |
403 | return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b); |
404 | } |
405 | |
406 | /// Get the relocation section that contains \a Rel. |
407 | const Elf_Shdr *getRelSection(DataRefImpl Rel) const { |
408 | auto RelSecOrErr = EF.getSection(Rel.d.a); |
409 | if (!RelSecOrErr) |
410 | report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message()); |
411 | return *RelSecOrErr; |
412 | } |
413 | |
414 | const Elf_Shdr *getSection(DataRefImpl Sec) const { |
415 | return reinterpret_cast<const Elf_Shdr *>(Sec.p); |
416 | } |
417 | |
418 | basic_symbol_iterator symbol_begin() const override; |
419 | basic_symbol_iterator symbol_end() const override; |
420 | |
421 | elf_symbol_iterator dynamic_symbol_begin() const; |
422 | elf_symbol_iterator dynamic_symbol_end() const; |
423 | |
424 | section_iterator section_begin() const override; |
425 | section_iterator section_end() const override; |
426 | |
427 | Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const override; |
428 | |
429 | uint8_t getBytesInAddress() const override; |
430 | StringRef getFileFormatName() const override; |
431 | Triple::ArchType getArch() const override; |
432 | Expected<uint64_t> getStartAddress() const override; |
433 | |
434 | unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; } |
435 | |
436 | const ELFFile<ELFT> &getELFFile() const { return EF; } |
437 | |
438 | bool isDyldType() const { return isDyldELFObject; } |
439 | static bool classof(const Binary *v) { |
440 | return v->getType() == getELFType(ELFT::TargetEndianness == support::little, |
441 | ELFT::Is64Bits); |
442 | } |
443 | |
444 | elf_symbol_iterator_range getDynamicSymbolIterators() const override; |
445 | |
446 | bool isRelocatableObject() const override; |
447 | }; |
448 | |
449 | using ELF32LEObjectFile = ELFObjectFile<ELF32LE>; |
450 | using ELF64LEObjectFile = ELFObjectFile<ELF64LE>; |
451 | using ELF32BEObjectFile = ELFObjectFile<ELF32BE>; |
452 | using ELF64BEObjectFile = ELFObjectFile<ELF64BE>; |
453 | |
454 | template <class ELFT> |
455 | void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const { |
456 | ++Sym.d.b; |
457 | } |
458 | |
459 | template <class ELFT> Error ELFObjectFile<ELFT>::initContent() { |
460 | auto SectionsOrErr = EF.sections(); |
461 | if (!SectionsOrErr) |
462 | return SectionsOrErr.takeError(); |
463 | |
464 | for (const Elf_Shdr &Sec : *SectionsOrErr) { |
465 | switch (Sec.sh_type) { |
466 | case ELF::SHT_DYNSYM: { |
467 | if (!DotDynSymSec) |
468 | DotDynSymSec = &Sec; |
469 | break; |
470 | } |
471 | case ELF::SHT_SYMTAB: { |
472 | if (!DotSymtabSec) |
473 | DotSymtabSec = &Sec; |
474 | break; |
475 | } |
476 | case ELF::SHT_SYMTAB_SHNDX: { |
477 | if (!DotSymtabShndxSec) |
478 | DotSymtabShndxSec = &Sec; |
479 | break; |
480 | } |
481 | } |
482 | } |
483 | |
484 | ContentValid = true; |
485 | return Error::success(); |
486 | } |
487 | |
488 | template <class ELFT> |
489 | Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const { |
490 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym); |
491 | if (!SymOrErr) |
492 | return SymOrErr.takeError(); |
493 | auto SymTabOrErr = EF.getSection(Sym.d.a); |
494 | if (!SymTabOrErr) |
495 | return SymTabOrErr.takeError(); |
496 | const Elf_Shdr *SymTableSec = *SymTabOrErr; |
497 | auto StrTabOrErr = EF.getSection(SymTableSec->sh_link); |
498 | if (!StrTabOrErr) |
499 | return StrTabOrErr.takeError(); |
500 | const Elf_Shdr *StringTableSec = *StrTabOrErr; |
501 | auto SymStrTabOrErr = EF.getStringTable(*StringTableSec); |
502 | if (!SymStrTabOrErr) |
503 | return SymStrTabOrErr.takeError(); |
504 | Expected<StringRef> Name = (*SymOrErr)->getName(*SymStrTabOrErr); |
505 | if (Name && !Name->empty()) |
506 | return Name; |
507 | |
508 | // If the symbol name is empty use the section name. |
509 | if ((*SymOrErr)->getType() == ELF::STT_SECTION) { |
510 | if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) { |
511 | consumeError(Name.takeError()); |
512 | return (*SecOrErr)->getName(); |
513 | } |
514 | } |
515 | return Name; |
516 | } |
517 | |
518 | template <class ELFT> |
519 | uint64_t ELFObjectFile<ELFT>::getSectionFlags(DataRefImpl Sec) const { |
520 | return getSection(Sec)->sh_flags; |
521 | } |
522 | |
523 | template <class ELFT> |
524 | uint32_t ELFObjectFile<ELFT>::getSectionType(DataRefImpl Sec) const { |
525 | return getSection(Sec)->sh_type; |
526 | } |
527 | |
528 | template <class ELFT> |
529 | uint64_t ELFObjectFile<ELFT>::getSectionOffset(DataRefImpl Sec) const { |
530 | return getSection(Sec)->sh_offset; |
531 | } |
532 | |
533 | template <class ELFT> |
534 | uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const { |
535 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
536 | if (!SymOrErr) |
537 | report_fatal_error(SymOrErr.takeError()); |
538 | |
539 | uint64_t Ret = (*SymOrErr)->st_value; |
540 | if ((*SymOrErr)->st_shndx == ELF::SHN_ABS) |
541 | return Ret; |
542 | |
543 | const Elf_Ehdr & = EF.getHeader(); |
544 | // Clear the ARM/Thumb or microMIPS indicator flag. |
545 | if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) && |
546 | (*SymOrErr)->getType() == ELF::STT_FUNC) |
547 | Ret &= ~1; |
548 | |
549 | return Ret; |
550 | } |
551 | |
552 | template <class ELFT> |
553 | Expected<uint64_t> |
554 | ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const { |
555 | Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb); |
556 | if (!SymbolValueOrErr) |
557 | // TODO: Test this error. |
558 | return SymbolValueOrErr.takeError(); |
559 | |
560 | uint64_t Result = *SymbolValueOrErr; |
561 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
562 | if (!SymOrErr) |
563 | return SymOrErr.takeError(); |
564 | |
565 | switch ((*SymOrErr)->st_shndx) { |
566 | case ELF::SHN_COMMON: |
567 | case ELF::SHN_UNDEF: |
568 | case ELF::SHN_ABS: |
569 | return Result; |
570 | } |
571 | |
572 | auto SymTabOrErr = EF.getSection(Symb.d.a); |
573 | if (!SymTabOrErr) |
574 | return SymTabOrErr.takeError(); |
575 | |
576 | if (EF.getHeader().e_type == ELF::ET_REL) { |
577 | ArrayRef<Elf_Word> ShndxTable; |
578 | if (DotSymtabShndxSec) { |
579 | // TODO: Test this error. |
580 | if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr = |
581 | EF.getSHNDXTable(*DotSymtabShndxSec)) |
582 | ShndxTable = *ShndxTableOrErr; |
583 | else |
584 | return ShndxTableOrErr.takeError(); |
585 | } |
586 | |
587 | Expected<const Elf_Shdr *> SectionOrErr = |
588 | EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable); |
589 | if (!SectionOrErr) |
590 | return SectionOrErr.takeError(); |
591 | const Elf_Shdr *Section = *SectionOrErr; |
592 | if (Section) |
593 | Result += Section->sh_addr; |
594 | } |
595 | |
596 | return Result; |
597 | } |
598 | |
599 | template <class ELFT> |
600 | uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const { |
601 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
602 | if (!SymOrErr) |
603 | report_fatal_error(SymOrErr.takeError()); |
604 | if ((*SymOrErr)->st_shndx == ELF::SHN_COMMON) |
605 | return (*SymOrErr)->st_value; |
606 | return 0; |
607 | } |
608 | |
609 | template <class ELFT> |
610 | uint16_t ELFObjectFile<ELFT>::getEMachine() const { |
611 | return EF.getHeader().e_machine; |
612 | } |
613 | |
614 | template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const { |
615 | return EF.getHeader().e_type; |
616 | } |
617 | |
618 | template <class ELFT> |
619 | uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const { |
620 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym); |
621 | if (!SymOrErr) |
622 | report_fatal_error(SymOrErr.takeError()); |
623 | return (*SymOrErr)->st_size; |
624 | } |
625 | |
626 | template <class ELFT> |
627 | uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const { |
628 | return getSymbolSize(Symb); |
629 | } |
630 | |
631 | template <class ELFT> |
632 | uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const { |
633 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
634 | if (!SymOrErr) |
635 | report_fatal_error(SymOrErr.takeError()); |
636 | return (*SymOrErr)->getBinding(); |
637 | } |
638 | |
639 | template <class ELFT> |
640 | uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const { |
641 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
642 | if (!SymOrErr) |
643 | report_fatal_error(SymOrErr.takeError()); |
644 | return (*SymOrErr)->st_other; |
645 | } |
646 | |
647 | template <class ELFT> |
648 | uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const { |
649 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
650 | if (!SymOrErr) |
651 | report_fatal_error(SymOrErr.takeError()); |
652 | return (*SymOrErr)->getType(); |
653 | } |
654 | |
655 | template <class ELFT> |
656 | Expected<SymbolRef::Type> |
657 | ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const { |
658 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
659 | if (!SymOrErr) |
660 | return SymOrErr.takeError(); |
661 | |
662 | switch ((*SymOrErr)->getType()) { |
663 | case ELF::STT_NOTYPE: |
664 | return SymbolRef::ST_Unknown; |
665 | case ELF::STT_SECTION: |
666 | return SymbolRef::ST_Debug; |
667 | case ELF::STT_FILE: |
668 | return SymbolRef::ST_File; |
669 | case ELF::STT_FUNC: |
670 | return SymbolRef::ST_Function; |
671 | case ELF::STT_OBJECT: |
672 | case ELF::STT_COMMON: |
673 | return SymbolRef::ST_Data; |
674 | case ELF::STT_TLS: |
675 | default: |
676 | return SymbolRef::ST_Other; |
677 | } |
678 | } |
679 | |
680 | template <class ELFT> |
681 | Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const { |
682 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym); |
683 | if (!SymOrErr) |
684 | return SymOrErr.takeError(); |
685 | |
686 | const Elf_Sym *ESym = *SymOrErr; |
687 | uint32_t Result = SymbolRef::SF_None; |
688 | |
689 | if (ESym->getBinding() != ELF::STB_LOCAL) |
690 | Result |= SymbolRef::SF_Global; |
691 | |
692 | if (ESym->getBinding() == ELF::STB_WEAK) |
693 | Result |= SymbolRef::SF_Weak; |
694 | |
695 | if (ESym->st_shndx == ELF::SHN_ABS) |
696 | Result |= SymbolRef::SF_Absolute; |
697 | |
698 | if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION) |
699 | Result |= SymbolRef::SF_FormatSpecific; |
700 | |
701 | if (Expected<typename ELFT::SymRange> SymbolsOrErr = |
702 | EF.symbols(DotSymtabSec)) { |
703 | // Set the SF_FormatSpecific flag for the 0-index null symbol. |
704 | if (ESym == SymbolsOrErr->begin()) |
705 | Result |= SymbolRef::SF_FormatSpecific; |
706 | } else |
707 | // TODO: Test this error. |
708 | return SymbolsOrErr.takeError(); |
709 | |
710 | if (Expected<typename ELFT::SymRange> SymbolsOrErr = |
711 | EF.symbols(DotDynSymSec)) { |
712 | // Set the SF_FormatSpecific flag for the 0-index null symbol. |
713 | if (ESym == SymbolsOrErr->begin()) |
714 | Result |= SymbolRef::SF_FormatSpecific; |
715 | } else |
716 | // TODO: Test this error. |
717 | return SymbolsOrErr.takeError(); |
718 | |
719 | if (EF.getHeader().e_machine == ELF::EM_AARCH64) { |
720 | if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) { |
721 | StringRef Name = *NameOrErr; |
722 | if (Name.startswith("$d" ) || Name.startswith("$x" )) |
723 | Result |= SymbolRef::SF_FormatSpecific; |
724 | } else { |
725 | // TODO: Actually report errors helpfully. |
726 | consumeError(NameOrErr.takeError()); |
727 | } |
728 | } else if (EF.getHeader().e_machine == ELF::EM_ARM) { |
729 | if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) { |
730 | StringRef Name = *NameOrErr; |
731 | if (Name.startswith("$d" ) || Name.startswith("$t" ) || |
732 | Name.startswith("$a" )) |
733 | Result |= SymbolRef::SF_FormatSpecific; |
734 | } else { |
735 | // TODO: Actually report errors helpfully. |
736 | consumeError(NameOrErr.takeError()); |
737 | } |
738 | if (ESym->getType() == ELF::STT_FUNC && (ESym->st_value & 1) == 1) |
739 | Result |= SymbolRef::SF_Thumb; |
740 | } else if (EF.getHeader().e_machine == ELF::EM_RISCV) { |
741 | if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) { |
742 | // Mark empty name symbols used for label differences. |
743 | if (NameOrErr->empty()) |
744 | Result |= SymbolRef::SF_FormatSpecific; |
745 | } else { |
746 | // TODO: Actually report errors helpfully. |
747 | consumeError(NameOrErr.takeError()); |
748 | } |
749 | } |
750 | |
751 | if (ESym->st_shndx == ELF::SHN_UNDEF) |
752 | Result |= SymbolRef::SF_Undefined; |
753 | |
754 | if (ESym->getType() == ELF::STT_COMMON || ESym->st_shndx == ELF::SHN_COMMON) |
755 | Result |= SymbolRef::SF_Common; |
756 | |
757 | if (isExportedToOtherDSO(ESym)) |
758 | Result |= SymbolRef::SF_Exported; |
759 | |
760 | if (ESym->getVisibility() == ELF::STV_HIDDEN) |
761 | Result |= SymbolRef::SF_Hidden; |
762 | |
763 | return Result; |
764 | } |
765 | |
766 | template <class ELFT> |
767 | Expected<section_iterator> |
768 | ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym, |
769 | const Elf_Shdr *SymTab) const { |
770 | ArrayRef<Elf_Word> ShndxTable; |
771 | if (DotSymtabShndxSec) { |
772 | // TODO: Test this error. |
773 | Expected<ArrayRef<Elf_Word>> ShndxTableOrErr = |
774 | EF.getSHNDXTable(*DotSymtabShndxSec); |
775 | if (!ShndxTableOrErr) |
776 | return ShndxTableOrErr.takeError(); |
777 | ShndxTable = *ShndxTableOrErr; |
778 | } |
779 | |
780 | auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable); |
781 | if (!ESecOrErr) |
782 | return ESecOrErr.takeError(); |
783 | |
784 | const Elf_Shdr *ESec = *ESecOrErr; |
785 | if (!ESec) |
786 | return section_end(); |
787 | |
788 | DataRefImpl Sec; |
789 | Sec.p = reinterpret_cast<intptr_t>(ESec); |
790 | return section_iterator(SectionRef(Sec, this)); |
791 | } |
792 | |
793 | template <class ELFT> |
794 | Expected<section_iterator> |
795 | ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const { |
796 | Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb); |
797 | if (!SymOrErr) |
798 | return SymOrErr.takeError(); |
799 | |
800 | auto SymTabOrErr = EF.getSection(Symb.d.a); |
801 | if (!SymTabOrErr) |
802 | return SymTabOrErr.takeError(); |
803 | return getSymbolSection(*SymOrErr, *SymTabOrErr); |
804 | } |
805 | |
806 | template <class ELFT> |
807 | void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const { |
808 | const Elf_Shdr *ESec = getSection(Sec); |
809 | Sec = toDRI(++ESec); |
810 | } |
811 | |
812 | template <class ELFT> |
813 | Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const { |
814 | return EF.getSectionName(*getSection(Sec)); |
815 | } |
816 | |
817 | template <class ELFT> |
818 | uint64_t ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec) const { |
819 | return getSection(Sec)->sh_addr; |
820 | } |
821 | |
822 | template <class ELFT> |
823 | uint64_t ELFObjectFile<ELFT>::getSectionIndex(DataRefImpl Sec) const { |
824 | auto SectionsOrErr = EF.sections(); |
825 | handleAllErrors(std::move(SectionsOrErr.takeError()), |
826 | [](const ErrorInfoBase &) { |
827 | llvm_unreachable("unable to get section index" ); |
828 | }); |
829 | const Elf_Shdr *First = SectionsOrErr->begin(); |
830 | return getSection(Sec) - First; |
831 | } |
832 | |
833 | template <class ELFT> |
834 | uint64_t ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec) const { |
835 | return getSection(Sec)->sh_size; |
836 | } |
837 | |
838 | template <class ELFT> |
839 | Expected<ArrayRef<uint8_t>> |
840 | ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const { |
841 | const Elf_Shdr *EShdr = getSection(Sec); |
842 | if (EShdr->sh_type == ELF::SHT_NOBITS) |
843 | return makeArrayRef((const uint8_t *)base(), 0); |
844 | if (Error E = |
845 | checkOffset(getMemoryBufferRef(), |
846 | (uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size)) |
847 | return std::move(E); |
848 | return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset, |
849 | EShdr->sh_size); |
850 | } |
851 | |
852 | template <class ELFT> |
853 | uint64_t ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec) const { |
854 | return getSection(Sec)->sh_addralign; |
855 | } |
856 | |
857 | template <class ELFT> |
858 | bool ELFObjectFile<ELFT>::isSectionCompressed(DataRefImpl Sec) const { |
859 | return getSection(Sec)->sh_flags & ELF::SHF_COMPRESSED; |
860 | } |
861 | |
862 | template <class ELFT> |
863 | bool ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec) const { |
864 | return getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR; |
865 | } |
866 | |
867 | template <class ELFT> |
868 | bool ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec) const { |
869 | const Elf_Shdr *EShdr = getSection(Sec); |
870 | return EShdr->sh_type == ELF::SHT_PROGBITS && |
871 | EShdr->sh_flags & ELF::SHF_ALLOC && |
872 | !(EShdr->sh_flags & ELF::SHF_EXECINSTR); |
873 | } |
874 | |
875 | template <class ELFT> |
876 | bool ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec) const { |
877 | const Elf_Shdr *EShdr = getSection(Sec); |
878 | return EShdr->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) && |
879 | EShdr->sh_type == ELF::SHT_NOBITS; |
880 | } |
881 | |
882 | template <class ELFT> |
883 | std::vector<SectionRef> |
884 | ELFObjectFile<ELFT>::dynamic_relocation_sections() const { |
885 | std::vector<SectionRef> Res; |
886 | std::vector<uintptr_t> Offsets; |
887 | |
888 | auto SectionsOrErr = EF.sections(); |
889 | if (!SectionsOrErr) |
890 | return Res; |
891 | |
892 | for (const Elf_Shdr &Sec : *SectionsOrErr) { |
893 | if (Sec.sh_type != ELF::SHT_DYNAMIC) |
894 | continue; |
895 | Elf_Dyn *Dynamic = |
896 | reinterpret_cast<Elf_Dyn *>((uintptr_t)base() + Sec.sh_offset); |
897 | for (; Dynamic->d_tag != ELF::DT_NULL; Dynamic++) { |
898 | if (Dynamic->d_tag == ELF::DT_REL || Dynamic->d_tag == ELF::DT_RELA || |
899 | Dynamic->d_tag == ELF::DT_JMPREL) { |
900 | Offsets.push_back(Dynamic->d_un.d_val); |
901 | } |
902 | } |
903 | } |
904 | for (const Elf_Shdr &Sec : *SectionsOrErr) { |
905 | if (is_contained(Offsets, Sec.sh_addr)) |
906 | Res.emplace_back(toDRI(&Sec), this); |
907 | } |
908 | return Res; |
909 | } |
910 | |
911 | template <class ELFT> |
912 | bool ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec) const { |
913 | return getSection(Sec)->sh_type == ELF::SHT_NOBITS; |
914 | } |
915 | |
916 | template <class ELFT> |
917 | bool ELFObjectFile<ELFT>::isBerkeleyText(DataRefImpl Sec) const { |
918 | return getSection(Sec)->sh_flags & ELF::SHF_ALLOC && |
919 | (getSection(Sec)->sh_flags & ELF::SHF_EXECINSTR || |
920 | !(getSection(Sec)->sh_flags & ELF::SHF_WRITE)); |
921 | } |
922 | |
923 | template <class ELFT> |
924 | bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const { |
925 | const Elf_Shdr *EShdr = getSection(Sec); |
926 | return !isBerkeleyText(Sec) && EShdr->sh_type != ELF::SHT_NOBITS && |
927 | EShdr->sh_flags & ELF::SHF_ALLOC; |
928 | } |
929 | |
930 | template <class ELFT> |
931 | bool ELFObjectFile<ELFT>::isDebugSection(StringRef SectionName) const { |
932 | return SectionName.startswith(".debug" ) || |
933 | SectionName.startswith(".zdebug" ) || SectionName == ".gdb_index" ; |
934 | } |
935 | |
936 | template <class ELFT> |
937 | relocation_iterator |
938 | ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { |
939 | DataRefImpl RelData; |
940 | auto SectionsOrErr = EF.sections(); |
941 | if (!SectionsOrErr) |
942 | return relocation_iterator(RelocationRef()); |
943 | uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin()); |
944 | RelData.d.a = (Sec.p - SHT) / EF.getHeader().e_shentsize; |
945 | RelData.d.b = 0; |
946 | return relocation_iterator(RelocationRef(RelData, this)); |
947 | } |
948 | |
949 | template <class ELFT> |
950 | relocation_iterator |
951 | ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { |
952 | const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); |
953 | relocation_iterator Begin = section_rel_begin(Sec); |
954 | if (S->sh_type != ELF::SHT_RELA && S->sh_type != ELF::SHT_REL) |
955 | return Begin; |
956 | DataRefImpl RelData = Begin->getRawDataRefImpl(); |
957 | const Elf_Shdr *RelSec = getRelSection(RelData); |
958 | |
959 | // Error check sh_link here so that getRelocationSymbol can just use it. |
960 | auto SymSecOrErr = EF.getSection(RelSec->sh_link); |
961 | if (!SymSecOrErr) |
962 | report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message()); |
963 | |
964 | RelData.d.b += S->sh_size / S->sh_entsize; |
965 | return relocation_iterator(RelocationRef(RelData, this)); |
966 | } |
967 | |
968 | template <class ELFT> |
969 | Expected<section_iterator> |
970 | ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { |
971 | if (EF.getHeader().e_type != ELF::ET_REL) |
972 | return section_end(); |
973 | |
974 | const Elf_Shdr *EShdr = getSection(Sec); |
975 | uintX_t Type = EShdr->sh_type; |
976 | if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) |
977 | return section_end(); |
978 | |
979 | Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info); |
980 | if (!SecOrErr) |
981 | return SecOrErr.takeError(); |
982 | return section_iterator(SectionRef(toDRI(*SecOrErr), this)); |
983 | } |
984 | |
985 | // Relocations |
986 | template <class ELFT> |
987 | void ELFObjectFile<ELFT>::moveRelocationNext(DataRefImpl &Rel) const { |
988 | ++Rel.d.b; |
989 | } |
990 | |
991 | template <class ELFT> |
992 | symbol_iterator |
993 | ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { |
994 | uint32_t symbolIdx; |
995 | const Elf_Shdr *sec = getRelSection(Rel); |
996 | if (sec->sh_type == ELF::SHT_REL) |
997 | symbolIdx = getRel(Rel)->getSymbol(EF.isMips64EL()); |
998 | else |
999 | symbolIdx = getRela(Rel)->getSymbol(EF.isMips64EL()); |
1000 | if (!symbolIdx) |
1001 | return symbol_end(); |
1002 | |
1003 | // FIXME: error check symbolIdx |
1004 | DataRefImpl SymbolData; |
1005 | SymbolData.d.a = sec->sh_link; |
1006 | SymbolData.d.b = symbolIdx; |
1007 | return symbol_iterator(SymbolRef(SymbolData, this)); |
1008 | } |
1009 | |
1010 | template <class ELFT> |
1011 | uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const { |
1012 | const Elf_Shdr *sec = getRelSection(Rel); |
1013 | if (sec->sh_type == ELF::SHT_REL) |
1014 | return getRel(Rel)->r_offset; |
1015 | |
1016 | return getRela(Rel)->r_offset; |
1017 | } |
1018 | |
1019 | template <class ELFT> |
1020 | uint64_t ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel) const { |
1021 | const Elf_Shdr *sec = getRelSection(Rel); |
1022 | if (sec->sh_type == ELF::SHT_REL) |
1023 | return getRel(Rel)->getType(EF.isMips64EL()); |
1024 | else |
1025 | return getRela(Rel)->getType(EF.isMips64EL()); |
1026 | } |
1027 | |
1028 | template <class ELFT> |
1029 | StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { |
1030 | return getELFRelocationTypeName(EF.getHeader().e_machine, Type); |
1031 | } |
1032 | |
1033 | template <class ELFT> |
1034 | void ELFObjectFile<ELFT>::getRelocationTypeName( |
1035 | DataRefImpl Rel, SmallVectorImpl<char> &Result) const { |
1036 | uint32_t type = getRelocationType(Rel); |
1037 | EF.getRelocationTypeName(type, Result); |
1038 | } |
1039 | |
1040 | template <class ELFT> |
1041 | Expected<int64_t> |
1042 | ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const { |
1043 | if (getRelSection(Rel)->sh_type != ELF::SHT_RELA) |
1044 | return createError("Section is not SHT_RELA" ); |
1045 | return (int64_t)getRela(Rel)->r_addend; |
1046 | } |
1047 | |
1048 | template <class ELFT> |
1049 | const typename ELFObjectFile<ELFT>::Elf_Rel * |
1050 | ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { |
1051 | assert(getRelSection(Rel)->sh_type == ELF::SHT_REL); |
1052 | auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); |
1053 | if (!Ret) |
1054 | report_fatal_error(errorToErrorCode(Ret.takeError()).message()); |
1055 | return *Ret; |
1056 | } |
1057 | |
1058 | template <class ELFT> |
1059 | const typename ELFObjectFile<ELFT>::Elf_Rela * |
1060 | ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { |
1061 | assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA); |
1062 | auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); |
1063 | if (!Ret) |
1064 | report_fatal_error(errorToErrorCode(Ret.takeError()).message()); |
1065 | return *Ret; |
1066 | } |
1067 | |
1068 | template <class ELFT> |
1069 | Expected<ELFObjectFile<ELFT>> |
1070 | ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) { |
1071 | auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer()); |
1072 | if (Error E = EFOrErr.takeError()) |
1073 | return std::move(E); |
1074 | |
1075 | ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr, |
1076 | nullptr}; |
1077 | if (InitContent) |
1078 | if (Error E = Obj.initContent()) |
1079 | return std::move(E); |
1080 | return std::move(Obj); |
1081 | } |
1082 | |
1083 | template <class ELFT> |
1084 | ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF, |
1085 | const Elf_Shdr *DotDynSymSec, |
1086 | const Elf_Shdr *DotSymtabSec, |
1087 | const Elf_Shdr *DotSymtabShndx) |
1088 | : ELFObjectFileBase( |
1089 | getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits), |
1090 | Object), |
1091 | EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec), |
1092 | DotSymtabShndxSec(DotSymtabShndx) {} |
1093 | |
1094 | template <class ELFT> |
1095 | ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other) |
1096 | : ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec, |
1097 | Other.DotSymtabSec, Other.DotSymtabShndxSec) {} |
1098 | |
1099 | template <class ELFT> |
1100 | basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const { |
1101 | DataRefImpl Sym = |
1102 | toDRI(DotSymtabSec, |
1103 | DotSymtabSec && DotSymtabSec->sh_size >= sizeof(Elf_Sym) ? 1 : 0); |
1104 | return basic_symbol_iterator(SymbolRef(Sym, this)); |
1105 | } |
1106 | |
1107 | template <class ELFT> |
1108 | basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const { |
1109 | const Elf_Shdr *SymTab = DotSymtabSec; |
1110 | if (!SymTab) |
1111 | return symbol_begin(); |
1112 | DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); |
1113 | return basic_symbol_iterator(SymbolRef(Sym, this)); |
1114 | } |
1115 | |
1116 | template <class ELFT> |
1117 | elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { |
1118 | if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym)) |
1119 | // Ignore errors here where the dynsym is empty or sh_size less than the |
1120 | // size of one symbol. These should be handled elsewhere. |
1121 | return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this)); |
1122 | // Skip 0-index NULL symbol. |
1123 | return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this)); |
1124 | } |
1125 | |
1126 | template <class ELFT> |
1127 | elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { |
1128 | const Elf_Shdr *SymTab = DotDynSymSec; |
1129 | if (!SymTab) |
1130 | return dynamic_symbol_begin(); |
1131 | DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); |
1132 | return basic_symbol_iterator(SymbolRef(Sym, this)); |
1133 | } |
1134 | |
1135 | template <class ELFT> |
1136 | section_iterator ELFObjectFile<ELFT>::section_begin() const { |
1137 | auto SectionsOrErr = EF.sections(); |
1138 | if (!SectionsOrErr) |
1139 | return section_iterator(SectionRef()); |
1140 | return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this)); |
1141 | } |
1142 | |
1143 | template <class ELFT> |
1144 | section_iterator ELFObjectFile<ELFT>::section_end() const { |
1145 | auto SectionsOrErr = EF.sections(); |
1146 | if (!SectionsOrErr) |
1147 | return section_iterator(SectionRef()); |
1148 | return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this)); |
1149 | } |
1150 | |
1151 | template <class ELFT> |
1152 | uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const { |
1153 | return ELFT::Is64Bits ? 8 : 4; |
1154 | } |
1155 | |
1156 | template <class ELFT> |
1157 | StringRef ELFObjectFile<ELFT>::getFileFormatName() const { |
1158 | bool IsLittleEndian = ELFT::TargetEndianness == support::little; |
1159 | switch (EF.getHeader().e_ident[ELF::EI_CLASS]) { |
1160 | case ELF::ELFCLASS32: |
1161 | switch (EF.getHeader().e_machine) { |
1162 | case ELF::EM_68K: |
1163 | return "elf32-m68k" ; |
1164 | case ELF::EM_386: |
1165 | return "elf32-i386" ; |
1166 | case ELF::EM_IAMCU: |
1167 | return "elf32-iamcu" ; |
1168 | case ELF::EM_X86_64: |
1169 | return "elf32-x86-64" ; |
1170 | case ELF::EM_ARM: |
1171 | return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm" ); |
1172 | case ELF::EM_AVR: |
1173 | return "elf32-avr" ; |
1174 | case ELF::EM_HEXAGON: |
1175 | return "elf32-hexagon" ; |
1176 | case ELF::EM_LANAI: |
1177 | return "elf32-lanai" ; |
1178 | case ELF::EM_MIPS: |
1179 | return "elf32-mips" ; |
1180 | case ELF::EM_MSP430: |
1181 | return "elf32-msp430" ; |
1182 | case ELF::EM_PPC: |
1183 | return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc" ); |
1184 | case ELF::EM_RISCV: |
1185 | return "elf32-littleriscv" ; |
1186 | case ELF::EM_CSKY: |
1187 | return "elf32-csky" ; |
1188 | case ELF::EM_SPARC: |
1189 | case ELF::EM_SPARC32PLUS: |
1190 | return "elf32-sparc" ; |
1191 | case ELF::EM_AMDGPU: |
1192 | return "elf32-amdgpu" ; |
1193 | default: |
1194 | return "elf32-unknown" ; |
1195 | } |
1196 | case ELF::ELFCLASS64: |
1197 | switch (EF.getHeader().e_machine) { |
1198 | case ELF::EM_386: |
1199 | return "elf64-i386" ; |
1200 | case ELF::EM_X86_64: |
1201 | return "elf64-x86-64" ; |
1202 | case ELF::EM_AARCH64: |
1203 | return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64" ); |
1204 | case ELF::EM_PPC64: |
1205 | return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc" ); |
1206 | case ELF::EM_RISCV: |
1207 | return "elf64-littleriscv" ; |
1208 | case ELF::EM_S390: |
1209 | return "elf64-s390" ; |
1210 | case ELF::EM_SPARCV9: |
1211 | return "elf64-sparc" ; |
1212 | case ELF::EM_MIPS: |
1213 | return "elf64-mips" ; |
1214 | case ELF::EM_AMDGPU: |
1215 | return "elf64-amdgpu" ; |
1216 | case ELF::EM_BPF: |
1217 | return "elf64-bpf" ; |
1218 | case ELF::EM_VE: |
1219 | return "elf64-ve" ; |
1220 | default: |
1221 | return "elf64-unknown" ; |
1222 | } |
1223 | default: |
1224 | // FIXME: Proper error handling. |
1225 | report_fatal_error("Invalid ELFCLASS!" ); |
1226 | } |
1227 | } |
1228 | |
1229 | template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const { |
1230 | bool IsLittleEndian = ELFT::TargetEndianness == support::little; |
1231 | switch (EF.getHeader().e_machine) { |
1232 | case ELF::EM_68K: |
1233 | return Triple::m68k; |
1234 | case ELF::EM_386: |
1235 | case ELF::EM_IAMCU: |
1236 | return Triple::x86; |
1237 | case ELF::EM_X86_64: |
1238 | return Triple::x86_64; |
1239 | case ELF::EM_AARCH64: |
1240 | return IsLittleEndian ? Triple::aarch64 : Triple::aarch64_be; |
1241 | case ELF::EM_ARM: |
1242 | return Triple::arm; |
1243 | case ELF::EM_AVR: |
1244 | return Triple::avr; |
1245 | case ELF::EM_HEXAGON: |
1246 | return Triple::hexagon; |
1247 | case ELF::EM_LANAI: |
1248 | return Triple::lanai; |
1249 | case ELF::EM_MIPS: |
1250 | switch (EF.getHeader().e_ident[ELF::EI_CLASS]) { |
1251 | case ELF::ELFCLASS32: |
1252 | return IsLittleEndian ? Triple::mipsel : Triple::mips; |
1253 | case ELF::ELFCLASS64: |
1254 | return IsLittleEndian ? Triple::mips64el : Triple::mips64; |
1255 | default: |
1256 | report_fatal_error("Invalid ELFCLASS!" ); |
1257 | } |
1258 | case ELF::EM_MSP430: |
1259 | return Triple::msp430; |
1260 | case ELF::EM_PPC: |
1261 | return IsLittleEndian ? Triple::ppcle : Triple::ppc; |
1262 | case ELF::EM_PPC64: |
1263 | return IsLittleEndian ? Triple::ppc64le : Triple::ppc64; |
1264 | case ELF::EM_RISCV: |
1265 | switch (EF.getHeader().e_ident[ELF::EI_CLASS]) { |
1266 | case ELF::ELFCLASS32: |
1267 | return Triple::riscv32; |
1268 | case ELF::ELFCLASS64: |
1269 | return Triple::riscv64; |
1270 | default: |
1271 | report_fatal_error("Invalid ELFCLASS!" ); |
1272 | } |
1273 | case ELF::EM_S390: |
1274 | return Triple::systemz; |
1275 | |
1276 | case ELF::EM_SPARC: |
1277 | case ELF::EM_SPARC32PLUS: |
1278 | return IsLittleEndian ? Triple::sparcel : Triple::sparc; |
1279 | case ELF::EM_SPARCV9: |
1280 | return Triple::sparcv9; |
1281 | |
1282 | case ELF::EM_AMDGPU: { |
1283 | if (!IsLittleEndian) |
1284 | return Triple::UnknownArch; |
1285 | |
1286 | unsigned MACH = EF.getHeader().e_flags & ELF::EF_AMDGPU_MACH; |
1287 | if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST && |
1288 | MACH <= ELF::EF_AMDGPU_MACH_R600_LAST) |
1289 | return Triple::r600; |
1290 | if (MACH >= ELF::EF_AMDGPU_MACH_AMDGCN_FIRST && |
1291 | MACH <= ELF::EF_AMDGPU_MACH_AMDGCN_LAST) |
1292 | return Triple::amdgcn; |
1293 | |
1294 | return Triple::UnknownArch; |
1295 | } |
1296 | |
1297 | case ELF::EM_BPF: |
1298 | return IsLittleEndian ? Triple::bpfel : Triple::bpfeb; |
1299 | |
1300 | case ELF::EM_VE: |
1301 | return Triple::ve; |
1302 | case ELF::EM_CSKY: |
1303 | return Triple::csky; |
1304 | default: |
1305 | return Triple::UnknownArch; |
1306 | } |
1307 | } |
1308 | |
1309 | template <class ELFT> |
1310 | Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const { |
1311 | return EF.getHeader().e_entry; |
1312 | } |
1313 | |
1314 | template <class ELFT> |
1315 | ELFObjectFileBase::elf_symbol_iterator_range |
1316 | ELFObjectFile<ELFT>::getDynamicSymbolIterators() const { |
1317 | return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); |
1318 | } |
1319 | |
1320 | template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const { |
1321 | return EF.getHeader().e_type == ELF::ET_REL; |
1322 | } |
1323 | |
1324 | } // end namespace object |
1325 | } // end namespace llvm |
1326 | |
1327 | #endif // LLVM_OBJECT_ELFOBJECTFILE_H |
1328 | |