• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
ExportEntryExportEntry82   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)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)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