xref: /llvm-project/llvm/unittests/Object/XCOFFObjectFileTest.cpp (revision 7ed515d16803f12fc06258ebf8a405931dc8a637)
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().getValue(), "i, f, d");
87 
88   ASSERT_TRUE(TT.getTraceBackTableOffset());
89   EXPECT_EQ(TT.getTraceBackTableOffset().getValue(), 64u);
90 
91   EXPECT_FALSE(TT.getHandlerMask());
92 
93   ASSERT_TRUE(TT.getFunctionName());
94   EXPECT_EQ(TT.getFunctionName().getValue(), "add_all");
95   EXPECT_EQ(TT.getFunctionName().getValue().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().getValue(), "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().getValue(), "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().getValue(), "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().getValue(), "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().getValue(),
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().getValue(), 2u);
175 
176   ASSERT_TRUE(TT.getControlledStorageInfoDisp());
177 
178   SmallVector<uint32_t, 8> Disp = TT.getControlledStorageInfoDisp().getValue();
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().getValue(), 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().getValue(), "v, i, f, i, d, i, v");
211 
212   ASSERT_TRUE(TT.getVectorExt());
213   TBVectorExt VecExt = TT.getVectorExt().getValue();
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().getValue(),
226             ExtendedTBTableFlag::TB_SSP_CANARY);
227 
228   EXPECT_EQ(Size, 45u);
229 }
230 
231 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
232   const uint8_t TBTableData[] = {
233       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5, 0x00, 0x00,
234       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
235       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
236       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
237   uint64_t Size = sizeof(TBTableData);
238   Expected<XCOFFTracebackTable> TTOrErr =
239       XCOFFTracebackTable::create(TBTableData, Size);
240   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
241   XCOFFTracebackTable TT = *TTOrErr;
242 
243   ASSERT_TRUE(TT.getParmsType());
244   EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i, v, v");
245 
246   ASSERT_TRUE(TT.getVectorExt());
247   TBVectorExt VecExt = TT.getVectorExt().getValue();
248 
249   EXPECT_EQ(VecExt.getNumberOfVRSaved(), 4);
250   EXPECT_FALSE(VecExt.isVRSavedOnStack());
251   EXPECT_TRUE(VecExt.hasVarArgs());
252 
253   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
254   EXPECT_TRUE(VecExt.hasVMXInstruction());
255 
256   EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
257 
258   ASSERT_TRUE(TT.getExtensionTable());
259   EXPECT_EQ(TT.getExtensionTable().getValue(),
260             ExtendedTBTableFlag::TB_SSP_CANARY);
261 
262   EXPECT_EQ(Size, 44u);
263 }
264 
265 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtMandatory) {
266   uint64_t Size = 6;
267   Expected<XCOFFTracebackTable> TTOrErr =
268       XCOFFTracebackTable::create(TBTableData, Size);
269   EXPECT_THAT_ERROR(
270       TTOrErr.takeError(),
271       FailedWithMessage(
272           "unexpected end of data at offset 0x6 while reading [0x0, 0x8)"));
273   EXPECT_EQ(Size, 0u);
274 }
275 
276 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtParmsType) {
277   uint64_t Size = 9;
278   Expected<XCOFFTracebackTable> TTOrErr =
279       XCOFFTracebackTable::create(TBTableData, Size);
280   EXPECT_THAT_ERROR(
281       TTOrErr.takeError(),
282       FailedWithMessage(
283           "unexpected end of data at offset 0x9 while reading [0x8, 0xc)"));
284   EXPECT_EQ(Size, 8u);
285 }
286 
287 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtTBOffset) {
288   uint64_t Size = 14;
289   Expected<XCOFFTracebackTable> TTOrErr =
290       XCOFFTracebackTable::create(TBTableData, Size);
291   EXPECT_THAT_ERROR(
292       TTOrErr.takeError(),
293       FailedWithMessage(
294           "unexpected end of data at offset 0xe while reading [0xc, 0x10)"));
295   EXPECT_EQ(Size, 12u);
296 }
297 
298 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtHandlerMask) {
299   uint8_t V[] = {0x00, 0x00, 0x22, 0xC0, 0x80, 0x00, 0x01, 0x05, 0x58,
300                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07};
301   uint64_t Size = sizeof(V);
302   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
303   EXPECT_THAT_ERROR(
304       TTOrErr.takeError(),
305       FailedWithMessage(
306           "unexpected end of data at offset 0x12 while reading [0x10, 0x14)"));
307   EXPECT_EQ(Size, 16u);
308 }
309 
310 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNumOfCtlAnchors) {
311   uint64_t Size = 19;
312   Expected<XCOFFTracebackTable> TTOrErr =
313       XCOFFTracebackTable::create(TBTableData, Size);
314   EXPECT_THAT_ERROR(
315       TTOrErr.takeError(),
316       FailedWithMessage(
317           "unexpected end of data at offset 0x13 while reading [0x10, 0x14)"));
318   EXPECT_EQ(Size, 16u);
319 }
320 
321 TEST(XCOFFObjectFileTest,
322      XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp) {
323   uint64_t Size = 21;
324   Expected<XCOFFTracebackTable> TTOrErr =
325       XCOFFTracebackTable::create(TBTableData, Size);
326   EXPECT_THAT_ERROR(
327       TTOrErr.takeError(),
328       FailedWithMessage(
329           "unexpected end of data at offset 0x15 while reading [0x14, 0x18)"));
330   EXPECT_EQ(Size, 20u);
331 }
332 
333 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNameLen) {
334   uint64_t Size = 29;
335   Expected<XCOFFTracebackTable> TTOrErr =
336       XCOFFTracebackTable::create(TBTableData, Size);
337   EXPECT_THAT_ERROR(
338       TTOrErr.takeError(),
339       FailedWithMessage(
340           "unexpected end of data at offset 0x1d while reading [0x1c, 0x1e)"));
341   EXPECT_EQ(Size, 28u);
342 }
343 
344 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtFunctionName) {
345   uint64_t Size = 36;
346   Expected<XCOFFTracebackTable> TTOrErr =
347       XCOFFTracebackTable::create(TBTableData, Size);
348   EXPECT_THAT_ERROR(
349       TTOrErr.takeError(),
350       FailedWithMessage(
351           "unexpected end of data at offset 0x24 while reading [0x1e, 0x25)"));
352   EXPECT_EQ(Size, 30u);
353 }
354 
355 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtAllocaUsed) {
356   uint64_t Size = 37;
357   Expected<XCOFFTracebackTable> TTOrErr =
358       XCOFFTracebackTable::create(TBTableData, Size);
359   EXPECT_THAT_ERROR(
360       TTOrErr.takeError(),
361       FailedWithMessage(
362           "unexpected end of data at offset 0x25 while reading [0x25, 0x26)"));
363   EXPECT_EQ(Size, 37u);
364 }
365 
366 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoData) {
367   uint64_t Size = 39;
368   Expected<XCOFFTracebackTable> TTOrErr =
369       XCOFFTracebackTable::create(TBTableData, Size);
370 
371   EXPECT_THAT_ERROR(
372       TTOrErr.takeError(),
373       FailedWithMessage(
374           "unexpected end of data at offset 0x27 while reading [0x26, 0x2c)"));
375   EXPECT_EQ(Size, 38u);
376 }
377 
378 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoParmsInfo) {
379   uint64_t Size = 43;
380   Expected<XCOFFTracebackTable> TTOrErr =
381       XCOFFTracebackTable::create(TBTableData, Size);
382 
383   EXPECT_THAT_ERROR(
384       TTOrErr.takeError(),
385       FailedWithMessage(
386           "unexpected end of data at offset 0x2b while reading [0x26, 0x2c)"));
387   EXPECT_EQ(Size, 38u);
388 }
389 
390 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
391   uint64_t Size = 44;
392   Expected<XCOFFTracebackTable> TTOrErr =
393       XCOFFTracebackTable::create(TBTableData, Size);
394 
395   EXPECT_THAT_ERROR(
396       TTOrErr.takeError(),
397       FailedWithMessage(
398           "unexpected end of data at offset 0x2c while reading [0x2c, 0x2d)"));
399   EXPECT_EQ(Size, 44u);
400 }
401 
402 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef32) {
403   uint8_t XCOFF32Binary[] = {
404       // File header.
405       0x01, 0xdf, 0x00, 0x01, 0x5f, 0x58, 0xf8, 0x95, 0x00, 0x00, 0x00, 0x3c,
406       0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
407 
408       // Section header for empty .data section.
409       0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412       0x00, 0x00, 0x00, 0x40,
413 
414       // Start of symbol table.
415       // C_File symbol.
416       0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417       0xff, 0xfe, 0x00, 0x03, 0x67, 0x01,
418       // File Auxiliary Entry.
419       0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420       0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 
422       // Csect symbol.
423       0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424       0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
425       // Csect auxiliary entry.
426       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
427       0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
428 
429   ArrayRef<uint8_t> XCOFF32Ref(XCOFF32Binary, sizeof(XCOFF32Binary));
430   Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
431       object::ObjectFile::createObjectFile(
432           MemoryBufferRef(toStringRef(XCOFF32Ref), "dummyXCOFF"),
433           file_magic::xcoff_object_32);
434   ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
435 
436   const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
437   DataRefImpl Ref;
438   Ref.p = File.getSymbolEntryAddressByIndex(2);
439   XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
440   Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
441   ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
442 
443   // Set csect symbol's auxiliary entry count to 0.
444   XCOFF32Binary[113] = 0;
445   Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
446   EXPECT_THAT_ERROR(
447       ExpectErr.takeError(),
448       FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
449 }
450 
451 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
452   uint8_t XCOFF64Binary[] = {
453       // File header.
454       0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00,
455       0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
456 
457       // Section header for empty .data section.
458       0x2e, 0x64, 0x61, 0x74, 0x61, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
463       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
464 
465       // Start of symbol table.
466       // C_File symbol.
467       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
468       0xff, 0xfe, 0x00, 0x02, 0x67, 0x01,
469       // File Auxiliary Entry.
470       0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471       0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
472 
473       // Csect symbol.
474       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
475       0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
476       // Csect auxiliary entry.
477       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
478       0x00, 0x00, 0x00, 0x00, 0x00, 0xfb,
479 
480       // String table.
481       0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64,
482       0x61, 0x74, 0x61, 0x00};
483 
484   ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary));
485   Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
486       object::ObjectFile::createObjectFile(
487           MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"),
488           file_magic::xcoff_object_64);
489   ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
490 
491   const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
492   DataRefImpl Ref;
493   Ref.p = File.getSymbolEntryAddressByIndex(2);
494   XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
495   Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
496   ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
497 
498   // Inject incorrect auxiliary type value.
499   XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM);
500   Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef();
501   EXPECT_THAT_ERROR(
502       NotFoundErr.takeError(),
503       FailedWithMessage(
504           "a csect auxiliary entry is not found for symbol \".data\""));
505 
506   // Set csect symbol's auxiliary entry count to 0.
507   XCOFF64Binary[149] = 0;
508   Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
509   EXPECT_THAT_ERROR(
510       ExpectErr.takeError(),
511       FailedWithMessage("csect symbol \".data\" 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