• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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