Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- ELFYAML.h - ELF YAMLIO implementation --------------------*- C++ -*-===//
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
/// \file
10
/// This file declares classes for handling the YAML representation
11
/// of ELF.
12
///
13
//===----------------------------------------------------------------------===//
14
 
15
#ifndef LLVM_OBJECTYAML_ELFYAML_H
16
#define LLVM_OBJECTYAML_ELFYAML_H
17
 
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/BinaryFormat/ELF.h"
20
#include "llvm/Object/ELFTypes.h"
21
#include "llvm/ObjectYAML/DWARFYAML.h"
22
#include "llvm/ObjectYAML/YAML.h"
23
#include "llvm/Support/YAMLTraits.h"
24
#include <cstdint>
25
#include <memory>
26
#include <optional>
27
#include <vector>
28
 
29
namespace llvm {
30
namespace ELFYAML {
31
 
32
StringRef dropUniqueSuffix(StringRef S);
33
std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
34
 
35
// These types are invariant across 32/64-bit ELF, so for simplicity just
36
// directly give them their exact sizes. We don't need to worry about
37
// endianness because these are just the types in the YAMLIO structures,
38
// and are appropriately converted to the necessary endianness when
39
// reading/generating binary object files.
40
// The naming of these types is intended to be ELF_PREFIX, where PREFIX is
41
// the common prefix of the respective constants. E.g. ELF_EM corresponds
42
// to the `e_machine` constants, like `EM_X86_64`.
43
// In the future, these would probably be better suited by C++11 enum
44
// class's with appropriate fixed underlying type.
45
LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET)
46
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PT)
47
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM)
48
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS)
49
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA)
50
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
51
// Just use 64, since it can hold 32-bit values too.
52
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF)
53
// Just use 64, since it can hold 32-bit values too.
54
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_DYNTAG)
55
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_PF)
56
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
57
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
58
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
59
// Just use 64, since it can hold 32-bit values too.
60
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
61
LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
62
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
63
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
64
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_NT)
65
 
66
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
67
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
68
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
69
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
70
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
71
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
72
 
73
LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
74
LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
75
 
76
template <class ELFT>
77
unsigned getDefaultShEntSize(unsigned EMachine, ELF_SHT SecType,
78
                             StringRef SecName) {
79
  if (EMachine == ELF::EM_MIPS && SecType == ELF::SHT_MIPS_ABIFLAGS)
80
    return sizeof(object::Elf_Mips_ABIFlags<ELFT>);
81
 
82
  switch (SecType) {
83
  case ELF::SHT_SYMTAB:
84
  case ELF::SHT_DYNSYM:
85
    return sizeof(typename ELFT::Sym);
86
  case ELF::SHT_GROUP:
87
    return sizeof(typename ELFT::Word);
88
  case ELF::SHT_REL:
89
    return sizeof(typename ELFT::Rel);
90
  case ELF::SHT_RELA:
91
    return sizeof(typename ELFT::Rela);
92
  case ELF::SHT_RELR:
93
    return sizeof(typename ELFT::Relr);
94
  case ELF::SHT_DYNAMIC:
95
    return sizeof(typename ELFT::Dyn);
96
  case ELF::SHT_HASH:
97
    return sizeof(typename ELFT::Word);
98
  case ELF::SHT_SYMTAB_SHNDX:
99
    return sizeof(typename ELFT::Word);
100
  case ELF::SHT_GNU_versym:
101
    return sizeof(typename ELFT::Half);
102
  case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
103
    return sizeof(object::Elf_CGProfile_Impl<ELFT>);
104
  default:
105
    if (SecName == ".debug_str")
106
      return 1;
107
    return 0;
108
  }
109
}
110
 
