xref: /llvm-project/llvm/unittests/Object/XCOFFObjectFileTest.cpp (revision d6d7f7b1d2639a06002779aed5dccf53fee20c6e)
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 
TEST(XCOFFObjectFileTest,XCOFFObjectType)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 
TEST(XCOFFObjectFileTest,doesXCOFFTracebackTableBegin)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableAPIGeneral)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(), "i, f, d");
87 
88   ASSERT_TRUE(TT.getTraceBackTableOffset());
89   EXPECT_EQ(*TT.getTraceBackTableOffset(), 64u);
90 
91   EXPECT_FALSE(TT.getHandlerMask());
92 
93   ASSERT_TRUE(TT.getFunctionName());
94   EXPECT_EQ(*TT.getFunctionName(), "add_all");
95   EXPECT_EQ(TT.getFunctionName()->size(), 7u);
96 
97   EXPECT_FALSE(TT.getAllocaRegister());
98   EXPECT_EQ(Size, 25u);
99 }
100 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableAPIParmsType)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,
162     0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
163     0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
164     0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x1f, 0x02, 0x05,
165     0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
166 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableAPIControlledStorageInfoDisp)167 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIControlledStorageInfoDisp) {
168   uint64_t Size = sizeof(TBTableData);
169   Expected<XCOFFTracebackTable> TTOrErr =
170       XCOFFTracebackTable::create(TBTableData, Size);
171   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
172   XCOFFTracebackTable TT = *TTOrErr;
173   EXPECT_TRUE(TT.hasControlledStorage());
174   ASSERT_TRUE(TT.getNumOfCtlAnchors());
175   EXPECT_EQ(*TT.getNumOfCtlAnchors(), 2u);
176 
177   ASSERT_TRUE(TT.getControlledStorageInfoDisp());
178 
179   SmallVector<uint32_t, 8> Disp = *TT.getControlledStorageInfoDisp();
180 
181   ASSERT_EQ(Disp.size(), 2UL);
182   EXPECT_EQ(Disp[0], 0x05050000u);
183   EXPECT_EQ(Disp[1], 0x06060000u);
184   EXPECT_EQ(Size, 47u);
185 }
186 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableAPIAllocaRegister)187 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIAllocaRegister) {
188   uint64_t Size = sizeof(TBTableData);
189   Expected<XCOFFTracebackTable> TTOrErr =
190       XCOFFTracebackTable::create(TBTableData, Size);
191   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
192   XCOFFTracebackTable TT = *TTOrErr;
193   ASSERT_TRUE(TT.getAllocaRegister());
194   EXPECT_EQ(*TT.getAllocaRegister(), 31u);
195 }
196 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableAPIHasVectorInfo)197 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
198 
199   uint64_t Size = sizeof(TBTableData);
200   Expected<XCOFFTracebackTable> TTOrErr =
201       XCOFFTracebackTable::create(TBTableData, Size);
202   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
203   XCOFFTracebackTable TT = *TTOrErr;
204 
205   EXPECT_EQ(TT.getNumberOfFixedParms(), 3);
206   EXPECT_EQ(TT.getNumberOfFPParms(), 2);
207   EXPECT_TRUE(TT.hasVectorInfo());
208   EXPECT_TRUE(TT.hasExtensionTable());
209 
210   ASSERT_TRUE(TT.getParmsType());
211   EXPECT_EQ(*TT.getParmsType(), "v, i, f, i, d, i, v");
212 
213   ASSERT_TRUE(TT.getVectorExt());
214   TBVectorExt VecExt = *TT.getVectorExt();
215 
216   EXPECT_EQ(VecExt.getNumberOfVRSaved(), 0);
217   EXPECT_TRUE(VecExt.isVRSavedOnStack());
218   EXPECT_FALSE(VecExt.hasVarArgs());
219 
220   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
221   EXPECT_TRUE(VecExt.hasVMXInstruction());
222 
223   EXPECT_EQ(VecExt.getVectorParmsInfo(), "vf, vf");
224 
225   ASSERT_TRUE(TT.getExtensionTable());
226   EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY);
227 
228   EXPECT_EQ(Size, 47u);
229 }
230 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableAPIHasVectorInfo1)231 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
232   const uint8_t TBTableData[] = {
233       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5,
234       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
235       0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
236       0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x11, 0x07, 0x90,
237       0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
238   uint64_t Size = sizeof(TBTableData);
239   Expected<XCOFFTracebackTable> TTOrErr =
240       XCOFFTracebackTable::create(TBTableData, Size);
241   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
242   XCOFFTracebackTable TT = *TTOrErr;
243 
244   ASSERT_TRUE(TT.getParmsType());
245   EXPECT_EQ(*TT.getParmsType(), "v, i, f, i, d, i, v, v");
246 
247   ASSERT_TRUE(TT.getVectorExt());
248   TBVectorExt VecExt = *TT.getVectorExt();
249 
250   EXPECT_EQ(VecExt.getNumberOfVRSaved(), 4);
251   EXPECT_FALSE(VecExt.isVRSavedOnStack());
252   EXPECT_TRUE(VecExt.hasVarArgs());
253 
254   EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
255   EXPECT_TRUE(VecExt.hasVMXInstruction());
256 
257   EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
258 
259   ASSERT_TRUE(TT.getExtensionTable());
260   EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY);
261 
262   EXPECT_EQ(Size, 46u);
263 }
264 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtMandatory)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtParmsType)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtTBOffset)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtHandlerMask)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtNumOfCtlAnchors)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtNameLen)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtFunctionName)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtAllocaUsed)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtVectorInfoData)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtVectorInfoParmsInfo)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableTruncatedAtExtLongTBTable)390 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
391   uint64_t Size = 46;
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 0x2e while reading [0x2e, 0x2f)"));
399   EXPECT_EQ(Size, 46u);
400 }
401 
TEST(XCOFFObjectFileTest,XCOFFGetCsectAuxRef32)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 
TEST(XCOFFObjectFileTest,XCOFFGetCsectAuxRef64)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableErrorAtParameterType)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 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableErrorAtParameterTypeWithVecInfo)531 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
532   const uint8_t TBTableData[] = {
533       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0,
534       0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
535       0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
536       0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x11, 0x07, 0x90,
537       0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
538   uint64_t Size = 46;
539   Expected<XCOFFTracebackTable> TTOrErr =
540       XCOFFTracebackTable::create(TBTableData, Size);
541 
542   EXPECT_THAT_ERROR(
543       TTOrErr.takeError(),
544       FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
545                         "in parseParmsTypeWithVecInfo."));
546 }
547 
TEST(XCOFFObjectFileTest,XCOFFTracebackTableErrorAtVecParameterType)548 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
549   const uint8_t TBTableData[] = {
550       0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0,
551       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
552       0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
553       0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x11, 0x07, 0x90,
554       0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
555   uint64_t Size = 46;
556   Expected<XCOFFTracebackTable> TTOrErr =
557       XCOFFTracebackTable::create(TBTableData, Size);
558 
559   EXPECT_THAT_ERROR(TTOrErr.takeError(),
560                     FailedWithMessage("ParmsType encodes more than ParmsNum "
561                                       "parameters in parseVectorParmsType."));
562 }
563