1 //===- lld/unittest/MachOTests/MachONormalizedFileYAMLTests.cpp -----------===//
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 #include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"
10 #include "lld/ReaderWriter/MachOLinkingContext.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/BinaryFormat/MachO.h"
13 #include "llvm/Support/Error.h"
14 #include "llvm/Support/MemoryBuffer.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include "gtest/gtest.h"
17 #include <cstdint>
18 #include <memory>
19 #include <string>
20 #include <system_error>
21 
22 using llvm::StringRef;
23 using llvm::MemoryBuffer;
24 using lld::mach_o::normalized::NormalizedFile;
25 using lld::mach_o::normalized::Symbol;
26 using lld::mach_o::normalized::Section;
27 using lld::mach_o::normalized::Relocation;
28 
fromYAML(StringRef str)29 static std::unique_ptr<NormalizedFile> fromYAML(StringRef str) {
30   std::unique_ptr<MemoryBuffer> mb(MemoryBuffer::getMemBuffer(str));
31   llvm::Expected<std::unique_ptr<NormalizedFile>> r
32                                     = lld::mach_o::normalized::readYaml(mb);
33   EXPECT_FALSE(!r);
34   return std::move(*r);
35 }
36 
toYAML(const NormalizedFile & f,std::string & out)37 static void toYAML(const NormalizedFile &f, std::string &out) {
38   llvm::raw_string_ostream ostr(out);
39   std::error_code ec = lld::mach_o::normalized::writeYaml(f, ostr);
40   EXPECT_TRUE(!ec);
41 }
42 
43 // ppc is no longer supported, but it is here to test endianness handling.
TEST(ObjectFileYAML,empty_ppc)44 TEST(ObjectFileYAML, empty_ppc) {
45   std::unique_ptr<NormalizedFile> f = fromYAML(
46     "---\n"
47     "arch:      ppc\n"
48     "file-type: MH_OBJECT\n"
49     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
50     "...\n");
51   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_ppc);
52   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
53   EXPECT_EQ((int)(f->flags), (int)(int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
54   EXPECT_TRUE(f->sections.empty());
55   EXPECT_TRUE(f->localSymbols.empty());
56   EXPECT_TRUE(f->globalSymbols.empty());
57   EXPECT_TRUE(f->undefinedSymbols.empty());
58 }
59 
TEST(ObjectFileYAML,empty_x86_64)60 TEST(ObjectFileYAML, empty_x86_64) {
61   std::unique_ptr<NormalizedFile> f = fromYAML(
62     "---\n"
63     "arch:      x86_64\n"
64     "file-type: MH_OBJECT\n"
65     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
66     "...\n");
67   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
68   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
69   EXPECT_EQ((int)(f->flags), (int)(int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
70   EXPECT_TRUE(f->sections.empty());
71   EXPECT_TRUE(f->localSymbols.empty());
72   EXPECT_TRUE(f->globalSymbols.empty());
73   EXPECT_TRUE(f->undefinedSymbols.empty());
74 }
75 
TEST(ObjectFileYAML,empty_x86)76 TEST(ObjectFileYAML, empty_x86) {
77   std::unique_ptr<NormalizedFile> f = fromYAML(
78     "---\n"
79     "arch:      x86\n"
80     "file-type: MH_OBJECT\n"
81     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
82     "...\n");
83   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);
84   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
85   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
86   EXPECT_TRUE(f->sections.empty());
87   EXPECT_TRUE(f->localSymbols.empty());
88   EXPECT_TRUE(f->globalSymbols.empty());
89   EXPECT_TRUE(f->undefinedSymbols.empty());
90 }
91 
TEST(ObjectFileYAML,empty_armv6)92 TEST(ObjectFileYAML, empty_armv6) {
93   std::unique_ptr<NormalizedFile> f = fromYAML(
94     "---\n"
95     "arch:      armv6\n"
96     "file-type: MH_OBJECT\n"
97     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
98     "...\n");
99   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv6);
100   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
101   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
102   EXPECT_TRUE(f->sections.empty());
103   EXPECT_TRUE(f->localSymbols.empty());
104   EXPECT_TRUE(f->globalSymbols.empty());
105   EXPECT_TRUE(f->undefinedSymbols.empty());
106 }
107 
TEST(ObjectFileYAML,empty_armv7)108 TEST(ObjectFileYAML, empty_armv7) {
109   std::unique_ptr<NormalizedFile> f = fromYAML(
110     "---\n"
111     "arch:      armv7\n"
112     "file-type: MH_OBJECT\n"
113     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
114     "...\n");
115   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);
116   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
117   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
118   EXPECT_TRUE(f->sections.empty());
119   EXPECT_TRUE(f->localSymbols.empty());
120   EXPECT_TRUE(f->globalSymbols.empty());
121   EXPECT_TRUE(f->undefinedSymbols.empty());
122 }
123 
TEST(ObjectFileYAML,empty_armv7s)124 TEST(ObjectFileYAML, empty_armv7s) {
125   std::unique_ptr<NormalizedFile> f = fromYAML(
126     "---\n"
127     "arch:      armv7s\n"
128     "file-type: MH_OBJECT\n"
129     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
130     "...\n");
131   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7s);
132   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
133   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
134   EXPECT_TRUE(f->sections.empty());
135   EXPECT_TRUE(f->localSymbols.empty());
136   EXPECT_TRUE(f->globalSymbols.empty());
137   EXPECT_TRUE(f->undefinedSymbols.empty());
138 }
139 
TEST(ObjectFileYAML,roundTrip)140 TEST(ObjectFileYAML, roundTrip) {
141   std::string intermediate;
142   {
143     NormalizedFile f;
144     f.arch = lld::MachOLinkingContext::arch_x86_64;
145     f.fileType = llvm::MachO::MH_OBJECT;
146     f.flags = (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
147     f.os = lld::MachOLinkingContext::OS::macOSX;
148     toYAML(f, intermediate);
149   }
150   {
151     std::unique_ptr<NormalizedFile> f2 = fromYAML(intermediate);
152     EXPECT_EQ(f2->arch, lld::MachOLinkingContext::arch_x86_64);
153     EXPECT_EQ((int)(f2->fileType), llvm::MachO::MH_OBJECT);
154     EXPECT_EQ((int)(f2->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
155     EXPECT_TRUE(f2->sections.empty());
156     EXPECT_TRUE(f2->localSymbols.empty());
157     EXPECT_TRUE(f2->globalSymbols.empty());
158     EXPECT_TRUE(f2->undefinedSymbols.empty());
159   }
160 }
161 
TEST(ObjectFileYAML,oneSymbol)162 TEST(ObjectFileYAML, oneSymbol) {
163   std::unique_ptr<NormalizedFile> f = fromYAML(
164     "---\n"
165     "arch:      x86_64\n"
166     "file-type: MH_OBJECT\n"
167     "global-symbols:\n"
168     "  - name:   _main\n"
169     "    type:   N_SECT\n"
170     "    scope:  [ N_EXT ]\n"
171     "    sect:   1\n"
172     "    desc:   [ ]\n"
173     "    value:  0x100\n"
174     "...\n");
175   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
176   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
177   EXPECT_TRUE(f->sections.empty());
178   EXPECT_TRUE(f->localSymbols.empty());
179   EXPECT_TRUE(f->undefinedSymbols.empty());
180   EXPECT_EQ(f->globalSymbols.size(), 1UL);
181   const Symbol& sym = f->globalSymbols[0];
182   EXPECT_TRUE(sym.name.equals("_main"));
183   EXPECT_EQ((int)(sym.type), llvm::MachO::N_SECT);
184   EXPECT_EQ((int)(sym.scope), llvm::MachO::N_EXT);
185   EXPECT_EQ(sym.sect, 1);
186   EXPECT_EQ((int)(sym.desc), 0);
187   EXPECT_EQ((uint64_t)sym.value, 0x100ULL);
188 }
189 
TEST(ObjectFileYAML,oneSection)190 TEST(ObjectFileYAML, oneSection) {
191   std::unique_ptr<NormalizedFile> f = fromYAML(
192     "---\n"
193     "arch:      x86_64\n"
194     "file-type: MH_OBJECT\n"
195     "sections:\n"
196     "  - segment:     __TEXT\n"
197     "    section:     __text\n"
198     "    type:        S_REGULAR\n"
199     "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS ]\n"
200     "    alignment:   2\n"
201     "    address:     0x12345678\n"
202     "    content:     [ 0x90, 0x90 ]\n"
203     "...\n");
204   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
205   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
206   EXPECT_TRUE(f->localSymbols.empty());
207   EXPECT_TRUE(f->globalSymbols.empty());
208   EXPECT_TRUE(f->undefinedSymbols.empty());
209   EXPECT_EQ(f->sections.size(), 1UL);
210   const Section& sect = f->sections[0];
211   EXPECT_TRUE(sect.segmentName.equals("__TEXT"));
212   EXPECT_TRUE(sect.sectionName.equals("__text"));
213   EXPECT_EQ((uint32_t)(sect.type), (uint32_t)(llvm::MachO::S_REGULAR));
214   EXPECT_EQ((uint32_t)(sect.attributes),
215                             (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS));
216   EXPECT_EQ((uint16_t)sect.alignment, 2U);
217   EXPECT_EQ((uint64_t)sect.address, 0x12345678ULL);
218   EXPECT_EQ(sect.content.size(), 2UL);
219   EXPECT_EQ((int)(sect.content[0]), 0x90);
220   EXPECT_EQ((int)(sect.content[1]), 0x90);
221 }
222 
TEST(ObjectFileYAML,hello_x86_64)223 TEST(ObjectFileYAML, hello_x86_64) {
224   std::unique_ptr<NormalizedFile> f = fromYAML(
225     "---\n"
226     "arch:      x86_64\n"
227     "file-type: MH_OBJECT\n"
228     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
229     "sections:\n"
230     "  - segment:     __TEXT\n"
231     "    section:     __text\n"
232     "    type:        S_REGULAR\n"
233     "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
234     "    alignment:   1\n"
235     "    address:     0x0000\n"
236     "    content:     [ 0x55, 0x48, 0x89, 0xe5, 0x48, 0x8d, 0x3d, 0x00,\n"
237     "                   0x00, 0x00, 0x00, 0x30, 0xc0, 0xe8, 0x00, 0x00,\n"
238     "                   0x00, 0x00, 0x31, 0xc0, 0x5d, 0xc3 ]\n"
239     "    relocations:\n"
240     "     - offset:     0x0e\n"
241     "       type:       X86_64_RELOC_BRANCH\n"
242     "       length:     2\n"
243     "       pc-rel:     true\n"
244     "       extern:     true\n"
245     "       symbol:     2\n"
246     "     - offset:     0x07\n"
247     "       type:       X86_64_RELOC_SIGNED\n"
248     "       length:     2\n"
249     "       pc-rel:     true\n"
250     "       extern:     true\n"
251     "       symbol:     1\n"
252     "  - segment:     __TEXT\n"
253     "    section:     __cstring\n"
254     "    type:        S_CSTRING_LITERALS\n"
255     "    attributes:  [ ]\n"
256     "    alignment:   1\n"
257     "    address:     0x0016\n"
258     "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
259     "global-symbols:\n"
260     "  - name:   _main\n"
261     "    type:   N_SECT\n"
262     "    scope:  [ N_EXT ]\n"
263     "    sect:   1\n"
264     "    value:  0x0\n"
265     "local-symbols:\n"
266     "  - name:   L_.str\n"
267     "    type:   N_SECT\n"
268     "    scope:  [ ]\n"
269     "    sect:   2\n"
270     "    value:  0x16\n"
271     "undefined-symbols:\n"
272     "  - name:   _printf\n"
273     "    type:   N_UNDF\n"
274     "    value:  0x0\n"
275     "...\n");
276   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
277   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
278   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
279   EXPECT_EQ(f->sections.size(), 2UL);
280 
281   const Section& sect1 = f->sections[0];
282   EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
283   EXPECT_TRUE(sect1.sectionName.equals("__text"));
284   EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
285   EXPECT_EQ((uint32_t)(sect1.attributes),
286                             (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
287                                      | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
288   EXPECT_EQ((uint16_t)sect1.alignment, 1U);
289   EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
290   EXPECT_EQ(sect1.content.size(), 22UL);
291   EXPECT_EQ((int)(sect1.content[0]), 0x55);
292   EXPECT_EQ((int)(sect1.content[1]), 0x48);
293   EXPECT_EQ(sect1.relocations.size(), 2UL);
294   const Relocation& reloc1 = sect1.relocations[0];
295   EXPECT_EQ(reloc1.offset, 0x0eU);
296   EXPECT_FALSE(reloc1.scattered);
297   EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::X86_64_RELOC_BRANCH);
298   EXPECT_EQ(reloc1.length, 2);
299   EXPECT_TRUE(reloc1.pcRel);
300   EXPECT_TRUE(reloc1.isExtern);
301   EXPECT_EQ(reloc1.symbol, 2U);
302   EXPECT_EQ((int)(reloc1.value), 0);
303   const Relocation& reloc2 = sect1.relocations[1];
304   EXPECT_EQ(reloc2.offset, 0x07U);
305   EXPECT_FALSE(reloc2.scattered);
306   EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::X86_64_RELOC_SIGNED);
307   EXPECT_EQ(reloc2.length, 2);
308   EXPECT_TRUE(reloc2.pcRel);
309   EXPECT_TRUE(reloc2.isExtern);
310   EXPECT_EQ(reloc2.symbol, 1U);
311   EXPECT_EQ((int)(reloc2.value), 0);
312 
313   const Section& sect2 = f->sections[1];
314   EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
315   EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
316   EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
317   EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
318   EXPECT_EQ((uint16_t)sect2.alignment, 1U);
319   EXPECT_EQ((uint64_t)sect2.address, 0x016ULL);
320   EXPECT_EQ(sect2.content.size(), 7UL);
321   EXPECT_EQ((int)(sect2.content[0]), 0x68);
322   EXPECT_EQ((int)(sect2.content[1]), 0x65);
323   EXPECT_EQ((int)(sect2.content[2]), 0x6c);
324 
325   EXPECT_EQ(f->globalSymbols.size(), 1UL);
326   const Symbol& sym1 = f->globalSymbols[0];
327   EXPECT_TRUE(sym1.name.equals("_main"));
328   EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
329   EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
330   EXPECT_EQ(sym1.sect, 1);
331   EXPECT_EQ((int)(sym1.desc), 0);
332   EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
333   EXPECT_EQ(f->localSymbols.size(), 1UL);
334   const Symbol& sym2 = f->localSymbols[0];
335   EXPECT_TRUE(sym2.name.equals("L_.str"));
336   EXPECT_EQ((int)(sym2.type), llvm::MachO::N_SECT);
337   EXPECT_EQ((int)(sym2.scope), 0);
338   EXPECT_EQ(sym2.sect, 2);
339   EXPECT_EQ((int)(sym2.desc), 0);
340   EXPECT_EQ((uint64_t)sym2.value, 0x16ULL);
341   EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
342   const Symbol& sym3 = f->undefinedSymbols[0];
343   EXPECT_TRUE(sym3.name.equals("_printf"));
344   EXPECT_EQ((int)(sym3.type), llvm::MachO::N_UNDF);
345   EXPECT_EQ((int)(sym3.scope), 0);
346   EXPECT_EQ(sym3.sect, 0);
347   EXPECT_EQ((int)(sym3.desc), 0);
348   EXPECT_EQ((uint64_t)sym3.value, 0x0ULL);
349 }
350 
TEST(ObjectFileYAML,hello_x86)351 TEST(ObjectFileYAML, hello_x86) {
352   std::unique_ptr<NormalizedFile> f = fromYAML(
353     "---\n"
354     "arch:      x86\n"
355     "file-type: MH_OBJECT\n"
356     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
357     "sections:\n"
358     "  - segment:     __TEXT\n"
359     "    section:     __text\n"
360     "    type:        S_REGULAR\n"
361     "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
362     "    alignment:   1\n"
363     "    address:     0x0000\n"
364     "    content:     [ 0x55, 0x89, 0xe5, 0x83, 0xec, 0x08, 0xe8, 0x00,\n"
365     "                   0x00, 0x00, 0x00, 0x58, 0x8d, 0x80, 0x16, 0x00,\n"
366     "                   0x00, 0x00, 0x89, 0x04, 0x24, 0xe8, 0xe6, 0xff,\n"
367     "                   0xff, 0xff, 0x31, 0xc0, 0x83, 0xc4, 0x08, 0x5d,\n"
368     "                   0xc3 ]\n"
369     "    relocations:\n"
370     "     - offset:     0x16\n"
371     "       type:       GENERIC_RELOC_VANILLA\n"
372     "       length:     2\n"
373     "       pc-rel:     true\n"
374     "       extern:     true\n"
375     "       symbol:     1\n"
376     "     - offset:     0x0e\n"
377     "       scattered:  true\n"
378     "       type:       GENERIC_RELOC_LOCAL_SECTDIFF\n"
379     "       length:     2\n"
380     "       pc-rel:     false\n"
381     "       value:      0x21\n"
382     "     - offset:     0x0\n"
383     "       scattered:  true\n"
384     "       type:       GENERIC_RELOC_PAIR\n"
385     "       length:     2\n"
386     "       pc-rel:     false\n"
387     "       value:      0xb\n"
388     "  - segment:     __TEXT\n"
389     "    section:     __cstring\n"
390     "    type:        S_CSTRING_LITERALS\n"
391     "    attributes:  [ ]\n"
392     "    alignment:   1\n"
393     "    address:     0x0021\n"
394     "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
395     "global-symbols:\n"
396     "  - name:   _main\n"
397     "    type:   N_SECT\n"
398     "    scope:  [ N_EXT ]\n"
399     "    sect:   1\n"
400     "    value:  0x0\n"
401     "undefined-symbols:\n"
402     "  - name:   _printf\n"
403     "    type:   N_UNDF\n"
404     "    value:  0x0\n"
405     "...\n");
406   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);
407   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
408   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
409   EXPECT_EQ(f->sections.size(), 2UL);
410 
411   const Section& sect1 = f->sections[0];
412   EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
413   EXPECT_TRUE(sect1.sectionName.equals("__text"));
414   EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
415   EXPECT_EQ((uint32_t)(sect1.attributes),
416                             (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
417                                      | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
418   EXPECT_EQ((uint16_t)sect1.alignment, 1U);
419   EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
420   EXPECT_EQ(sect1.content.size(), 33UL);
421   EXPECT_EQ((int)(sect1.content[0]), 0x55);
422   EXPECT_EQ((int)(sect1.content[1]), 0x89);
423   EXPECT_EQ(sect1.relocations.size(), 3UL);
424   const Relocation& reloc1 = sect1.relocations[0];
425   EXPECT_EQ(reloc1.offset, 0x16U);
426   EXPECT_FALSE(reloc1.scattered);
427   EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::GENERIC_RELOC_VANILLA);
428   EXPECT_EQ(reloc1.length, 2);
429   EXPECT_TRUE(reloc1.pcRel);
430   EXPECT_TRUE(reloc1.isExtern);
431   EXPECT_EQ(reloc1.symbol, 1U);
432   EXPECT_EQ((int)(reloc1.value), 0);
433   const Relocation& reloc2 = sect1.relocations[1];
434   EXPECT_EQ(reloc2.offset, 0x0eU);
435   EXPECT_TRUE(reloc2.scattered);
436   EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::GENERIC_RELOC_LOCAL_SECTDIFF);
437   EXPECT_EQ(reloc2.length, 2);
438   EXPECT_FALSE(reloc2.pcRel);
439   EXPECT_EQ(reloc2.symbol, 0U);
440   EXPECT_EQ((int)(reloc2.value), 0x21);
441   const Relocation& reloc3 = sect1.relocations[2];
442   EXPECT_EQ(reloc3.offset, 0U);
443   EXPECT_TRUE(reloc3.scattered);
444   EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::GENERIC_RELOC_PAIR);
445   EXPECT_EQ(reloc3.length, 2);
446   EXPECT_FALSE(reloc3.pcRel);
447   EXPECT_EQ(reloc3.symbol, 0U);
448   EXPECT_EQ((int)(reloc3.value), 0xb);
449 
450   const Section& sect2 = f->sections[1];
451   EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
452   EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
453   EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
454   EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
455   EXPECT_EQ((uint16_t)sect2.alignment, 1U);
456   EXPECT_EQ((uint64_t)sect2.address, 0x021ULL);
457   EXPECT_EQ(sect2.content.size(), 7UL);
458   EXPECT_EQ((int)(sect2.content[0]), 0x68);
459   EXPECT_EQ((int)(sect2.content[1]), 0x65);
460   EXPECT_EQ((int)(sect2.content[2]), 0x6c);
461 
462   EXPECT_EQ(f->globalSymbols.size(), 1UL);
463   const Symbol& sym1 = f->globalSymbols[0];
464   EXPECT_TRUE(sym1.name.equals("_main"));
465   EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
466   EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
467   EXPECT_EQ(sym1.sect, 1);
468   EXPECT_EQ((int)(sym1.desc), 0);
469   EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
470   EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
471   const Symbol& sym2 = f->undefinedSymbols[0];
472   EXPECT_TRUE(sym2.name.equals("_printf"));
473   EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);
474   EXPECT_EQ((int)(sym2.scope), 0);
475   EXPECT_EQ(sym2.sect, 0);
476   EXPECT_EQ((int)(sym2.desc), 0);
477   EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);
478 }
479 
TEST(ObjectFileYAML,hello_armv6)480 TEST(ObjectFileYAML, hello_armv6) {
481   std::unique_ptr<NormalizedFile> f = fromYAML(
482     "---\n"
483     "arch:      armv6\n"
484     "file-type: MH_OBJECT\n"
485     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
486     "sections:\n"
487     "  - segment:     __TEXT\n"
488     "    section:     __text\n"
489     "    type:        S_REGULAR\n"
490     "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
491     "    alignment:   4\n"
492     "    address:     0x0000\n"
493     "    content:     [ 0x80, 0x40, 0x2d, 0xe9, 0x10, 0x00, 0x9f, 0xe5,\n"
494     "                   0x0d, 0x70, 0xa0, 0xe1, 0x00, 0x00, 0x8f, 0xe0,\n"
495     "                   0xfa, 0xff, 0xff, 0xeb, 0x00, 0x00, 0xa0, 0xe3,\n"
496     "                   0x80, 0x80, 0xbd, 0xe8, 0x0c, 0x00, 0x00, 0x00 ]\n"
497     "    relocations:\n"
498     "     - offset:     0x1c\n"
499     "       scattered:  true\n"
500     "       type:       ARM_RELOC_SECTDIFF\n"
501     "       length:     2\n"
502     "       pc-rel:     false\n"
503     "       value:      0x20\n"
504     "     - offset:     0x0\n"
505     "       scattered:  true\n"
506     "       type:       ARM_RELOC_PAIR\n"
507     "       length:     2\n"
508     "       pc-rel:     false\n"
509     "       value:      0xc\n"
510     "     - offset:     0x10\n"
511     "       type:       ARM_RELOC_BR24\n"
512     "       length:     2\n"
513     "       pc-rel:     true\n"
514     "       extern:     true\n"
515     "       symbol:     1\n"
516     "  - segment:     __TEXT\n"
517     "    section:     __cstring\n"
518     "    type:        S_CSTRING_LITERALS\n"
519     "    attributes:  [ ]\n"
520     "    alignment:   1\n"
521     "    address:     0x0020\n"
522     "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
523     "global-symbols:\n"
524     "  - name:   _main\n"
525     "    type:   N_SECT\n"
526     "    scope:  [ N_EXT ]\n"
527     "    sect:   1\n"
528     "    value:  0x0\n"
529     "undefined-symbols:\n"
530     "  - name:   _printf\n"
531     "    type:   N_UNDF\n"
532     "    value:  0x0\n"
533     "...\n");
534   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv6);
535   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
536   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
537   EXPECT_EQ(f->sections.size(), 2UL);
538 
539   const Section& sect1 = f->sections[0];
540   EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
541   EXPECT_TRUE(sect1.sectionName.equals("__text"));
542   EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
543   EXPECT_EQ((uint32_t)(sect1.attributes),
544                             (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
545                                      | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
546   EXPECT_EQ((uint16_t)sect1.alignment, 4U);
547   EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
548   EXPECT_EQ(sect1.content.size(), 32UL);
549   EXPECT_EQ((int)(sect1.content[0]), 0x80);
550   EXPECT_EQ((int)(sect1.content[1]), 0x40);
551   EXPECT_EQ(sect1.relocations.size(), 3UL);
552   const Relocation& reloc1 = sect1.relocations[0];
553   EXPECT_EQ(reloc1.offset, 0x1cU);
554   EXPECT_TRUE(reloc1.scattered);
555   EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::ARM_RELOC_SECTDIFF);
556   EXPECT_EQ(reloc1.length, 2);
557   EXPECT_FALSE(reloc1.pcRel);
558   EXPECT_EQ(reloc1.symbol, 0U);
559   EXPECT_EQ((int)(reloc1.value), 0x20);
560   const Relocation& reloc2 = sect1.relocations[1];
561   EXPECT_EQ(reloc2.offset, 0x0U);
562   EXPECT_TRUE(reloc2.scattered);
563   EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::ARM_RELOC_PAIR);
564   EXPECT_EQ(reloc2.length, 2);
565   EXPECT_FALSE(reloc2.pcRel);
566   EXPECT_EQ(reloc2.symbol, 0U);
567   EXPECT_EQ((int)(reloc2.value), 0xc);
568   const Relocation& reloc3 = sect1.relocations[2];
569   EXPECT_EQ(reloc3.offset, 0x10U);
570   EXPECT_FALSE(reloc3.scattered);
571   EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::ARM_RELOC_BR24);
572   EXPECT_EQ(reloc3.length, 2);
573   EXPECT_TRUE(reloc3.pcRel);
574   EXPECT_TRUE(reloc3.isExtern);
575   EXPECT_EQ(reloc3.symbol, 1U);
576   EXPECT_EQ((int)(reloc3.value), 0);
577 
578   const Section& sect2 = f->sections[1];
579   EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
580   EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
581   EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
582   EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
583   EXPECT_EQ((uint16_t)sect2.alignment, 1U);
584   EXPECT_EQ((uint64_t)sect2.address, 0x020ULL);
585   EXPECT_EQ(sect2.content.size(), 7UL);
586   EXPECT_EQ((int)(sect2.content[0]), 0x68);
587   EXPECT_EQ((int)(sect2.content[1]), 0x65);
588   EXPECT_EQ((int)(sect2.content[2]), 0x6c);
589 
590   EXPECT_EQ(f->globalSymbols.size(), 1UL);
591   const Symbol& sym1 = f->globalSymbols[0];
592   EXPECT_TRUE(sym1.name.equals("_main"));
593   EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
594   EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
595   EXPECT_EQ(sym1.sect, 1);
596   EXPECT_EQ((int)(sym1.desc), 0);
597   EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
598   EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
599   const Symbol& sym2 = f->undefinedSymbols[0];
600   EXPECT_TRUE(sym2.name.equals("_printf"));
601   EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);
602   EXPECT_EQ((int)(sym2.scope), 0);
603   EXPECT_EQ(sym2.sect, 0);
604   EXPECT_EQ((int)(sym2.desc), 0);
605   EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);
606 }
607 
TEST(ObjectFileYAML,hello_armv7)608 TEST(ObjectFileYAML, hello_armv7) {
609   std::unique_ptr<NormalizedFile> f = fromYAML(
610     "---\n"
611     "arch:      armv7\n"
612     "file-type: MH_OBJECT\n"
613     "flags:     [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
614     "sections:\n"
615     "  - segment:     __TEXT\n"
616     "    section:     __text\n"
617     "    type:        S_REGULAR\n"
618     "    attributes:  [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
619     "    alignment:   2\n"
620     "    address:     0x0000\n"
621     "    content:     [ 0x80, 0xb5, 0x40, 0xf2, 0x06, 0x00, 0x6f, 0x46,\n"
622     "                   0xc0, 0xf2, 0x00, 0x00, 0x78, 0x44, 0xff, 0xf7,\n"
623     "                   0xf8, 0xef, 0x00, 0x20, 0x80, 0xbd ]\n"
624     "    relocations:\n"
625     "     - offset:     0x0e\n"
626     "       type:       ARM_THUMB_RELOC_BR22\n"
627     "       length:     2\n"
628     "       pc-rel:     true\n"
629     "       extern:     true\n"
630     "       symbol:     1\n"
631     "     - offset:     0x08\n"
632     "       scattered:  true\n"
633     "       type:       ARM_RELOC_HALF_SECTDIFF\n"
634     "       length:     3\n"
635     "       pc-rel:     false\n"
636     "       value:      0x16\n"
637     "     - offset:     0x06\n"
638     "       scattered:  true\n"
639     "       type:       ARM_RELOC_PAIR\n"
640     "       length:     3\n"
641     "       pc-rel:     false\n"
642     "       value:      0xc\n"
643     "     - offset:     0x02\n"
644     "       scattered:  true\n"
645     "       type:       ARM_RELOC_HALF_SECTDIFF\n"
646     "       length:     2\n"
647     "       pc-rel:     false\n"
648     "       value:      0x16\n"
649     "     - offset:     0x0\n"
650     "       scattered:  true\n"
651     "       type:       ARM_RELOC_PAIR\n"
652     "       length:     2\n"
653     "       pc-rel:     false\n"
654     "       value:      0xc\n"
655     "  - segment:     __TEXT\n"
656     "    section:     __cstring\n"
657     "    type:        S_CSTRING_LITERALS\n"
658     "    attributes:  [ ]\n"
659     "    alignment:   1\n"
660     "    address:     0x0016\n"
661     "    content:     [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
662     "global-symbols:\n"
663     "  - name:   _main\n"
664     "    type:   N_SECT\n"
665     "    scope:  [ N_EXT ]\n"
666     "    sect:   1\n"
667     "    desc:   [ N_ARM_THUMB_DEF ]\n"
668     "    value:  0x0\n"
669     "undefined-symbols:\n"
670     "  - name:   _printf\n"
671     "    type:   N_UNDF\n"
672     "    value:  0x0\n"
673     "...\n");
674   EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);
675   EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
676   EXPECT_EQ((int)(f->flags), (int)llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
677   EXPECT_EQ(f->sections.size(), 2UL);
678 
679   const Section& sect1 = f->sections[0];
680   EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
681   EXPECT_TRUE(sect1.sectionName.equals("__text"));
682   EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
683   EXPECT_EQ((uint32_t)(sect1.attributes),
684                             (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
685                                      | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
686   EXPECT_EQ((uint16_t)sect1.alignment, 2U);
687   EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
688   EXPECT_EQ(sect1.content.size(), 22UL);
689   EXPECT_EQ((int)(sect1.content[0]), 0x80);
690   EXPECT_EQ((int)(sect1.content[1]), 0xb5);
691   EXPECT_EQ(sect1.relocations.size(), 5UL);
692   const Relocation& reloc1 = sect1.relocations[0];
693   EXPECT_EQ(reloc1.offset, 0x0eU);
694   EXPECT_FALSE(reloc1.scattered);
695   EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::ARM_THUMB_RELOC_BR22);
696   EXPECT_EQ(reloc1.length, 2);
697   EXPECT_TRUE(reloc1.pcRel);
698   EXPECT_TRUE(reloc1.isExtern);
699   EXPECT_EQ(reloc1.symbol, 1U);
700   EXPECT_EQ((int)(reloc1.value), 0);
701   const Relocation& reloc2 = sect1.relocations[1];
702   EXPECT_EQ(reloc2.offset, 0x8U);
703   EXPECT_TRUE(reloc2.scattered);
704   EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::ARM_RELOC_HALF_SECTDIFF);
705   EXPECT_EQ(reloc2.length, 3);
706   EXPECT_FALSE(reloc2.pcRel);
707   EXPECT_EQ(reloc2.symbol, 0U);
708   EXPECT_EQ((int)(reloc2.value), 0x16);
709   const Relocation& reloc3 = sect1.relocations[2];
710   EXPECT_EQ(reloc3.offset, 0x6U);
711   EXPECT_TRUE(reloc3.scattered);
712   EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::ARM_RELOC_PAIR);
713   EXPECT_EQ(reloc3.length, 3);
714   EXPECT_FALSE(reloc3.pcRel);
715   EXPECT_EQ(reloc3.symbol, 0U);
716   EXPECT_EQ((int)(reloc3.value), 0xc);
717    const Relocation& reloc4 = sect1.relocations[3];
718   EXPECT_EQ(reloc4.offset, 0x2U);
719   EXPECT_TRUE(reloc4.scattered);
720   EXPECT_EQ((int)reloc4.type, (int)llvm::MachO::ARM_RELOC_HALF_SECTDIFF);
721   EXPECT_EQ(reloc4.length, 2);
722   EXPECT_FALSE(reloc4.pcRel);
723   EXPECT_EQ(reloc4.symbol, 0U);
724   EXPECT_EQ((int)(reloc4.value), 0x16);
725   const Relocation& reloc5 = sect1.relocations[4];
726   EXPECT_EQ(reloc5.offset, 0x0U);
727   EXPECT_TRUE(reloc5.scattered);
728   EXPECT_EQ((int)reloc5.type, (int)llvm::MachO::ARM_RELOC_PAIR);
729   EXPECT_EQ(reloc5.length, 2);
730   EXPECT_FALSE(reloc5.pcRel);
731   EXPECT_EQ(reloc5.symbol, 0U);
732   EXPECT_EQ((int)(reloc5.value), 0xc);
733 
734   const Section& sect2 = f->sections[1];
735   EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
736   EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
737   EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
738   EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
739   EXPECT_EQ((uint16_t)sect2.alignment, 1U);
740   EXPECT_EQ((uint64_t)sect2.address, 0x016ULL);
741   EXPECT_EQ(sect2.content.size(), 7UL);
742   EXPECT_EQ((int)(sect2.content[0]), 0x68);
743   EXPECT_EQ((int)(sect2.content[1]), 0x65);
744   EXPECT_EQ((int)(sect2.content[2]), 0x6c);
745 
746   EXPECT_EQ(f->globalSymbols.size(), 1UL);
747   const Symbol& sym1 = f->globalSymbols[0];
748   EXPECT_TRUE(sym1.name.equals("_main"));
749   EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
750   EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
751   EXPECT_EQ(sym1.sect, 1);
752   EXPECT_EQ((int)(sym1.desc), (int)(llvm::MachO::N_ARM_THUMB_DEF));
753   EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
754   EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
755   const Symbol& sym2 = f->undefinedSymbols[0];
756   EXPECT_TRUE(sym2.name.equals("_printf"));
757   EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);
758   EXPECT_EQ((int)(sym2.scope), 0);
759   EXPECT_EQ(sym2.sect, 0);
760   EXPECT_EQ((int)(sym2.desc), 0);
761   EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);
762 }
763