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