LLVM 24.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_LLVM_DYNDBG_ELF);
340 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_SFRAME);
341 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
342 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
343 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
344 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
345 STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
346 default:
347 return "Unknown";
348 }
349}
350
351template <class ELFT>
352std::vector<typename ELFT::Rel>
353ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
354 // This function decodes the contents of an SHT_RELR packed relocation
355 // section.
356 //
357 // Proposal for adding SHT_RELR sections to generic-abi is here:
358 // https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
359 //
360 // The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
361 // like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
362 //
363 // i.e. start with an address, followed by any number of bitmaps. The address
364 // entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
365 // relocations each, at subsequent offsets following the last address entry.
366 //
367 // The bitmap entries must have 1 in the least significant bit. The assumption
368 // here is that an address cannot have 1 in lsb. Odd addresses are not
369 // supported.
370 //
371 // Excluding the least significant bit in the bitmap, each non-zero bit in
372 // the bitmap represents a relocation to be applied to a corresponding machine
373 // word that follows the base address word. The second least significant bit
374 // represents the machine word immediately following the initial address, and
375 // each bit that follows represents the next word, in linear order. As such,
376 // a single bitmap can encode up to 31 relocations in a 32-bit object, and
377 // 63 relocations in a 64-bit object.
378 //
379 // This encoding has a couple of interesting properties:
380 // 1. Looking at any entry, it is clear whether it's an address or a bitmap:
381 // even means address, odd means bitmap.
382 // 2. Just a simple list of addresses is a valid encoding.
383
384 Elf_Rel Rel;
385 Rel.r_info = 0;
386 Rel.setType(getRelativeRelocationType(), false);
387 std::vector<Elf_Rel> Relocs;
388
389 // Word type: uint32_t for Elf32, and uint64_t for Elf64.
390 using Addr = typename ELFT::uint;
391
392 Addr Base = 0;
393 for (Elf_Relr R : relrs) {
394 typename ELFT::uint Entry = R;
395 if ((Entry & 1) == 0) {
396 // Even entry: encodes the offset for next relocation.
397 Rel.r_offset = Entry;
398 Relocs.push_back(Rel);
399 // Set base offset for subsequent bitmap entries.
400 Base = Entry + sizeof(Addr);
401 } else {
402 // Odd entry: encodes bitmap for relocations starting at base.
403 for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr))
404 if ((Entry & 1) != 0) {
405 Rel.r_offset = Offset;
406 Relocs.push_back(Rel);
407 }
408 Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr);
410 }
411
412 return Relocs;
413}
414
415template <class ELFT>
418 DataExtractor Data(Content, isLE());
419 Error Err = Error::success();
420 uint64_t Hdr = 0;
421 Hdr = Data.getULEB128(&Hdr, &Err);
422 if (Err)
423 return Err;
424 return Hdr;
425}
426
427template <class ELFT>
430 std::vector<Elf_Rel> Rels;
431 std::vector<Elf_Rela> Relas;
432 size_t I = 0;
433 bool HasAddend;
435 Content,
436 [&](uint64_t Count, bool HasA) {
437 HasAddend = HasA;
438 if (HasAddend)
439 Relas.resize(Count);
440 else
441 Rels.resize(Count);
442 },
443 [&](Elf_Crel Crel) {
444 if (HasAddend) {
445 Relas[I].r_offset = Crel.r_offset;
446 Relas[I].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);
447 Relas[I++].r_addend = Crel.r_addend;
448 } else {
449 Rels[I].r_offset = Crel.r_offset;
450 Rels[I++].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);
451 }
452 });
453 if (Err)
454 return std::move(Err);
455 return std::make_pair(std::move(Rels), std::move(Relas));
456}
457
458template <class ELFT>
460ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const {
462 if (!ContentsOrErr)
463 return ContentsOrErr.takeError();
464 return decodeCrel(*ContentsOrErr);
465}
466
467template <class ELFT>
469ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
470 // This function reads relocations in Android's packed relocation format,
471 // which is based on SLEB128 and delta encoding.
473 if (!ContentsOrErr)
474 return ContentsOrErr.takeError();
475 ArrayRef<uint8_t> Content = *ContentsOrErr;
476 if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||
477 Content[2] != 'S' || Content[3] != '2')
478 return createError("invalid packed relocation header");
479 DataExtractor Data(Content, isLE());
480 DataExtractor::Cursor Cur(/*Offset=*/4);
481
482 uint64_t NumRelocs = Data.getSLEB128(Cur);
483 uint64_t Offset = Data.getSLEB128(Cur);
484 uint64_t Addend = 0;
485
486 if (!Cur)
487 return std::move(Cur.takeError());
488
489 std::vector<Elf_Rela> Relocs;
490 Relocs.reserve(NumRelocs);
491 while (NumRelocs) {
492 uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);
493 if (!Cur)
494 return std::move(Cur.takeError());
495 if (NumRelocsInGroup > NumRelocs)
496 return createError("relocation group unexpectedly large");
497 NumRelocs -= NumRelocsInGroup;
498
499 uint64_t GroupFlags = Data.getSLEB128(Cur);
500 bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
501 bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
502 bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
503 bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
504
505 uint64_t GroupOffsetDelta;
506 if (GroupedByOffsetDelta)
507 GroupOffsetDelta = Data.getSLEB128(Cur);
508
509 uint64_t GroupRInfo;
510 if (GroupedByInfo)
511 GroupRInfo = Data.getSLEB128(Cur);
512
513 if (GroupedByAddend && GroupHasAddend)
514 Addend += Data.getSLEB128(Cur);
515
516 if (!GroupHasAddend)
517 Addend = 0;
518
519 for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {
520 Elf_Rela R;
521 Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);
522 R.r_offset = Offset;
523 R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);
524 if (GroupHasAddend && !GroupedByAddend)
525 Addend += Data.getSLEB128(Cur);
526 R.r_addend = Addend;
527 Relocs.push_back(R);
528 }
529 if (!Cur)
530 return std::move(Cur.takeError());
531 }
532
533 return Relocs;
534}
535
536template <class ELFT>
537std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
538 uint64_t Type) const {
539#define DYNAMIC_STRINGIFY_ENUM(tag, value) \
540 case value: \
541 return #tag;
542
543#define DYNAMIC_TAG(n, v)
544 switch (Arch) {
545 case ELF::EM_AARCH64:
546 switch (Type) {
547#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
548#include "llvm/BinaryFormat/DynamicTags.def"
549#undef AARCH64_DYNAMIC_TAG
550 }
551 break;
552
553 case ELF::EM_HEXAGON:
554 switch (Type) {
555#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
556#include "llvm/BinaryFormat/DynamicTags.def"
557#undef HEXAGON_DYNAMIC_TAG
558 }
559 break;
560
561 case ELF::EM_MIPS:
562 switch (Type) {
563#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
564#include "llvm/BinaryFormat/DynamicTags.def"
565#undef MIPS_DYNAMIC_TAG
566 }
567 break;
568
569 case ELF::EM_PPC:
570 switch (Type) {
571#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
572#include "llvm/BinaryFormat/DynamicTags.def"
573#undef PPC_DYNAMIC_TAG
574 }
575 break;
576
577 case ELF::EM_PPC64:
578 switch (Type) {
579#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
580#include "llvm/BinaryFormat/DynamicTags.def"
581#undef PPC64_DYNAMIC_TAG
582 }
583 break;
584
585 case ELF::EM_RISCV:
586 switch (Type) {
587#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
588#include "llvm/BinaryFormat/DynamicTags.def"
589#undef RISCV_DYNAMIC_TAG
590 }
591 break;
592
593 case ELF::EM_SPARC:
595 case ELF::EM_SPARCV9:
596 switch (Type) {
597#define SPARC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
598#include "llvm/BinaryFormat/DynamicTags.def"
599#undef SPARC_DYNAMIC_TAG
600 }
601 break;
602
603 case ELF::EM_X86_64:
604 switch (Type) {
605#define X86_64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
606#include "llvm/BinaryFormat/DynamicTags.def"
607#undef X86_64_DYNAMIC_TAG
608 }
609 break;
610 }
611#undef DYNAMIC_TAG
612 switch (Type) {
613// Now handle all dynamic tags except the architecture specific ones
614#define AARCH64_DYNAMIC_TAG(name, value)
615#define MIPS_DYNAMIC_TAG(name, value)
616#define HEXAGON_DYNAMIC_TAG(name, value)
617#define PPC_DYNAMIC_TAG(name, value)
618#define PPC64_DYNAMIC_TAG(name, value)
619#define RISCV_DYNAMIC_TAG(name, value)
620#define SPARC_DYNAMIC_TAG(name, value)
621#define X86_64_DYNAMIC_TAG(name, value)
622// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
623#define DYNAMIC_TAG_MARKER(name, value)
624#define DYNAMIC_TAG(name, value) case value: return #name;
625#include "llvm/BinaryFormat/DynamicTags.def"
626#undef DYNAMIC_TAG
627#undef AARCH64_DYNAMIC_TAG
628#undef MIPS_DYNAMIC_TAG
629#undef HEXAGON_DYNAMIC_TAG
630#undef PPC_DYNAMIC_TAG
631#undef PPC64_DYNAMIC_TAG
632#undef RISCV_DYNAMIC_TAG
633#undef SPARC_DYNAMIC_TAG
634#undef X86_64_DYNAMIC_TAG
635#undef DYNAMIC_TAG_MARKER
636#undef DYNAMIC_STRINGIFY_ENUM
637 default:
638 return "<unknown:>0x" + utohexstr(Type, true);
639 }
640}
641
642template <class ELFT>
644 return getDynamicTagAsString(getHeader().e_machine, Type);
645}
646
647template <class ELFT>
650
651 auto ProgramHeadersOrError = program_headers();
652 if (!ProgramHeadersOrError)
653 return ProgramHeadersOrError.takeError();
654
655 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
656 if (Phdr.p_type == ELF::PT_DYNAMIC) {
657 const uint8_t *DynOffset = base() + Phdr.p_offset;
658 if (DynOffset > end())
659 return createError(
660 "dynamic section offset past file size: corrupted ELF");
661 Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(DynOffset),
662 Phdr.p_filesz / sizeof(Elf_Dyn));
663 break;
664 }
665 }
666
667 // If we can't find the dynamic section in the program headers, we just fall
668 // back on the sections.
669 if (Dyn.empty()) {
670 auto SectionsOrError = sections();
671 if (!SectionsOrError)
672 return SectionsOrError.takeError();
673
674 for (const Elf_Shdr &Sec : *SectionsOrError) {
675 if (Sec.sh_type == ELF::SHT_DYNAMIC) {
676 Expected<ArrayRef<Elf_Dyn>> DynOrError =
678 if (!DynOrError)
679 return DynOrError.takeError();
680 Dyn = *DynOrError;
681 break;
682 }
683 }
684
685 if (!Dyn.data())
686 return ArrayRef<Elf_Dyn>();
687 }
688
689 if (Dyn.empty())
690 return createError("invalid empty dynamic section");
691
692 if (Dyn.back().d_tag != ELF::DT_NULL)
693 return createError("dynamic sections must be DT_NULL terminated");
694
695 return Dyn;
696}
697
698template <class ELFT>
701 auto ProgramHeadersOrError = program_headers();
702 if (!ProgramHeadersOrError)
703 return ProgramHeadersOrError.takeError();
704
706
707 for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)
708 if (Phdr.p_type == ELF::PT_LOAD)
709 LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
710
711 auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,
712 const Elf_Phdr_Impl<ELFT> *B) {
713 return A->p_vaddr < B->p_vaddr;
714 };
715 if (!llvm::is_sorted(LoadSegments, SortPred)) {
716 if (Error E =
717 WarnHandler("loadable segments are unsorted by virtual address"))
718 return std::move(E);
719 llvm::stable_sort(LoadSegments, SortPred);
720 }
721
722 const Elf_Phdr *const *I = llvm::upper_bound(
723 LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
724 return VAddr < Phdr->p_vaddr;
725 });
726
727 if (I == LoadSegments.begin())
728 return createError("virtual address is not in any segment: 0x" +
729 Twine::utohexstr(VAddr));
730 --I;
731 const Elf_Phdr &Phdr = **I;
732 uint64_t Delta = VAddr - Phdr.p_vaddr;
733 if (Delta >= Phdr.p_filesz)
734 return createError("virtual address is not in any segment: 0x" +
735 Twine::utohexstr(VAddr));
736
737 uint64_t Offset = Phdr.p_offset + Delta;
738 if (Offset >= getBufSize())
739 return createError("can't map virtual address 0x" +
740 Twine::utohexstr(VAddr) + " to the segment with index " +
741 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
742 ": the segment ends at 0x" +
743 Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +
744 ", which is greater than the file size (0x" +
746
747 return base() + Offset;
748}
749
750/// Address extractor for ELF BB address map sections.
751class ELFBBAddrMapAddressExtractor : public AddressExtractor {
752 bool IsRelocatable;
753 // Maps the offset of each address field in the BB addr map section to the
754 // resolved function address (the relocation addend).
755 DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
756
757 ELFBBAddrMapAddressExtractor(
758 const DataExtractor &Data, unsigned AddressSize, bool IsRelocatable,
759 DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations)
760 : AddressExtractor(Data, AddressSize), IsRelocatable(IsRelocatable),
761 FunctionOffsetTranslations(std::move(FunctionOffsetTranslations)) {}
762
763public:
764 template <typename ELFT>
766 create(const DataExtractor &Data, const ELFFile<ELFT> &EF,
767 const typename ELFFile<ELFT>::Elf_Shdr &Sec,
768 const typename ELFFile<ELFT>::Elf_Shdr *RelaSec) {
769 bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;
770
771 // Build relocation offset-to-addend map.
772 DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
773 if (IsRelocatable && RelaSec) {
774 assert(RelaSec &&
775 "Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
776 "object file without providing a relocation section.");
777 if (RelaSec->sh_type == ELF::SHT_CREL) {
779 EF.crels(*RelaSec);
780 if (!Relas)
781 return createError("unable to read CREL relocations for section " +
782 describe(EF, Sec) + ": " +
783 toString(Relas.takeError()));
784 for (typename ELFFile<ELFT>::Elf_Rela Rela : std::get<1>(*Relas))
785 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
786 } else {
788 EF.relas(*RelaSec);
789 if (!Relas)
790 return createError("unable to read relocations for section " +
791 describe(EF, Sec) + ": " +
792 toString(Relas.takeError()));
793 for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
794 FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
795 }
796 }
797
798 unsigned AddressSize = sizeof(typename ELFFile<ELFT>::uintX_t);
799 return ELFBBAddrMapAddressExtractor(Data, AddressSize, IsRelocatable,
800 std::move(FunctionOffsetTranslations));
801 }
802
804 uint64_t Offset = Cur.tell();
806 if (!AddressOrErr)
807 return AddressOrErr.takeError();
808 if (!IsRelocatable)
809 return *AddressOrErr;
810 auto FOTIterator = FunctionOffsetTranslations.find(Offset);
811 if (FOTIterator == FunctionOffsetTranslations.end())
812 return createError("failed to get relocation data for offset: " +
814 return FOTIterator->second;
815 }
816};
817
818template <typename ELFT>
821 const typename ELFFile<ELFT>::Elf_Shdr &Sec,
822 const typename ELFFile<ELFT>::Elf_Shdr *RelaSec,
823 std::vector<PGOAnalysisMap> *PGOAnalyses) {
824 // Read and optionally decompress section contents.
825 Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);
826 if (!ContentsOrErr)
827 return ContentsOrErr.takeError();
828 ArrayRef<uint8_t> Content = *ContentsOrErr;
829
830 std::unique_ptr<uint8_t[]> DecompressedContent;
831 if (Sec.sh_flags & llvm::ELF::SHF_COMPRESSED) {
832 Expected<StringRef> SectionNameOrErr = EF.getSectionName(Sec);
833 if (!SectionNameOrErr)
834 return SectionNameOrErr.takeError();
835 auto DecompressorOrErr =
836 Decompressor::create(*SectionNameOrErr, toStringRef(*ContentsOrErr),
837 EF.isLE(), ELFT::Is64Bits);
838 if (!DecompressorOrErr)
839 return DecompressorOrErr.takeError();
840 size_t DecompressedSize = DecompressorOrErr->getDecompressedSize();
841 DecompressedContent = std::make_unique<uint8_t[]>(DecompressedSize);
842 MutableArrayRef<uint8_t> DecompressedContentRef(DecompressedContent.get(),
843 DecompressedSize);
844 if (Error Err = DecompressorOrErr->decompress(DecompressedContentRef))
845 return std::move(Err);
846 Content = DecompressedContentRef;
847 }
848
849 DataExtractor Data(Content, EF.isLE());
850 auto ExtractorOrErr =
852 if (!ExtractorOrErr)
853 return ExtractorOrErr.takeError();
854 auto BBAddrMapsOrErr = decodeBBAddrMapPayload(*ExtractorOrErr, PGOAnalyses);
855 if (!BBAddrMapsOrErr)
856 return createError(toString(BBAddrMapsOrErr.takeError()) + " in " +
857 describe(EF, Sec));
858 return BBAddrMapsOrErr;
859}
860
861template <class ELFT>
863ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec,
864 std::vector<PGOAnalysisMap> *PGOAnalyses) const {
865 size_t OriginalPGOSize = PGOAnalyses ? PGOAnalyses->size() : 0;
866 auto AddrMapsOrErr = decodeBBAddrMapImpl(*this, Sec, RelaSec, PGOAnalyses);
867 // remove new analyses when an error occurs
868 if (!AddrMapsOrErr && PGOAnalyses)
869 PGOAnalyses->resize(OriginalPGOSize);
870 return std::move(AddrMapsOrErr);
871}
872
873template <class ELFT>
877 std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const {
879 Error Errors = Error::success();
880 for (const Elf_Shdr &Sec : cantFail(this->sections())) {
881 Expected<bool> DoesSectionMatch = IsMatch(Sec);
882 if (!DoesSectionMatch) {
883 Errors = joinErrors(std::move(Errors), DoesSectionMatch.takeError());
884 continue;
885 }
886 if (*DoesSectionMatch) {
887 if (SecToRelocMap.try_emplace(&Sec).second)
888 continue;
889 }
890
891 if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL &&
892 Sec.sh_type != ELF::SHT_CREL)
893 continue;
894
895 Expected<const Elf_Shdr *> RelSecOrErr = this->getSection(Sec.sh_info);
896 if (!RelSecOrErr) {
897 Errors = joinErrors(std::move(Errors),
898 createError(describe(*this, Sec) +
899 ": failed to get a relocated section: " +
900 toString(RelSecOrErr.takeError())));
901 continue;
902 }
903 const Elf_Shdr *ContentsSec = *RelSecOrErr;
904 Expected<bool> DoesRelTargetMatch = IsMatch(*ContentsSec);
905 if (!DoesRelTargetMatch) {
906 Errors = joinErrors(std::move(Errors), DoesRelTargetMatch.takeError());
907 continue;
908 }
909 if (*DoesRelTargetMatch)
910 SecToRelocMap[ContentsSec] = &Sec;
911 }
912 if(Errors)
913 return std::move(Errors);
914 return SecToRelocMap;
915}
916
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:217
#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:820
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:803
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:766
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & back() const
Get the last element.
Definition ArrayRef.h:150
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
const T * data() const
Definition ArrayRef.h:138
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:38
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition MapVector.h:118
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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
virtual Expected< uint64_t > extractAddress(DataExtractor::Cursor &Cur)
Extract and resolve an address at the current Cur position.
Definition BBAddrMap.h:269
AddressExtractor(const DataExtractor &Data, unsigned AddressSize)
Definition BBAddrMap.h:261
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:346
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr &Sec) const
Definition ELF.cpp:469
std::string getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Definition ELF.cpp:537
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:863
uint32_t getRelativeRelocationType() const
Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr &Sec) const
Definition ELF.h:745
Expected< Elf_Rela_Range > relas(const Elf_Shdr &Sec) const
Definition ELF.h:421
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Definition ELF.h:443
size_t getBufSize() const
Definition ELF.h:277
Expected< RelsOrRelas > decodeCrel(ArrayRef< uint8_t > Content) const
Definition ELF.cpp:429
const uint8_t * end() const
Definition ELF.h:275
Expected< uint64_t > getCrelHeader(ArrayRef< uint8_t > Content) const
Definition ELF.cpp:417
Expected< Elf_Dyn_Range > dynamicEntries() const
Definition ELF.cpp:648
const uint8_t * base() const
Definition ELF.h:274
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition ELF.cpp:700
Expected< Elf_Relr_Range > relrs(const Elf_Shdr &Sec) const
Definition ELF.h:429
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:876
bool isLE() const
Definition ELF.h:396
Expected< StringRef > getSectionName(const Elf_Shdr &Section, WarningHandler WarnHandler=&defaultWarningHandler) const
Definition ELF.h:1437
llvm::function_ref< Error(const Twine &Msg)> WarningHandler
Definition ELF.h:272
Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr &Sec) const
Definition ELF.h:689
Expected< RelsOrRelas > crels(const Elf_Shdr &Sec) const
Definition ELF.cpp:460
std::vector< Elf_Rel > decode_relrs(Elf_Relr_Range relrs) const
Definition ELF.cpp:353
@ SHF_COMPRESSED
Definition ELF.h:1286
@ 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:1164
@ SHT_CREL
Definition ELF.h:1177
@ SHT_DYNAMIC
Definition ELF.h:1161
@ SHT_RELA
Definition ELF.h:1159
@ PT_LOAD
Definition ELF.h:1568
@ PT_DYNAMIC
Definition ELF.h:1569
@ ET_REL
Definition ELF.h:119
@ RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG
Definition ELF.h:2020
@ RELOCATION_GROUPED_BY_INFO_FLAG
Definition ELF.h:2019
@ RELOCATION_GROUPED_BY_ADDEND_FLAG
Definition ELF.h:2021
@ RELOCATION_GROUP_HAS_ADDEND_FLAG
Definition ELF.h:2022
Error decodeCrel(ArrayRef< uint8_t > Content, function_ref< void(uint64_t, bool)> HdrHandler, function_ref< void(Elf_Crel_Impl< Is64 >)> EntryHandler)
Definition ELF.h:217
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Definition ELF.h:607
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)
LLVM_ABI StringRef getRISCVVendorRelocationTypeName(uint32_t Type, StringRef Vendor)
Definition ELF.cpp:194
LLVM_ABI Expected< std::vector< BBAddrMap > > decodeBBAddrMapPayload(AddressExtractor &Extractor, std::vector< PGOAnalysisMap > *PGOAnalyses=nullptr)
Decodes one BB address map section payload.
Definition BBAddrMap.cpp:47
std::string describe(const ELFFile< ELFT > &Obj, const typename ELFT::Shdr &Sec)
Definition ELF.h:147
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
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
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
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
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.