Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Object/ELF.cpp
35232 views
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/Support/DataExtractor.h"
13
14
using namespace llvm;
15
using namespace object;
16
17
#define STRINGIFY_ENUM_CASE(ns, name) \
18
case ns::name: \
19
return #name;
20
21
#define ELF_RELOC(name, value) STRINGIFY_ENUM_CASE(ELF, name)
22
23
StringRef llvm::object::getELFRelocationTypeName(uint32_t Machine,
24
uint32_t Type) {
25
switch (Machine) {
26
case ELF::EM_68K:
27
switch (Type) {
28
#include "llvm/BinaryFormat/ELFRelocs/M68k.def"
29
default:
30
break;
31
}
32
break;
33
case ELF::EM_X86_64:
34
switch (Type) {
35
#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
36
default:
37
break;
38
}
39
break;
40
case ELF::EM_386:
41
case ELF::EM_IAMCU:
42
switch (Type) {
43
#include "llvm/BinaryFormat/ELFRelocs/i386.def"
44
default:
45
break;
46
}
47
break;
48
case ELF::EM_MIPS:
49
switch (Type) {
50
#include "llvm/BinaryFormat/ELFRelocs/Mips.def"
51
default:
52
break;
53
}
54
break;
55
case ELF::EM_AARCH64:
56
switch (Type) {
57
#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
58
default:
59
break;
60
}
61
break;
62
case ELF::EM_ARM:
63
switch (Type) {
64
#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
65
default:
66
break;
67
}
68
break;
69
case ELF::EM_ARC_COMPACT:
70
case ELF::EM_ARC_COMPACT2:
71
switch (Type) {
72
#include "llvm/BinaryFormat/ELFRelocs/ARC.def"
73
default:
74
break;
75
}
76
break;
77
case ELF::EM_AVR:
78
switch (Type) {
79
#include "llvm/BinaryFormat/ELFRelocs/AVR.def"
80
default:
81
break;
82
}
83
break;
84
case ELF::EM_HEXAGON:
85
switch (Type) {
86
#include "llvm/BinaryFormat/ELFRelocs/Hexagon.def"
87
default:
88
break;
89
}
90
break;
91
case ELF::EM_LANAI:
92
switch (Type) {
93
#include "llvm/BinaryFormat/ELFRelocs/Lanai.def"
94
default:
95
break;
96
}
97
break;
98
case ELF::EM_PPC:
99
switch (Type) {
100
#include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
101
default:
102
break;
103
}
104
break;
105
case ELF::EM_PPC64:
106
switch (Type) {
107
#include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
108
default:
109
break;
110
}
111
break;
112
case ELF::EM_RISCV:
113
switch (Type) {
114
#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
115
default:
116
break;
117
}
118
break;
119
case ELF::EM_S390:
120
switch (Type) {
121
#include "llvm/BinaryFormat/ELFRelocs/SystemZ.def"
122
default:
123
break;
124
}
125
break;
126
case ELF::EM_SPARC:
127
case ELF::EM_SPARC32PLUS:
128
case ELF::EM_SPARCV9:
129
switch (Type) {
130
#include "llvm/BinaryFormat/ELFRelocs/Sparc.def"
131
default:
132
break;
133
}
134
break;
135
case ELF::EM_AMDGPU:
136
switch (Type) {
137
#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
138
default:
139
break;
140
}
141
break;
142
case ELF::EM_BPF:
143
switch (Type) {
144
#include "llvm/BinaryFormat/ELFRelocs/BPF.def"
145
default:
146
break;
147
}
148
break;
149
case ELF::EM_MSP430:
150
switch (Type) {
151
#include "llvm/BinaryFormat/ELFRelocs/MSP430.def"
152
default:
153
break;
154
}
155
break;
156
case ELF::EM_VE:
157
switch (Type) {
158
#include "llvm/BinaryFormat/ELFRelocs/VE.def"
159
default:
160
break;
161
}
162
break;
163
case ELF::EM_CSKY:
164
switch (Type) {
165
#include "llvm/BinaryFormat/ELFRelocs/CSKY.def"
166
default:
167
break;
168
}
169
break;
170
case ELF::EM_LOONGARCH:
171
switch (Type) {
172
#include "llvm/BinaryFormat/ELFRelocs/LoongArch.def"
173
default:
174
break;
175
}
176
break;
177
case ELF::EM_XTENSA:
178
switch (Type) {
179
#include "llvm/BinaryFormat/ELFRelocs/Xtensa.def"
180
default:
181
break;
182
}
183
break;
184
default:
185
break;
186
}
187
return "Unknown";
188
}
189
190
#undef ELF_RELOC
191
192
uint32_t llvm::object::getELFRelativeRelocationType(uint32_t Machine) {
193
switch (Machine) {
194
case ELF::EM_X86_64:
195
return ELF::R_X86_64_RELATIVE;
196
case ELF::EM_386:
197
case ELF::EM_IAMCU:
198
return ELF::R_386_RELATIVE;
199
case ELF::EM_MIPS:
200
break;
201
case ELF::EM_AARCH64:
202
return ELF::R_AARCH64_RELATIVE;
203
case ELF::EM_ARM:
204
return ELF::R_ARM_RELATIVE;
205
case ELF::EM_ARC_COMPACT:
206
case ELF::EM_ARC_COMPACT2:
207
return ELF::R_ARC_RELATIVE;
208
case ELF::EM_AVR:
209
break;
210
case ELF::EM_HEXAGON:
211
return ELF::R_HEX_RELATIVE;
212
case ELF::EM_LANAI:
213
break;
214
case ELF::EM_PPC:
215
break;
216
case ELF::EM_PPC64:
217
return ELF::R_PPC64_RELATIVE;
218
case ELF::EM_RISCV:
219
return ELF::R_RISCV_RELATIVE;
220
case ELF::EM_S390:
221
return ELF::R_390_RELATIVE;
222
case ELF::EM_SPARC:
223
case ELF::EM_SPARC32PLUS:
224
case ELF::EM_SPARCV9:
225
return ELF::R_SPARC_RELATIVE;
226
case ELF::EM_CSKY:
227
return ELF::R_CKCORE_RELATIVE;
228
case ELF::EM_VE:
229
return ELF::R_VE_RELATIVE;
230
case ELF::EM_AMDGPU:
231
break;
232
case ELF::EM_BPF:
233
break;
234
case ELF::EM_LOONGARCH:
235
return ELF::R_LARCH_RELATIVE;
236
default:
237
break;
238
}
239
return 0;
240
}
241
242
StringRef llvm::object::getELFSectionTypeName(uint32_t Machine, unsigned Type) {
243
switch (Machine) {
244
case ELF::EM_ARM:
245
switch (Type) {
246
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_EXIDX);
247
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
248
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
249
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
250
STRINGIFY_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
251
}
252
break;
253
case ELF::EM_HEXAGON:
254
switch (Type) {
255
STRINGIFY_ENUM_CASE(ELF, SHT_HEX_ORDERED);
256
STRINGIFY_ENUM_CASE(ELF, SHT_HEXAGON_ATTRIBUTES);
257
}
258
break;
259
case ELF::EM_X86_64:
260
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_X86_64_UNWIND); }
261
break;
262
case ELF::EM_MIPS:
263
case ELF::EM_MIPS_RS3_LE:
264
switch (Type) {
265
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
266
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
267
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_DWARF);
268
STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS);
269
}
270
break;
271
case ELF::EM_MSP430:
272
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); }
273
break;
274
case ELF::EM_RISCV:
275
switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); }
276
break;
277
case ELF::EM_AARCH64:
278
switch (Type) {
279
STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_AUTH_RELR);
280
STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_DYNAMIC);
281
STRINGIFY_ENUM_CASE(ELF, SHT_AARCH64_MEMTAG_GLOBALS_STATIC);
282
}
283
default:
284
break;
285
}
286
287
switch (Type) {
288
STRINGIFY_ENUM_CASE(ELF, SHT_NULL);
289
STRINGIFY_ENUM_CASE(ELF, SHT_PROGBITS);
290
STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB);
291
STRINGIFY_ENUM_CASE(ELF, SHT_STRTAB);
292
STRINGIFY_ENUM_CASE(ELF, SHT_RELA);
293
STRINGIFY_ENUM_CASE(ELF, SHT_HASH);
294
STRINGIFY_ENUM_CASE(ELF, SHT_DYNAMIC);
295
STRINGIFY_ENUM_CASE(ELF, SHT_NOTE);
296
STRINGIFY_ENUM_CASE(ELF, SHT_NOBITS);
297
STRINGIFY_ENUM_CASE(ELF, SHT_REL);
298
STRINGIFY_ENUM_CASE(ELF, SHT_SHLIB);
299
STRINGIFY_ENUM_CASE(ELF, SHT_DYNSYM);
300
STRINGIFY_ENUM_CASE(ELF, SHT_INIT_ARRAY);
301
STRINGIFY_ENUM_CASE(ELF, SHT_FINI_ARRAY);
302
STRINGIFY_ENUM_CASE(ELF, SHT_PREINIT_ARRAY);
303
STRINGIFY_ENUM_CASE(ELF, SHT_GROUP);
304
STRINGIFY_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX);
305
STRINGIFY_ENUM_CASE(ELF, SHT_RELR);
306
STRINGIFY_ENUM_CASE(ELF, SHT_CREL);
307
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_REL);
308
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELA);
309
STRINGIFY_ENUM_CASE(ELF, SHT_ANDROID_RELR);
310
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ODRTAB);
311
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LINKER_OPTIONS);
312
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_CALL_GRAPH_PROFILE);
313
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_ADDRSIG);
314
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_DEPENDENT_LIBRARIES);
315
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_SYMPART);
316
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_EHDR);
317
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_PART_PHDR);
318
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP_V0);
319
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_BB_ADDR_MAP);
320
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_OFFLOADING);
321
STRINGIFY_ENUM_CASE(ELF, SHT_LLVM_LTO);
322
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES);
323
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_HASH);
324
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verdef);
325
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_verneed);
326
STRINGIFY_ENUM_CASE(ELF, SHT_GNU_versym);
327
default:
328
return "Unknown";
329
}
330
}
331
332
template <class ELFT>
333
std::vector<typename ELFT::Rel>
334
ELFFile<ELFT>::decode_relrs(Elf_Relr_Range relrs) const {
335
// This function decodes the contents of an SHT_RELR packed relocation
336
// section.
337
//
338
// Proposal for adding SHT_RELR sections to generic-abi is here:
339
// https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
340
//
341
// The encoded sequence of Elf64_Relr entries in a SHT_RELR section looks
342
// like [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
343
//
344
// i.e. start with an address, followed by any number of bitmaps. The address
345
// entry encodes 1 relocation. The subsequent bitmap entries encode up to 63
346
// relocations each, at subsequent offsets following the last address entry.
347
//
348
// The bitmap entries must have 1 in the least significant bit. The assumption
349
// here is that an address cannot have 1 in lsb. Odd addresses are not
350
// supported.
351
//
352
// Excluding the least significant bit in the bitmap, each non-zero bit in
353
// the bitmap represents a relocation to be applied to a corresponding machine
354
// word that follows the base address word. The second least significant bit
355
// represents the machine word immediately following the initial address, and
356
// each bit that follows represents the next word, in linear order. As such,
357
// a single bitmap can encode up to 31 relocations in a 32-bit object, and
358
// 63 relocations in a 64-bit object.
359
//
360
// This encoding has a couple of interesting properties:
361
// 1. Looking at any entry, it is clear whether it's an address or a bitmap:
362
// even means address, odd means bitmap.
363
// 2. Just a simple list of addresses is a valid encoding.
364
365
Elf_Rel Rel;
366
Rel.r_info = 0;
367
Rel.setType(getRelativeRelocationType(), false);
368
std::vector<Elf_Rel> Relocs;
369
370
// Word type: uint32_t for Elf32, and uint64_t for Elf64.
371
using Addr = typename ELFT::uint;
372
373
Addr Base = 0;
374
for (Elf_Relr R : relrs) {
375
typename ELFT::uint Entry = R;
376
if ((Entry & 1) == 0) {
377
// Even entry: encodes the offset for next relocation.
378
Rel.r_offset = Entry;
379
Relocs.push_back(Rel);
380
// Set base offset for subsequent bitmap entries.
381
Base = Entry + sizeof(Addr);
382
} else {
383
// Odd entry: encodes bitmap for relocations starting at base.
384
for (Addr Offset = Base; (Entry >>= 1) != 0; Offset += sizeof(Addr))
385
if ((Entry & 1) != 0) {
386
Rel.r_offset = Offset;
387
Relocs.push_back(Rel);
388
}
389
Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(Addr);
390
}
391
}
392
393
return Relocs;
394
}
395
396
template <class ELFT>
397
Expected<uint64_t>
398
ELFFile<ELFT>::getCrelHeader(ArrayRef<uint8_t> Content) const {
399
DataExtractor Data(Content, isLE(), sizeof(typename ELFT::Addr));
400
Error Err = Error::success();
401
uint64_t Hdr = 0;
402
Hdr = Data.getULEB128(&Hdr, &Err);
403
if (Err)
404
return Err;
405
return Hdr;
406
}
407
408
template <class ELFT>
409
Expected<typename ELFFile<ELFT>::RelsOrRelas>
410
ELFFile<ELFT>::decodeCrel(ArrayRef<uint8_t> Content) const {
411
std::vector<Elf_Rel> Rels;
412
std::vector<Elf_Rela> Relas;
413
size_t I = 0;
414
bool HasAddend;
415
Error Err = object::decodeCrel<ELFT::Is64Bits>(
416
Content,
417
[&](uint64_t Count, bool HasA) {
418
HasAddend = HasA;
419
if (HasAddend)
420
Relas.resize(Count);
421
else
422
Rels.resize(Count);
423
},
424
[&](Elf_Crel Crel) {
425
if (HasAddend) {
426
Relas[I].r_offset = Crel.r_offset;
427
Relas[I].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);
428
Relas[I++].r_addend = Crel.r_addend;
429
} else {
430
Rels[I].r_offset = Crel.r_offset;
431
Rels[I++].setSymbolAndType(Crel.r_symidx, Crel.r_type, false);
432
}
433
});
434
if (Err)
435
return std::move(Err);
436
return std::make_pair(std::move(Rels), std::move(Relas));
437
}
438
439
template <class ELFT>
440
Expected<typename ELFFile<ELFT>::RelsOrRelas>
441
ELFFile<ELFT>::crels(const Elf_Shdr &Sec) const {
442
Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
443
if (!ContentsOrErr)
444
return ContentsOrErr.takeError();
445
return decodeCrel(*ContentsOrErr);
446
}
447
448
template <class ELFT>
449
Expected<std::vector<typename ELFT::Rela>>
450
ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
451
// This function reads relocations in Android's packed relocation format,
452
// which is based on SLEB128 and delta encoding.
453
Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
454
if (!ContentsOrErr)
455
return ContentsOrErr.takeError();
456
ArrayRef<uint8_t> Content = *ContentsOrErr;
457
if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||
458
Content[2] != 'S' || Content[3] != '2')
459
return createError("invalid packed relocation header");
460
DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
461
DataExtractor::Cursor Cur(/*Offset=*/4);
462
463
uint64_t NumRelocs = Data.getSLEB128(Cur);
464
uint64_t Offset = Data.getSLEB128(Cur);
465
uint64_t Addend = 0;
466
467
if (!Cur)
468
return std::move(Cur.takeError());
469
470
std::vector<Elf_Rela> Relocs;
471
Relocs.reserve(NumRelocs);
472
while (NumRelocs) {
473
uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);
474
if (!Cur)
475
return std::move(Cur.takeError());
476
if (NumRelocsInGroup > NumRelocs)
477
return createError("relocation group unexpectedly large");
478
NumRelocs -= NumRelocsInGroup;
479
480
uint64_t GroupFlags = Data.getSLEB128(Cur);
481
bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
482
bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
483
bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
484
bool GroupHasAddend = GroupFlags & ELF::RELOCATION_GROUP_HAS_ADDEND_FLAG;
485
486
uint64_t GroupOffsetDelta;
487
if (GroupedByOffsetDelta)
488
GroupOffsetDelta = Data.getSLEB128(Cur);
489
490
uint64_t GroupRInfo;
491
if (GroupedByInfo)
492
GroupRInfo = Data.getSLEB128(Cur);
493
494
if (GroupedByAddend && GroupHasAddend)
495
Addend += Data.getSLEB128(Cur);
496
497
if (!GroupHasAddend)
498
Addend = 0;
499
500
for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {
501
Elf_Rela R;
502
Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);
503
R.r_offset = Offset;
504
R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);
505
if (GroupHasAddend && !GroupedByAddend)
506
Addend += Data.getSLEB128(Cur);
507
R.r_addend = Addend;
508
Relocs.push_back(R);
509
}
510
if (!Cur)
511
return std::move(Cur.takeError());
512
}
513
514
return Relocs;
515
}
516
517
template <class ELFT>
518
std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
519
uint64_t Type) const {
520
#define DYNAMIC_STRINGIFY_ENUM(tag, value) \
521
case value: \
522
return #tag;
523
524
#define DYNAMIC_TAG(n, v)
525
switch (Arch) {
526
case ELF::EM_AARCH64:
527
switch (Type) {
528
#define AARCH64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
529
#include "llvm/BinaryFormat/DynamicTags.def"
530
#undef AARCH64_DYNAMIC_TAG
531
}
532
break;
533
534
case ELF::EM_HEXAGON:
535
switch (Type) {
536
#define HEXAGON_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
537
#include "llvm/BinaryFormat/DynamicTags.def"
538
#undef HEXAGON_DYNAMIC_TAG
539
}
540
break;
541
542
case ELF::EM_MIPS:
543
switch (Type) {
544
#define MIPS_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
545
#include "llvm/BinaryFormat/DynamicTags.def"
546
#undef MIPS_DYNAMIC_TAG
547
}
548
break;
549
550
case ELF::EM_PPC:
551
switch (Type) {
552
#define PPC_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
553
#include "llvm/BinaryFormat/DynamicTags.def"
554
#undef PPC_DYNAMIC_TAG
555
}
556
break;
557
558
case ELF::EM_PPC64:
559
switch (Type) {
560
#define PPC64_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
561
#include "llvm/BinaryFormat/DynamicTags.def"
562
#undef PPC64_DYNAMIC_TAG
563
}
564
break;
565
566
case ELF::EM_RISCV:
567
switch (Type) {
568
#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
569
#include "llvm/BinaryFormat/DynamicTags.def"
570
#undef RISCV_DYNAMIC_TAG
571
}
572
break;
573
}
574
#undef DYNAMIC_TAG
575
switch (Type) {
576
// Now handle all dynamic tags except the architecture specific ones
577
#define AARCH64_DYNAMIC_TAG(name, value)
578
#define MIPS_DYNAMIC_TAG(name, value)
579
#define HEXAGON_DYNAMIC_TAG(name, value)
580
#define PPC_DYNAMIC_TAG(name, value)
581
#define PPC64_DYNAMIC_TAG(name, value)
582
#define RISCV_DYNAMIC_TAG(name, value)
583
// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
584
#define DYNAMIC_TAG_MARKER(name, value)
585
#define DYNAMIC_TAG(name, value) case value: return #name;
586
#include "llvm/BinaryFormat/DynamicTags.def"
587
#undef DYNAMIC_TAG
588
#undef AARCH64_DYNAMIC_TAG
589
#undef MIPS_DYNAMIC_TAG
590
#undef HEXAGON_DYNAMIC_TAG
591
#undef PPC_DYNAMIC_TAG
592
#undef PPC64_DYNAMIC_TAG
593
#undef RISCV_DYNAMIC_TAG
594
#undef DYNAMIC_TAG_MARKER
595
#undef DYNAMIC_STRINGIFY_ENUM
596
default:
597
return "<unknown:>0x" + utohexstr(Type, true);
598
}
599
}
600
601
template <class ELFT>
602
std::string ELFFile<ELFT>::getDynamicTagAsString(uint64_t Type) const {
603
return getDynamicTagAsString(getHeader().e_machine, Type);
604
}
605
606
template <class ELFT>
607
Expected<typename ELFT::DynRange> ELFFile<ELFT>::dynamicEntries() const {
608
ArrayRef<Elf_Dyn> Dyn;
609
610
auto ProgramHeadersOrError = program_headers();
611
if (!ProgramHeadersOrError)
612
return ProgramHeadersOrError.takeError();
613
614
for (const Elf_Phdr &Phdr : *ProgramHeadersOrError) {
615
if (Phdr.p_type == ELF::PT_DYNAMIC) {
616
const uint8_t *DynOffset = base() + Phdr.p_offset;
617
if (DynOffset > end())
618
return createError(
619
"dynamic section offset past file size: corrupted ELF");
620
Dyn = ArrayRef(reinterpret_cast<const Elf_Dyn *>(DynOffset),
621
Phdr.p_filesz / sizeof(Elf_Dyn));
622
break;
623
}
624
}
625
626
// If we can't find the dynamic section in the program headers, we just fall
627
// back on the sections.
628
if (Dyn.empty()) {
629
auto SectionsOrError = sections();
630
if (!SectionsOrError)
631
return SectionsOrError.takeError();
632
633
for (const Elf_Shdr &Sec : *SectionsOrError) {
634
if (Sec.sh_type == ELF::SHT_DYNAMIC) {
635
Expected<ArrayRef<Elf_Dyn>> DynOrError =
636
getSectionContentsAsArray<Elf_Dyn>(Sec);
637
if (!DynOrError)
638
return DynOrError.takeError();
639
Dyn = *DynOrError;
640
break;
641
}
642
}
643
644
if (!Dyn.data())
645
return ArrayRef<Elf_Dyn>();
646
}
647
648
if (Dyn.empty())
649
return createError("invalid empty dynamic section");
650
651
if (Dyn.back().d_tag != ELF::DT_NULL)
652
return createError("dynamic sections must be DT_NULL terminated");
653
654
return Dyn;
655
}
656
657
template <class ELFT>
658
Expected<const uint8_t *>
659
ELFFile<ELFT>::toMappedAddr(uint64_t VAddr, WarningHandler WarnHandler) const {
660
auto ProgramHeadersOrError = program_headers();
661
if (!ProgramHeadersOrError)
662
return ProgramHeadersOrError.takeError();
663
664
llvm::SmallVector<Elf_Phdr *, 4> LoadSegments;
665
666
for (const Elf_Phdr &Phdr : *ProgramHeadersOrError)
667
if (Phdr.p_type == ELF::PT_LOAD)
668
LoadSegments.push_back(const_cast<Elf_Phdr *>(&Phdr));
669
670
auto SortPred = [](const Elf_Phdr_Impl<ELFT> *A,
671
const Elf_Phdr_Impl<ELFT> *B) {
672
return A->p_vaddr < B->p_vaddr;
673
};
674
if (!llvm::is_sorted(LoadSegments, SortPred)) {
675
if (Error E =
676
WarnHandler("loadable segments are unsorted by virtual address"))
677
return std::move(E);
678
llvm::stable_sort(LoadSegments, SortPred);
679
}
680
681
const Elf_Phdr *const *I = llvm::upper_bound(
682
LoadSegments, VAddr, [](uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
683
return VAddr < Phdr->p_vaddr;
684
});
685
686
if (I == LoadSegments.begin())
687
return createError("virtual address is not in any segment: 0x" +
688
Twine::utohexstr(VAddr));
689
--I;
690
const Elf_Phdr &Phdr = **I;
691
uint64_t Delta = VAddr - Phdr.p_vaddr;
692
if (Delta >= Phdr.p_filesz)
693
return createError("virtual address is not in any segment: 0x" +
694
Twine::utohexstr(VAddr));
695
696
uint64_t Offset = Phdr.p_offset + Delta;
697
if (Offset >= getBufSize())
698
return createError("can't map virtual address 0x" +
699
Twine::utohexstr(VAddr) + " to the segment with index " +
700
Twine(&Phdr - (*ProgramHeadersOrError).data() + 1) +
701
": the segment ends at 0x" +
702
Twine::utohexstr(Phdr.p_offset + Phdr.p_filesz) +
703
", which is greater than the file size (0x" +
704
Twine::utohexstr(getBufSize()) + ")");
705
706
return base() + Offset;
707
}
708
709
// Helper to extract and decode the next ULEB128 value as unsigned int.
710
// Returns zero and sets ULEBSizeErr if the ULEB128 value exceeds the unsigned
711
// int limit.
712
// Also returns zero if ULEBSizeErr is already in an error state.
713
// ULEBSizeErr is an out variable if an error occurs.
714
template <typename IntTy, std::enable_if_t<std::is_unsigned_v<IntTy>, int> = 0>
715
static IntTy readULEB128As(DataExtractor &Data, DataExtractor::Cursor &Cur,
716
Error &ULEBSizeErr) {
717
// Bail out and do not extract data if ULEBSizeErr is already set.
718
if (ULEBSizeErr)
719
return 0;
720
uint64_t Offset = Cur.tell();
721
uint64_t Value = Data.getULEB128(Cur);
722
if (Value > std::numeric_limits<IntTy>::max()) {
723
ULEBSizeErr = createError("ULEB128 value at offset 0x" +
724
Twine::utohexstr(Offset) + " exceeds UINT" +
725
Twine(std::numeric_limits<IntTy>::digits) +
726
"_MAX (0x" + Twine::utohexstr(Value) + ")");
727
return 0;
728
}
729
return static_cast<IntTy>(Value);
730
}
731
732
template <typename ELFT>
733
static Expected<std::vector<BBAddrMap>>
734
decodeBBAddrMapImpl(const ELFFile<ELFT> &EF,
735
const typename ELFFile<ELFT>::Elf_Shdr &Sec,
736
const typename ELFFile<ELFT>::Elf_Shdr *RelaSec,
737
std::vector<PGOAnalysisMap> *PGOAnalyses) {
738
bool IsRelocatable = EF.getHeader().e_type == ELF::ET_REL;
739
740
// This DenseMap maps the offset of each function (the location of the
741
// reference to the function in the SHT_LLVM_BB_ADDR_MAP section) to the
742
// addend (the location of the function in the text section).
743
llvm::DenseMap<uint64_t, uint64_t> FunctionOffsetTranslations;
744
if (IsRelocatable && RelaSec) {
745
assert(RelaSec &&
746
"Can't read a SHT_LLVM_BB_ADDR_MAP section in a relocatable "
747
"object file without providing a relocation section.");
748
Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas = EF.relas(*RelaSec);
749
if (!Relas)
750
return createError("unable to read relocations for section " +
751
describe(EF, Sec) + ": " +
752
toString(Relas.takeError()));
753
for (typename ELFFile<ELFT>::Elf_Rela Rela : *Relas)
754
FunctionOffsetTranslations[Rela.r_offset] = Rela.r_addend;
755
}
756
auto GetAddressForRelocation =
757
[&](unsigned RelocationOffsetInSection) -> Expected<unsigned> {
758
auto FOTIterator =
759
FunctionOffsetTranslations.find(RelocationOffsetInSection);
760
if (FOTIterator == FunctionOffsetTranslations.end()) {
761
return createError("failed to get relocation data for offset: " +
762
Twine::utohexstr(RelocationOffsetInSection) +
763
" in section " + describe(EF, Sec));
764
}
765
return FOTIterator->second;
766
};
767
Expected<ArrayRef<uint8_t>> ContentsOrErr = EF.getSectionContents(Sec);
768
if (!ContentsOrErr)
769
return ContentsOrErr.takeError();
770
ArrayRef<uint8_t> Content = *ContentsOrErr;
771
DataExtractor Data(Content, EF.isLE(), ELFT::Is64Bits ? 8 : 4);
772
std::vector<BBAddrMap> FunctionEntries;
773
774
DataExtractor::Cursor Cur(0);
775
Error ULEBSizeErr = Error::success();
776
Error MetadataDecodeErr = Error::success();
777
778
// Helper lampda to extract the (possiblly relocatable) address stored at Cur.
779
auto ExtractAddress = [&]() -> Expected<typename ELFFile<ELFT>::uintX_t> {
780
uint64_t RelocationOffsetInSection = Cur.tell();
781
auto Address =
782
static_cast<typename ELFFile<ELFT>::uintX_t>(Data.getAddress(Cur));
783
if (!Cur)
784
return Cur.takeError();
785
if (!IsRelocatable)
786
return Address;
787
assert(Address == 0);
788
Expected<unsigned> AddressOrErr =
789
GetAddressForRelocation(RelocationOffsetInSection);
790
if (!AddressOrErr)
791
return AddressOrErr.takeError();
792
return *AddressOrErr;
793
};
794
795
uint8_t Version = 0;
796
uint8_t Feature = 0;
797
BBAddrMap::Features FeatEnable{};
798
while (!ULEBSizeErr && !MetadataDecodeErr && Cur &&
799
Cur.tell() < Content.size()) {
800
if (Sec.sh_type == ELF::SHT_LLVM_BB_ADDR_MAP) {
801
Version = Data.getU8(Cur);
802
if (!Cur)
803
break;
804
if (Version > 2)
805
return createError("unsupported SHT_LLVM_BB_ADDR_MAP version: " +
806
Twine(static_cast<int>(Version)));
807
Feature = Data.getU8(Cur); // Feature byte
808
if (!Cur)
809
break;
810
auto FeatEnableOrErr = BBAddrMap::Features::decode(Feature);
811
if (!FeatEnableOrErr)
812
return FeatEnableOrErr.takeError();
813
FeatEnable = *FeatEnableOrErr;
814
if (Feature != 0 && Version < 2 && Cur)
815
return createError(
816
"version should be >= 2 for SHT_LLVM_BB_ADDR_MAP when "
817
"PGO features are enabled: version = " +
818
Twine(static_cast<int>(Version)) +
819
" feature = " + Twine(static_cast<int>(Feature)));
820
}
821
uint32_t NumBlocksInBBRange = 0;
822
uint32_t NumBBRanges = 1;
823
typename ELFFile<ELFT>::uintX_t RangeBaseAddress = 0;
824
std::vector<BBAddrMap::BBEntry> BBEntries;
825
if (FeatEnable.MultiBBRange) {
826
NumBBRanges = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
827
if (!Cur || ULEBSizeErr)
828
break;
829
if (!NumBBRanges)
830
return createError("invalid zero number of BB ranges at offset " +
831
Twine::utohexstr(Cur.tell()) + " in " +
832
describe(EF, Sec));
833
} else {
834
auto AddressOrErr = ExtractAddress();
835
if (!AddressOrErr)
836
return AddressOrErr.takeError();
837
RangeBaseAddress = *AddressOrErr;
838
NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
839
}
840
std::vector<BBAddrMap::BBRangeEntry> BBRangeEntries;
841
uint32_t TotalNumBlocks = 0;
842
for (uint32_t BBRangeIndex = 0; BBRangeIndex < NumBBRanges;
843
++BBRangeIndex) {
844
uint32_t PrevBBEndOffset = 0;
845
if (FeatEnable.MultiBBRange) {
846
auto AddressOrErr = ExtractAddress();
847
if (!AddressOrErr)
848
return AddressOrErr.takeError();
849
RangeBaseAddress = *AddressOrErr;
850
NumBlocksInBBRange = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
851
}
852
for (uint32_t BlockIndex = 0; !MetadataDecodeErr && !ULEBSizeErr && Cur &&
853
(BlockIndex < NumBlocksInBBRange);
854
++BlockIndex) {
855
uint32_t ID = Version >= 2
856
? readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr)
857
: BlockIndex;
858
uint32_t Offset = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
859
uint32_t Size = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
860
uint32_t MD = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
861
if (Version >= 1) {
862
// Offset is calculated relative to the end of the previous BB.
863
Offset += PrevBBEndOffset;
864
PrevBBEndOffset = Offset + Size;
865
}
866
Expected<BBAddrMap::BBEntry::Metadata> MetadataOrErr =
867
BBAddrMap::BBEntry::Metadata::decode(MD);
868
if (!MetadataOrErr) {
869
MetadataDecodeErr = MetadataOrErr.takeError();
870
break;
871
}
872
BBEntries.push_back({ID, Offset, Size, *MetadataOrErr});
873
}
874
TotalNumBlocks += BBEntries.size();
875
BBRangeEntries.push_back({RangeBaseAddress, std::move(BBEntries)});
876
}
877
FunctionEntries.push_back({std::move(BBRangeEntries)});
878
879
if (PGOAnalyses || FeatEnable.hasPGOAnalysis()) {
880
// Function entry count
881
uint64_t FuncEntryCount =
882
FeatEnable.FuncEntryCount
883
? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
884
: 0;
885
886
std::vector<PGOAnalysisMap::PGOBBEntry> PGOBBEntries;
887
for (uint32_t BlockIndex = 0;
888
FeatEnable.hasPGOAnalysisBBData() && !MetadataDecodeErr &&
889
!ULEBSizeErr && Cur && (BlockIndex < TotalNumBlocks);
890
++BlockIndex) {
891
// Block frequency
892
uint64_t BBF = FeatEnable.BBFreq
893
? readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr)
894
: 0;
895
896
// Branch probability
897
llvm::SmallVector<PGOAnalysisMap::PGOBBEntry::SuccessorEntry, 2>
898
Successors;
899
if (FeatEnable.BrProb) {
900
auto SuccCount = readULEB128As<uint64_t>(Data, Cur, ULEBSizeErr);
901
for (uint64_t I = 0; I < SuccCount; ++I) {
902
uint32_t BBID = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
903
uint32_t BrProb = readULEB128As<uint32_t>(Data, Cur, ULEBSizeErr);
904
if (PGOAnalyses)
905
Successors.push_back({BBID, BranchProbability::getRaw(BrProb)});
906
}
907
}
908
909
if (PGOAnalyses)
910
PGOBBEntries.push_back({BlockFrequency(BBF), std::move(Successors)});
911
}
912
913
if (PGOAnalyses)
914
PGOAnalyses->push_back(
915
{FuncEntryCount, std::move(PGOBBEntries), FeatEnable});
916
}
917
}
918
// Either Cur is in the error state, or we have an error in ULEBSizeErr or
919
// MetadataDecodeErr (but not both), but we join all errors here to be safe.
920
if (!Cur || ULEBSizeErr || MetadataDecodeErr)
921
return joinErrors(joinErrors(Cur.takeError(), std::move(ULEBSizeErr)),
922
std::move(MetadataDecodeErr));
923
return FunctionEntries;
924
}
925
926
template <class ELFT>
927
Expected<std::vector<BBAddrMap>>
928
ELFFile<ELFT>::decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec,
929
std::vector<PGOAnalysisMap> *PGOAnalyses) const {
930
size_t OriginalPGOSize = PGOAnalyses ? PGOAnalyses->size() : 0;
931
auto AddrMapsOrErr = decodeBBAddrMapImpl(*this, Sec, RelaSec, PGOAnalyses);
932
// remove new analyses when an error occurs
933
if (!AddrMapsOrErr && PGOAnalyses)
934
PGOAnalyses->resize(OriginalPGOSize);
935
return std::move(AddrMapsOrErr);
936
}
937
938
template <class ELFT>
939
Expected<
940
MapVector<const typename ELFT::Shdr *, const typename ELFT::Shdr *>>
941
ELFFile<ELFT>::getSectionAndRelocations(
942
std::function<Expected<bool>(const Elf_Shdr &)> IsMatch) const {
943
MapVector<const Elf_Shdr *, const Elf_Shdr *> SecToRelocMap;
944
Error Errors = Error::success();
945
for (const Elf_Shdr &Sec : cantFail(this->sections())) {
946
Expected<bool> DoesSectionMatch = IsMatch(Sec);
947
if (!DoesSectionMatch) {
948
Errors = joinErrors(std::move(Errors), DoesSectionMatch.takeError());
949
continue;
950
}
951
if (*DoesSectionMatch) {
952
if (SecToRelocMap.insert(std::make_pair(&Sec, (const Elf_Shdr *)nullptr))
953
.second)
954
continue;
955
}
956
957
if (Sec.sh_type != ELF::SHT_RELA && Sec.sh_type != ELF::SHT_REL)
958
continue;
959
960
Expected<const Elf_Shdr *> RelSecOrErr = this->getSection(Sec.sh_info);
961
if (!RelSecOrErr) {
962
Errors = joinErrors(std::move(Errors),
963
createError(describe(*this, Sec) +
964
": failed to get a relocated section: " +
965
toString(RelSecOrErr.takeError())));
966
continue;
967
}
968
const Elf_Shdr *ContentsSec = *RelSecOrErr;
969
Expected<bool> DoesRelTargetMatch = IsMatch(*ContentsSec);
970
if (!DoesRelTargetMatch) {
971
Errors = joinErrors(std::move(Errors), DoesRelTargetMatch.takeError());
972
continue;
973
}
974
if (*DoesRelTargetMatch)
975
SecToRelocMap[ContentsSec] = &Sec;
976
}
977
if(Errors)
978
return std::move(Errors);
979
return SecToRelocMap;
980
}
981
982
template class llvm::object::ELFFile<ELF32LE>;
983
template class llvm::object::ELFFile<ELF32BE>;
984
template class llvm::object::ELFFile<ELF64LE>;
985
template class llvm::object::ELFFile<ELF64BE>;
986
987