Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- MachOYAML.h - Mach-O 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 Mach-O.
  12. ///
  13. //===----------------------------------------------------------------------===//
  14.  
  15. #ifndef LLVM_OBJECTYAML_MACHOYAML_H
  16. #define LLVM_OBJECTYAML_MACHOYAML_H
  17.  
  18. #include "llvm/ADT/StringRef.h"
  19. #include "llvm/BinaryFormat/MachO.h"
  20. #include "llvm/ObjectYAML/DWARFYAML.h"
  21. #include "llvm/ObjectYAML/YAML.h"
  22. #include "llvm/Support/YAMLTraits.h"
  23. #include <cstdint>
  24. #include <optional>
  25. #include <string>
  26. #include <vector>
  27.  
  28. namespace llvm {
  29. namespace MachOYAML {
  30.  
  31. struct Relocation {
  32.   // Offset in the section to what is being relocated.
  33.   llvm::yaml::Hex32 address;
  34.   // Symbol index if r_extern == 1 else section index.
  35.   uint32_t symbolnum;
  36.   bool is_pcrel;
  37.   // Real length = 2 ^ length.
  38.   uint8_t length;
  39.   bool is_extern;
  40.   uint8_t type;
  41.   bool is_scattered;
  42.   int32_t value;
  43. };
  44.  
  45. struct Section {
  46.   char sectname[16];
  47.   char segname[16];
  48.   llvm::yaml::Hex64 addr;
  49.   uint64_t size;
  50.   llvm::yaml::Hex32 offset;
  51.   uint32_t align;
  52.   llvm::yaml::Hex32 reloff;
  53.   uint32_t nreloc;
  54.   llvm::yaml::Hex32 flags;
  55.   llvm::yaml::Hex32 reserved1;
  56.   llvm::yaml::Hex32 reserved2;
  57.   llvm::yaml::Hex32 reserved3;
  58.   std::optional<llvm::yaml::BinaryRef> content;
  59.   std::vector<Relocation> relocations;
  60. };
  61.  
  62. struct FileHeader {
  63.   llvm::yaml::Hex32 magic;
  64.   llvm::yaml::Hex32 cputype;
  65.   llvm::yaml::Hex32 cpusubtype;
  66.   llvm::yaml::Hex32 filetype;
  67.   uint32_t ncmds;
  68.   uint32_t sizeofcmds;
  69.   llvm::yaml::Hex32 flags;
  70.   llvm::yaml::Hex32 reserved;
  71. };
  72.  
  73. struct LoadCommand {
  74.   virtual ~LoadCommand();
  75.  
  76.   llvm::MachO::macho_load_command Data;
  77.   std::vector<Section> Sections;
  78.   std::vector<MachO::build_tool_version> Tools;
  79.   std::vector<llvm::yaml::Hex8> PayloadBytes;
  80.   std::string Content;
  81.   uint64_t ZeroPadBytes;
  82. };
  83.  
  84. struct NListEntry {
  85.   uint32_t n_strx;
  86.   llvm::yaml::Hex8 n_type;
  87.   uint8_t n_sect;
  88.   uint16_t n_desc;
  89.   uint64_t n_value;
  90. };
  91.  
  92. struct RebaseOpcode {
  93.   MachO::RebaseOpcode Opcode;
  94.   uint8_t Imm;
  95.   std::vector<yaml::Hex64> ExtraData;
  96. };
  97.  
  98. struct BindOpcode {
  99.   MachO::BindOpcode Opcode;
  100.   uint8_t Imm;
  101.   std::vector<yaml::Hex64> ULEBExtraData;
  102.   std::vector<int64_t> SLEBExtraData;
  103.   StringRef Symbol;
  104. };
  105.  
  106. struct ExportEntry {
  107.   uint64_t TerminalSize = 0;
  108.   uint64_t NodeOffset = 0;
  109.   std::string Name;
  110.   llvm::yaml::Hex64 Flags = 0;
  111.   llvm::yaml::Hex64 Address = 0;
  112.   llvm::yaml::Hex64 Other = 0;
  113.   std::string ImportName;
  114.   std::vector<MachOYAML::ExportEntry> Children;
  115. };
  116.  
  117. struct DataInCodeEntry {
  118.   llvm::yaml::Hex32 Offset;
  119.   uint16_t Length;
  120.   llvm::yaml::Hex16 Kind;
  121. };
  122.  
  123. struct LinkEditData {
  124.   std::vector<MachOYAML::RebaseOpcode> RebaseOpcodes;
  125.   std::vector<MachOYAML::BindOpcode> BindOpcodes;
  126.   std::vector<MachOYAML::BindOpcode> WeakBindOpcodes;
  127.   std::vector<MachOYAML::BindOpcode> LazyBindOpcodes;
  128.   MachOYAML::ExportEntry ExportTrie;
  129.   std::vector<NListEntry> NameList;
  130.   std::vector<StringRef> StringTable;
  131.   std::vector<yaml::Hex32> IndirectSymbols;
  132.   std::vector<yaml::Hex64> FunctionStarts;
  133.   std::vector<DataInCodeEntry> DataInCode;
  134.   std::vector<yaml::Hex8> ChainedFixups;
  135.  
  136.   bool isEmpty() const;
  137. };
  138.  
  139. struct Object {
  140.   bool IsLittleEndian;
  141.   FileHeader Header;
  142.   std::vector<LoadCommand> LoadCommands;
  143.   std::vector<Section> Sections;
  144.   LinkEditData LinkEdit;
  145.   std::optional<llvm::yaml::BinaryRef> RawLinkEditSegment;
  146.   DWARFYAML::Data DWARF;
  147. };
  148.  
  149. struct FatHeader {
  150.   llvm::yaml::Hex32 magic;
  151.   uint32_t nfat_arch;
  152. };
  153.  
  154. struct FatArch {
  155.   llvm::yaml::Hex32 cputype;
  156.   llvm::yaml::Hex32 cpusubtype;
  157.   llvm::yaml::Hex64 offset;
  158.   uint64_t size;
  159.   uint32_t align;
  160.   llvm::yaml::Hex32 reserved;
  161. };
  162.  
  163. struct UniversalBinary {
  164.   FatHeader Header;
  165.   std::vector<FatArch> FatArchs;
  166.   std::vector<Object> Slices;
  167. };
  168.  
  169. } // end namespace MachOYAML
  170. } // end namespace llvm
  171.  
  172. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
  173. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Relocation)
  174. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
  175. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
  176. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
  177. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry)
  178. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry)
  179. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object)
  180. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch)
  181. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DataInCodeEntry)
  182. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO::build_tool_version)
  183.  
  184. namespace llvm {
  185.  
  186. class raw_ostream;
  187.  
  188. namespace yaml {
  189.  
  190. template <> struct MappingTraits<MachOYAML::FileHeader> {
  191.   static void mapping(IO &IO, MachOYAML::FileHeader &FileHeader);
  192. };
  193.  
  194. template <> struct MappingTraits<MachOYAML::Object> {
  195.   static void mapping(IO &IO, MachOYAML::Object &Object);
  196. };
  197.  
  198. template <> struct MappingTraits<MachOYAML::FatHeader> {
  199.   static void mapping(IO &IO, MachOYAML::FatHeader &FatHeader);
  200. };
  201.  
  202. template <> struct MappingTraits<MachOYAML::FatArch> {
  203.   static void mapping(IO &IO, MachOYAML::FatArch &FatArch);
  204. };
  205.  
  206. template <> struct MappingTraits<MachOYAML::UniversalBinary> {
  207.   static void mapping(IO &IO, MachOYAML::UniversalBinary &UniversalBinary);
  208. };
  209.  
  210. template <> struct MappingTraits<MachOYAML::LoadCommand> {
  211.   static void mapping(IO &IO, MachOYAML::LoadCommand &LoadCommand);
  212. };
  213.  
  214. template <> struct MappingTraits<MachOYAML::LinkEditData> {
  215.   static void mapping(IO &IO, MachOYAML::LinkEditData &LinkEditData);
  216. };
  217.  
  218. template <> struct MappingTraits<MachOYAML::RebaseOpcode> {
  219.   static void mapping(IO &IO, MachOYAML::RebaseOpcode &RebaseOpcode);
  220. };
  221.  
  222. template <> struct MappingTraits<MachOYAML::BindOpcode> {
  223.   static void mapping(IO &IO, MachOYAML::BindOpcode &BindOpcode);
  224. };
  225.  
  226. template <> struct MappingTraits<MachOYAML::ExportEntry> {
  227.   static void mapping(IO &IO, MachOYAML::ExportEntry &ExportEntry);
  228. };
  229.  
  230. template <> struct MappingTraits<MachOYAML::Relocation> {
  231.   static void mapping(IO &IO, MachOYAML::Relocation &R);
  232. };
  233.  
  234. template <> struct MappingTraits<MachOYAML::Section> {
  235.   static void mapping(IO &IO, MachOYAML::Section &Section);
  236.   static std::string validate(IO &io, MachOYAML::Section &Section);
  237. };
  238.  
  239. template <> struct MappingTraits<MachOYAML::NListEntry> {
  240.   static void mapping(IO &IO, MachOYAML::NListEntry &NListEntry);
  241. };
  242.  
  243. template <> struct MappingTraits<MachO::build_tool_version> {
  244.   static void mapping(IO &IO, MachO::build_tool_version &tool);
  245. };
  246.  
  247. template <> struct MappingTraits<MachOYAML::DataInCodeEntry> {
  248.   static void mapping(IO &IO, MachOYAML::DataInCodeEntry &DataInCodeEntry);
  249. };
  250.  
  251. #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct)                         \
  252.   io.enumCase(value, #LCName, MachO::LCName);
  253.  
  254. template <> struct ScalarEnumerationTraits<MachO::LoadCommandType> {
  255.   static void enumeration(IO &io, MachO::LoadCommandType &value) {
  256. #include "llvm/BinaryFormat/MachO.def"
  257.     io.enumFallback<Hex32>(value);
  258.   }
  259. };
  260.  
  261. #define ENUM_CASE(Enum) io.enumCase(value, #Enum, MachO::Enum);
  262.  
  263. template <> struct ScalarEnumerationTraits<MachO::RebaseOpcode> {
  264.   static void enumeration(IO &io, MachO::RebaseOpcode &value) {
  265.     ENUM_CASE(REBASE_OPCODE_DONE)
  266.     ENUM_CASE(REBASE_OPCODE_SET_TYPE_IMM)
  267.     ENUM_CASE(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
  268.     ENUM_CASE(REBASE_OPCODE_ADD_ADDR_ULEB)
  269.     ENUM_CASE(REBASE_OPCODE_ADD_ADDR_IMM_SCALED)
  270.     ENUM_CASE(REBASE_OPCODE_DO_REBASE_IMM_TIMES)
  271.     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES)
  272.     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB)
  273.     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB)
  274.     io.enumFallback<Hex8>(value);
  275.   }
  276. };
  277.  
  278. template <> struct ScalarEnumerationTraits<MachO::BindOpcode> {
  279.   static void enumeration(IO &io, MachO::BindOpcode &value) {
  280.     ENUM_CASE(BIND_OPCODE_DONE)
  281.     ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM)
  282.     ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB)
  283.     ENUM_CASE(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM)
  284.     ENUM_CASE(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
  285.     ENUM_CASE(BIND_OPCODE_SET_TYPE_IMM)
  286.     ENUM_CASE(BIND_OPCODE_SET_ADDEND_SLEB)
  287.     ENUM_CASE(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
  288.     ENUM_CASE(BIND_OPCODE_ADD_ADDR_ULEB)
  289.     ENUM_CASE(BIND_OPCODE_DO_BIND)
  290.     ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB)
  291.     ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED)
  292.     ENUM_CASE(BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB)
  293.     io.enumFallback<Hex8>(value);
  294.   }
  295. };
  296.  
  297. // This trait is used for 16-byte chars in Mach structures used for strings
  298. using char_16 = char[16];
  299.  
  300. template <> struct ScalarTraits<char_16> {
  301.   static void output(const char_16 &Val, void *, raw_ostream &Out);
  302.   static StringRef input(StringRef Scalar, void *, char_16 &Val);
  303.   static QuotingType mustQuote(StringRef S);
  304. };
  305.  
  306. // This trait is used for UUIDs. It reads and writes them matching otool's
  307. // formatting style.
  308. using uuid_t = raw_ostream::uuid_t;
  309.  
  310. template <> struct ScalarTraits<uuid_t> {
  311.   static void output(const uuid_t &Val, void *, raw_ostream &Out);
  312.   static StringRef input(StringRef Scalar, void *, uuid_t &Val);
  313.   static QuotingType mustQuote(StringRef S);
  314. };
  315.  
  316. // Load Command struct mapping traits
  317.  
  318. #define LOAD_COMMAND_STRUCT(LCStruct)                                          \
  319.   template <> struct MappingTraits<MachO::LCStruct> {                          \
  320.     static void mapping(IO &IO, MachO::LCStruct &LoadCommand);                 \
  321.   };
  322.  
  323. #include "llvm/BinaryFormat/MachO.def"
  324.  
  325. // Extra structures used by load commands
  326. template <> struct MappingTraits<MachO::dylib> {
  327.   static void mapping(IO &IO, MachO::dylib &LoadCommand);
  328. };
  329.  
  330. template <> struct MappingTraits<MachO::fvmlib> {
  331.   static void mapping(IO &IO, MachO::fvmlib &LoadCommand);
  332. };
  333.  
  334. template <> struct MappingTraits<MachO::section> {
  335.   static void mapping(IO &IO, MachO::section &LoadCommand);
  336. };
  337.  
  338. template <> struct MappingTraits<MachO::section_64> {
  339.   static void mapping(IO &IO, MachO::section_64 &LoadCommand);
  340. };
  341.  
  342. } // end namespace yaml
  343.  
  344. } // end namespace llvm
  345.  
  346. #endif // LLVM_OBJECTYAML_MACHOYAML_H
  347.