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