Home | History | Annotate | Download | only in ObjectYAML
      1 //===- MachOYAML.h - Mach-O YAMLIO implementation ---------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 ///
     10 /// \file
     11 /// \brief This file declares classes for handling the YAML representation
     12 /// of Mach-O.
     13 ///
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_OBJECTYAML_MACHOYAML_H
     17 #define LLVM_OBJECTYAML_MACHOYAML_H
     18 
     19 #include "llvm/ObjectYAML/YAML.h"
     20 #include "llvm/ObjectYAML/DWARFYAML.h"
     21 #include "llvm/Support/MachO.h"
     22 
     23 namespace llvm {
     24 namespace MachOYAML {
     25 
     26 struct Section {
     27   char sectname[16];
     28   char segname[16];
     29   llvm::yaml::Hex64 addr;
     30   uint64_t size;
     31   llvm::yaml::Hex32 offset;
     32   uint32_t align;
     33   llvm::yaml::Hex32 reloff;
     34   uint32_t nreloc;
     35   llvm::yaml::Hex32 flags;
     36   llvm::yaml::Hex32 reserved1;
     37   llvm::yaml::Hex32 reserved2;
     38   llvm::yaml::Hex32 reserved3;
     39 };
     40 
     41 struct FileHeader {
     42   llvm::yaml::Hex32 magic;
     43   llvm::yaml::Hex32 cputype;
     44   llvm::yaml::Hex32 cpusubtype;
     45   llvm::yaml::Hex32 filetype;
     46   uint32_t ncmds;
     47   uint32_t sizeofcmds;
     48   llvm::yaml::Hex32 flags;
     49   llvm::yaml::Hex32 reserved;
     50 };
     51 
     52 struct LoadCommand {
     53   virtual ~LoadCommand();
     54   llvm::MachO::macho_load_command Data;
     55   std::vector<Section> Sections;
     56   std::vector<MachO::build_tool_version> Tools;
     57   std::vector<llvm::yaml::Hex8> PayloadBytes;
     58   std::string PayloadString;
     59   uint64_t ZeroPadBytes;
     60 };
     61 
     62 struct NListEntry {
     63   uint32_t n_strx;
     64   llvm::yaml::Hex8 n_type;
     65   uint8_t n_sect;
     66   uint16_t n_desc;
     67   uint64_t n_value;
     68 };
     69 struct RebaseOpcode {
     70   MachO::RebaseOpcode Opcode;
     71   uint8_t Imm;
     72   std::vector<yaml::Hex64> ExtraData;
     73 };
     74 
     75 struct BindOpcode {
     76   MachO::BindOpcode Opcode;
     77   uint8_t Imm;
     78   std::vector<yaml::Hex64> ULEBExtraData;
     79   std::vector<int64_t> SLEBExtraData;
     80   StringRef Symbol;
     81 };
     82 
     83 struct ExportEntry {
     84   ExportEntry()
     85       : TerminalSize(0), NodeOffset(0), Name(), Flags(0), Address(0), Other(0),
     86         ImportName(), Children() {}
     87   uint64_t TerminalSize;
     88   uint64_t NodeOffset;
     89   std::string Name;
     90   llvm::yaml::Hex64 Flags;
     91   llvm::yaml::Hex64 Address;
     92   llvm::yaml::Hex64 Other;
     93   std::string ImportName;
     94   std::vector<MachOYAML::ExportEntry> Children;
     95 };
     96 
     97 struct LinkEditData {
     98   std::vector<MachOYAML::RebaseOpcode> RebaseOpcodes;
     99   std::vector<MachOYAML::BindOpcode> BindOpcodes;
    100   std::vector<MachOYAML::BindOpcode> WeakBindOpcodes;
    101   std::vector<MachOYAML::BindOpcode> LazyBindOpcodes;
    102   MachOYAML::ExportEntry ExportTrie;
    103   std::vector<NListEntry> NameList;
    104   std::vector<StringRef> StringTable;
    105 
    106   bool isEmpty() const;
    107 };
    108 
    109 struct Object {
    110   bool IsLittleEndian;
    111   FileHeader Header;
    112   std::vector<LoadCommand> LoadCommands;
    113   std::vector<Section> Sections;
    114   LinkEditData LinkEdit;
    115   DWARFYAML::Data DWARF;
    116 };
    117 
    118 struct FatHeader {
    119   llvm::yaml::Hex32 magic;
    120   uint32_t nfat_arch;
    121 };
    122 
    123 struct FatArch {
    124   llvm::yaml::Hex32 cputype;
    125   llvm::yaml::Hex32 cpusubtype;
    126   llvm::yaml::Hex64 offset;
    127   uint64_t size;
    128   uint32_t align;
    129   llvm::yaml::Hex32 reserved;
    130 };
    131 
    132 struct UniversalBinary {
    133   FatHeader Header;
    134   std::vector<FatArch> FatArchs;
    135   std::vector<Object> Slices;
    136 };
    137 
    138 } // namespace llvm::MachOYAML
    139 } // namespace llvm
    140 
    141 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
    142 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
    143 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(int64_t)
    144 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
    145 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
    146 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry)
    147 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry)
    148 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object)
    149 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch)
    150 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachO::build_tool_version)
    151 
    152 namespace llvm {
    153 namespace yaml {
    154 
    155 template <> struct MappingTraits<MachOYAML::FileHeader> {
    156   static void mapping(IO &IO, MachOYAML::FileHeader &FileHeader);
    157 };
    158 
    159 template <> struct MappingTraits<MachOYAML::Object> {
    160   static void mapping(IO &IO, MachOYAML::Object &Object);
    161 };
    162 
    163 template <> struct MappingTraits<MachOYAML::FatHeader> {
    164   static void mapping(IO &IO, MachOYAML::FatHeader &FatHeader);
    165 };
    166 
    167 template <> struct MappingTraits<MachOYAML::FatArch> {
    168   static void mapping(IO &IO, MachOYAML::FatArch &FatArch);
    169 };
    170 
    171 template <> struct MappingTraits<MachOYAML::UniversalBinary> {
    172   static void mapping(IO &IO, MachOYAML::UniversalBinary &UniversalBinary);
    173 };
    174 
    175 template <> struct MappingTraits<MachOYAML::LoadCommand> {
    176   static void mapping(IO &IO, MachOYAML::LoadCommand &LoadCommand);
    177 };
    178 
    179 template <> struct MappingTraits<MachOYAML::LinkEditData> {
    180   static void mapping(IO &IO, MachOYAML::LinkEditData &LinkEditData);
    181 };
    182 
    183 template <> struct MappingTraits<MachOYAML::RebaseOpcode> {
    184   static void mapping(IO &IO, MachOYAML::RebaseOpcode &RebaseOpcode);
    185 };
    186 
    187 template <> struct MappingTraits<MachOYAML::BindOpcode> {
    188   static void mapping(IO &IO, MachOYAML::BindOpcode &BindOpcode);
    189 };
    190 
    191 template <> struct MappingTraits<MachOYAML::ExportEntry> {
    192   static void mapping(IO &IO, MachOYAML::ExportEntry &ExportEntry);
    193 };
    194 
    195 template <> struct MappingTraits<MachOYAML::Section> {
    196   static void mapping(IO &IO, MachOYAML::Section &Section);
    197 };
    198 
    199 template <> struct MappingTraits<MachOYAML::NListEntry> {
    200   static void mapping(IO &IO, MachOYAML::NListEntry &NListEntry);
    201 };
    202 
    203 template <> struct MappingTraits<MachO::build_tool_version> {
    204   static void mapping(IO &IO, MachO::build_tool_version &tool);
    205 };
    206 
    207 #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct)                         \
    208   io.enumCase(value, #LCName, MachO::LCName);
    209 
    210 template <> struct ScalarEnumerationTraits<MachO::LoadCommandType> {
    211   static void enumeration(IO &io, MachO::LoadCommandType &value) {
    212 #include "llvm/Support/MachO.def"
    213     io.enumFallback<Hex32>(value);
    214   }
    215 };
    216 
    217 #define ENUM_CASE(Enum) io.enumCase(value, #Enum, MachO::Enum);
    218 
    219 template <> struct ScalarEnumerationTraits<MachO::RebaseOpcode> {
    220   static void enumeration(IO &io, MachO::RebaseOpcode &value) {
    221     ENUM_CASE(REBASE_OPCODE_DONE)
    222     ENUM_CASE(REBASE_OPCODE_SET_TYPE_IMM)
    223     ENUM_CASE(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
    224     ENUM_CASE(REBASE_OPCODE_ADD_ADDR_ULEB)
    225     ENUM_CASE(REBASE_OPCODE_ADD_ADDR_IMM_SCALED)
    226     ENUM_CASE(REBASE_OPCODE_DO_REBASE_IMM_TIMES)
    227     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES)
    228     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB)
    229     ENUM_CASE(REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB)
    230     io.enumFallback<Hex8>(value);
    231   }
    232 };
    233 
    234 template <> struct ScalarEnumerationTraits<MachO::BindOpcode> {
    235   static void enumeration(IO &io, MachO::BindOpcode &value) {
    236     ENUM_CASE(BIND_OPCODE_DONE)
    237     ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM)
    238     ENUM_CASE(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB)
    239     ENUM_CASE(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM)
    240     ENUM_CASE(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
    241     ENUM_CASE(BIND_OPCODE_SET_TYPE_IMM)
    242     ENUM_CASE(BIND_OPCODE_SET_ADDEND_SLEB)
    243     ENUM_CASE(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB)
    244     ENUM_CASE(BIND_OPCODE_ADD_ADDR_ULEB)
    245     ENUM_CASE(BIND_OPCODE_DO_BIND)
    246     ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB)
    247     ENUM_CASE(BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED)
    248     ENUM_CASE(BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB)
    249     io.enumFallback<Hex8>(value);
    250   }
    251 };
    252 
    253 // This trait is used for 16-byte chars in Mach structures used for strings
    254 typedef char char_16[16];
    255 
    256 template <> struct ScalarTraits<char_16> {
    257   static void output(const char_16 &Val, void *, llvm::raw_ostream &Out);
    258 
    259   static StringRef input(StringRef Scalar, void *, char_16 &Val);
    260   static bool mustQuote(StringRef S);
    261 };
    262 
    263 // This trait is used for UUIDs. It reads and writes them matching otool's
    264 // formatting style.
    265 typedef uint8_t uuid_t[16];
    266 
    267 template <> struct ScalarTraits<uuid_t> {
    268   static void output(const uuid_t &Val, void *, llvm::raw_ostream &Out);
    269 
    270   static StringRef input(StringRef Scalar, void *, uuid_t &Val);
    271   static bool mustQuote(StringRef S);
    272 };
    273 
    274 // Load Command struct mapping traits
    275 
    276 #define LOAD_COMMAND_STRUCT(LCStruct)                                          \
    277   template <> struct MappingTraits<MachO::LCStruct> {                          \
    278     static void mapping(IO &IO, MachO::LCStruct &LoadCommand);                 \
    279   };
    280 
    281 #include "llvm/Support/MachO.def"
    282 
    283 // Extra structures used by load commands
    284 template <> struct MappingTraits<MachO::dylib> {
    285   static void mapping(IO &IO, MachO::dylib &LoadCommand);
    286 };
    287 
    288 template <> struct MappingTraits<MachO::fvmlib> {
    289   static void mapping(IO &IO, MachO::fvmlib &LoadCommand);
    290 };
    291 
    292 template <> struct MappingTraits<MachO::section> {
    293   static void mapping(IO &IO, MachO::section &LoadCommand);
    294 };
    295 
    296 template <> struct MappingTraits<MachO::section_64> {
    297   static void mapping(IO &IO, MachO::section_64 &LoadCommand);
    298 };
    299 
    300 } // namespace llvm::yaml
    301 
    302 } // namespace llvm
    303 
    304 #endif
    305