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"
10#include "llvm/ADT/StringExtras.h"
11#include "llvm/BinaryFormat/ELF.h"
12#include "llvm/Object/BBAddrMap.h"
13#include "llvm/Object/Decompressor.h"
14#include "llvm/Support/Compiler.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
25StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
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;
71 case ELF::EM_ARC_COMPACT:
72 case ELF::EM_ARC_COMPACT2:
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:
129 case ELF::EM_SPARC32PLUS:
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;
172 case ELF::EM_LOONGARCH:
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
194StringRef llvm::object::getRISCVVendorRelocationTypeName(uint32_t Type,
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
207uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) {
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;
220 case ELF::EM_ARC_COMPACT:
221 case ELF::EM_ARC_COMPACT2:
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:
238 case ELF::EM_SPARC32PLUS:
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;
249 case ELF::EM_LOONGARCH:
250 return ELF::R_LARCH_RELATIVE;
251 default:
252 break;
253 }
254 return 0;
255}
256
257StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
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:
278 case ELF::EM_MIPS_RS3_LE:
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);
409 }
410 }
411
412 return Relocs;
413}
414
415template <class ELFT>
416Expected<uint64_t>
417ELFFile<ELFT>::getCrelHeader(ArrayRef<uint8_t> Content) const {
418 DataExtractor Data(Content, isLE());
419 Error Err = Error::success();
420 uint64_t Hdr = 0;
421 Hdr = Data.getULEB128(offset_ptr: &Hdr, Err: &Err);
422 if (Err)
423 return Err;
424 return Hdr;
425}
426
427template <class ELFT>
428Expected<typename ELFFile<ELFT>::RelsOrRelas>
429ELFFile<ELFT>::decodeCrel(ArrayRef<uint8_t> Content) const {
430 std::vector<Elf_Rel> Rels;
431 std::vector<Elf_Rela> Relas;
432 size_t I = 0;
433 bool HasAddend;
434 Error Err = object::decodeCrel<ELFT::Is64Bits>(
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>
459Expected<typename ELFFile<ELFT>::RelsOrRelas>
460ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const {
461 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
462 if (!ContentsOrErr)
463 return ContentsOrErr.takeError();
464 return decodeCrel(Content: *ContentsOrErr);
465}
466
467template <class ELFT>
468Expected<std::vector<typename ELFT::Rela>>
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.
472 Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
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(Err: "invalid packed relocation header");
479 DataExtractor Data(Content, isLE());
480 DataExtractor::Cursor Cur(/*Offset=*/4);
481
482 uint64_t NumRelocs = Data.getSLEB128(C&: Cur);
483 uint64_t Offset = Data.getSLEB128(C&: 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(C&: Cur);
493 if (!Cur)
494 return std::move(Cur.takeError());
495 if (NumRelocsInGroup > NumRelocs)
496 return createError(Err: "relocation group unexpectedly large");
497 NumRelocs -= NumRelocsInGroup;
498
499 uint64_t GroupFlags = Data.getSLEB128(C&: 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(C&: Cur);
508
509 uint64_t GroupRInfo;
510 if (GroupedByInfo)
511 GroupRInfo = Data.getSLEB128(C&: Cur);
512
513 if (GroupedByAddend && GroupHasAddend)
514 Addend += Data.getSLEB128(C&: 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(C&: Cur);
522 R.r_offset = Offset;
523 R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(C&: Cur);
524 if (GroupHasAddend && !GroupedByAddend)
525 Addend += Data.getSLEB128(C&: 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:
594 case ELF::EM_SPARC32PLUS:
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(X: Type, LowerCase: true);
639 }
640}
641
642template <class ELFT>
643std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {
644 return getDynamicTagAsString(getHeader().e_machine, Type);
645}
646
647template <class ELFT>
648Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
649 ArrayRef<Elf_Dyn> Dyn;
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 Err: "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 =
677 getSectionContentsAsArray<Elf_Dyn>(Sec);
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(Err: "invalid empty dynamic section");
691
692 if (Dyn.back().d_tag != ELF::DT_NULL)
693 return createError(Err: "dynamic sections must be DT_NULL terminated");
694
695 return Dyn;
696}
697
698template <class ELFT>
699Expected<const uint8_t *>
700ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
701 auto ProgramHeadersOrError = program_headers();
702 if (!ProgramHeadersOrError)
703 return ProgramHeadersOrError.takeError();
704
705 llvm::SmallVector<Elf_Phdr *, 4> LoadSegments;
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(Err: "virtual address is not in any segment: 0x" +
729 Twine::utohexstr(Val: 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(Err: "virtual address is not in any segment: 0x" +
735 Twine::utohexstr(Val: 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(Val: VAddr) + " to the segment with index " +
741 Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
742 ": the segment ends at 0x" +
743 Twine::utohexstr(Val: Phdr.p_offset + Phdr.p_filesz) +
744 ", which is greater than the file size (0x" +
745 Twine::utohexstr(Val: getBufSize()) + ")");
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>
765 static Expected<ELFBBAddrMapAddressExtractor>
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) {
778 Expected<typename ELFFile<ELFT>::RelsOrRelas> Relas =
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 {
787 Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
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
803 Expected<uint64_t> extractAddress(DataExtractor::Cursor &Cur) override {
804 uint64_t Offset = Cur.tell();
805 Expected<uint64_t> AddressOrErr = AddressExtractor::extractAddress(Cur);
806 if (!AddressOrErr)
807 return AddressOrErr.takeError();
808 if (!IsRelocatable)
809 return *AddressOrErr;
810 auto FOTIterator = FunctionOffsetTranslations.find(Val: Offset);
811 if (FOTIterator == FunctionOffsetTranslations.end())
812 return createError(Err: "failed to get relocation data for offset: " +
813 Twine::utohexstr(Val: Offset));
814 return FOTIterator->second;
815 }
816};
817
818template <typename ELFT>
819static Expected<std::vector<BBAddrMap>>
820decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
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(Name: *SectionNameOrErr, Data: toStringRef(Input: *ContentsOrErr),
837 IsLE: EF.isLE(), Is64Bit: ELFT::Is64Bits);
838 if (!DecompressorOrErr)
839 return DecompressorOrErr.takeError();
840 size_t DecompressedSize = DecompressorOrErr->getDecompressedSize();
841 DecompressedContent = std::make_unique<uint8_t[]>(num: 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 =
851 ELFBBAddrMapAddressExtractor::create(Data, EF, Sec, RelaSec);
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>
862Expected<std::vector<BBAddrMap>>
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(new_size: OriginalPGOSize);
870 return std::move(AddrMapsOrErr);
871}
872
873template <class ELFT>
874Expected<
875 MapVector<const typename ELFT::Shdr *, const typename ELFT::Shdr *>>
876ELFFile<ELFT>::getSectionAndRelocations(
877 std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const {
878 MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap;
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(E1: std::move(Errors), E2: 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(E1: std::move(Errors), E2: 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
917template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF32LE>;
918template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF32BE>;
919template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF64LE>;
920template class LLVM_EXPORT_TEMPLATE llvm::object::ELFFile<ELF64BE>;
921