xref: /llvm-project/llvm/unittests/Object/XCOFFObjectFileTest.cpp (revision 1bf0732443ee464d40ff534a94bb42fed92c6efc)
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/XCOFFObjectFile.h"
10 #include "llvm/Testing/Support/Error.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 using namespace llvm::object;
15 
16 TEST(XCOFFObjectFileTest, doesXCOFFTracebackTableBegin) {
17   EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0}));
18   EXPECT_TRUE(doesXCOFFTracebackTableBegin({0, 0, 0, 0, 1}));
19   EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0, 1}));
20   EXPECT_FALSE(doesXCOFFTracebackTableBegin({0, 0, 0}));
21 }
22 
23 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIGeneral) {
24   uint8_t V[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01, 0x05, 0x58, 0x00,
25                  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
26                  0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
27   uint64_t Size = sizeof(V);
28   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
29   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
30   XCOFFTracebackTable TT = *TTOrErr;
31 
32   EXPECT_EQ(TT.getVersion(), 0);
33 
34   EXPECT_EQ(TT.getLanguageID(), 0);
35 
36   EXPECT_FALSE(TT.isGlobalLinkage());
37   EXPECT_FALSE(TT.isOutOfLineEpilogOrPrologue());
38   EXPECT_TRUE(TT.hasTraceBackTableOffset());
39   EXPECT_FALSE(TT.isInternalProcedure());
40   EXPECT_FALSE(TT.hasControlledStorage());
41   EXPECT_FALSE(TT.isTOCless());
42   EXPECT_TRUE(TT.isFloatingPointPresent());
43   EXPECT_FALSE(TT.isFloatingPointOperationLogOrAbortEnabled());
44 
45   EXPECT_FALSE(TT.isInterruptHandler());
46   EXPECT_TRUE(TT.isFuncNamePresent());
47   EXPECT_FALSE(TT.isAllocaUsed());
48   EXPECT_EQ(TT.getOnConditionDirective(), 0);
49   EXPECT_FALSE(TT.isCRSaved());
50   EXPECT_FALSE(TT.isLRSaved());
51 
52   EXPECT_TRUE(TT.isBackChainStored());
53   EXPECT_FALSE(TT.isFixup());
54   EXPECT_EQ(TT.getNumOfFPRsSaved(), 0);
55 
56   EXPECT_FALSE(TT.hasExtensionTable());
57   EXPECT_FALSE(TT.hasVectorInfo());
58   EXPECT_EQ(TT.getNumofGPRsSaved(), 0);
59 
60   EXPECT_EQ(TT.getNumberOfFixedParms(), 1);
61 
62   EXPECT_EQ(TT.getNumberOfFPParms(), 2);
63   EXPECT_TRUE(TT.hasParmsOnStack());
64 
65   ASSERT_TRUE(TT.getParmsType());
66   EXPECT_EQ(TT.getParmsType().getValue(), "i, f, d");
67 
68   ASSERT_TRUE(TT.getTraceBackTableOffset());
69   EXPECT_EQ(TT.getTraceBackTableOffset().getValue(), 64u);
70 
71   EXPECT_FALSE(TT.getHandlerMask());
72 
73   ASSERT_TRUE(TT.getFunctionName());
74   EXPECT_EQ(TT.getFunctionName().getValue(), "add_all");
75   EXPECT_EQ(TT.getFunctionName().getValue().size(), 7u);
76 
77   EXPECT_FALSE(TT.getAllocaRegister());
78   EXPECT_EQ(Size, 25u);
79 }
80 
81 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIParmsType) {
82   uint8_t V[] = {0x01, 0x02, 0xA2, 0x40, 0x80, 0x00, 0x02, 0x07, 0x2B, 0x00,
83                  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07, 0x61, 0x64,
84                  0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
85   uint64_t Size = sizeof(V);
86   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
87 
88   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
89   XCOFFTracebackTable TT = *TTOrErr;
90   EXPECT_EQ(TT.getVersion(), 1);
91   EXPECT_EQ(TT.getLanguageID(), 2);
92 
93   EXPECT_TRUE(TT.isGlobalLinkage());
94   EXPECT_EQ(TT.getNumberOfFixedParms(), 2);
95 
96   EXPECT_EQ(TT.getNumberOfFPParms(), 3);
97 
98   ASSERT_TRUE(TT.getParmsType());
99   EXPECT_EQ(TT.getParmsType().getValue(), "i, i, f, f, d");
100 
101   V[8] = 0xAC;
102   Size = sizeof(V);
103   Expected<XCOFFTracebackTable> TTOrErr1 = XCOFFTracebackTable::create(V, Size);
104   ASSERT_THAT_EXPECTED(TTOrErr1, Succeeded());
105   XCOFFTracebackTable TT1 = *TTOrErr1;
106   ASSERT_TRUE(TT1.getParmsType());
107   EXPECT_EQ(TT1.getParmsType().getValue(), "f, f, d, i, i");
108 
109   V[8] = 0xD4;
110   Size = sizeof(V);
111   Expected<XCOFFTracebackTable> TTOrErr2 = XCOFFTracebackTable::create(V, Size);
112   ASSERT_THAT_EXPECTED(TTOrErr2, Succeeded());
113   XCOFFTracebackTable TT2 = *TTOrErr2;
114   ASSERT_TRUE(TT2.getParmsType());
115   EXPECT_EQ(TT2.getParmsType().getValue(), "d, i, f, f, i");
116 
117   V[6] = 0x01;
118   Size = sizeof(V);
119   Expected<XCOFFTracebackTable> TTOrErr3 = XCOFFTracebackTable::create(V, Size);
120   ASSERT_THAT_EXPECTED(TTOrErr3, Succeeded());
121   XCOFFTracebackTable TT3 = *TTOrErr3;
122   ASSERT_TRUE(TT3.getParmsType());
123   EXPECT_EQ(TT3.getParmsType().getValue(), "d, i, f, f");
124 }
125 
126 const uint8_t TBTableData[] = {0x00, 0x00, 0x2A, 0x40, 0x80, 0x40, 0x01, 0x05,
127                                0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
128                                0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
129                                0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64,
130                                0x64, 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
131 
132 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIControlledStorageInfoDisp) {
133   uint64_t Size = 40;
134   Expected<XCOFFTracebackTable> TTOrErr =
135       XCOFFTracebackTable::create(TBTableData, Size);
136   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
137   XCOFFTracebackTable TT = *TTOrErr;
138   EXPECT_TRUE(TT.hasControlledStorage());
139   ASSERT_TRUE(TT.getNumOfCtlAnchors());
140   EXPECT_EQ(TT.getNumOfCtlAnchors().getValue(), 2u);
141 
142   ASSERT_TRUE(TT.getControlledStorageInfoDisp());
143 
144   SmallVector<uint32_t, 8> Disp = TT.getControlledStorageInfoDisp().getValue();
145 
146   ASSERT_EQ(Disp.size(), 2UL);
147   EXPECT_EQ(Disp[0], 0x05050000u);
148   EXPECT_EQ(Disp[1], 0x06060000u);
149 }
150 
151 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
152   uint64_t Size = 40;
153   Expected<XCOFFTracebackTable> TTOrErr =
154       XCOFFTracebackTable::create(TBTableData, Size);
155   ASSERT_THAT_EXPECTED(TTOrErr, Succeeded());
156   XCOFFTracebackTable TT = *TTOrErr;
157 
158   EXPECT_TRUE(TT.hasVectorInfo());
159   EXPECT_FALSE(TT.getParmsType());
160 }
161 
162 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtMandatory) {
163   uint64_t Size = 6;
164   Expected<XCOFFTracebackTable> TTOrErr =
165       XCOFFTracebackTable::create(TBTableData, Size);
166   EXPECT_THAT_ERROR(
167       TTOrErr.takeError(),
168       FailedWithMessage(
169           "unexpected end of data at offset 0x6 while reading [0x0, 0x8)"));
170   EXPECT_EQ(Size, 0);
171 }
172 
173 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtParmsType) {
174   uint64_t Size = 9;
175   Expected<XCOFFTracebackTable> TTOrErr =
176       XCOFFTracebackTable::create(TBTableData, Size);
177   EXPECT_THAT_ERROR(
178       TTOrErr.takeError(),
179       FailedWithMessage(
180           "unexpected end of data at offset 0x9 while reading [0x8, 0xc)"));
181   EXPECT_EQ(Size, 8u);
182 }
183 
184 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtTBOffset) {
185   uint64_t Size = 14;
186   Expected<XCOFFTracebackTable> TTOrErr =
187       XCOFFTracebackTable::create(TBTableData, Size);
188   EXPECT_THAT_ERROR(
189       TTOrErr.takeError(),
190       FailedWithMessage(
191           "unexpected end of data at offset 0xe while reading [0xc, 0x10)"));
192   EXPECT_EQ(Size, 12u);
193 }
194 
195 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtHandlerMask) {
196   uint8_t V[] = {0x00, 0x00, 0x22, 0xC0, 0x80, 0x00, 0x01, 0x05, 0x58,
197                  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07};
198   uint64_t Size = sizeof(V);
199   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
200   EXPECT_THAT_ERROR(
201       TTOrErr.takeError(),
202       FailedWithMessage(
203           "unexpected end of data at offset 0x12 while reading [0x10, 0x14)"));
204   EXPECT_EQ(Size, 16u);
205 }
206 
207 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNumOfCtlAnchors) {
208   uint64_t Size = 19;
209   Expected<XCOFFTracebackTable> TTOrErr =
210       XCOFFTracebackTable::create(TBTableData, Size);
211   EXPECT_THAT_ERROR(
212       TTOrErr.takeError(),
213       FailedWithMessage(
214           "unexpected end of data at offset 0x13 while reading [0x10, 0x14)"));
215   EXPECT_EQ(Size, 16u);
216 }
217 
218 TEST(XCOFFObjectFileTest,
219      XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp) {
220   uint64_t Size = 21;
221   Expected<XCOFFTracebackTable> TTOrErr =
222       XCOFFTracebackTable::create(TBTableData, Size);
223   EXPECT_THAT_ERROR(
224       TTOrErr.takeError(),
225       FailedWithMessage(
226           "unexpected end of data at offset 0x15 while reading [0x14, 0x18)"));
227   EXPECT_EQ(Size, 20u);
228 }
229 
230 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNameLen) {
231   uint64_t Size = 29;
232   Expected<XCOFFTracebackTable> TTOrErr =
233       XCOFFTracebackTable::create(TBTableData, Size);
234   EXPECT_THAT_ERROR(
235       TTOrErr.takeError(),
236       FailedWithMessage(
237           "unexpected end of data at offset 0x1d while reading [0x1c, 0x1e)"));
238   EXPECT_EQ(Size, 28u);
239 }
240 
241 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtFunctionName) {
242   uint64_t Size = 36;
243   Expected<XCOFFTracebackTable> TTOrErr =
244       XCOFFTracebackTable::create(TBTableData, Size);
245   EXPECT_THAT_ERROR(
246       TTOrErr.takeError(),
247       FailedWithMessage(
248           "unexpected end of data at offset 0x24 while reading [0x1e, 0x25)"));
249   EXPECT_EQ(Size, 30u);
250 }
251 
252 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtAllocaUsed) {
253   uint8_t V[] = {0x00, 0x00, 0x2A, 0x60, 0x80, 0x00, 0x01, 0x05, 0x58, 0x00,
254                  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02,
255                  0x05, 0x05, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07,
256                  0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 0x6c};
257   uint64_t Size = sizeof(V);
258   Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size);
259   EXPECT_THAT_ERROR(
260       TTOrErr.takeError(),
261       FailedWithMessage(
262           "unexpected end of data at offset 0x25 while reading [0x25, 0x26)"));
263   EXPECT_EQ(Size, 37u);
264 }
265