1 //===- lld/unittest/MachOTests/MachONormalizedFileBinaryWriterTests.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 "llvm/ADT/Twine.h"
11 #include "llvm/BinaryFormat/MachO.h"
12 #include "llvm/Support/FileSystem.h"
13 #include "gtest/gtest.h"
14 #include <cassert>
15 #include <memory>
16 #include <system_error>
17 #include <vector>
18
19 using llvm::StringRef;
20 using llvm::MemoryBuffer;
21 using llvm::SmallString;
22 using llvm::Twine;
23 using llvm::ErrorOr;
24 using namespace llvm::MachO;
25 using namespace lld::mach_o::normalized;
26
27 // Parses binary mach-o file at specified path and returns
28 // ownership of buffer to mb parameter and ownership of
29 // Normalized file to nf parameter.
fromBinary(StringRef path,std::unique_ptr<MemoryBuffer> & mb,std::unique_ptr<NormalizedFile> & nf,StringRef archStr)30 static void fromBinary(StringRef path, std::unique_ptr<MemoryBuffer> &mb,
31 std::unique_ptr<NormalizedFile> &nf, StringRef archStr) {
32 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = MemoryBuffer::getFile(path);
33 std::error_code ec = mbOrErr.getError();
34 EXPECT_FALSE(ec);
35 mb = std::move(mbOrErr.get());
36
37 llvm::Expected<std::unique_ptr<NormalizedFile>> r =
38 lld::mach_o::normalized::readBinary(
39 mb, lld::MachOLinkingContext::archFromName(archStr));
40 EXPECT_FALSE(!r);
41 nf.reset(r->release());
42 }
43
44 static Relocation
makeReloc(unsigned addr,bool rel,bool ext,RelocationInfoType type,unsigned sym)45 makeReloc(unsigned addr, bool rel, bool ext, RelocationInfoType type,
46 unsigned sym) {
47 Relocation result;
48 result.offset = addr;
49 result.scattered = false;
50 result.type = type;
51 result.length = 2;
52 result.pcRel = rel;
53 result.isExtern = ext;
54 result.value = 0;
55 result.symbol = sym;
56 return result;
57 }
58
59 static Relocation
makeScatReloc(unsigned addr,RelocationInfoType type,unsigned value)60 makeScatReloc(unsigned addr, RelocationInfoType type, unsigned value) {
61 Relocation result;
62 result.offset = addr;
63 result.scattered = true;
64 result.type = type;
65 result.length = 2;
66 result.pcRel = false;
67 result.isExtern = true;
68 result.value = value;
69 result.symbol = 0;
70 return result;
71 }
72
73 static Symbol
makeUndefSymbol(StringRef name)74 makeUndefSymbol(StringRef name) {
75 Symbol sym;
76 sym.name = name;
77 sym.type = N_UNDF;
78 sym.scope = N_EXT;
79 sym.sect = NO_SECT;
80 sym.desc = 0;
81 sym.value = 0;
82 return sym;
83 }
84
85
86 static Symbol
makeSymbol(StringRef name,unsigned addr)87 makeSymbol(StringRef name, unsigned addr) {
88 Symbol sym;
89 sym.name = name;
90 sym.type = N_SECT;
91 sym.scope = N_EXT;
92 sym.sect = 1;
93 sym.desc = 0;
94 sym.value = addr;
95 return sym;
96 }
97
98 static Symbol
makeThumbSymbol(StringRef name,unsigned addr)99 makeThumbSymbol(StringRef name, unsigned addr) {
100 Symbol sym;
101 sym.name = name;
102 sym.type = N_SECT;
103 sym.scope = N_EXT;
104 sym.sect = 1;
105 sym.desc = N_ARM_THUMB_DEF;
106 sym.value = addr;
107 return sym;
108 }
109
TEST(BinaryWriterTest,obj_relocs_x86_64)110 TEST(BinaryWriterTest, obj_relocs_x86_64) {
111 SmallString<128> tmpFl;
112 {
113 NormalizedFile f;
114 f.arch = lld::MachOLinkingContext::arch_x86_64;
115 f.fileType = MH_OBJECT;
116 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
117 f.os = lld::MachOLinkingContext::OS::macOSX;
118 f.sections.resize(1);
119 Section& text = f.sections.front();
120 text.segmentName = "__TEXT";
121 text.sectionName = "__text";
122 text.type = S_REGULAR;
123 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
124 | S_ATTR_SOME_INSTRUCTIONS);
125 text.alignment = 16;
126 text.address = 0;
127 const uint8_t textBytes[] = {
128 0xe8, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x05,
129 0x00, 0x00, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00,
130 0x00, 0x00, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
131 0xc6, 0x05, 0xff, 0xff, 0xff, 0xff, 0x12, 0xc7,
132 0x05, 0xfc, 0xff, 0xff, 0xff, 0x78, 0x56, 0x34,
133 0x12, 0x48, 0x8b, 0x3d, 0x00, 0x00, 0x00, 0x00 };
134
135 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
136 text.relocations.push_back(makeReloc(0x01, false, true, X86_64_RELOC_BRANCH, 1));
137 text.relocations.push_back(makeReloc(0x08, false, true, X86_64_RELOC_GOT_LOAD, 1));
138 text.relocations.push_back(makeReloc(0x0E, false, true, X86_64_RELOC_GOT, 1));
139 text.relocations.push_back(makeReloc(0x14, false, true, X86_64_RELOC_SIGNED, 1));
140 text.relocations.push_back(makeReloc(0x1A, false, true, X86_64_RELOC_SIGNED_1, 1));
141 text.relocations.push_back(makeReloc(0x21, false, true, X86_64_RELOC_SIGNED_4, 1));
142 text.relocations.push_back(makeReloc(0x2C, false, true, X86_64_RELOC_TLV, 2));
143
144 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
145 f.undefinedSymbols.push_back(makeUndefSymbol("_tbar"));
146
147 std::error_code ec =
148 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
149 EXPECT_FALSE(ec);
150 llvm::Error ec2 = writeBinary(f, tmpFl);
151 EXPECT_FALSE(ec2);
152 }
153
154 std::unique_ptr<MemoryBuffer> bufferOwner;
155 std::unique_ptr<NormalizedFile> f2;
156 fromBinary(tmpFl, bufferOwner, f2, "x86_64");
157
158 EXPECT_EQ(lld::MachOLinkingContext::arch_x86_64, f2->arch);
159 EXPECT_EQ(MH_OBJECT, f2->fileType);
160 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
161
162 EXPECT_TRUE(f2->localSymbols.empty());
163 EXPECT_TRUE(f2->globalSymbols.empty());
164 EXPECT_EQ(2UL, f2->undefinedSymbols.size());
165 const Symbol& barUndef = f2->undefinedSymbols[0];
166 EXPECT_TRUE(barUndef.name.equals("_bar"));
167 EXPECT_EQ(N_UNDF, barUndef.type);
168 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
169 const Symbol& tbarUndef = f2->undefinedSymbols[1];
170 EXPECT_TRUE(tbarUndef.name.equals("_tbar"));
171 EXPECT_EQ(N_UNDF, tbarUndef.type);
172 EXPECT_EQ(SymbolScope(N_EXT), tbarUndef.scope);
173
174 EXPECT_EQ(1UL, f2->sections.size());
175 const Section& text = f2->sections[0];
176 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
177 EXPECT_TRUE(text.sectionName.equals("__text"));
178 EXPECT_EQ(S_REGULAR, text.type);
179 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
180 | S_ATTR_SOME_INSTRUCTIONS));
181 EXPECT_EQ((uint16_t)text.alignment, 16U);
182 EXPECT_EQ(text.address, Hex64(0x0));
183 EXPECT_EQ(48UL, text.content.size());
184 const Relocation& call = text.relocations[0];
185 EXPECT_EQ(call.offset, Hex32(0x1));
186 EXPECT_EQ(call.type, X86_64_RELOC_BRANCH);
187 EXPECT_EQ(call.length, 2);
188 EXPECT_EQ(call.isExtern, true);
189 EXPECT_EQ(call.symbol, 1U);
190 const Relocation& gotLoad = text.relocations[1];
191 EXPECT_EQ(gotLoad.offset, Hex32(0x8));
192 EXPECT_EQ(gotLoad.type, X86_64_RELOC_GOT_LOAD);
193 EXPECT_EQ(gotLoad.length, 2);
194 EXPECT_EQ(gotLoad.isExtern, true);
195 EXPECT_EQ(gotLoad.symbol, 1U);
196 const Relocation& gotUse = text.relocations[2];
197 EXPECT_EQ(gotUse.offset, Hex32(0xE));
198 EXPECT_EQ(gotUse.type, X86_64_RELOC_GOT);
199 EXPECT_EQ(gotUse.length, 2);
200 EXPECT_EQ(gotUse.isExtern, true);
201 EXPECT_EQ(gotUse.symbol, 1U);
202 const Relocation& signed0 = text.relocations[3];
203 EXPECT_EQ(signed0.offset, Hex32(0x14));
204 EXPECT_EQ(signed0.type, X86_64_RELOC_SIGNED);
205 EXPECT_EQ(signed0.length, 2);
206 EXPECT_EQ(signed0.isExtern, true);
207 EXPECT_EQ(signed0.symbol, 1U);
208 const Relocation& signed1 = text.relocations[4];
209 EXPECT_EQ(signed1.offset, Hex32(0x1A));
210 EXPECT_EQ(signed1.type, X86_64_RELOC_SIGNED_1);
211 EXPECT_EQ(signed1.length, 2);
212 EXPECT_EQ(signed1.isExtern, true);
213 EXPECT_EQ(signed1.symbol, 1U);
214 const Relocation& signed4 = text.relocations[5];
215 EXPECT_EQ(signed4.offset, Hex32(0x21));
216 EXPECT_EQ(signed4.type, X86_64_RELOC_SIGNED_4);
217 EXPECT_EQ(signed4.length, 2);
218 EXPECT_EQ(signed4.isExtern, true);
219 EXPECT_EQ(signed4.symbol, 1U);
220
221 bufferOwner.reset(nullptr);
222 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
223 EXPECT_FALSE(ec);
224 }
225
226
227
TEST(BinaryWriterTest,obj_relocs_x86)228 TEST(BinaryWriterTest, obj_relocs_x86) {
229 SmallString<128> tmpFl;
230 {
231 NormalizedFile f;
232 f.arch = lld::MachOLinkingContext::arch_x86;
233 f.fileType = MH_OBJECT;
234 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
235 f.os = lld::MachOLinkingContext::OS::macOSX;
236 f.sections.resize(1);
237 Section& text = f.sections.front();
238 text.segmentName = "__TEXT";
239 text.sectionName = "__text";
240 text.type = S_REGULAR;
241 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
242 | S_ATTR_SOME_INSTRUCTIONS);
243 text.alignment = 16;
244 text.address = 0;
245 const uint8_t textBytes[] = {
246 0xe8, 0xfb, 0xff, 0xff, 0xff, 0xa1, 0x00, 0x00,
247 0x00, 0x00, 0x8b, 0xb0, 0xfb, 0xff, 0xff, 0xff,
248 0x8b, 0x80, 0x11, 0x00, 0x00, 0x00 };
249
250 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
251 text.relocations.push_back(makeReloc(0x01, true, true, GENERIC_RELOC_VANILLA, 0));
252 text.relocations.push_back(makeReloc(0x06, false, true, GENERIC_RELOC_VANILLA, 0));
253 text.relocations.push_back(makeScatReloc(0x0c, GENERIC_RELOC_LOCAL_SECTDIFF, 0));
254 text.relocations.push_back(makeScatReloc(0x0, GENERIC_RELOC_PAIR, 5));
255 text.relocations.push_back(makeReloc(0x12, true, true, GENERIC_RELOC_TLV, 1));
256
257 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
258 f.undefinedSymbols.push_back(makeUndefSymbol("_tbar"));
259
260 std::error_code ec =
261 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
262 EXPECT_FALSE(ec);
263 llvm::Error ec2 = writeBinary(f, tmpFl);
264 EXPECT_FALSE(ec2);
265 }
266 std::unique_ptr<MemoryBuffer> bufferOwner;
267 std::unique_ptr<NormalizedFile> f2;
268 fromBinary(tmpFl, bufferOwner, f2, "i386");
269
270 EXPECT_EQ(lld::MachOLinkingContext::arch_x86, f2->arch);
271 EXPECT_EQ(MH_OBJECT, f2->fileType);
272 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
273
274 EXPECT_TRUE(f2->localSymbols.empty());
275 EXPECT_TRUE(f2->globalSymbols.empty());
276 EXPECT_EQ(2UL, f2->undefinedSymbols.size());
277 const Symbol& barUndef = f2->undefinedSymbols[0];
278 EXPECT_TRUE(barUndef.name.equals("_bar"));
279 EXPECT_EQ(N_UNDF, barUndef.type);
280 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
281 const Symbol& tbarUndef = f2->undefinedSymbols[1];
282 EXPECT_TRUE(tbarUndef.name.equals("_tbar"));
283 EXPECT_EQ(N_UNDF, tbarUndef.type);
284 EXPECT_EQ(SymbolScope(N_EXT), tbarUndef.scope);
285
286 EXPECT_EQ(1UL, f2->sections.size());
287 const Section& text = f2->sections[0];
288 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
289 EXPECT_TRUE(text.sectionName.equals("__text"));
290 EXPECT_EQ(S_REGULAR, text.type);
291 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
292 | S_ATTR_SOME_INSTRUCTIONS));
293 EXPECT_EQ((uint16_t)text.alignment, 16U);
294 EXPECT_EQ(text.address, Hex64(0x0));
295 EXPECT_EQ(22UL, text.content.size());
296 const Relocation& call = text.relocations[0];
297 EXPECT_EQ(call.offset, Hex32(0x1));
298 EXPECT_EQ(call.scattered, false);
299 EXPECT_EQ(call.type, GENERIC_RELOC_VANILLA);
300 EXPECT_EQ(call.pcRel, true);
301 EXPECT_EQ(call.length, 2);
302 EXPECT_EQ(call.isExtern, true);
303 EXPECT_EQ(call.symbol, 0U);
304 const Relocation& absLoad = text.relocations[1];
305 EXPECT_EQ(absLoad.offset, Hex32(0x6));
306 EXPECT_EQ(absLoad.scattered, false);
307 EXPECT_EQ(absLoad.type, GENERIC_RELOC_VANILLA);
308 EXPECT_EQ(absLoad.pcRel, false);
309 EXPECT_EQ(absLoad.length, 2);
310 EXPECT_EQ(absLoad.isExtern, true);
311 EXPECT_EQ(absLoad.symbol,0U);
312 const Relocation& pic1 = text.relocations[2];
313 EXPECT_EQ(pic1.offset, Hex32(0xc));
314 EXPECT_EQ(pic1.scattered, true);
315 EXPECT_EQ(pic1.type, GENERIC_RELOC_LOCAL_SECTDIFF);
316 EXPECT_EQ(pic1.length, 2);
317 EXPECT_EQ(pic1.value, 0U);
318 const Relocation& pic2 = text.relocations[3];
319 EXPECT_EQ(pic2.offset, Hex32(0x0));
320 EXPECT_EQ(pic1.scattered, true);
321 EXPECT_EQ(pic2.type, GENERIC_RELOC_PAIR);
322 EXPECT_EQ(pic2.length, 2);
323 EXPECT_EQ(pic2.value, 5U);
324 const Relocation& tlv = text.relocations[4];
325 EXPECT_EQ(tlv.offset, Hex32(0x12));
326 EXPECT_EQ(tlv.type, GENERIC_RELOC_TLV);
327 EXPECT_EQ(tlv.length, 2);
328 EXPECT_EQ(tlv.isExtern, true);
329 EXPECT_EQ(tlv.symbol, 1U);
330
331 // lld::errs() << "temp = " << tmpFl << "\n";
332 bufferOwner.reset(nullptr);
333 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
334 EXPECT_FALSE(ec);
335 }
336
337
338
TEST(BinaryWriterTest,obj_relocs_armv7)339 TEST(BinaryWriterTest, obj_relocs_armv7) {
340 SmallString<128> tmpFl;
341 {
342 NormalizedFile f;
343 f.arch = lld::MachOLinkingContext::arch_armv7;
344 f.fileType = MH_OBJECT;
345 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
346 f.os = lld::MachOLinkingContext::OS::macOSX;
347 f.sections.resize(1);
348 Section& text = f.sections.front();
349 text.segmentName = "__TEXT";
350 text.sectionName = "__text";
351 text.type = S_REGULAR;
352 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
353 | S_ATTR_SOME_INSTRUCTIONS);
354 text.alignment = 4;
355 text.address = 0;
356 const uint8_t textBytes[] = {
357 0xff, 0xf7, 0xfe, 0xef, 0x40, 0xf2, 0x05, 0x01,
358 0xc0, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0xbf };
360
361 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
362 text.relocations.push_back(makeReloc(0x00, true, true,
363 ARM_THUMB_RELOC_BR22, 2));
364 text.relocations.push_back(makeScatReloc(0x04,
365 ARM_RELOC_HALF_SECTDIFF, 0x10));
366 text.relocations.push_back(makeScatReloc(0x00,
367 ARM_RELOC_PAIR, 0xC));
368 text.relocations.push_back(makeScatReloc(0x08,
369 ARM_RELOC_HALF_SECTDIFF, 0x10));
370 text.relocations.push_back(makeScatReloc(0x00,
371 ARM_RELOC_PAIR, 0xC));
372 text.relocations.push_back(makeReloc(0x0C, false, true,
373 ARM_RELOC_VANILLA, 2));
374
375 f.globalSymbols.push_back(makeThumbSymbol("_foo", 0x00));
376 f.globalSymbols.push_back(makeThumbSymbol("_foo2", 0x10));
377 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
378
379 std::error_code ec =
380 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
381 EXPECT_FALSE(ec);
382 llvm::Error ec2 = writeBinary(f, tmpFl);
383 EXPECT_FALSE(ec2);
384 }
385 std::unique_ptr<MemoryBuffer> bufferOwner;
386 std::unique_ptr<NormalizedFile> f2;
387 fromBinary(tmpFl, bufferOwner, f2, "armv7");
388
389 EXPECT_EQ(lld::MachOLinkingContext::arch_armv7, f2->arch);
390 EXPECT_EQ(MH_OBJECT, f2->fileType);
391 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
392
393 EXPECT_TRUE(f2->localSymbols.empty());
394 EXPECT_EQ(2UL, f2->globalSymbols.size());
395 const Symbol& fooDef = f2->globalSymbols[0];
396 EXPECT_TRUE(fooDef.name.equals("_foo"));
397 EXPECT_EQ(N_SECT, fooDef.type);
398 EXPECT_EQ(1, fooDef.sect);
399 EXPECT_EQ(SymbolScope(N_EXT), fooDef.scope);
400 const Symbol& foo2Def = f2->globalSymbols[1];
401 EXPECT_TRUE(foo2Def.name.equals("_foo2"));
402 EXPECT_EQ(N_SECT, foo2Def.type);
403 EXPECT_EQ(1, foo2Def.sect);
404 EXPECT_EQ(SymbolScope(N_EXT), foo2Def.scope);
405
406 EXPECT_EQ(1UL, f2->undefinedSymbols.size());
407 const Symbol& barUndef = f2->undefinedSymbols[0];
408 EXPECT_TRUE(barUndef.name.equals("_bar"));
409 EXPECT_EQ(N_UNDF, barUndef.type);
410 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
411
412 EXPECT_EQ(1UL, f2->sections.size());
413 const Section& text = f2->sections[0];
414 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
415 EXPECT_TRUE(text.sectionName.equals("__text"));
416 EXPECT_EQ(S_REGULAR, text.type);
417 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
418 | S_ATTR_SOME_INSTRUCTIONS));
419 EXPECT_EQ((uint16_t)text.alignment, 4U);
420 EXPECT_EQ(text.address, Hex64(0x0));
421 EXPECT_EQ(18UL, text.content.size());
422 const Relocation& blx = text.relocations[0];
423 EXPECT_EQ(blx.offset, Hex32(0x0));
424 EXPECT_EQ(blx.scattered, false);
425 EXPECT_EQ(blx.type, ARM_THUMB_RELOC_BR22);
426 EXPECT_EQ(blx.pcRel, true);
427 EXPECT_EQ(blx.length, 2);
428 EXPECT_EQ(blx.isExtern, true);
429 EXPECT_EQ(blx.symbol, 2U);
430 const Relocation& movw1 = text.relocations[1];
431 EXPECT_EQ(movw1.offset, Hex32(0x4));
432 EXPECT_EQ(movw1.scattered, true);
433 EXPECT_EQ(movw1.type, ARM_RELOC_HALF_SECTDIFF);
434 EXPECT_EQ(movw1.length, 2);
435 EXPECT_EQ(movw1.value, 0x10U);
436 const Relocation& movw2 = text.relocations[2];
437 EXPECT_EQ(movw2.offset, Hex32(0x0));
438 EXPECT_EQ(movw2.scattered, true);
439 EXPECT_EQ(movw2.type, ARM_RELOC_PAIR);
440 EXPECT_EQ(movw2.length, 2);
441 EXPECT_EQ(movw2.value, Hex32(0xC));
442 const Relocation& movt1 = text.relocations[3];
443 EXPECT_EQ(movt1.offset, Hex32(0x8));
444 EXPECT_EQ(movt1.scattered, true);
445 EXPECT_EQ(movt1.type, ARM_RELOC_HALF_SECTDIFF);
446 EXPECT_EQ(movt1.length, 2);
447 EXPECT_EQ(movt1.value, Hex32(0x10));
448 const Relocation& movt2 = text.relocations[4];
449 EXPECT_EQ(movt2.offset, Hex32(0x0));
450 EXPECT_EQ(movt2.scattered, true);
451 EXPECT_EQ(movt2.type, ARM_RELOC_PAIR);
452 EXPECT_EQ(movt2.length, 2);
453 EXPECT_EQ(movt2.value, Hex32(0xC));
454 const Relocation& absPointer = text.relocations[5];
455 EXPECT_EQ(absPointer.offset, Hex32(0xC));
456 EXPECT_EQ(absPointer.type, ARM_RELOC_VANILLA);
457 EXPECT_EQ(absPointer.length, 2);
458 EXPECT_EQ(absPointer.isExtern, true);
459 EXPECT_EQ(absPointer.symbol, 2U);
460
461 // lld::errs() << "temp = " << tmpFl << "\n";
462 bufferOwner.reset(nullptr);
463 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
464 EXPECT_FALSE(ec);
465 }
466
467
468
TEST(BinaryWriterTest,obj_relocs_ppc)469 TEST(BinaryWriterTest, obj_relocs_ppc) {
470 SmallString<128> tmpFl;
471 {
472 NormalizedFile f;
473 f.arch = lld::MachOLinkingContext::arch_ppc;
474 f.fileType = MH_OBJECT;
475 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
476 f.os = lld::MachOLinkingContext::OS::macOSX;
477 f.sections.resize(1);
478 Section& text = f.sections.front();
479 text.segmentName = "__TEXT";
480 text.sectionName = "__text";
481 text.type = S_REGULAR;
482 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
483 | S_ATTR_SOME_INSTRUCTIONS);
484 text.alignment = 4;
485 text.address = 0;
486 const uint8_t textBytes[] = {
487 0x48, 0x00, 0x00, 0x01, 0x40, 0x82, 0xff, 0xfc,
488 0x3c, 0x62, 0x00, 0x00, 0x3c, 0x62, 0x00, 0x00,
489 0x80, 0x63, 0x00, 0x24, 0x80, 0x63, 0x00, 0x24,
490 0x3c, 0x40, 0x00, 0x00, 0x3c, 0x60, 0x00, 0x00,
491 0x80, 0x42, 0x00, 0x28, 0x80, 0x63, 0x00, 0x28,
492 0x60, 0x00, 0x00, 0x00 };
493
494 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
495 text.relocations.push_back(makeReloc(0x00, true, true,
496 PPC_RELOC_BR24, 2));
497 text.relocations.push_back(makeReloc(0x04, true, true,
498 PPC_RELOC_BR14, 2));
499 text.relocations.push_back(makeScatReloc(0x08,
500 PPC_RELOC_HI16_SECTDIFF, 0x28));
501 text.relocations.push_back(makeScatReloc(0x24,
502 PPC_RELOC_PAIR, 0x4));
503 text.relocations.push_back(makeScatReloc(0x0C,
504 PPC_RELOC_HA16_SECTDIFF, 0x28));
505 text.relocations.push_back(makeScatReloc(0x24,
506 PPC_RELOC_PAIR, 0x4));
507 text.relocations.push_back(makeScatReloc(0x10,
508 PPC_RELOC_LO16_SECTDIFF, 0x28));
509 text.relocations.push_back(makeScatReloc(0x00,
510 PPC_RELOC_PAIR, 0x4));
511 text.relocations.push_back(makeScatReloc(0x14,
512 PPC_RELOC_LO14_SECTDIFF, 0x28));
513 text.relocations.push_back(makeScatReloc(0x00,
514 PPC_RELOC_PAIR, 0x4));
515 text.relocations.push_back(makeReloc(0x18, false, false,
516 PPC_RELOC_HI16, 1));
517 text.relocations.push_back(makeReloc(0x28, false, false,
518 PPC_RELOC_PAIR, 0));
519 text.relocations.push_back(makeReloc(0x1C, false, false,
520 PPC_RELOC_HA16, 1));
521 text.relocations.push_back(makeReloc(0x28, false, false,
522 PPC_RELOC_PAIR, 0));
523 text.relocations.push_back(makeReloc(0x20, false, false,
524 PPC_RELOC_LO16, 1));
525 text.relocations.push_back(makeReloc(0x00, false, false,
526 PPC_RELOC_PAIR, 0));
527 text.relocations.push_back(makeReloc(0x24, false, false,
528 PPC_RELOC_LO14, 1));
529 text.relocations.push_back(makeReloc(0x00, false, false,
530 PPC_RELOC_PAIR, 0));
531
532 f.globalSymbols.push_back(makeSymbol("_foo", 0x00));
533 f.globalSymbols.push_back(makeSymbol("_foo2", 0x28));
534 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
535
536 std::error_code ec =
537 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
538 EXPECT_FALSE(ec);
539 llvm::Error ec2 = writeBinary(f, tmpFl);
540 EXPECT_FALSE(ec2);
541 }
542 std::unique_ptr<MemoryBuffer> bufferOwner;
543 std::unique_ptr<NormalizedFile> f2;
544 fromBinary(tmpFl, bufferOwner, f2, "ppc");
545
546 EXPECT_EQ(lld::MachOLinkingContext::arch_ppc, f2->arch);
547 EXPECT_EQ(MH_OBJECT, f2->fileType);
548 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
549
550 EXPECT_TRUE(f2->localSymbols.empty());
551 EXPECT_EQ(2UL, f2->globalSymbols.size());
552 const Symbol& fooDef = f2->globalSymbols[0];
553 EXPECT_TRUE(fooDef.name.equals("_foo"));
554 EXPECT_EQ(N_SECT, fooDef.type);
555 EXPECT_EQ(1, fooDef.sect);
556 EXPECT_EQ(SymbolScope(N_EXT), fooDef.scope);
557 const Symbol& foo2Def = f2->globalSymbols[1];
558 EXPECT_TRUE(foo2Def.name.equals("_foo2"));
559 EXPECT_EQ(N_SECT, foo2Def.type);
560 EXPECT_EQ(1, foo2Def.sect);
561 EXPECT_EQ(SymbolScope(N_EXT), foo2Def.scope);
562
563 EXPECT_EQ(1UL, f2->undefinedSymbols.size());
564 const Symbol& barUndef = f2->undefinedSymbols[0];
565 EXPECT_TRUE(barUndef.name.equals("_bar"));
566 EXPECT_EQ(N_UNDF, barUndef.type);
567 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
568
569 EXPECT_EQ(1UL, f2->sections.size());
570 const Section& text = f2->sections[0];
571 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
572 EXPECT_TRUE(text.sectionName.equals("__text"));
573 EXPECT_EQ(S_REGULAR, text.type);
574 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
575 | S_ATTR_SOME_INSTRUCTIONS));
576 EXPECT_EQ((uint16_t)text.alignment, 4U);
577 EXPECT_EQ(text.address, Hex64(0x0));
578 EXPECT_EQ(44UL, text.content.size());
579 const Relocation& br24 = text.relocations[0];
580 EXPECT_EQ(br24.offset, Hex32(0x0));
581 EXPECT_EQ(br24.scattered, false);
582 EXPECT_EQ(br24.type, PPC_RELOC_BR24);
583 EXPECT_EQ(br24.pcRel, true);
584 EXPECT_EQ(br24.length, 2);
585 EXPECT_EQ(br24.isExtern, true);
586 EXPECT_EQ(br24.symbol, 2U);
587 const Relocation& br14 = text.relocations[1];
588 EXPECT_EQ(br14.offset, Hex32(0x4));
589 EXPECT_EQ(br14.scattered, false);
590 EXPECT_EQ(br14.type, PPC_RELOC_BR14);
591 EXPECT_EQ(br14.pcRel, true);
592 EXPECT_EQ(br14.length, 2);
593 EXPECT_EQ(br14.isExtern, true);
594 EXPECT_EQ(br14.symbol, 2U);
595 const Relocation& pichi1 = text.relocations[2];
596 EXPECT_EQ(pichi1.offset, Hex32(0x8));
597 EXPECT_EQ(pichi1.scattered, true);
598 EXPECT_EQ(pichi1.type, PPC_RELOC_HI16_SECTDIFF);
599 EXPECT_EQ(pichi1.length, 2);
600 EXPECT_EQ(pichi1.value, 0x28U);
601 const Relocation& pichi2 = text.relocations[3];
602 EXPECT_EQ(pichi2.offset, Hex32(0x24));
603 EXPECT_EQ(pichi2.scattered, true);
604 EXPECT_EQ(pichi2.type, PPC_RELOC_PAIR);
605 EXPECT_EQ(pichi2.length, 2);
606 EXPECT_EQ(pichi2.value, 0x4U);
607 const Relocation& picha1 = text.relocations[4];
608 EXPECT_EQ(picha1.offset, Hex32(0xC));
609 EXPECT_EQ(picha1.scattered, true);
610 EXPECT_EQ(picha1.type, PPC_RELOC_HA16_SECTDIFF);
611 EXPECT_EQ(picha1.length, 2);
612 EXPECT_EQ(picha1.value, 0x28U);
613 const Relocation& picha2 = text.relocations[5];
614 EXPECT_EQ(picha2.offset, Hex32(0x24));
615 EXPECT_EQ(picha2.scattered, true);
616 EXPECT_EQ(picha2.type, PPC_RELOC_PAIR);
617 EXPECT_EQ(picha2.length, 2);
618 EXPECT_EQ(picha2.value, 0x4U);
619 const Relocation& piclo1 = text.relocations[6];
620 EXPECT_EQ(piclo1.offset, Hex32(0x10));
621 EXPECT_EQ(piclo1.scattered, true);
622 EXPECT_EQ(piclo1.type, PPC_RELOC_LO16_SECTDIFF);
623 EXPECT_EQ(piclo1.length, 2);
624 EXPECT_EQ(piclo1.value, 0x28U);
625 const Relocation& piclo2 = text.relocations[7];
626 EXPECT_EQ(piclo2.offset, Hex32(0x0));
627 EXPECT_EQ(piclo2.scattered, true);
628 EXPECT_EQ(piclo2.type, PPC_RELOC_PAIR);
629 EXPECT_EQ(piclo2.length, 2);
630 EXPECT_EQ(piclo2.value, 0x4U);
631 const Relocation& picloa1 = text.relocations[8];
632 EXPECT_EQ(picloa1.offset, Hex32(0x14));
633 EXPECT_EQ(picloa1.scattered, true);
634 EXPECT_EQ(picloa1.type, PPC_RELOC_LO14_SECTDIFF);
635 EXPECT_EQ(picloa1.length, 2);
636 EXPECT_EQ(picloa1.value, 0x28U);
637 const Relocation& picloa2 = text.relocations[9];
638 EXPECT_EQ(picloa2.offset, Hex32(0x0));
639 EXPECT_EQ(picloa2.scattered, true);
640 EXPECT_EQ(picloa2.type, PPC_RELOC_PAIR);
641 EXPECT_EQ(picloa2.length, 2);
642 EXPECT_EQ(picloa2.value, 0x4U);
643 const Relocation& abshi1 = text.relocations[10];
644 EXPECT_EQ(abshi1.offset, Hex32(0x18));
645 EXPECT_EQ(abshi1.scattered, false);
646 EXPECT_EQ(abshi1.type, PPC_RELOC_HI16);
647 EXPECT_EQ(abshi1.length, 2);
648 EXPECT_EQ(abshi1.symbol, 1U);
649 const Relocation& abshi2 = text.relocations[11];
650 EXPECT_EQ(abshi2.offset, Hex32(0x28));
651 EXPECT_EQ(abshi2.scattered, false);
652 EXPECT_EQ(abshi2.type, PPC_RELOC_PAIR);
653 EXPECT_EQ(abshi2.length, 2);
654 EXPECT_EQ(abshi2.symbol, 0U);
655 const Relocation& absha1 = text.relocations[12];
656 EXPECT_EQ(absha1.offset, Hex32(0x1C));
657 EXPECT_EQ(absha1.scattered, false);
658 EXPECT_EQ(absha1.type, PPC_RELOC_HA16);
659 EXPECT_EQ(absha1.length, 2);
660 EXPECT_EQ(absha1.symbol, 1U);
661 const Relocation& absha2 = text.relocations[13];
662 EXPECT_EQ(absha2.offset, Hex32(0x28));
663 EXPECT_EQ(absha2.scattered, false);
664 EXPECT_EQ(absha2.type, PPC_RELOC_PAIR);
665 EXPECT_EQ(absha2.length, 2);
666 EXPECT_EQ(absha2.symbol, 0U);
667 const Relocation& abslo1 = text.relocations[14];
668 EXPECT_EQ(abslo1.offset, Hex32(0x20));
669 EXPECT_EQ(abslo1.scattered, false);
670 EXPECT_EQ(abslo1.type, PPC_RELOC_LO16);
671 EXPECT_EQ(abslo1.length, 2);
672 EXPECT_EQ(abslo1.symbol, 1U);
673 const Relocation& abslo2 = text.relocations[15];
674 EXPECT_EQ(abslo2.offset, Hex32(0x00));
675 EXPECT_EQ(abslo2.scattered, false);
676 EXPECT_EQ(abslo2.type, PPC_RELOC_PAIR);
677 EXPECT_EQ(abslo2.length, 2);
678 EXPECT_EQ(abslo2.symbol, 0U);
679 const Relocation& absloa1 = text.relocations[16];
680 EXPECT_EQ(absloa1.offset, Hex32(0x24));
681 EXPECT_EQ(absloa1.scattered, false);
682 EXPECT_EQ(absloa1.type, PPC_RELOC_LO14);
683 EXPECT_EQ(absloa1.length, 2);
684 EXPECT_EQ(absloa1.symbol, 1U);
685 const Relocation& absloa2 = text.relocations[17];
686 EXPECT_EQ(absloa2.offset, Hex32(0x00));
687 EXPECT_EQ(absloa2.scattered, false);
688 EXPECT_EQ(absloa2.type, PPC_RELOC_PAIR);
689 EXPECT_EQ(absloa2.length, 2);
690 EXPECT_EQ(absloa2.symbol, 0U);
691
692 bufferOwner.reset(nullptr);
693 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
694 EXPECT_FALSE(ec);
695 }
696