111
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
112
// since 64-bit can hold 32-bit values too.
113
struct FileHeader {
114
  ELF_ELFCLASS Class;
115
  ELF_ELFDATA Data;
116
  ELF_ELFOSABI OSABI;
117
  llvm::yaml::Hex8 ABIVersion;
118
  ELF_ET Type;
119
  std::optional<ELF_EM> Machine;
120
  ELF_EF Flags;
121
  llvm::yaml::Hex64 Entry;
122
  std::optional<StringRef> SectionHeaderStringTable;
123
 
124
  std::optional<llvm::yaml::Hex64> EPhOff;
125
  std::optional<llvm::yaml::Hex16> EPhEntSize;
126
  std::optional<llvm::yaml::Hex16> EPhNum;
127
  std::optional<llvm::yaml::Hex16> EShEntSize;
128
  std::optional<llvm::yaml::Hex64> EShOff;
129
  std::optional<llvm::yaml::Hex16> EShNum;
130
  std::optional<llvm::yaml::Hex16> EShStrNdx;
131
};
132
 
133
struct SectionHeader {
134
  StringRef Name;
135
};
136
 
137
struct Symbol {
138
  StringRef Name;
139
  ELF_STT Type;
140
  std::optional<StringRef> Section;
141
  std::optional<ELF_SHN> Index;
142
  ELF_STB Binding;
143
  std::optional<llvm::yaml::Hex64> Value;
144
  std::optional<llvm::yaml::Hex64> Size;
145
  std::optional<uint8_t> Other;
146
 
147
  std::optional<uint32_t> StName;
148
};
149
 
150
struct SectionOrType {
151
  StringRef sectionNameOrType;
152
};
153
 
154
struct DynamicEntry {
155
  ELF_DYNTAG Tag;
156
  llvm::yaml::Hex64 Val;
157
};
158
 
159
struct BBAddrMapEntry {
160
  struct BBEntry {
161
    uint32_t ID;
162
    llvm::yaml::Hex64 AddressOffset;
163
    llvm::yaml::Hex64 Size;
164
    llvm::yaml::Hex64 Metadata;
165
  };
166
  uint8_t Version;
167
  llvm::yaml::Hex8 Feature;
168
  llvm::yaml::Hex64 Address;
169
  std::optional<uint64_t> NumBlocks;
170
  std::optional<std::vector<BBEntry>> BBEntries;
171
};
172
 
173
struct StackSizeEntry {
174
  llvm::yaml::Hex64 Address;
175
  llvm::yaml::Hex64 Size;
176
};
177
 
178
struct NoteEntry {
179
  StringRef Name;
180
  yaml::BinaryRef Desc;
181
  ELF_NT Type;
182
};
183
 
184
struct Chunk {
185
  enum class ChunkKind {
186
    Dynamic,
187
    Group,
188
    RawContent,
189
    Relocation,
190
    Relr,
191
    NoBits,
192
    Note,
193
    Hash,
194
    GnuHash,
195
    Verdef,
196
    Verneed,
197
    StackSizes,
198
    SymtabShndxSection,
199
    Symver,
200
    ARMIndexTable,
201
    MipsABIFlags,
202
    Addrsig,
203
    LinkerOptions,
204
    DependentLibraries,
205
    CallGraphProfile,
206
    BBAddrMap,
207
 
208
    // Special chunks.
209
    SpecialChunksStart,
210
    Fill = SpecialChunksStart,
211
    SectionHeaderTable,
212
  };
213
 
214
  ChunkKind Kind;
215
  StringRef Name;
216
  std::optional<llvm::yaml::Hex64> Offset;
217
 
218
  // Usually chunks are not created implicitly, but rather loaded from YAML.
219
  // This flag is used to signal whether this is the case or not.
220
  bool IsImplicit;
221
 
222
  Chunk(ChunkKind K, bool Implicit) : Kind(K), IsImplicit(Implicit) {}
223
  virtual ~Chunk();
224
};
225
 
