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