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
14using namespace llvm;
15using namespace llvm::object;
16using namespace llvm::XCOFF;
17
18TEST(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(dest: Buf, src: "\177ELF", n: 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(Object: Source);
31 ASSERT_THAT_EXPECTED(ObjOrErr, Succeeded());
32
33 EXPECT_TRUE(dyn_cast<XCOFFObjectFile>((*ObjOrErr).get()) == nullptr);
34}
35
36TEST(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
43TEST(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(Ptr: 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
101TEST(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(Ptr: 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(Ptr: 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(Ptr: 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(Ptr: 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(Ptr: 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
160const 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
167TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIControlledStorageInfoDisp) {
168 uint64_t Size = sizeof(TBTableData);
169 Expected<XCOFFTracebackTable> TTOrErr =
170 XCOFFTracebackTable::create(Ptr: 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
187TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIAllocaRegister) {
188 uint64_t Size = sizeof(TBTableData);
189 Expected<XCOFFTracebackTable> TTOrErr =
190 XCOFFTracebackTable::create(Ptr: 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
197TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
198
199 uint64_t Size = sizeof(TBTableData);
200 Expected<XCOFFTracebackTable> TTOrErr =
201 XCOFFTracebackTable::create(Ptr: 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
231TEST(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(Ptr: 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
265TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtMandatory) {
266 uint64_t Size = 6;
267 Expected<XCOFFTracebackTable> TTOrErr =
268 XCOFFTracebackTable::create(Ptr: 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
276TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtParmsType) {
277 uint64_t Size = 9;
278 Expected<XCOFFTracebackTable> TTOrErr =
279 XCOFFTracebackTable::create(Ptr: 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
287TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtTBOffset) {
288 uint64_t Size = 14;
289 Expected<XCOFFTracebackTable> TTOrErr =
290 XCOFFTracebackTable::create(Ptr: 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
298TEST(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(Ptr: 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
310TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNumOfCtlAnchors) {
311 uint64_t Size = 19;
312 Expected<XCOFFTracebackTable> TTOrErr =
313 XCOFFTracebackTable::create(Ptr: 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
321TEST(XCOFFObjectFileTest,
322 XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp) {
323 uint64_t Size = 21;
324 Expected<XCOFFTracebackTable> TTOrErr =
325 XCOFFTracebackTable::create(Ptr: 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
333TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNameLen) {
334 uint64_t Size = 29;
335 Expected<XCOFFTracebackTable> TTOrErr =
336 XCOFFTracebackTable::create(Ptr: 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
344TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtFunctionName) {
345 uint64_t Size = 36;
346 Expected<XCOFFTracebackTable> TTOrErr =
347 XCOFFTracebackTable::create(Ptr: 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
355TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtAllocaUsed) {
356 uint64_t Size = 37;
357 Expected<XCOFFTracebackTable> TTOrErr =
358 XCOFFTracebackTable::create(Ptr: 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
366TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoData) {
367 uint64_t Size = 39;
368 Expected<XCOFFTracebackTable> TTOrErr =
369 XCOFFTracebackTable::create(Ptr: 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
378TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoParmsInfo) {
379 uint64_t Size = 43;
380 Expected<XCOFFTracebackTable> TTOrErr =
381 XCOFFTracebackTable::create(Ptr: 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
390TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) {
391 uint64_t Size = 46;
392 Expected<XCOFFTracebackTable> TTOrErr =
393 XCOFFTracebackTable::create(Ptr: 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
402TEST(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 Object: MemoryBufferRef(toStringRef(Input: XCOFF32Ref), "dummyXCOFF"),
433 Type: file_magic::xcoff_object_32);
434 ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
435
436 const XCOFFObjectFile &File = *cast<XCOFFObjectFile>(Val: (*XCOFFObjOrErr).get());
437 DataRefImpl Ref;
438 Ref.p = File.getSymbolEntryAddressByIndex(SymbolTableIndex: 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
452TEST(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 Object: MemoryBufferRef(toStringRef(Input: XCOFF64Ref), "dummyXCOFF"),
489 Type: file_magic::xcoff_object_64);
490 ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded());
491
492 const XCOFFObjectFile &File = *cast<XCOFFObjectFile>(Val: (*XCOFFObjOrErr).get());
493 DataRefImpl Ref;
494 Ref.p = File.getSymbolEntryAddressByIndex(SymbolTableIndex: 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
516TEST(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(Ptr: 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
531TEST(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(Ptr: 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
548TEST(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(Ptr: TBTableData, Size);
558
559 EXPECT_THAT_ERROR(TTOrErr.takeError(),
560 FailedWithMessage("ParmsType encodes more than ParmsNum "
561 "parameters in parseVectorParmsType."));
562}
563

source code of llvm/unittests/Object/XCOFFObjectFileTest.cpp