226
struct Section : public Chunk {
227
  ELF_SHT Type;
228
  std::optional<ELF_SHF> Flags;
229
  std::optional<llvm::yaml::Hex64> Address;
230
  std::optional<StringRef> Link;
231
  llvm::yaml::Hex64 AddressAlign;
232
  std::optional<llvm::yaml::Hex64> EntSize;
233
 
234
  std::optional<yaml::BinaryRef> Content;
235
  std::optional<llvm::yaml::Hex64> Size;
236
 
237
  // Holds the original section index.
238
  unsigned OriginalSecNdx;
239
 
240
  Section(ChunkKind Kind, bool IsImplicit = false) : Chunk(Kind, IsImplicit) {}
241
 
242
  static bool classof(const Chunk *S) {
243
    return S->Kind < ChunkKind::SpecialChunksStart;
244
  }
245
 
246
  // Some derived sections might have their own special entries. This method
247
  // returns a vector of <entry name, is used> pairs. It is used for section
248
  // validation.
249
  virtual std::vector<std::pair<StringRef, bool>> getEntries() const {
250
    return {};
251
  };
252
 
253
  // The following members are used to override section fields which is
254
  // useful for creating invalid objects.
255
 
256
  // This can be used to override the sh_addralign field.
257
  std::optional<llvm::yaml::Hex64> ShAddrAlign;
258
 
259
  // This can be used to override the offset stored in the sh_name field.
260
  // It does not affect the name stored in the string table.
261
  std::optional<llvm::yaml::Hex64> ShName;
262
 
263
  // This can be used to override the sh_offset field. It does not place the
264
  // section data at the offset specified.
265
  std::optional<llvm::yaml::Hex64> ShOffset;
266
 
267
  // This can be used to override the sh_size field. It does not affect the
268
  // content written.
269
  std::optional<llvm::yaml::Hex64> ShSize;
270
 
271
  // This can be used to override the sh_flags field.
272
  std::optional<llvm::yaml::Hex64> ShFlags;
273
 
274
  // This can be used to override the sh_type field. It is useful when we
275
  // want to use specific YAML keys for a section of a particular type to
276
  // describe the content, but still want to have a different final type
277
  // for the section.
278
  std::optional<ELF_SHT> ShType;
279
};
280
 
281
// Fill is a block of data which is placed outside of sections. It is
282
// not present in the sections header table, but it might affect the output file
283
// size and program headers produced.
284
struct Fill : Chunk {
285
  std::optional<yaml::BinaryRef> Pattern;
286
  llvm::yaml::Hex64 Size;
287
 
288
  Fill() : Chunk(ChunkKind::Fill, /*Implicit=*/false) {}
289
 
290
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
291
};
292
 
293
struct SectionHeaderTable : Chunk {
294
  SectionHeaderTable(bool IsImplicit)
295
      : Chunk(ChunkKind::SectionHeaderTable, IsImplicit) {}
296
 
297
  static bool classof(const Chunk *S) {
298
    return S->Kind == ChunkKind::SectionHeaderTable;
299
  }
300
 
301
  std::optional<std::vector<SectionHeader>> Sections;
302
  std::optional<std::vector<SectionHeader>> Excluded;
303
  std::optional<bool> NoHeaders;
304
 
305
  size_t getNumHeaders(size_t SectionsNum) const {
306
    if (IsImplicit || isDefault())
307
      return SectionsNum;
308
    if (NoHeaders)
309
      return (*NoHeaders) ? 0 : SectionsNum;
310
    return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
311
  }
312
 
313
  bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
314
 
315
  static constexpr StringRef TypeStr = "SectionHeaderTable";
316
};
317
 
318
struct BBAddrMapSection : Section {
319
  std::optional<std::vector<BBAddrMapEntry>> Entries;
320
 
321
  BBAddrMapSection() : Section(ChunkKind::BBAddrMap) {}
322
 
323
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
324
    return {{"Entries", Entries.has_value()}};
325
  };
326
 
327
  static bool classof(const Chunk *S) {
328
    return S->Kind == ChunkKind::BBAddrMap;
329
  }
330
};
331
 
332
struct StackSizesSection : Section {
333
  std::optional<std::vector<StackSizeEntry>> Entries;
334
 
335
  StackSizesSection() : Section(ChunkKind::StackSizes) {}
336
 
337
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
338
    return {{"Entries", Entries.has_value()}};
339
  };
340
 
341
  static bool classof(const Chunk *S) {
342
    return S->Kind == ChunkKind::StackSizes;
343
  }
344
 
345
  static bool nameMatches(StringRef Name) {
346
    return Name == ".stack_sizes";
347
  }
348
};
349
 
350
struct DynamicSection : Section {
351
  std::optional<std::vector<DynamicEntry>> Entries;
352
 
353
  DynamicSection() : Section(ChunkKind::Dynamic) {}
354
 
355
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
356
    return {{"Entries", Entries.has_value()}};
357
  };
