LLVM 23.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"
15
16using namespace llvm;
17using namespace object;
18
19#define STRINGIFY_ENUM_CASE(ns, name) \
20 case ns::name: \
21 return #name;
22
23#define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
24
26 uint32_t Type) {
27 switch (Machine) {
28 case ELF::EM_68K:
29 switch (Type) {
30#include "llvm/BinaryFormat/ELFRelocs/M68k.def"
31 default:
32 break;
33 }
34 break;
35 case ELF::EM_X86_64:
36 switch (Type) {
37#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
38 default:
39 break;
40 }
41 break;
42 case ELF::EM_386:
43 case ELF::EM_IAMCU:
44 switch (Type) {
45#include "llvm/BinaryFormat/ELFRelocs/i386.def"
46 default:
47 break;
48 }
49 break;
50 case ELF::EM_MIPS:
51 switch (Type) {
52#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
53 default:
54 break;
55 }
56 break;
57 case ELF::EM_AARCH64:
58 switch (Type) {
59#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
60 default:
61 break;
62 }
63 break;
64 case ELF::EM_ARM:
65 switch (Type) {
66#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
67 default:
68 break;
69 }
70 break;
73 switch (Type) {
74#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
75 default:
76 break;
77 }
78 break;
79 case ELF::EM_AVR:
80 switch (Type) {
81#include "llvm/BinaryFormat/ELFRelocs/AVR.def"
82 default:
83 break;
84 }
85 break;
86 case ELF::EM_HEXAGON:
87 switch (Type) {
88#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
89 default:
90 break;
91 }
92 break;
93 case ELF::EM_LANAI:
94 switch (Type) {
95#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
96 default:
97 break;
98 }
99 break;
100 case ELF::EM_PPC:
101 switch (Type) {
102#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
103 default:
104 break;
105 }
106 break;
107 case ELF::EM_PPC64:
108 switch (Type) {
109#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
110 default:
111 break;
112 }
113 break;
114 case ELF::EM_RISCV:
115 switch (Type) {
116#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
117 default:
118 break;
119 }
120 break;
121 case ELF::EM_S390:
122 switch (Type) {
123#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
124 default:
125 break;
126 }
127 break;
128 case ELF::EM_SPARC:
130 case ELF::EM_SPARCV9:
131 switch (Type) {
132#include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
133 default:
134 break;
135 }
136 break;
137 case ELF::EM_AMDGPU:
138 switch (Type) {
139#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
140 default:
141 break;
142 }
143 break;
144 case ELF::EM_BPF:
145 switch (Type) {
146#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
147 default:
148 break;
149 }
150 break;
151 case ELF::EM_MSP430:
152 switch (Type) {
153#include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
154 default:
155 break;
156 }
157 break;
158 case ELF::EM_VE:
159 switch (Type) {
160#include "llvm/BinaryFormat/ELFRelocs/VE.def"
161 default:
162 break;
163 }
164 break;
165 case ELF::EM_CSKY:
166 switch (Type) {
167#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
168 default:
169 break;
170 }
171 break;
173 switch (Type) {
174#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
175 default:
176 break;
177 }
178 break;
179 case ELF::EM_XTENSA:
180 switch (Type) {
181#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
182 default:
183 break;
184 }
185 break;
186 default:
187 break;
188 }
189 return "Unknown";
190}
191
192#undef ELF_RELOC
193
195 StringRef Vendor) {
196#define ELF_RISCV_NONSTANDARD_RELOC(vendor, name, number) \
197 if (Vendor == #vendor && Type == number) \
198 return #name;
199
200#include "llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def"
201
202#undef ELF_RISCV_NONSTANDARD_RELOC
203
204 return "Unknown";
205}
206
208 switch (Machine) {
209 case ELF::EM_X86_64:
210 return ELF::R_X86_64_RELATIVE;
211 case ELF::EM_386:
212 case ELF::EM_IAMCU:
213 return ELF::R_386_RELATIVE;
214 case ELF::EM_MIPS:
215 break;
216 case ELF::EM_AARCH64:
217 return ELF::R_AARCH64_RELATIVE;
218 case ELF::EM_ARM:
219 return ELF::R_ARM_RELATIVE;
222 return ELF::R_ARC_RELATIVE;
223 case ELF::EM_AVR:
224 break;
225 case ELF::EM_HEXAGON:
226 return ELF::R_HEX_RELATIVE;
227 case ELF::EM_LANAI:
228 break;
229 case ELF::EM_PPC:
230 break;
231 case ELF::EM_PPC64:
232 return ELF::R_PPC64_RELATIVE;
233 case ELF::EM_RISCV:
234 return ELF::R_RISCV_RELATIVE;
235 case ELF::EM_S390:
236 return ELF::R_390_RELATIVE;
237 case ELF::EM_SPARC:
239 case ELF::EM_SPARCV9:
240 return ELF::R_SPARC_RELATIVE;
241 case ELF::EM_CSKY:
242 return ELF::R_CKCORE_RELATIVE;
243 case ELF::EM_VE:
244 return ELF::R_VE_RELATIVE;
245 case ELF::EM_AMDGPU:
246 break;
247 case ELF::EM_BPF:
248 break;
250 return ELF::R_LARCH_RELATIVE;
251 default:
252 break;
253 }
254 return 0;
255}
256
258 switch (Machine) {
259 case ELF::EM_ARM:
260 switch (Type) {
261 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
262 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
263 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
264 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
265 STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
266 }
267 break;
268 case ELF::EM_HEXAGON:
269 switch (Type) {
270 STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);
271 STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES);
272 }
273 break;
274 case ELF::EM_X86_64:
275 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
276 break;
277 case ELF::EM_MIPS:
279 switch (Type) {
280 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
281 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
282 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
283 STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
284 }
285 break;
286 case ELF::EM_MSP430:
287 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); }
288 break;
289 case ELF::EM_RISCV:
290 switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }
291 break;
292 case ELF::EM_AARCH64:
293 switch (Type) {
294 STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_AUTH_RELR);
295 STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC);
296 STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_STATIC);
297 }
298 default:
299 break;
300 }
301
302 switch (Type) {
303 STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
304 STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
305 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
306 STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
307 STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
308 STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
309 STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
310 STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
311 STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
312 STRINGIFY_ENUM_CASE(ELF, SHT_REL);
313 STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
314 STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
315 STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
316 STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
317 STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
318 STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
319 STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
320 STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
321 STRINGIFY_ENUM_CASE(ELF, SHT_CREL);
322 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
323 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
324 STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
325 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
326 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
327 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
328 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);
329 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES);
330 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);
331 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);
332 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);
333 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);
334 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING);
335 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO);
336 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_JT_SIZES)
337 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CFI_JUMP_TABLE)
338 STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH);
339 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_SFRAME);
340 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
341 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
342 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
343 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
344 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
345 default:
346 return "Unknown";
347 }
348}
349
350template <class ELFT>
351std::vector<typename ELFT::Rel>
352ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
353 // This function decodes the contents of an SHT_RELR packed relocation
354 // section.
355 //
356 // Proposal for adding SHT_RELR sections to generic-abi is here:
357 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
358 //
359 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
360 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
361 //
362 // i.e. start with an address, followed by any number of bitmaps. The address
363 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
364 // relocations each, at subsequent offsets following the last address entry.
365 //
366 // The bitmap entries must have 1 in the least significant bit. The assumption
367 // here is that an address cannot have 1 in lsb. Odd addresses are not
368 // supported.
369 //
370 // Excluding the least significant bit in the bitmap, each non-zero bit in
371 // the bitmap represents a relocation to be applied to a corresponding machine
372 // word that follows the base address word. The second least significant bit
373 // represents the machine word immediately following the initial address, and
374 // each bit that follows represents the next word, in linear order. As such,
375 // a single bitmap can encode up to 31 relocations in a 32-bit object, and
376 // 63 relocations in a 64-bit object.
377 //
378 // This encoding has a couple of interesting properties:
379 // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
380 // even means address, odd means bitmap.
381 // 2. Just a simple list of addresses is a valid encoding.
382
383 Elf_Rel Rel;
384 Rel.r_info = 0;
385 Rel.setType(getRelativeRelocationType(), false);
386 std::vector<Elf_Rel> Relocs;
387
388 // Word type: uint32_t for Elf32, and uint64_t for Elf64.
389 using Addr = typename ELFT::uint;
390
391 Addr Base = 0;
392 for (Elf_Relr R : relrs) {
393 typename ELFT::uint Entry = R;
394 if ((Entry & 1) == 0) {
395 // Even entry: encodes the offset for next relocation.
396 Rel.r_offset = Entry;
397 Relocs.push_back(Rel);
398 // Set base offset for subsequent bitmap entries.
399 Base = Entry + sizeof(Addr);
400 } else {
401 // Odd entry: encodes bitmap for relocations starting at base.
402 for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr))
403 if ((Entry & 1) != 0) {
404 Rel.r_offset = Offset;
405 Relocs.push_back(Rel);
406 }
407 Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr);
408 }
409 }
411 return Relocs;
412}
414template <class ELFT>
417 DataExtractor Data(Content, isLE(), sizeof(typename ELFT::Addr));
418 Error Err = Error::success();
419 uint64_t Hdr = 0;
420 Hdr = Data.getULEB128(&Hdr, &Err);
421 if (Err)
422 return Err;
423 return Hdr;
424}
425
426template <class ELFT>
429 std::vector<Elf_Rel> Rels;
430 std::vector<Elf_Rela> Relas;
431 size_t I = 0;
432 bool HasAddend;
434 Content,
435 [&](uint64_t Count, bool HasA) {
436 HasAddend = HasA;
437 if (HasAddend)
438 Relas.resize(Count);
439 else
440 Rels.resize(Count);
441 },
442 [&](Elf_Crel Crel) {
443 if (HasAddend) {
444 Relas[I].r_offset = Crel.r_offset;
445 Relas[I].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);
446 Relas[I++].r_addend = Crel.r_addend;
447 } else {
448 Rels[I].r_offset = Crel.r_offset;
449 Rels[I++].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);
450 }
451 });
452 if (Err)
453 return std::move(Err);
454 return std::make_pair(std::move(Rels), std::move(Relas));
455}
456
457template <class ELFT>
459ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const {
461 if (!ContentsOrErr)
462 return ContentsOrErr.takeError();
463 return decodeCrel(*ContentsOrErr);
464}
465
466template <class ELFT>
468ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
469 // This function reads relocations in Android's packed relocation format,
470 // which is based on SLEB128 and delta encoding.
472 if (!ContentsOrErr)
473 return ContentsOrErr.takeError();
474 ArrayRef<uint8_t> Content = *ContentsOrErr;
475 if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||
476 Content[2] != 'S' || Content[3] != '2')
477 return createError("invalid packed relocation header");
478 DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
479 DataExtractor::Cursor Cur(/*Offset=*/4);
480
481 uint64_t NumRelocs = Data.getSLEB128(Cur);
482 uint64_t Offset = Data.getSLEB128(Cur);
483 uint64_t Addend = 0;
484
485 if (!Cur)
486 return std::move(Cur.takeError());
487
488 std::vector<Elf_Rela> Relocs;
489 Relocs.reserve(NumRelocs);
490 while (NumRelocs) {
491 uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);
492 if (!Cur)
493 return std::move(Cur.takeError());
494 if (NumRelocsInGroup > NumRelocs)
495 return createError("relocation group unexpectedly large");
496 NumRelocs -= NumRelocsInGroup;
497
498 uint64_t GroupFlags = Data.getSLEB128(Cur);
499 bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
500 bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
501 bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
502 bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
503
504 uint64_t GroupOffsetDelta;
505 if (GroupedByOffsetDelta)
506 GroupOffsetDelta = Data.getSLEB128(Cur);
507
508 uint64_t GroupRInfo;
509 if (GroupedByInfo)
510 GroupRInfo = Data.getSLEB128(Cur);
511
512 if (GroupedByAddend && GroupHasAddend)
513 Addend += Data.getSLEB128(Cur);
514
515 if (!GroupHasAddend)
516 Addend = 0;
517
518 for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {
519 Elf_Rela R;
520 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);
521 R.r_offset = Offset;
522 R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);
523 if (GroupHasAddend && !GroupedByAddend)
524 Addend += Data.getSLEB128(Cur);
525 R.r_addend = Addend;
526 Relocs.push_back(R);
527 }
528 if (!Cur)
529 return std::move(Cur.takeError());
530 }
531
532 return Relocs;
533}
534
535template <class ELFT>
536std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
537 uint64_t Type) const {
538#define DYNAMIC_STRINGIFY_ENUM(tag, value) \
539 case value: \
540 return #tag;
541
542#define DYNAMIC_TAG(n, v)
543 switch (Arch) {
544 case ELF::EM_AARCH64:
545 switch (Type) {
546#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
547#include "llvm/BinaryFormat/DynamicTags.def"
548#undef AARCH64_DYNAMIC_TAG
549 }
550 break;
551
552 case ELF::EM_HEXAGON:
553 switch (Type) {
554#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
555#include "llvm/BinaryFormat/DynamicTags.def"
556#undef HEXAGON_DYNAMIC_TAG
557 }
558 break;
559
560 case ELF::EM_MIPS:
561 switch (Type) {
562#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
563#include "llvm/BinaryFormat/DynamicTags.def"
564#undef MIPS_DYNAMIC_TAG
565 }
566 break;
567
568 case ELF::EM_PPC:
569 switch (Type) {
570#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
571#include "llvm/BinaryFormat/DynamicTags.def"
572#undef PPC_DYNAMIC_TAG
573 }
574 break;
575
576 case ELF::EM_PPC64:
577 switch (Type) {
578#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
579#include "llvm/BinaryFormat/DynamicTags.def"
580#undef PPC64_DYNAMIC_TAG
581 }
582 break;
583
584 case ELF::EM_RISCV:
585 switch (Type) {
586#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
587#include "llvm/BinaryFormat/DynamicTags.def"
588#undef RISCV_DYNAMIC_TAG
589 }
590 break;
591 }
592#undef DYNAMIC_TAG
593 switch (Type) {
594// Now handle all dynamic tags except the architecture specific ones
595#define AARCH64_DYNAMIC_TAG(name, value)
596#define MIPS_DYNAMIC_TAG(name, value)
597#define HEXAGON_DYNAMIC_TAG(name, value)
598#define PPC_DYNAMIC_TAG(name, value)
599#define PPC64_DYNAMIC_TAG(name, value)
600#define RISCV_DYNAMIC_TAG(name, value)
601// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
602#define DYNAMIC_TAG_MARKER(name, value)
603#define DYNAMIC_TAG(name, value) case value: return #name;
604#include "llvm/BinaryFormat/DynamicTags.def"
605#undef DYNAMIC_TAG
606#undef AARCH64_DYNAMIC_TAG
607#undef MIPS_DYNAMIC_TAG
608#undef HEXAGON_DYNAMIC_TAG
609#undef PPC_DYNAMIC_TAG
610#undef PPC64_DYNAMIC_TAG
611#undef RISCV_DYNAMIC_TAG
612#undef DYNAMIC_TAG_MARKER
613#undef DYNAMIC_STRINGIFY_ENUM
614 default:
615 return "<unknown:>0x" + utohexstr(Type, true);
616 }
617}
618
619template <class ELFT>
621 return getDynamicTagAsString(getHeader().e_machine, Type);
622}
623
624template <class ELFT>
627
628 auto ProgramHeadersOrError = program_headers();
629 if (!ProgramHeadersOrError)
630 return ProgramHeadersOrError.takeError();
631
632 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
633 if (Phdr.p_type == ELF::PT_DYNAMIC) {
634 const uint8_t *DynOffset = base() + Phdr.p_offset;
635 if (DynOffset > end())
636 return createError(
637 "dynamic section offset past file size: corrupted ELF");
638 Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(DynOffset),
639 Phdr.p_filesz / sizeof(Elf_Dyn));
640 break;
641 }
642 }
643
644 // If we can't find the dynamic section in the program headers, we just fall
645 // back on the sections.
646 if (Dyn.empty()) {
647 auto SectionsOrError = sections();
648 if (!SectionsOrError)
649 return SectionsOrError.takeError();
650
651 for (const Elf_Shdr &Sec : *SectionsOrError) {
652 if (Sec.sh_type == ELF::SHT_DYNAMIC) {
653 Expected<ArrayRef<Elf_Dyn>> DynOrError =
655 if (!DynOrError)
656 return DynOrError.takeError();
657 Dyn = *DynOrError;
658 break;
659 }
660 }
661
662 if (!Dyn.data())
663 return ArrayRef<Elf_Dyn>();
664 }
665
666 if (Dyn.empty())
667 return createError("invalid empty dynamic section");
668
669 if (Dyn.back().d_tag != ELF::DT_NULL)
670 return createError("dynamic sections must be DT_NULL terminated");
671
672 return Dyn;
673}
674
675template <class ELFT>
678 auto ProgramHeadersOrError = program_headers();
679 if (!ProgramHeadersOrError)
680 return ProgramHeadersOrError.takeError();
681
683
684 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)
685 if (Phdr.p_type == ELF::PT_LOAD)
686 LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
687
688 auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,
689 const Elf_Phdr_Impl<ELFT> *B) {
690 return A->p_vaddr < B->p_vaddr;
691 };
692 if (!llvm::is_sorted(LoadSegments, SortPred)) {
693 if (Error E =
694 WarnHandler("loadable segments are unsorted by virtual address"))
695 return std::move(E);
696 llvm::stable_sort(LoadSegments, SortPred);
697 }
698
699 const Elf_Phdr *const *I = llvm::upper_bound(
700 LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
701 return VAddr < Phdr->p_vaddr;
702 });
703
704 if (I == LoadSegments.begin())
705 return createError("virtual address is not in any segment: 0x" +
706 Twine::utohexstr(VAddr));
707 --I;
708 const Elf_Phdr &Phdr = **I;
709 uint64_t Delta = VAddr - Phdr.p_vaddr;
710 if (Delta >= Phdr.p_filesz)
711 return createError("virtual address is not in any segment: 0x" +
712 Twine::utohexstr(VAddr));
713
714 uint64_t Offset = Phdr.p_offset + Delta;
715 if (Offset >= getBufSize())
716 return createError("can't map virtual address 0x" +
717 Twine::utohexstr(VAddr) + " to the segment with index " +
718 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
719 ": the segment ends at 0x" +
720 Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +
721 ", which is greater than the file size (0x" +
723
724 return base() + Offset;
725}
726
727/// Address extractor for ELF BB address map sections.
728class ELFBBAddrMapAddressExtractor : public AddressExtractor {
729 bool IsRelocatable;
730 // Maps the offset of each address field in the BB addr map section to the
731 // resolved function address (the relocation addend).
732 DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
733
734 ELFBBAddrMapAddressExtractor(
735 const DataExtractor &Data, bool IsRelocatable,
736 DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations)
737 : AddressExtractor(Data), IsRelocatable(IsRelocatable),
738 FunctionOffsetTranslations(std::move(FunctionOffsetTranslations)) {}
739
740public:
741 template <typename ELFT>
743 create(const DataExtractor &Data, const ELFFile<ELFT> &EF,
744 const typename ELFFile<ELFT>::Elf_Shdr &Sec,
745 const typename ELFFile<ELFT>::Elf_Shdr *RelaSec) {
746 bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;
747
748 // Build relocation offset-to-addend map.
749 DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
750 if (IsRelocatable && RelaSec) {
751 assert(RelaSec &&
752 "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
753 "object file without providing a relocation section.");
754 if (RelaSec->sh_type == ELF::SHT_CREL) {
756 EF.crels(*RelaSec);
757 if (!Relas)
758 return createError("unable to read CREL relocations for section " +
759 describe(EF, Sec) + ": " +
760 toString(Relas.takeError()));
761 for (typename ELFFile<ELFT>::Elf_Rela Rela : std::get<1>(*Relas))
762 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
763 } else {
765 EF.relas(*RelaSec);
766 if (!Relas)
767 return createError("unable to read relocations for section " +
768 describe(EF, Sec) + ": " +
769 toString(Relas.takeError()));
770 for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
771 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
772 }
773 }
774
775 return ELFBBAddrMapAddressExtractor(Data, IsRelocatable,
776 std::move(FunctionOffsetTranslations));
777 }
778
780 uint64_t Offset = Cur.tell();
782 if (!AddressOrErr)
783 return AddressOrErr.takeError();
784 if (!IsRelocatable)
785 return *AddressOrErr;
786 auto FOTIterator = FunctionOffsetTranslations.find(Offset);
787 if (FOTIterator == FunctionOffsetTranslations.end())
788 return createError("failed to get relocation data for offset: " +
790 return FOTIterator->second;
791 }
792};
793
794template <typename ELFT>
797 const typename ELFFile<ELFT>::Elf_Shdr &Sec,
798 const typename ELFFile<ELFT>::Elf_Shdr *RelaSec,
799 std::vector<PGOAnalysisMap> *PGOAnalyses) {
800 // Read and optionally decompress section contents.
801 Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);
802 if (!ContentsOrErr)
803 return ContentsOrErr.takeError();
804 ArrayRef<uint8_t> Content = *ContentsOrErr;
805
806 std::unique_ptr<uint8_t[]> DecompressedContent;
807 if (Sec.sh_flags & llvm::ELF::SHF_COMPRESSED) {
808 Expected<StringRef> SectionNameOrErr = EF.getSectionName(Sec);
809 if (!SectionNameOrErr)
810 return SectionNameOrErr.takeError();
811 auto DecompressorOrErr =
812 Decompressor::create(*SectionNameOrErr, toStringRef(*ContentsOrErr),
813 EF.isLE(), ELFT::Is64Bits);
814 if (!DecompressorOrErr)
815 return DecompressorOrErr.takeError();
816 size_t DecompressedSize = DecompressorOrErr->getDecompressedSize();
817 DecompressedContent = std::make_unique<uint8_t[]>(DecompressedSize);
818 MutableArrayRef<uint8_t> DecompressedContentRef(DecompressedContent.get(),
819 DecompressedSize);
820 if (Error Err = DecompressorOrErr->decompress(DecompressedContentRef))
821 return std::move(Err);
822 Content = DecompressedContentRef;
823 }
824
825 DataExtractor Data(Content, EF.isLE(),
826 sizeof(typename ELFFile<ELFT>::uintX_t));
827 auto ExtractorOrErr =
829 if (!ExtractorOrErr)
830 return ExtractorOrErr.takeError();
831 auto BBAddrMapsOrErr = decodeBBAddrMapPayload(*ExtractorOrErr, PGOAnalyses);
832 if (!BBAddrMapsOrErr)
833 return createError(toString(BBAddrMapsOrErr.takeError()) + " in " +
834 describe(EF, Sec));
835 return BBAddrMapsOrErr;
836}
837
838template <class ELFT>
840ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec,
841 std::vector<PGOAnalysisMap> *PGOAnalyses) const {
842 size_t OriginalPGOSize = PGOAnalyses ? PGOAnalyses->size() : 0;
843 auto AddrMapsOrErr = decodeBBAddrMapImpl(*this, Sec, RelaSec, PGOAnalyses);
844 // remove new analyses when an error occurs
845 if (!AddrMapsOrErr && PGOAnalyses)
846 PGOAnalyses->resize(OriginalPGOSize);
847 return std::move(AddrMapsOrErr);
848}
849
850template <class ELFT>
854 std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const {
856 Error Errors = Error::success();
857 for (const Elf_Shdr &Sec : cantFail(this->sections())) {
858 Expected<bool> DoesSectionMatch = IsMatch(Sec);
859 if (!DoesSectionMatch) {
860 Errors = joinErrors(std::move(Errors), DoesSectionMatch.takeError());
861 continue;
862 }
863 if (*DoesSectionMatch) {
864 if (SecToRelocMap.try_emplace(&Sec).second)
865 continue;
866 }
867
868 if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL &&
869 Sec.sh_type != ELF::SHT_CREL)
870 continue;
871
872 Expected<const Elf_Shdr *> RelSecOrErr = this->getSection(Sec.sh_info);
873 if (!RelSecOrErr) {
874 Errors = joinErrors(std::move(Errors),
875 createError(describe(*this, Sec) +
876 ": failed to get a relocated section: " +
877 toString(RelSecOrErr.takeError())));
878 continue;
879 }
880 const Elf_Shdr *ContentsSec = *RelSecOrErr;
881 Expected<bool> DoesRelTargetMatch = IsMatch(*ContentsSec);
882 if (!DoesRelTargetMatch) {
883 Errors = joinErrors(std::move(Errors), DoesRelTargetMatch.takeError());
884 continue;
885 }
886 if (*DoesRelTargetMatch)
887 SecToRelocMap[ContentsSec] = &Sec;
888 }
889 if(Errors)
890 return std::move(Errors);
891 return SecToRelocMap;
892}
893
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares common types and utilities for basic-block address maps.
bbsections Prepares for basic block sections
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXPORT_TEMPLATE
Definition Compiler.h:215
#define I(x, y, z)
Definition MD5.cpp:57
#define STRINGIFY_ENUM_CASE(ns, name)
Definition ELF.cpp:19
static Expected< std::vector< BBAddrMap > > decodeBBAddrMapImpl(const ELFFile< ELFT > &EF, const typename ELFFile< ELFT >::Elf_Shdr &Sec, const typename ELFFile< ELFT >::Elf_Shdr *RelaSec, std::vector< PGOAnalysisMap > *PGOAnalyses)
Definition ELF.cpp:796
Function const char TargetMachine * Machine
This file contains some functions that are useful when dealing with strings.
Expected< uint64_t > extractAddress(DataExtractor::Cursor &Cur) override
Extract and resolve an address at the current Cur position.
Definition ELF.cpp:779
static Expected< ELFBBAddrMapAddressExtractor > create(const DataExtractor &Data, const ELFFile< ELFT > &EF, const typename ELFFile< ELFT >::Elf_Shdr &Sec, const typename ELFFile< ELFT >::Elf_Shdr *RelaSec)
Definition ELF.cpp:743
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & back() const
back - Get the last element.
Definition ArrayRef.h:151
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
const T * data() const
Definition ArrayRef.h:139
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
uint64_t tell() const
Return the current position of this Cursor.
Error takeError()
Return error contained inside this Cursor, if any.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:36
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition MapVector.h:116
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition ArrayRef.h:298
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
AddressExtractor(const DataExtractor &Data)
Definition BBAddrMap.h:263
virtual Expected< uint64_t > extractAddress(DataExtractor::Cursor &Cur)
Extract and resolve an address at the current Cur position.
Definition BBAddrMap.h:269
static LLVM_ABI Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
const Elf_Ehdr & getHeader() const
Definition ELF.h:347
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr &Sec) const
Definition ELF.cpp:468
std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Definition ELF.cpp:536
Expected< std::vector< BBAddrMap > > decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec=nullptr, std::vector< PGOAnalysisMap > *PGOAnalyses=nullptr) const
Returns a vector of BBAddrMap structs corresponding to each function within the text section that the...
Definition ELF.cpp:840
uint32_t getRelativeRelocationType() const
Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr &Sec) const
Definition ELF.h:746
Expected< Elf_Rela_Range > relas(const Elf_Shdr &Sec) const
Definition ELF.h:422
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Definition ELF.h:444
size_t getBufSize() const
Definition ELF.h:278
Expected< RelsOrRelas > decodeCrel(ArrayRef< uint8_t > Content) const
Definition ELF.cpp:428
const uint8_t * end() const
Definition ELF.h:276
Expected< uint64_t > getCrelHeader(ArrayRef< uint8_t > Content) const
Definition ELF.cpp:416
Expected< Elf_Dyn_Range > dynamicEntries() const
Definition ELF.cpp:625
const uint8_t * base() const
Definition ELF.h:275
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition ELF.cpp:677
Expected< Elf_Relr_Range > relrs(const Elf_Shdr &Sec) const
Definition ELF.h:430
Expected< MapVector< const Elf_Shdr *, const Elf_Shdr * > > getSectionAndRelocations(std::function< Expected< bool >(const Elf_Shdr &)> IsMatch) const
Returns a map from every section matching IsMatch to its relocation section, or nullptr if it has no ...
Definition ELF.cpp:853
bool isLE() const
Definition ELF.h:397
Expected< StringRef > getSectionName(const Elf_Shdr &Section, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition ELF.h:1438
llvm::function_ref< Error(const Twine &Msg)> WarningHandler
Definition ELF.h:273
Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr &Sec) const
Definition ELF.h:690
Expected< RelsOrRelas > crels(const Elf_Shdr &Sec) const
Definition ELF.cpp:459
std::vector< Elf_Rel > decode_relrs(Elf_Relr_Range relrs) const
Definition ELF.cpp:352
@ SHF_COMPRESSED
Definition ELF.h:1277
@ EM_MSP430
Definition ELF.h:227
@ EM_S390
Definition ELF.h:155
@ EM_PPC64
Definition ELF.h:154
@ EM_SPARC
Definition ELF.h:140
@ EM_CSKY
Definition ELF.h:326
@ EM_SPARC32PLUS
Definition ELF.h:151
@ EM_MIPS_RS3_LE
Definition ELF.h:148
@ EM_68K
Definition ELF.h:142
@ EM_386
Definition ELF.h:141
@ EM_LOONGARCH
Definition ELF.h:327
@ EM_BPF
Definition ELF.h:324
@ EM_PPC
Definition ELF.h:153
@ EM_X86_64
Definition ELF.h:183
@ EM_HEXAGON
Definition ELF.h:262
@ EM_LANAI
Definition ELF.h:323
@ EM_MIPS
Definition ELF.h:146
@ EM_SPARCV9
Definition ELF.h:164
@ EM_AARCH64
Definition ELF.h:285
@ EM_XTENSA
Definition ELF.h:216
@ EM_ARC_COMPACT2
Definition ELF.h:296
@ EM_RISCV
Definition ELF.h:322
@ EM_ARC_COMPACT
Definition ELF.h:214
@ EM_ARM
Definition ELF.h:161
@ EM_VE
Definition ELF.h:325
@ EM_IAMCU
Definition ELF.h:144
@ EM_AMDGPU
Definition ELF.h:321
@ EM_AVR
Definition ELF.h:204
@ SHT_REL
Definition ELF.h:1156
@ SHT_CREL
Definition ELF.h:1169
@ SHT_DYNAMIC
Definition ELF.h:1153
@ SHT_RELA
Definition ELF.h:1151
@ PT_LOAD
Definition ELF.h:1559
@ PT_DYNAMIC
Definition ELF.h:1560
@ ET_REL
Definition ELF.h:119
@ RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG
Definition ELF.h:2011
@ RELOCATION_GROUPED_BY_INFO_FLAG
Definition ELF.h:2010
@ RELOCATION_GROUPED_BY_ADDEND_FLAG
Definition ELF.h:2012
@ RELOCATION_GROUP_HAS_ADDEND_FLAG
Definition ELF.h:2013
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Definition ELF.h:608
Error createError(const Twine &Err)
Definition Error.h:86
LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Definition ELF.cpp:25
LLVM_ABI uint32_t getELFRelativeRelocationType(uint32_t Machine)
Definition ELF.cpp:207
LLVM_ABI StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
static std::string describe(const ELFFile< ELFT > &Obj, const typename ELFT::Shdr &Sec)
Definition ELF.h:147
LLVM_ABI StringRef getRISCVVendorRelocationTypeName(uint32_t Type, StringRef Vendor)
Definition ELF.cpp:194
Expected< std::vector< BBAddrMap > > decodeBBAddrMapPayload(AddressExtractor &Extractor, std::vector< PGOAnalysisMap > *PGOAnalyses=nullptr)
Decodes one BB address map section payload.
Definition BBAddrMap.cpp:47
static Error decodeCrel(ArrayRef< uint8_t > Content, function_ref< void(uint64_t, bool)> HdrHandler, function_ref< void(Elf_Crel_Impl< Is64 >)> EntryHandler)
Definition ELF.h:218
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:532
void stable_sort(R &&Range)
Definition STLExtras.h:2116
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
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:2065
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition Error.h:442
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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:1970
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:221
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
StringRef toStringRef(bool B)
Construct a string ref from a boolean.