LLVM 17.0.0git
ELF.cpp
Go to the documentation of this file.
1//===- ELF.cpp - ELF object file implementation ---------------------------===//
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#include "llvm/Object/ELF.h"
12
13using namespace llvm;
14using namespace object;
15
16#define STRINGIFY_ENUM_CASE(ns, name) \
17 case ns::name: \
18 return #name;
19
20#define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
21
23 uint32_t Type) {
24 switch (Machine) {
25 case ELF::EM_68K:
26 switch (Type) {
27#include "llvm/BinaryFormat/ELFRelocs/M68k.def"
28 default:
29 break;
30 }
31 break;
32 case ELF::EM_X86_64:
33 switch (Type) {
34#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
35 default:
36 break;
37 }
38 break;
39 case ELF::EM_386:
40 case ELF::EM_IAMCU:
41 switch (Type) {
42#include "llvm/BinaryFormat/ELFRelocs/i386.def"
43 default:
44 break;
45 }
46 break;
47 case ELF::EM_MIPS:
48 switch (Type) {
49#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
50 default:
51 break;
52 }
53 break;
54 case ELF::EM_AARCH64:
55 switch (Type) {
56#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
57 default:
58 break;
59 }
60 break;
61 case ELF::EM_ARM:
62 switch (Type) {
63#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
64 default:
65 break;
66 }
67 break;
70 switch (Type) {
71#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
72 default:
73 break;
74 }
75 break;
76 case ELF::EM_AVR:
77 switch (Type) {
78#include "llvm/BinaryFormat/ELFRelocs/AVR.def"
79 default:
80 break;
81 }
82 break;
83 case ELF::EM_HEXAGON:
84 switch (Type) {
85#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
86 default:
87 break;
88 }
89 break;
90 case ELF::EM_LANAI:
91 switch (Type) {
92#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
93 default:
94 break;
95 }
96 break;
97 case ELF::EM_PPC:
98 switch (Type) {
99#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
100 default:
101 break;
102 }
103 break;
104 case ELF::EM_PPC64:
105 switch (Type) {
106#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
107 default:
108 break;
109 }
110 break;
111 case ELF::EM_RISCV:
112 switch (Type) {
113#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
114 default:
115 break;
116 }
117 break;
118 case ELF::EM_S390:
119 switch (Type) {
120#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
121 default:
122 break;
123 }
124 break;
125 case ELF::EM_SPARC:
127 case ELF::EM_SPARCV9:
128 switch (Type) {
129#include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
130 default:
131 break;
132 }
133 break;
134 case ELF::EM_AMDGPU:
135 switch (Type) {
136#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
137 default:
138 break;
139 }
140 break;
141 case ELF::EM_BPF:
142 switch (Type) {
143#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
144 default:
145 break;
146 }
147 break;
148 case ELF::EM_MSP430:
149 switch (Type) {
150#include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
151 default:
152 break;
153 }
154 break;
155 case ELF::EM_VE:
156 switch (Type) {
157#include "llvm/BinaryFormat/ELFRelocs/VE.def"
158 default:
159 break;
160 }
161 break;
162 case ELF::EM_CSKY:
163 switch (Type) {
164#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
165 default:
166 break;
167 }
168 break;
170 switch (Type) {
171#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
172 default:
173 break;
174 }
175 break;
176 case ELF::EM_XTENSA:
177 switch (Type) {
178#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
179 default:
180 break;
181 }
182 break;
183 default:
184 break;
185 }
186 return "Unknown";
187}
188
189#undef ELF_RELOC
190
192 switch (Machine) {
193 case ELF::EM_X86_64:
194 return ELF::R_X86_64_RELATIVE;
195 case ELF::EM_386:
196 case ELF::EM_IAMCU:
197 return ELF::R_386_RELATIVE;
198 case ELF::EM_MIPS:
199 break;
200 case ELF::EM_AARCH64:
201 return ELF::R_AARCH64_RELATIVE;
202 case ELF::EM_ARM:
203 return ELF::R_ARM_RELATIVE;
206 return ELF::R_ARC_RELATIVE;
207 case ELF::EM_AVR:
208 break;
209 case ELF::EM_HEXAGON:
210 return ELF::R_HEX_RELATIVE;
211 case ELF::EM_LANAI:
212 break;
213 case ELF::EM_PPC:
214 break;
215 case ELF::EM_PPC64:
216 return ELF::R_PPC64_RELATIVE;
217 case ELF::EM_RISCV:
218 return ELF::R_RISCV_RELATIVE;
219 case ELF::EM_S390:
220 return ELF::R_390_RELATIVE;
221 case ELF::EM_SPARC:
223 case ELF::EM_SPARCV9:
224 return ELF::R_SPARC_RELATIVE;
225 case ELF::EM_CSKY:
226 return ELF::R_CKCORE_RELATIVE;
227 case ELF::EM_VE:
228 return ELF::R_VE_RELATIVE;
229 case ELF::EM_AMDGPU:
230 break;
231 case ELF::EM_BPF:
232 break;
234 return ELF::R_LARCH_RELATIVE;
235 default:
236 break;
237 }
238 return 0;
239}
240
242 switch (Machine) {
243 case ELF::EM_ARM:
244 switch (Type) {
245 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
246 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
247 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
248 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
249 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
250 }
251 break;
252 case ELF::EM_HEXAGON:
253 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED); }
254 break;
255 case ELF::EM_X86_64:
256 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
257 break;
258 case ELF::EM_MIPS:
260 switch (Type) {
261 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
262 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
263 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
264 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
265 }
266 break;
267 case ELF::EM_MSP430:
268 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); }
269 break;
270 case ELF::EM_RISCV:
271 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }
272 break;
273 default:
274 break;
275 }
276
277 switch (Type) {
278 STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
279 STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
280 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
281 STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
282 STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
283 STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
284 STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
285 STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
286 STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
287 STRINGIFY_ENUM_CASE(ELF, SHT_REL);
288 STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
289 STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
290 STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
291 STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
292 STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
293 STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
294 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
295 STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
296 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
297 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
298 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
299 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
300 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
301 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
302 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);
303 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES);
304 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);
305 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);
306 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);
307 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0);
308 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);
309 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING);
310 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
311 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
312 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
313 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
314 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
315 default:
316 return "Unknown";
317 }
318}
319
320template <class ELFT>
321std::vector<typename ELFT::Rel>
322ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
323 // This function decodes the contents of an SHT_RELR packed relocation
324 // section.
325 //
326 // Proposal for adding SHT_RELR sections to generic-abi is here:
327 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
328 //
329 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
330 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
331 //
332 // i.e. start with an address, followed by any number of bitmaps. The address
333 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
334 // relocations each, at subsequent offsets following the last address entry.
335 //
336 // The bitmap entries must have 1 in the least significant bit. The assumption
337 // here is that an address cannot have 1 in lsb. Odd addresses are not
338 // supported.
339 //
340 // Excluding the least significant bit in the bitmap, each non-zero bit in
341 // the bitmap represents a relocation to be applied to a corresponding machine
342 // word that follows the base address word. The second least significant bit
343 // represents the machine word immediately following the initial address, and
344 // each bit that follows represents the next word, in linear order. As such,
345 // a single bitmap can encode up to 31 relocations in a 32-bit object, and
346 // 63 relocations in a 64-bit object.
347 //
348 // This encoding has a couple of interesting properties:
349 // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
350 // even means address, odd means bitmap.
351 // 2. Just a simple list of addresses is a valid encoding.
352
353 Elf_Rel Rel;
354 Rel.r_info = 0;
355 Rel.setType(getRelativeRelocationType(), false);
356 std::vector<Elf_Rel> Relocs;
357
358 // Word type: uint32_t for Elf32, and uint64_t for Elf64.
359 using Addr = typename ELFT::uint;
360
361 Addr Base = 0;
362 for (Elf_Relr R : relrs) {
363 typename ELFT::uint Entry = R;
364 if ((Entry & 1) == 0) {
365 // Even entry: encodes the offset for next relocation.
366 Rel.r_offset = Entry;
367 Relocs.push_back(Rel);
368 // Set base offset for subsequent bitmap entries.
369 Base = Entry + sizeof(Addr);
370 } else {
371 // Odd entry: encodes bitmap for relocations starting at base.
372 for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr))
373 if ((Entry & 1) != 0) {
374 Rel.r_offset = Offset;
375 Relocs.push_back(Rel);
376 }
377 Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr);
378 }
379 }
380
381 return Relocs;
382}
383
384template <class ELFT>
386ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
387 // This function reads relocations in Android's packed relocation format,
388 // which is based on SLEB128 and delta encoding.
389 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
390 if (!ContentsOrErr)
391 return ContentsOrErr.takeError();
392 ArrayRef<uint8_t> Content = *ContentsOrErr;
393 if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||
394 Content[2] != 'S' || Content[3] != '2')
395 return createError("invalid packed relocation header");
396 DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
397 DataExtractor::Cursor Cur(/*Offset=*/4);
398
399 uint64_t NumRelocs = Data.getSLEB128(Cur);
400 uint64_t Offset = Data.getSLEB128(Cur);
401 uint64_t Addend = 0;
402
403 if (!Cur)
404 return std::move(Cur.takeError());
405
406 std::vector<Elf_Rela> Relocs;
407 Relocs.reserve(NumRelocs);
408 while (NumRelocs) {
409 uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);
410 if (!Cur)
411 return std::move(Cur.takeError());
412 if (NumRelocsInGroup > NumRelocs)
413 return createError("relocation group unexpectedly large");
414 NumRelocs -= NumRelocsInGroup;
415
416 uint64_t GroupFlags = Data.getSLEB128(Cur);
417 bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
418 bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
419 bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
420 bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
421
422 uint64_t GroupOffsetDelta;
423 if (GroupedByOffsetDelta)
424 GroupOffsetDelta = Data.getSLEB128(Cur);
425
426 uint64_t GroupRInfo;
427 if (GroupedByInfo)
428 GroupRInfo = Data.getSLEB128(Cur);
429
430 if (GroupedByAddend && GroupHasAddend)
431 Addend += Data.getSLEB128(Cur);
432
433 if (!GroupHasAddend)
434 Addend = 0;
435
436 for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {
437 Elf_Rela R;
438 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);
439 R.r_offset = Offset;
440 R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);
441 if (GroupHasAddend && !GroupedByAddend)
442 Addend += Data.getSLEB128(Cur);
443 R.r_addend = Addend;
444 Relocs.push_back(R);
445 }
446 if (!Cur)
447 return std::move(Cur.takeError());
448 }
449
450 return Relocs;
451}
452
453template <class ELFT>
454std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
455 uint64_t Type) const {
456#define DYNAMIC_STRINGIFY_ENUM(tag, value) \
457 case value: \
458 return #tag;
459
460#define DYNAMIC_TAG(n, v)
461 switch (Arch) {
462 case ELF::EM_AARCH64:
463 switch (Type) {
464#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
465#include "llvm/BinaryFormat/DynamicTags.def"
466#undef AARCH64_DYNAMIC_TAG
467 }
468 break;
469
470 case ELF::EM_HEXAGON:
471 switch (Type) {
472#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
473#include "llvm/BinaryFormat/DynamicTags.def"
474#undef HEXAGON_DYNAMIC_TAG
475 }
476 break;
477
478 case ELF::EM_MIPS:
479 switch (Type) {
480#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
481#include "llvm/BinaryFormat/DynamicTags.def"
482#undef MIPS_DYNAMIC_TAG
483 }
484 break;
485
486 case ELF::EM_PPC:
487 switch (Type) {
488#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
489#include "llvm/BinaryFormat/DynamicTags.def"
490#undef PPC_DYNAMIC_TAG
491 }
492 break;
493
494 case ELF::EM_PPC64:
495 switch (Type) {
496#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
497#include "llvm/BinaryFormat/DynamicTags.def"
498#undef PPC64_DYNAMIC_TAG
499 }
500 break;
501
502 case ELF::EM_RISCV:
503 switch (Type) {
504#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
505#include "llvm/BinaryFormat/DynamicTags.def"
506#undef RISCV_DYNAMIC_TAG
507 }
508 break;
509 }
510#undef DYNAMIC_TAG
511 switch (Type) {
512// Now handle all dynamic tags except the architecture specific ones
513#define AARCH64_DYNAMIC_TAG(name, value)
514#define MIPS_DYNAMIC_TAG(name, value)
515#define HEXAGON_DYNAMIC_TAG(name, value)
516#define PPC_DYNAMIC_TAG(name, value)
517#define PPC64_DYNAMIC_TAG(name, value)
518#define RISCV_DYNAMIC_TAG(name, value)
519// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
520#define DYNAMIC_TAG_MARKER(name, value)
521#define DYNAMIC_TAG(name, value) case value: return #name;
522#include "llvm/BinaryFormat/DynamicTags.def"
523#undef DYNAMIC_TAG
524#undef AARCH64_DYNAMIC_TAG
525#undef MIPS_DYNAMIC_TAG
526#undef HEXAGON_DYNAMIC_TAG
527#undef PPC_DYNAMIC_TAG
528#undef PPC64_DYNAMIC_TAG
529#undef RISCV_DYNAMIC_TAG
530#undef DYNAMIC_TAG_MARKER
531#undef DYNAMIC_STRINGIFY_ENUM
532 default:
533 return "<unknown:>0x" + utohexstr(Type, true);
534 }
535}
536
537template <class ELFT>
539 return getDynamicTagAsString(getHeader().e_machine, Type);
540}
541
542template <class ELFT>
545
546 auto ProgramHeadersOrError = program_headers();
547 if (!ProgramHeadersOrError)
548 return ProgramHeadersOrError.takeError();
549
550 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
551 if (Phdr.p_type == ELF::PT_DYNAMIC) {
552 Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(base() + Phdr.p_offset),
553 Phdr.p_filesz / sizeof(Elf_Dyn));
554 break;
555 }
556 }
557
558 // If we can't find the dynamic section in the program headers, we just fall
559 // back on the sections.
560 if (Dyn.empty()) {
561 auto SectionsOrError = sections();
562 if (!SectionsOrError)
563 return SectionsOrError.takeError();
564
565 for (const Elf_Shdr &Sec : *SectionsOrError) {
566 if (Sec.sh_type == ELF::SHT_DYNAMIC) {
567 Expected<ArrayRef<Elf_Dyn>> DynOrError =
568 getSectionContentsAsArray<Elf_Dyn>(Sec);
569 if (!DynOrError)
570 return DynOrError.takeError();
571 Dyn = *DynOrError;
572 break;
573 }
574 }
575
576 if (!Dyn.data())
577 return ArrayRef<Elf_Dyn>();
578 }
579
580 if (Dyn.empty())
581 return createError("invalid empty dynamic section");
582
583 if (Dyn.back().d_tag != ELF::DT_NULL)
584 return createError("dynamic sections must be DT_NULL terminated");
585
586 return Dyn;
587}
588
589template <class ELFT>
592 auto ProgramHeadersOrError = program_headers();
593 if (!ProgramHeadersOrError)
594 return ProgramHeadersOrError.takeError();
595
597
598 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)
599 if (Phdr.p_type == ELF::PT_LOAD)
600 LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
601
602 auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,
603 const Elf_Phdr_Impl<ELFT> *B) {
604 return A->p_vaddr < B->p_vaddr;
605 };
606 if (!llvm::is_sorted(LoadSegments, SortPred)) {
607 if (Error E =
608 WarnHandler("loadable segments are unsorted by virtual address"))
609 return std::move(E);
610 llvm::stable_sort(LoadSegments, SortPred);
611 }
612
613 const Elf_Phdr *const *I = llvm::upper_bound(
614 LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
615 return VAddr < Phdr->p_vaddr;
616 });
617
618 if (I == LoadSegments.begin())
619 return createError("virtual address is not in any segment: 0x" +
620 Twine::utohexstr(VAddr));
621 --I;
622 const Elf_Phdr &Phdr = **I;
623 uint64_t Delta = VAddr - Phdr.p_vaddr;
624 if (Delta >= Phdr.p_filesz)
625 return createError("virtual address is not in any segment: 0x" +
626 Twine::utohexstr(VAddr));
627
628 uint64_t Offset = Phdr.p_offset + Delta;
629 if (Offset >= getBufSize())
630 return createError("can't map virtual address 0x" +
631 Twine::utohexstr(VAddr) + " to the segment with index " +
632 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
633 ": the segment ends at 0x" +
634 Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +
635 ", which is greater than the file size (0x" +
636 Twine::utohexstr(getBufSize()) + ")");
637
638 return base() + Offset;
639}
640
641template <class ELFT>
643ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec) const {
644 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
645 if (!ContentsOrErr)
646 return ContentsOrErr.takeError();
647 ArrayRef<uint8_t> Content = *ContentsOrErr;
648 DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
649 std::vector<BBAddrMap> FunctionEntries;
650
652 Error ULEBSizeErr = Error::success();
653 // Helper to extract and decode the next ULEB128 value as uint32_t.
654 // Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the uint32_t
655 // limit.
656 // Also returns zero if ULEBSizeErr is already in an error state.
657 auto ReadULEB128AsUInt32 = [&Data, &Cur, &ULEBSizeErr]() -> uint32_t {
658 // Bail out and do not extract data if ULEBSizeErr is already set.
659 if (ULEBSizeErr)
660 return 0;
661 uint64_t Offset = Cur.tell();
662 uint64_t Value = Data.getULEB128(Cur);
663 if (Value > UINT32_MAX) {
664 ULEBSizeErr = createError(
665 "ULEB128 value at offset 0x" + Twine::utohexstr(Offset) +
666 " exceeds UINT32_MAX (0x" + Twine::utohexstr(Value) + ")");
667 return 0;
668 }
669 return static_cast<uint32_t>(Value);
670 };
671
672 uint8_t Version = 0;
673 while (!ULEBSizeErr && Cur && Cur.tell() < Content.size()) {
674 if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
675 Version = Data.getU8(Cur);
676 if (!Cur)
677 break;
678 if (Version > 2)
679 return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
680 Twine(static_cast<int>(Version)));
681 Data.getU8(Cur); // Feature byte
682 }
683 uintX_t Address = static_cast<uintX_t>(Data.getAddress(Cur));
684 uint32_t NumBlocks = ReadULEB128AsUInt32();
685 std::vector<BBAddrMap::BBEntry> BBEntries;
686 uint32_t PrevBBEndOffset = 0;
687 for (uint32_t BlockIndex = 0;
688 !ULEBSizeErr && Cur && (BlockIndex < NumBlocks); ++BlockIndex) {
689 uint32_t ID = Version >= 2 ? ReadULEB128AsUInt32() : BlockIndex;
690 uint32_t Offset = ReadULEB128AsUInt32();
691 uint32_t Size = ReadULEB128AsUInt32();
692 uint32_t Metadata = ReadULEB128AsUInt32();
693 if (Version >= 1) {
694 // Offset is calculated relative to the end of the previous BB.
695 Offset += PrevBBEndOffset;
696 PrevBBEndOffset = Offset + Size;
697 }
698 BBEntries.push_back({ID, Offset, Size, Metadata});
699 }
700 FunctionEntries.push_back({Address, std::move(BBEntries)});
701 }
702 // Either Cur is in the error state, or ULEBSizeError is set (not both), but
703 // we join the two errors here to be safe.
704 if (!Cur || ULEBSizeErr)
705 return joinErrors(Cur.takeError(), std::move(ULEBSizeErr));
706 return FunctionEntries;
707}
708
709template class llvm::object::ELFFile<ELF32LE>;
710template class llvm::object::ELFFile<ELF32BE>;
711template class llvm::object::ELFFile<ELF64LE>;
712template class llvm::object::ELFFile<ELF64BE>;
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
T Content
uint64_t Addr
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
#define STRINGIFY_ENUM_CASE(ns, name)
Definition: ELF.cpp:16
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:172
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
const T * data() const
Definition: ArrayRef.h:160
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Definition: DataExtractor.h:54
uint64_t tell() const
Return the current position of this Cursor.
Definition: DataExtractor.h:71
Error takeError()
Return error contained inside this Cursor, if any.
Definition: DataExtractor.h:78
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
Root of the metadata hierarchy.
Definition: Metadata.h:61
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:404
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
An efficient, type-erasing, non-owning reference to a callable.
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr &Sec) const
Definition: ELF.cpp:386
std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Definition: ELF.cpp:454
Expected< Elf_Dyn_Range > dynamicEntries() const
Definition: ELF.cpp:543
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition: ELF.cpp:591
Expected< std::vector< BBAddrMap > > decodeBBAddrMap(const Elf_Shdr &Sec) const
Definition: ELF.cpp:643
std::vector< Elf_Rel > decode_relrs(Elf_Relr_Range relrs) const
Definition: ELF.cpp:322
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ EM_MSP430
Definition: ELF.h:222
@ EM_S390
Definition: ELF.h:150
@ EM_PPC64
Definition: ELF.h:149
@ EM_SPARC
Definition: ELF.h:135
@ EM_CSKY
Definition: ELF.h:321
@ EM_SPARC32PLUS
Definition: ELF.h:146
@ EM_MIPS_RS3_LE
Definition: ELF.h:143
@ EM_68K
Definition: ELF.h:137
@ EM_386
Definition: ELF.h:136
@ EM_LOONGARCH
Definition: ELF.h:322
@ EM_BPF
Definition: ELF.h:319
@ EM_PPC
Definition: ELF.h:148
@ EM_X86_64
Definition: ELF.h:178
@ EM_HEXAGON
Definition: ELF.h:257
@ EM_LANAI
Definition: ELF.h:318
@ EM_MIPS
Definition: ELF.h:141
@ EM_SPARCV9
Definition: ELF.h:159
@ EM_AARCH64
Definition: ELF.h:280
@ EM_XTENSA
Definition: ELF.h:211
@ EM_ARC_COMPACT2
Definition: ELF.h:291
@ EM_RISCV
Definition: ELF.h:317
@ EM_ARC_COMPACT
Definition: ELF.h:209
@ EM_ARM
Definition: ELF.h:156
@ EM_VE
Definition: ELF.h:320
@ EM_IAMCU
Definition: ELF.h:139
@ EM_AMDGPU
Definition: ELF.h:316
@ EM_AVR
Definition: ELF.h:199
@ SHT_DYNAMIC
Definition: ELF.h:1000
@ SHT_LLVM_BB_ADDR_MAP
Definition: ELF.h:1032
@ RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG
Definition: ELF.h:1790
@ RELOCATION_GROUPED_BY_INFO_FLAG
Definition: ELF.h:1789
@ RELOCATION_GROUPED_BY_ADDEND_FLAG
Definition: ELF.h:1791
@ RELOCATION_GROUP_HAS_ADDEND_FLAG
Definition: ELF.h:1792
@ PT_LOAD
Definition: ELF.h:1382
@ PT_DYNAMIC
Definition: ELF.h:1383
Error createError(const Twine &Err)
Definition: Error.h:84
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition: ELF.cpp:22
uint32_t getELFRelativeRelocationType(uint32_t Machine)
Definition: ELF.cpp:191
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
void stable_sort(R &&Range)
Definition: STLExtras.h:1948
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1936
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:427
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1884