358
 
359
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Dynamic; }
360
};
361
 
362
struct RawContentSection : Section {
363
  std::optional<llvm::yaml::Hex64> Info;
364
 
365
  RawContentSection() : Section(ChunkKind::RawContent) {}
366
 
367
  static bool classof(const Chunk *S) {
368
    return S->Kind == ChunkKind::RawContent;
369
  }
370
 
371
  // Is used when a content is read as an array of bytes.
372
  std::optional<std::vector<uint8_t>> ContentBuf;
373
};
374
 
375
struct NoBitsSection : Section {
376
  NoBitsSection() : Section(ChunkKind::NoBits) {}
377
 
378
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::NoBits; }
379
};
380
 
381
struct NoteSection : Section {
382
  std::optional<std::vector<ELFYAML::NoteEntry>> Notes;
383
 
384
  NoteSection() : Section(ChunkKind::Note) {}
385
 
386
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
387
    return {{"Notes", Notes.has_value()}};
388
  };
389
 
390
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Note; }
391
};
392
 
393
struct HashSection : Section {
394
  std::optional<std::vector<uint32_t>> Bucket;
395
  std::optional<std::vector<uint32_t>> Chain;
396
 
397
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
398
    return {{"Bucket", Bucket.has_value()}, {"Chain", Chain.has_value()}};
399
  };
400
 
401
  // The following members are used to override section fields.
402
  // This is useful for creating invalid objects.
403
  std::optional<llvm::yaml::Hex64> NBucket;
404
  std::optional<llvm::yaml::Hex64> NChain;
405
 
406
  HashSection() : Section(ChunkKind::Hash) {}
407
 
408
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
409
};
410
 
411
struct GnuHashHeader {
412
  // The number of hash buckets.
413
  // Not used when dumping the object, but can be used to override
414
  // the real number of buckets when emiting an object from a YAML document.
415
  std::optional<llvm::yaml::Hex32> NBuckets;
416
 
417
  // Index of the first symbol in the dynamic symbol table
418
  // included in the hash table.
419
  llvm::yaml::Hex32 SymNdx;
420
 
421
  // The number of words in the Bloom filter.
422
  // Not used when dumping the object, but can be used to override the real
423
  // number of words in the Bloom filter when emiting an object from a YAML
424
  // document.
425
  std::optional<llvm::yaml::Hex32> MaskWords;
426
 
427
  // A shift constant used by the Bloom filter.
428
  llvm::yaml::Hex32 Shift2;
429
};
430
 
431
struct GnuHashSection : Section {
432
  std::optional<GnuHashHeader> Header;
433
  std::optional<std::vector<llvm::yaml::Hex64>> BloomFilter;
434
  std::optional<std::vector<llvm::yaml::Hex32>> HashBuckets;
435
  std::optional<std::vector<llvm::yaml::Hex32>> HashValues;
436
 
437
  GnuHashSection() : Section(ChunkKind::GnuHash) {}
438
 
439
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
440
    return {{"Header", Header.has_value()},
441
            {"BloomFilter", BloomFilter.has_value()},
442
            {"HashBuckets", HashBuckets.has_value()},
443
            {"HashValues", HashValues.has_value()}};
444
  };
445
 
446
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::GnuHash; }
447
};
448
 
449
struct VernauxEntry {
450
  uint32_t Hash;
451
  uint16_t Flags;
452
  uint16_t Other;
453
  StringRef Name;
454
};
455
 
456
struct VerneedEntry {
457
  uint16_t Version;
458
  StringRef File;
459
  std::vector<VernauxEntry> AuxV;
460
};
461
 
462
struct VerneedSection : Section {
463
  std::optional<std::vector<VerneedEntry>> VerneedV;
464
  std::optional<llvm::yaml::Hex64> Info;
465
 
466
  VerneedSection() : Section(ChunkKind::Verneed) {}
467
 
468
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
469
    return {{"Dependencies", VerneedV.has_value()}};
470
  };
471
 
472
  static bool classof(const Chunk *S) {
473
    return S->Kind == ChunkKind::Verneed;
474
  }
475
};
476
 
