xref: /llvm-project/llvm/unittests/Object/XCOFFObjectFileTest.cpp (revision aa8feeefd3ac6c78ee8f67bf033976fc7d68bc6d)
1 //===- XCOFFObjectFileTest.cpp - Tests for XCOFFObjectFile ----------------===//
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 "llvm/Object/ELFObjectFile.h"
10 #include "llvm/Object/XCOFFObjectFile.h"
11 #include "llvm/Testing/Support/Error.h"
12 #include "gtest/gtest.h"
13 
14 using namespace llvm;
15 using namespace llvm::object;
16 using namespace llvm::XCOFF;
17 
18 TEST(XCOFFObjectFileTest, XCOFFObjectType) {
19   // Create an arbitrary object of a non-XCOFF type and test that
20   // dyn_cast<XCOFFObjectFile> returns null for it.
21   char Buf[sizeof(typename ELF64LE::Ehdr)] = {};
22   memcpy(Buf, "\177ELF", 4);
23 
24   auto *EHdr = reinterpret_cast<typename ELF64LE::Ehdr *>(Buf);
25   EHdr->e_ident[llvm::ELF::EI_CLASS] = llvm::ELF::ELFCLASS64;
26   EHdr->e_ident[llvm::ELF::EI_DATA] = llvm::ELF::ELFDATA2LSB;
27 
28   MemoryBufferRef Source(StringRef(Buf, sizeof(Buf)), "non-XCOFF");
29   Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
30       ObjectFile::createObjectFile(Source);
31   ASSERT_THAT_EXPECTED(ObjOrErr, Succeeded());
32 
33   EXPECT_TRUE(dyn_cast<XCOFFObjectFile>((*ObjOrErr).get()) == nullptr);
34 }
35 
36 TEST(XCOFFObjectFileTest, doesXCOFFTracebackTableBegin) {
37   EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0}));
38   EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0, 1}));
39   EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0, 1}));
40   EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0}));
41 }
42 
43 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIGeneral) {
44   uint8_t V[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01, 0x05, 0x58, 0x00,
45                  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
46                  0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
47   uint64_t Size = sizeof(V);
48   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
49   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
50   XCOFFTracebackTable TT = *TTOrErr;
51 
52   EXPECT_EQ(TT.getVersion(), 0);
53 
54   EXPECT_EQ(TT.getLanguageID(), 0);
55 
56   EXPECT_FALSE(TT.isGlobalLinkage());
57   EXPECT_FALSE(TT.isOutOfLineEpilogOrPrologue());
58   EXPECT_TRUE(TT.hasTraceBackTableOffset());
59   EXPECT_FALSE(TT.isInternalProcedure());
60   EXPECT_FALSE(TT.hasControlledStorage());
61   EXPECT_FALSE(TT.isTOCless());
62   EXPECT_TRUE(TT.isFloatingPointPresent());
63   EXPECT_FALSE(TT.isFloatingPointOperationLogOrAbortEnabled());
64 
65   EXPECT_FALSE(TT.isInterruptHandler());
66   EXPECT_TRUE(TT.isFuncNamePresent());
67   EXPECT_FALSE(TT.isAllocaUsed());
68   EXPECT_EQ(TT.getOnConditionDirective(), 0);
69   EXPECT_FALSE(TT.isCRSaved());
70   EXPECT_FALSE(TT.isLRSaved());
71 
72   EXPECT_TRUE(TT.isBackChainStored());
73   EXPECT_FALSE(TT.isFixup());
74   EXPECT_EQ(TT.getNumOfFPRsSaved(), 0);
75 
76   EXPECT_FALSE(TT.hasExtensionTable());
77   EXPECT_FALSE(TT.hasVectorInfo());
78   EXPECT_EQ(TT.getNumOfGPRsSaved(), 0);
79 
80   EXPECT_EQ(TT.getNumberOfFixedParms(), 1);
81 
82   EXPECT_EQ(TT.getNumberOfFPParms(), 2);
83   EXPECT_TRUE(TT.hasParmsOnStack());
84 
85   ASSERT_TRUE(TT.getParmsType());
86   EXPECT_EQ(TT.getParmsType().value(), "i, f, d");
87 
88   ASSERT_TRUE(TT.getTraceBackTableOffset());
89   EXPECT_EQ(TT.getTraceBackTableOffset().value(), 64u);
90 
91   EXPECT_FALSE(TT.getHandlerMask());
92 
93   ASSERT_TRUE(TT.getFunctionName());
94   EXPECT_EQ(TT.getFunctionName().value(), "add_all");
95   EXPECT_EQ(TT.getFunctionName()->size(), 7u);
96 
97   EXPECT_FALSE(TT.getAllocaRegister());
98   EXPECT_EQ(Size, 25u);
99 }
100 
101 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIParmsType) {
102   uint8_t V[] = {0x01, 0x02, 0xA2, 0x40, 0x80, 0x00, 0x02, 0x07, 0x2B, 0x00,
103                  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
104                  0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
105   uint64_t Size = sizeof(V);
106   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
107 
108   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
109   XCOFFTracebackTable TT = *TTOrErr;
110   EXPECT_EQ(TT.getVersion(), 1);
111   EXPECT_EQ(TT.getLanguageID(), 2);
112 
113   EXPECT_TRUE(TT.isGlobalLinkage());
114   EXPECT_EQ(TT.getNumberOfFixedParms(), 2);
115 
116   EXPECT_EQ(TT.getNumberOfFPParms(), 3);
117 
118   ASSERT_TRUE(TT.getParmsType());
119   EXPECT_EQ(*TT.getParmsType(), "i, i, f, f, d");
120 
121   V[8] = 0xAC;
122   Size = sizeof(V);
123   Expected<XCOFFTracebackTable> TTOrErr1 = XCOFFTracebackTable::create(V, Size);
124   ASSERT_THAT_EXPECTED(TTOrErr1, Succeeded());
125   XCOFFTracebackTable TT1 = *TTOrErr1;
126   ASSERT_TRUE(TT1.getParmsType());
127   EXPECT_EQ(*TT1.getParmsType(), "f, f, d, i, i");
128 
129   V[8] = 0xD4;
130   Size = sizeof(V);
131   Expected<XCOFFTracebackTable> TTOrErr2 = XCOFFTracebackTable::create(V, Size);
132   ASSERT_THAT_EXPECTED(TTOrErr2, Succeeded());
133   XCOFFTracebackTable TT2 = *TTOrErr2;
134   ASSERT_TRUE(TT2.getParmsType());
135   EXPECT_EQ(*TT2.getParmsType(), "d, i, f, f, i");
136 
137   V[6] = 0x01;
138   Size = sizeof(V);
139   Expected<XCOFFTracebackTable> TTOrErr3 = XCOFFTracebackTable::create(V, Size);
140   ASSERT_THAT_EXPECTED(TTOrErr3, Succeeded());
141   XCOFFTracebackTable TT3 = *TTOrErr3;
142   ASSERT_TRUE(TT3.getParmsType());
143   EXPECT_EQ(*TT3.getParmsType(), "d, i, f, f");
144 
145   V[6] = 0x04;
146   V[7] = 0x1E;
147   V[8] = 0xAC;
148   V[9] = 0xAA;
149   V[10] = 0xAA;
150   V[11] = 0xAA;
151   Size = sizeof(V);
152   Expected<XCOFFTracebackTable> TTOrErr4 = XCOFFTracebackTable::create(V, Size);
153   ASSERT_THAT_EXPECTED(TTOrErr4, Succeeded());
154   XCOFFTracebackTable TT4 = *TTOrErr4;
155   ASSERT_TRUE(TT4.getParmsType());
156   EXPECT_EQ(*TT4.getParmsType(),
157             "f, f, d, i, i, f, f, f, f, f, f, f, f, f, f, f, f, ...");
158 }
159 
160 const uint8_t TBTableData[] = {
161     0x00, 0x00, 0x2A, 0x60, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc4, 0x00, 0x00,
162     0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
163     0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
164     0x6c, 0x1f, 0x02, 0x05, 0xf0, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
165 
166 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIControlledStorageInfoDisp) {
167   uint64_t Size = sizeof(TBTableData);
168   Expected<XCOFFTracebackTable> TTOrErr =
169       XCOFFTracebackTable::create(TBTableData, Size);
170   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
171   XCOFFTracebackTable TT = *TTOrErr;
172   EXPECT_TRUE(TT.hasControlledStorage());
173   ASSERT_TRUE(TT.getNumOfCtlAnchors());
174   EXPECT_EQ(TT.getNumOfCtlAnchors().value(), 2u);
175 
176   ASSERT_TRUE(TT.getControlledStorageInfoDisp());
177 
178   SmallVector<uint32_t, 8> Disp = TT.getControlledStorageInfoDisp().value();
179 
180   ASSERT_EQ(Disp.size(), 2UL);
181   EXPECT_EQ(Disp[0], 0x05050000u);
182   EXPECT_EQ(Disp[1], 0x06060000u);
183   EXPECT_EQ(Size, 45u);
184 }
185 
186 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIAllocaRegister) {
187   uint64_t Size = sizeof(TBTableData);
188   Expected<XCOFFTracebackTable> TTOrErr =
189       XCOFFTracebackTable::create(TBTableData, Size);
190   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
191   XCOFFTracebackTable TT = *TTOrErr;
192   ASSERT_TRUE(TT.getAllocaRegister());
193   EXPECT_EQ(*TT.getAllocaRegister(), 31u);
194 }
195 
196 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
197 
198   uint64_t Size = sizeof(TBTableData);
199   Expected<XCOFFTracebackTable> TTOrErr =
200       XCOFFTracebackTable::create(TBTableData, Size);
201   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
202   XCOFFTracebackTable TT = *TTOrErr;
203 
204   EXPECT_EQ(TT.getNumberOfFixedParms(), 3);
205   EXPECT_EQ(TT.getNumberOfFPParms(), 2);
206   EXPECT_TRUE(TT.hasVectorInfo());
207   EXPECT_TRUE(TT.hasExtensionTable());
208 
209   ASSERT_TRUE(TT.getParmsType());
210   EXPECT_EQ(TT.getParmsType().value(), "v, i, f, i, d, i, v");
211 
212   ASSERT_TRUE(TT.getVectorExt());
213   TBVectorExt VecExt = TT.getVectorExt().value();
214 
215   EXPECT_EQ(VecExt.getNumberOfVRSaved(), 0);
216   EXPECT_TRUE(VecExt.isVRSavedOnStack());
217   EXPECT_FALSE(VecExt.hasVarArgs());
218 
219   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
220   EXPECT_TRUE(VecExt.hasVMXInstruction());
221 
222   EXPECT_EQ(VecExt.getVectorParmsInfo(), "vf, vf");
223 
224   ASSERT_TRUE(TT.getExtensionTable());
225   EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY);
226 
227   EXPECT_EQ(Size, 45u);
228 }
229 
230 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
231   const uint8_t TBTableData[] = {
232       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5, 0x00, 0x00,
233       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
234       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
235       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
236   uint64_t Size = sizeof(TBTableData);
237   Expected<XCOFFTracebackTable> TTOrErr =
238       XCOFFTracebackTable::create(TBTableData, Size);
239   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
240   XCOFFTracebackTable TT = *TTOrErr;
241 
242   ASSERT_TRUE(TT.getParmsType());
243   EXPECT_EQ(TT.getParmsType().value(), "v, i, f, i, d, i, v, v");
244 
245   ASSERT_TRUE(TT.getVectorExt());
246   TBVectorExt VecExt = TT.getVectorExt().value();
247 
248   EXPECT_EQ(VecExt.getNumberOfVRSaved(), 4);
249   EXPECT_FALSE(VecExt.isVRSavedOnStack());
250   EXPECT_TRUE(VecExt.hasVarArgs());
251 
252   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
253   EXPECT_TRUE(VecExt.hasVMXInstruction());
254 
255   EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
256 
257   ASSERT_TRUE(TT.getExtensionTable());
258   EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY);
259 
260   EXPECT_EQ(Size, 44u);
261 }
262 
263 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtMandatory) {
264   uint64_t Size = 6;
265   Expected<XCOFFTracebackTable> TTOrErr =
266       XCOFFTracebackTable::create(TBTableData, Size);
267   EXPECT_THAT_ERROR(
268       TTOrErr.takeError(),
269       FailedWithMessage(
270           "unexpected end of data at offset 0x6 while reading [0x0, 0x8)"));
271   EXPECT_EQ(Size, 0u);
272 }
273 
274 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtParmsType) {
275   uint64_t Size = 9;
276   Expected<XCOFFTracebackTable> TTOrErr =
277       XCOFFTracebackTable::create(TBTableData, Size);
278   EXPECT_THAT_ERROR(
279       TTOrErr.takeError(),
280       FailedWithMessage(
281           "unexpected end of data at offset 0x9 while reading [0x8, 0xc)"));
282   EXPECT_EQ(Size, 8u);
283 }
284 
285 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtTBOffset) {
286   uint64_t Size = 14;
287   Expected<XCOFFTracebackTable> TTOrErr =
288       XCOFFTracebackTable::create(TBTableData, Size);
289   EXPECT_THAT_ERROR(
290       TTOrErr.takeError(),
291       FailedWithMessage(
292           "unexpected end of data at offset 0xe while reading [0xc, 0x10)"));
293   EXPECT_EQ(Size, 12u);
294 }
295 
296 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtHandlerMask) {
297   uint8_t V[] = {0x00, 0x00, 0x22, 0xC0, 0x80, 0x00, 0x01, 0x05, 0x58,
298                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07};
299   uint64_t Size = sizeof(V);
300   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
301   EXPECT_THAT_ERROR(
302       TTOrErr.takeError(),
303       FailedWithMessage(
304           "unexpected end of data at offset 0x12 while reading [0x10, 0x14)"));
305   EXPECT_EQ(Size, 16u);
306 }
307 
308 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNumOfCtlAnchors) {
309   uint64_t Size = 19;
310   Expected<XCOFFTracebackTable> TTOrErr =
311       XCOFFTracebackTable::create(TBTableData, Size);
312   EXPECT_THAT_ERROR(
313       TTOrErr.takeError(),
314       FailedWithMessage(
315           "unexpected end of data at offset 0x13 while reading [0x10, 0x14)"));
316   EXPECT_EQ(Size, 16u);
317 }
318 
319 TEST(XCOFFObjectFileTest,
320      XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp) {
321   uint64_t Size = 21;
322   Expected<XCOFFTracebackTable> TTOrErr =
323       XCOFFTracebackTable::create(TBTableData, Size);
324   EXPECT_THAT_ERROR(
325       TTOrErr.takeError(),
326       FailedWithMessage(
327           "unexpected end of data at offset 0x15 while reading [0x14, 0x18)"));
328   EXPECT_EQ(Size, 20u);
329 }
330 
331 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNameLen) {
332   uint64_t Size = 29;
333   Expected<XCOFFTracebackTable> TTOrErr =
334       XCOFFTracebackTable::create(TBTableData, Size);
335   EXPECT_THAT_ERROR(
336       TTOrErr.takeError(),
337       FailedWithMessage(
338           "unexpected end of data at offset 0x1d while reading [0x1c, 0x1e)"));
339   EXPECT_EQ(Size, 28u);
340 }
341 
342 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtFunctionName) {
343   uint64_t Size = 36;
344   Expected<XCOFFTracebackTable> TTOrErr =
345       XCOFFTracebackTable::create(TBTableData, Size);
346   EXPECT_THAT_ERROR(
347       TTOrErr.takeError(),
348       FailedWithMessage(
349           "unexpected end of data at offset 0x24 while reading [0x1e, 0x25)"));
350   EXPECT_EQ(Size, 30u);
351 }
352 
353 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtAllocaUsed) {
354   uint64_t Size = 37;
355   Expected<XCOFFTracebackTable> TTOrErr =
356       XCOFFTracebackTable::create(TBTableData, Size);
357   EXPECT_THAT_ERROR(
358       TTOrErr.takeError(),
359       FailedWithMessage(
360           "unexpected end of data at offset 0x25 while reading [0x25, 0x26)"));
361   EXPECT_EQ(Size, 37u);
362 }
363 
364 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoData) {
365   uint64_t Size = 39;
366   Expected<XCOFFTracebackTable> TTOrErr =
367       XCOFFTracebackTable::create(TBTableData, Size);
368 
369   EXPECT_THAT_ERROR(
370       TTOrErr.takeError(),
371       FailedWithMessage(
372           "unexpected end of data at offset 0x27 while reading [0x26, 0x2c)"));
373   EXPECT_EQ(Size, 38u);
374 }
375 
376 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoParmsInfo) {
377   uint64_t Size = 43;
378   Expected<XCOFFTracebackTable> TTOrErr =
379       XCOFFTracebackTable::create(TBTableData, Size);
380 
381   EXPECT_THAT_ERROR(
382       TTOrErr.takeError(),
383       FailedWithMessage(
384           "unexpected end of data at offset 0x2b while reading [0x26, 0x2c)"));
385   EXPECT_EQ(Size, 38u);
386 }
387 
388 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
389   uint64_t Size = 44;
390   Expected<XCOFFTracebackTable> TTOrErr =
391       XCOFFTracebackTable::create(TBTableData, Size);
392 
393   EXPECT_THAT_ERROR(
394       TTOrErr.takeError(),
395       FailedWithMessage(
396           "unexpected end of data at offset 0x2c while reading [0x2c, 0x2d)"));
397   EXPECT_EQ(Size, 44u);
398 }
399 
400 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef32) {
401   uint8_t XCOFF32Binary[] = {
402       // File header.
403       0x01, 0xdf, 0x00, 0x01, 0x5f, 0x58, 0xf8, 0x95, 0x00, 0x00, 0x00, 0x3c,
404       0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
405 
406       // Section header for empty .data section.
407       0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410       0x00, 0x00, 0x00, 0x40,
411 
412       // Start of symbol table.
413       // C_File symbol.
414       0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415       0xff, 0xfe, 0x00, 0x03, 0x67, 0x01,
416       // File Auxiliary Entry.
417       0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 
420       // Csect symbol.
421       0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422       0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
423       // Csect auxiliary entry.
424       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
425       0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
426 
427   ArrayRef<uint8_t> XCOFF32Ref(XCOFF32Binary, sizeof(XCOFF32Binary));
428   Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
429       object::ObjectFile::createObjectFile(
430           MemoryBufferRef(toStringRef(XCOFF32Ref), "dummyXCOFF"),
431           file_magic::xcoff_object_32);
432   ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
433 
434   const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
435   DataRefImpl Ref;
436   Ref.p = File.getSymbolEntryAddressByIndex(2);
437   XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
438   Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
439   ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
440 
441   // Set csect symbol's auxiliary entry count to 0.
442   XCOFF32Binary[113] = 0;
443   Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
444   EXPECT_THAT_ERROR(
445       ExpectErr.takeError(),
446       FailedWithMessage(
447           "csect symbol \".data\" with index 2 contains no auxiliary entry"));
448 }
449 
450 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
451   uint8_t XCOFF64Binary[] = {
452       // File header.
453       0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00,
454       0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
455 
456       // Section header for empty .data section.
457       0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
463 
464       // Start of symbol table.
465       // C_File symbol.
466       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
467       0xff, 0xfe, 0x00, 0x02, 0x67, 0x01,
468       // File Auxiliary Entry.
469       0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470       0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
471 
472       // Csect symbol.
473       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
474       0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
475       // Csect auxiliary entry.
476       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
477       0x00, 0x00, 0x00, 0x00, 0x00, 0xfb,
478 
479       // String table.
480       0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64,
481       0x61, 0x74, 0x61, 0x00};
482 
483   ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary));
484   Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
485       object::ObjectFile::createObjectFile(
486           MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"),
487           file_magic::xcoff_object_64);
488   ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
489 
490   const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
491   DataRefImpl Ref;
492   Ref.p = File.getSymbolEntryAddressByIndex(2);
493   XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
494   Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
495   ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
496 
497   // Inject incorrect auxiliary type value.
498   XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM);
499   Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef();
500   EXPECT_THAT_ERROR(
501       NotFoundErr.takeError(),
502       FailedWithMessage("a csect auxiliary entry has not been found for symbol "
503                         "\".data\" with index 2"));
504 
505   // Set csect symbol's auxiliary entry count to 0.
506   XCOFF64Binary[149] = 0;
507   Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
508   EXPECT_THAT_ERROR(
509       ExpectErr.takeError(),
510       FailedWithMessage(
511           "csect symbol \".data\" with index 2 contains no auxiliary entry"));
512 }
513 
514 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) {
515   const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01,
516                                  0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00,
517                                  0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64,
518                                  0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
519   uint64_t Size = 28;
520   Expected<XCOFFTracebackTable> TTOrErr =
521       XCOFFTracebackTable::create(TBTableData, Size);
522 
523   EXPECT_THAT_ERROR(
524       TTOrErr.takeError(),
525       FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
526                         "in parseParmsType."));
527 }
528 
529 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
530   const uint8_t TBTableData[] = {
531       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x10,
532       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
533       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
534       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
535   uint64_t Size = 44;
536   Expected<XCOFFTracebackTable> TTOrErr =
537       XCOFFTracebackTable::create(TBTableData, Size);
538 
539   EXPECT_THAT_ERROR(
540       TTOrErr.takeError(),
541       FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
542                         "in parseParmsTypeWithVecInfo."));
543 }
544 
545 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
546   const uint8_t TBTableData[] = {
547       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
548       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
549       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
550       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00};
551   uint64_t Size = 44;
552   Expected<XCOFFTracebackTable> TTOrErr =
553       XCOFFTracebackTable::create(TBTableData, Size);
554 
555   EXPECT_THAT_ERROR(TTOrErr.takeError(),
556                     FailedWithMessage("ParmsType encodes more than ParmsNum "
557                                       "parameters in parseVectorParmsType."));
558 }
559