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