ELFYAML.h 28 KB

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