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