xref: /llvm-project/llvm/unittests/Object/XCOFFObjectFileTest.cpp (revision a00ff71668202b2ee3e16a23f9b16dad01001def)
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(
449           "csect symbol \".data\" with index 2 contains no auxiliary entry"));
450 }
451 
452 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
453   uint8_t XCOFF64Binary[] = {
454       // File header.
455       0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00,
456       0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
457 
458       // Section header for empty .data section.
459       0x2e, 0x64, 0x61, 0x74, 0x61, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
464       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
465 
466       // Start of symbol table.
467       // C_File symbol.
468       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
469       0xff, 0xfe, 0x00, 0x02, 0x67, 0x01,
470       // File Auxiliary Entry.
471       0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472       0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
473 
474       // Csect symbol.
475       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
476       0x00, 0x01, 0x00, 0x00, 0x6b, 0x01,
477       // Csect auxiliary entry.
478       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05,
479       0x00, 0x00, 0x00, 0x00, 0x00, 0xfb,
480 
481       // String table.
482       0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64,
483       0x61, 0x74, 0x61, 0x00};
484 
485   ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary));
486   Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr =
487       object::ObjectFile::createObjectFile(
488           MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"),
489           file_magic::xcoff_object_64);
490   ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
491 
492   const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get());
493   DataRefImpl Ref;
494   Ref.p = File.getSymbolEntryAddressByIndex(2);
495   XCOFFSymbolRef SymRef = File.toSymbolRef(Ref);
496   Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef();
497   ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded());
498 
499   // Inject incorrect auxiliary type value.
500   XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM);
501   Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef();
502   EXPECT_THAT_ERROR(
503       NotFoundErr.takeError(),
504       FailedWithMessage("a csect auxiliary entry has not been found for symbol "
505                         "\".data\" with index 2"));
506 
507   // Set csect symbol's auxiliary entry count to 0.
508   XCOFF64Binary[149] = 0;
509   Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef();
510   EXPECT_THAT_ERROR(
511       ExpectErr.takeError(),
512       FailedWithMessage(
513           "csect symbol \".data\" with index 2 contains no auxiliary entry"));
514 }
515 
516 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) {
517   const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01,
518                                  0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00,
519                                  0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64,
520                                  0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
521   uint64_t Size = 28;
522   Expected<XCOFFTracebackTable> TTOrErr =
523       XCOFFTracebackTable::create(TBTableData, Size);
524 
525   EXPECT_THAT_ERROR(
526       TTOrErr.takeError(),
527       FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
528                         "in parseParmsType."));
529 }
530 
531 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
532   const uint8_t TBTableData[] = {
533       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x10,
534       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
535       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
536       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
537   uint64_t Size = 44;
538   Expected<XCOFFTracebackTable> TTOrErr =
539       XCOFFTracebackTable::create(TBTableData, Size);
540 
541   EXPECT_THAT_ERROR(
542       TTOrErr.takeError(),
543       FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
544                         "in parseParmsTypeWithVecInfo."));
545 }
546 
547 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
548   const uint8_t TBTableData[] = {
549       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
550       0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
551       0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
552       0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00};
553   uint64_t Size = 44;
554   Expected<XCOFFTracebackTable> TTOrErr =
555       XCOFFTracebackTable::create(TBTableData, Size);
556 
557   EXPECT_THAT_ERROR(TTOrErr.takeError(),
558                     FailedWithMessage("ParmsType encodes more than ParmsNum "
559                                       "parameters in parseVectorParmsType."));
560 }
561