477
struct AddrsigSection : Section {
478
  std::optional<std::vector<YAMLFlowString>> Symbols;
479
 
480
  AddrsigSection() : Section(ChunkKind::Addrsig) {}
481
 
482
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
483
    return {{"Symbols", Symbols.has_value()}};
484
  };
485
 
486
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
487
};
488
 
489
struct LinkerOption {
490
  StringRef Key;
491
  StringRef Value;
492
};
493
 
494
struct LinkerOptionsSection : Section {
495
  std::optional<std::vector<LinkerOption>> Options;
496
 
497
  LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
498
 
499
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
500
    return {{"Options", Options.has_value()}};
501
  };
502
 
503
  static bool classof(const Chunk *S) {
504
    return S->Kind == ChunkKind::LinkerOptions;
505
  }
506
};
507
 
508
struct DependentLibrariesSection : Section {
509
  std::optional<std::vector<YAMLFlowString>> Libs;
510
 
511
  DependentLibrariesSection() : Section(ChunkKind::DependentLibraries) {}
512
 
513
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
514
    return {{"Libraries", Libs.has_value()}};
515
  };
516
 
517
  static bool classof(const Chunk *S) {
518
    return S->Kind == ChunkKind::DependentLibraries;
519
  }
520
};
521
 
522
// Represents the call graph profile section entry.
523
struct CallGraphEntryWeight {
524
  // The weight of the edge.
525
  uint64_t Weight;
526
};
527
 
528
struct CallGraphProfileSection : Section {
529
  std::optional<std::vector<CallGraphEntryWeight>> Entries;
530
 
531
  CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
532
 
533
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
534
    return {{"Entries", Entries.has_value()}};
535
  };
536
 
537
  static bool classof(const Chunk *S) {
538
    return S->Kind == ChunkKind::CallGraphProfile;
539
  }
540
};
541
 
542
struct SymverSection : Section {
543
  std::optional<std::vector<uint16_t>> Entries;
544
 
545
  SymverSection() : Section(ChunkKind::Symver) {}
546
 
547
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
548
    return {{"Entries", Entries.has_value()}};
549
  };
550
 
551
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Symver; }
552
};
553
 
554
struct VerdefEntry {
555
  std::optional<uint16_t> Version;
556
  std::optional<uint16_t> Flags;
557
  std::optional<uint16_t> VersionNdx;
558
  std::optional<uint32_t> Hash;
559
  std::vector<StringRef> VerNames;
560
};
561
 
562
struct VerdefSection : Section {
563
  std::optional<std::vector<VerdefEntry>> Entries;
564
  std::optional<llvm::yaml::Hex64> Info;
565
 
566
  VerdefSection() : Section(ChunkKind::Verdef) {}
567
 
568
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
569
    return {{"Entries", Entries.has_value()}};
570
  };
571
 
572
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Verdef; }
573
};
574
 
575
struct GroupSection : Section {
576
  // Members of a group contain a flag and a list of section indices
577
  // that are part of the group.
578
  std::optional<std::vector<SectionOrType>> Members;
579
  std::optional<StringRef> Signature; /* Info */
580
 
581
  GroupSection() : Section(ChunkKind::Group) {}
582
 
583
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
584
    return {{"Members", Members.has_value()}};
585
  };
586
 
587
  static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Group; }
588
};
589
 
590
struct Relocation {
591
  llvm::yaml::Hex64 Offset;
592
  YAMLIntUInt Addend;
593
  ELF_REL Type;
594
  std::optional<StringRef> Symbol;
595
};
596
 
597
struct RelocationSection : Section {
598
  std::optional<std::vector<Relocation>> Relocations;
599
  StringRef RelocatableSec; /* Info */
600
 
601
  RelocationSection() : Section(ChunkKind::Relocation) {}
602
 
603
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
604
    return {{"Relocations", Relocations.has_value()}};
605
  };
606
 
607
  static bool classof(const Chunk *S) {
608
    return S->Kind == ChunkKind::Relocation;
609
  }
610
};
611
 
612
struct RelrSection : Section {
613
  std::optional<std::vector<llvm::yaml::Hex64>> Entries;
614
 
615
  RelrSection() : Section(ChunkKind::Relr) {}
616
 
617
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
618
    return {{"Entries", Entries.has_value()}};
619
  };
620
 
621
  static bool classof(const Chunk *S) {
622
    return S->Kind == ChunkKind::Relr;
623
  }
624
};
625
 
626
struct SymtabShndxSection : Section {
627
  std::optional<std::vector<uint32_t>> Entries;
628
 
629
  SymtabShndxSection() : Section(ChunkKind::SymtabShndxSection) {}
630
 
631
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
632
    return {{"Entries", Entries.has_value()}};
633
  };
634
 
635
  static bool classof(const Chunk *S) {
636
    return S->Kind == ChunkKind::SymtabShndxSection;
637
  }
638
};
639
 
640
struct ARMIndexTableEntry {
641
  llvm::yaml::Hex32 Offset;
642
  llvm::yaml::Hex32 Value;
643
};
644
 
645
struct ARMIndexTableSection : Section {
646
  std::optional<std::vector<ARMIndexTableEntry>> Entries;
647
 
648
  ARMIndexTableSection() : Section(ChunkKind::ARMIndexTable) {}
649
 
650
  std::vector<std::pair<StringRef, bool>> getEntries() const override {
651
    return {{"Entries", Entries.has_value()}};
652
  };
653
 
654
  static bool classof(const Chunk *S) {
655
    return S->Kind == ChunkKind::ARMIndexTable;
656
  }
657
};
658
 
659
// Represents .MIPS.abiflags section
660
struct MipsABIFlags : Section {
661
  llvm::yaml::Hex16 Version;
662
  MIPS_ISA ISALevel;
663
  llvm::yaml::Hex8 ISARevision;
664
  MIPS_AFL_REG GPRSize;
665
  MIPS_AFL_REG CPR1Size;
666
  MIPS_AFL_REG CPR2Size;
667
  MIPS_ABI_FP FpABI;
668
  MIPS_AFL_EXT ISAExtension;
669
  MIPS_AFL_ASE ASEs;
670
  MIPS_AFL_FLAGS1 Flags1;
671
  llvm::yaml::Hex32 Flags2;
672
 
673
  MipsABIFlags() : Section(ChunkKind::MipsABIFlags) {}
674
 
675
  static bool classof(const Chunk *S) {
676
    return S->Kind == ChunkKind::MipsABIFlags;
677
  }
678
};
679
 
680
struct ProgramHeader {
681
  ELF_PT Type;
682
  ELF_PF Flags;
683
  llvm::yaml::Hex64 VAddr;
684
  llvm::yaml::Hex64 PAddr;
685
  std::optional<llvm::yaml::Hex64> Align;
686
  std::optional<llvm::yaml::Hex64> FileSize;
687
  std::optional<llvm::yaml::Hex64> MemSize;
688
  std::optional<llvm::yaml::Hex64> Offset;
689
  std::optional<StringRef> FirstSec;
690
  std::optional<StringRef> LastSec;
691
 
692
  // This vector contains all chunks from [FirstSec, LastSec].
693
  std::vector<Chunk *> Chunks;
694
};
695
 
696
struct Object {
697
  FileHeader Header;
698
  std::vector<ProgramHeader> ProgramHeaders;
699
 
700
  // An object might contain output section descriptions as well as
701
  // custom data that does not belong to any section.
702
  std::vector<std::unique_ptr<Chunk>> Chunks;
703
 
704
  // Although in reality the symbols reside in a section, it is a lot
705
  // cleaner and nicer if we read them from the YAML as a separate
706
  // top-level key, which automatically ensures that invariants like there
707
  // being a single SHT_SYMTAB section are upheld.
708
  std::optional<std::vector<Symbol>> Symbols;
709
  std::optional<std::vector<Symbol>> DynamicSymbols;
710
  std::optional<DWARFYAML::Data> DWARF;
711
 
712
  std::vector<Section *> getSections() {
713
    std::vector<Section *> Ret;
714
    for (const std::unique_ptr<Chunk> &Sec : Chunks)
715
      if (auto S = dyn_cast<ELFYAML::Section>(Sec.get()))
716
        Ret.push_back(S);
717
    return Ret;
718
  }
719
 
720
  const SectionHeaderTable &getSectionHeaderTable() const {
721
    for (const std::unique_ptr<Chunk> &C : Chunks)
722
      if (auto *S = dyn_cast<ELFYAML::SectionHeaderTable>(C.get()))
723
        return *S;
724
    llvm_unreachable("the section header table chunk must always be present");
725
  }
726
 
727
  ELF_ELFOSABI getOSAbi() const;
728
  unsigned getMachine() const;
729
};
730
 
731
bool shouldAllocateFileSpace(ArrayRef<ProgramHeader> Phdrs,
732
                             const NoBitsSection &S);
733
 
734
} // end namespace ELFYAML
735
} // end namespace llvm
736
 
737
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
738
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry)
739
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::BBAddrMapEntry::BBEntry)
740
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
741
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
742
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntryWeight)
743
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
744
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
745
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
746
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
747
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
748
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
749
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VernauxEntry)
750
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerneedEntry)
751
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation)
752
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionOrType)
753
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ARMIndexTableEntry)
754
 
755
namespace llvm {
756
namespace yaml {
757
 
758
template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
759
  static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
760
                     raw_ostream &Out);
761
  static StringRef input(StringRef Scalar, void *Ctx,
762
                         ELFYAML::YAMLIntUInt &Val);
763
  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
764
};
765
 
766
template <>
767
struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
768
  static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
769
};
770
 
771
template <> struct ScalarEnumerationTraits<ELFYAML::ELF_PT> {
772
  static void enumeration(IO &IO, ELFYAML::ELF_PT &Value);
773
};
774
 
775
template <> struct ScalarEnumerationTraits<ELFYAML::ELF_NT> {
776
  static void enumeration(IO &IO, ELFYAML::ELF_NT &Value);
777
};
778
 
779
template <>
780
struct ScalarEnumerationTraits<ELFYAML::ELF_EM> {
781
  static void enumeration(IO &IO, ELFYAML::ELF_EM &Value);
782
};
783
 
784
template <>
785
struct ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS> {
786
  static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value);
787
};
788
 
789
template <>
790
struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> {
791
  static void enumeration(IO &IO, ELFYAML::ELF_ELFDATA &Value);
792
};
793
 
794
template <>
795
struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> {
796
  static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value);
797
};
798
 
799
template <>
800
struct ScalarBitSetTraits<ELFYAML::ELF_EF> {
801
  static void bitset(IO &IO, ELFYAML::ELF_EF &Value);
802
};
803
 
804
template <> struct ScalarBitSetTraits<ELFYAML::ELF_PF> {
805
  static void bitset(IO &IO, ELFYAML::ELF_PF &Value);
806
};
807
 
808
template <>
809
struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> {
810
  static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value);
811
};
812
 
813
template <>
814
struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
815
  static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
816
};
817
 
818
template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
819
  static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
820
};
821
 
822
template <> struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
823
  static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
824
};
825
 
826
template <>
827
struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
828
  static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
829
};
830
 
831
template <>
832
struct ScalarEnumerationTraits<ELFYAML::ELF_REL> {
833
  static void enumeration(IO &IO, ELFYAML::ELF_REL &Value);
834
};
835
 
836
template <>
837
struct ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG> {
838
  static void enumeration(IO &IO, ELFYAML::ELF_DYNTAG &Value);
839
};
840
 
841
template <>
842
struct ScalarEnumerationTraits<ELFYAML::ELF_RSS> {
843
  static void enumeration(IO &IO, ELFYAML::ELF_RSS &Value);
844
};
845
 
846
template <>
847
struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG> {
848
  static void enumeration(IO &IO, ELFYAML::MIPS_AFL_REG &Value);
849
};
850
 
851
template <>
852
struct ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP> {
853
  static void enumeration(IO &IO, ELFYAML::MIPS_ABI_FP &Value);
854
};
855
 
856
template <>
857
struct ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT> {
858
  static void enumeration(IO &IO, ELFYAML::MIPS_AFL_EXT &Value);
859
};
860
 
861
template <>
862
struct ScalarEnumerationTraits<ELFYAML::MIPS_ISA> {
863
  static void enumeration(IO &IO, ELFYAML::MIPS_ISA &Value);
864
};
865
 
866
template <>
867
struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE> {
868
  static void bitset(IO &IO, ELFYAML::MIPS_AFL_ASE &Value);
869
};
870
 
871
template <>
872
struct ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1> {
873
  static void bitset(IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value);
874
};
875
 
876
template <>
877
struct MappingTraits<ELFYAML::FileHeader> {
878
  static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
879
};
880
 
881
template <> struct MappingTraits<ELFYAML::SectionHeader> {
882
  static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
883
};
884
 
885
template <> struct MappingTraits<ELFYAML::ProgramHeader> {
886
  static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
887
  static std::string validate(IO &IO, ELFYAML::ProgramHeader &FileHdr);
888
};
889
 
890
template <>
891
struct MappingTraits<ELFYAML::Symbol> {
892
  static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
893
  static std::string validate(IO &IO, ELFYAML::Symbol &Symbol);
894
};
895
 
896
template <> struct MappingTraits<ELFYAML::StackSizeEntry> {
897
  static void mapping(IO &IO, ELFYAML::StackSizeEntry &Rel);
898
};
899
 
900
template <> struct MappingTraits<ELFYAML::BBAddrMapEntry> {
901
  static void mapping(IO &IO, ELFYAML::BBAddrMapEntry &Rel);
902
};
903
 
904
template <> struct MappingTraits<ELFYAML::BBAddrMapEntry::BBEntry> {
905
  static void mapping(IO &IO, ELFYAML::BBAddrMapEntry::BBEntry &Rel);
906
};
907
 
908
template <> struct MappingTraits<ELFYAML::GnuHashHeader> {
909
  static void mapping(IO &IO, ELFYAML::GnuHashHeader &Rel);
910
};
911
 
912
template <> struct MappingTraits<ELFYAML::DynamicEntry> {
913
  static void mapping(IO &IO, ELFYAML::DynamicEntry &Rel);
914
};
915
 
916
template <> struct MappingTraits<ELFYAML::NoteEntry> {
917
  static void mapping(IO &IO, ELFYAML::NoteEntry &N);
918
};
919
 
920
template <> struct MappingTraits<ELFYAML::VerdefEntry> {
921
  static void mapping(IO &IO, ELFYAML::VerdefEntry &E);
922
};
923
 
924
template <> struct MappingTraits<ELFYAML::VerneedEntry> {
925
  static void mapping(IO &IO, ELFYAML::VerneedEntry &E);
926
};
927
 
928
template <> struct MappingTraits<ELFYAML::VernauxEntry> {
929
  static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
930
};
931
 
932
template <> struct MappingTraits<ELFYAML::LinkerOption> {
933
  static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
934
};
935
 
936
template <> struct MappingTraits<ELFYAML::CallGraphEntryWeight> {
937
  static void mapping(IO &IO, ELFYAML::CallGraphEntryWeight &E);
938
};
939
 
940
template <> struct MappingTraits<ELFYAML::Relocation> {
941
  static void mapping(IO &IO, ELFYAML::Relocation &Rel);
942
};
943
 
944
template <> struct MappingTraits<ELFYAML::ARMIndexTableEntry> {
945
  static void mapping(IO &IO, ELFYAML::ARMIndexTableEntry &E);
946
};
947
 
948
template <> struct MappingTraits<std::unique_ptr<ELFYAML::Chunk>> {
949
  static void mapping(IO &IO, std::unique_ptr<ELFYAML::Chunk> &C);
950
  static std::string validate(IO &io, std::unique_ptr<ELFYAML::Chunk> &C);
951
};
952
 
953
template <>
954
struct MappingTraits<ELFYAML::Object> {
955
  static void mapping(IO &IO, ELFYAML::Object &Object);
956
};
957
 
958
template <> struct MappingTraits<ELFYAML::SectionOrType> {
959
  static void mapping(IO &IO, ELFYAML::SectionOrType &sectionOrType);
960
};
961
 
962
} // end namespace yaml
963
} // end namespace llvm
964
 
965
#endif // LLVM_OBJECTYAML_ELFYAML_H