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().value(), "i, f, d"); 87 88 ASSERT_TRUE(TT.getTraceBackTableOffset()); 89 EXPECT_EQ(TT.getTraceBackTableOffset().value(), 64u); 90 91 EXPECT_FALSE(TT.getHandlerMask()); 92 93 ASSERT_TRUE(TT.getFunctionName()); 94 EXPECT_EQ(TT.getFunctionName().value(), "add_all"); 95 EXPECT_EQ(TT.getFunctionName()->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(), "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, 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().value(), 2u); 175 176 ASSERT_TRUE(TT.getControlledStorageInfoDisp()); 177 178 SmallVector<uint32_t, 8> Disp = TT.getControlledStorageInfoDisp().value(); 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(), 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().value(), "v, i, f, i, d, i, v"); 211 212 ASSERT_TRUE(TT.getVectorExt()); 213 TBVectorExt VecExt = TT.getVectorExt().value(); 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(), ExtendedTBTableFlag::TB_SSP_CANARY); 226 227 EXPECT_EQ(Size, 45u); 228 } 229 230 TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) { 231 const uint8_t TBTableData[] = { 232 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5, 0x00, 0x00, 233 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00, 234 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 235 0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00}; 236 uint64_t Size = sizeof(TBTableData); 237 Expected<XCOFFTracebackTable> TTOrErr = 238 XCOFFTracebackTable::create(TBTableData, Size); 239 ASSERT_THAT_EXPECTED(TTOrErr, Succeeded()); 240 XCOFFTracebackTable TT = *TTOrErr; 241 242 ASSERT_TRUE(TT.getParmsType()); 243 EXPECT_EQ(TT.getParmsType().value(), "v, i, f, i, d, i, v, v"); 244 245 ASSERT_TRUE(TT.getVectorExt()); 246 TBVectorExt VecExt = TT.getVectorExt().value(); 247 248 EXPECT_EQ(VecExt.getNumberOfVRSaved(), 4); 249 EXPECT_FALSE(VecExt.isVRSavedOnStack()); 250 EXPECT_TRUE(VecExt.hasVarArgs()); 251 252 EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u); 253 EXPECT_TRUE(VecExt.hasVMXInstruction()); 254 255 EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc"); 256 257 ASSERT_TRUE(TT.getExtensionTable()); 258 EXPECT_EQ(*TT.getExtensionTable(), ExtendedTBTableFlag::TB_SSP_CANARY); 259 260 EXPECT_EQ(Size, 44u); 261 } 262 263 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtMandatory) { 264 uint64_t Size = 6; 265 Expected<XCOFFTracebackTable> TTOrErr = 266 XCOFFTracebackTable::create(TBTableData, Size); 267 EXPECT_THAT_ERROR( 268 TTOrErr.takeError(), 269 FailedWithMessage( 270 "unexpected end of data at offset 0x6 while reading [0x0, 0x8)")); 271 EXPECT_EQ(Size, 0u); 272 } 273 274 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtParmsType) { 275 uint64_t Size = 9; 276 Expected<XCOFFTracebackTable> TTOrErr = 277 XCOFFTracebackTable::create(TBTableData, Size); 278 EXPECT_THAT_ERROR( 279 TTOrErr.takeError(), 280 FailedWithMessage( 281 "unexpected end of data at offset 0x9 while reading [0x8, 0xc)")); 282 EXPECT_EQ(Size, 8u); 283 } 284 285 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtTBOffset) { 286 uint64_t Size = 14; 287 Expected<XCOFFTracebackTable> TTOrErr = 288 XCOFFTracebackTable::create(TBTableData, Size); 289 EXPECT_THAT_ERROR( 290 TTOrErr.takeError(), 291 FailedWithMessage( 292 "unexpected end of data at offset 0xe while reading [0xc, 0x10)")); 293 EXPECT_EQ(Size, 12u); 294 } 295 296 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtHandlerMask) { 297 uint8_t V[] = {0x00, 0x00, 0x22, 0xC0, 0x80, 0x00, 0x01, 0x05, 0x58, 298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x07}; 299 uint64_t Size = sizeof(V); 300 Expected<XCOFFTracebackTable> TTOrErr = XCOFFTracebackTable::create(V, Size); 301 EXPECT_THAT_ERROR( 302 TTOrErr.takeError(), 303 FailedWithMessage( 304 "unexpected end of data at offset 0x12 while reading [0x10, 0x14)")); 305 EXPECT_EQ(Size, 16u); 306 } 307 308 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNumOfCtlAnchors) { 309 uint64_t Size = 19; 310 Expected<XCOFFTracebackTable> TTOrErr = 311 XCOFFTracebackTable::create(TBTableData, Size); 312 EXPECT_THAT_ERROR( 313 TTOrErr.takeError(), 314 FailedWithMessage( 315 "unexpected end of data at offset 0x13 while reading [0x10, 0x14)")); 316 EXPECT_EQ(Size, 16u); 317 } 318 319 TEST(XCOFFObjectFileTest, 320 XCOFFTracebackTableTruncatedAtControlledStorageInfoDisp) { 321 uint64_t Size = 21; 322 Expected<XCOFFTracebackTable> TTOrErr = 323 XCOFFTracebackTable::create(TBTableData, Size); 324 EXPECT_THAT_ERROR( 325 TTOrErr.takeError(), 326 FailedWithMessage( 327 "unexpected end of data at offset 0x15 while reading [0x14, 0x18)")); 328 EXPECT_EQ(Size, 20u); 329 } 330 331 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtNameLen) { 332 uint64_t Size = 29; 333 Expected<XCOFFTracebackTable> TTOrErr = 334 XCOFFTracebackTable::create(TBTableData, Size); 335 EXPECT_THAT_ERROR( 336 TTOrErr.takeError(), 337 FailedWithMessage( 338 "unexpected end of data at offset 0x1d while reading [0x1c, 0x1e)")); 339 EXPECT_EQ(Size, 28u); 340 } 341 342 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtFunctionName) { 343 uint64_t Size = 36; 344 Expected<XCOFFTracebackTable> TTOrErr = 345 XCOFFTracebackTable::create(TBTableData, Size); 346 EXPECT_THAT_ERROR( 347 TTOrErr.takeError(), 348 FailedWithMessage( 349 "unexpected end of data at offset 0x24 while reading [0x1e, 0x25)")); 350 EXPECT_EQ(Size, 30u); 351 } 352 353 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtAllocaUsed) { 354 uint64_t Size = 37; 355 Expected<XCOFFTracebackTable> TTOrErr = 356 XCOFFTracebackTable::create(TBTableData, Size); 357 EXPECT_THAT_ERROR( 358 TTOrErr.takeError(), 359 FailedWithMessage( 360 "unexpected end of data at offset 0x25 while reading [0x25, 0x26)")); 361 EXPECT_EQ(Size, 37u); 362 } 363 364 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoData) { 365 uint64_t Size = 39; 366 Expected<XCOFFTracebackTable> TTOrErr = 367 XCOFFTracebackTable::create(TBTableData, Size); 368 369 EXPECT_THAT_ERROR( 370 TTOrErr.takeError(), 371 FailedWithMessage( 372 "unexpected end of data at offset 0x27 while reading [0x26, 0x2c)")); 373 EXPECT_EQ(Size, 38u); 374 } 375 376 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtVectorInfoParmsInfo) { 377 uint64_t Size = 43; 378 Expected<XCOFFTracebackTable> TTOrErr = 379 XCOFFTracebackTable::create(TBTableData, Size); 380 381 EXPECT_THAT_ERROR( 382 TTOrErr.takeError(), 383 FailedWithMessage( 384 "unexpected end of data at offset 0x2b while reading [0x26, 0x2c)")); 385 EXPECT_EQ(Size, 38u); 386 } 387 388 TEST(XCOFFObjectFileTest, XCOFFTracebackTableTruncatedAtExtLongTBTable) { 389 uint64_t Size = 44; 390 Expected<XCOFFTracebackTable> TTOrErr = 391 XCOFFTracebackTable::create(TBTableData, Size); 392 393 EXPECT_THAT_ERROR( 394 TTOrErr.takeError(), 395 FailedWithMessage( 396 "unexpected end of data at offset 0x2c while reading [0x2c, 0x2d)")); 397 EXPECT_EQ(Size, 44u); 398 } 399 400 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef32) { 401 uint8_t XCOFF32Binary[] = { 402 // File header. 403 0x01, 0xdf, 0x00, 0x01, 0x5f, 0x58, 0xf8, 0x95, 0x00, 0x00, 0x00, 0x3c, 404 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 405 406 // Section header for empty .data section. 407 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 410 0x00, 0x00, 0x00, 0x40, 411 412 // Start of symbol table. 413 // C_File symbol. 414 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 415 0xff, 0xfe, 0x00, 0x03, 0x67, 0x01, 416 // File Auxiliary Entry. 417 0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 419 420 // Csect symbol. 421 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 422 0x00, 0x01, 0x00, 0x00, 0x6b, 0x01, 423 // Csect auxiliary entry. 424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05, 425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 426 427 ArrayRef<uint8_t> XCOFF32Ref(XCOFF32Binary, sizeof(XCOFF32Binary)); 428 Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr = 429 object::ObjectFile::createObjectFile( 430 MemoryBufferRef(toStringRef(XCOFF32Ref), "dummyXCOFF"), 431 file_magic::xcoff_object_32); 432 ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded()); 433 434 const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get()); 435 DataRefImpl Ref; 436 Ref.p = File.getSymbolEntryAddressByIndex(2); 437 XCOFFSymbolRef SymRef = File.toSymbolRef(Ref); 438 Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef(); 439 ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded()); 440 441 // Set csect symbol's auxiliary entry count to 0. 442 XCOFF32Binary[113] = 0; 443 Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef(); 444 EXPECT_THAT_ERROR( 445 ExpectErr.takeError(), 446 FailedWithMessage( 447 "csect symbol \".data\" with index 2 contains no auxiliary entry")); 448 } 449 450 TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) { 451 uint8_t XCOFF64Binary[] = { 452 // File header. 453 0x01, 0xf7, 0x00, 0x01, 0x5f, 0x59, 0x25, 0xeb, 0x00, 0x00, 0x00, 0x00, 454 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 455 456 // Section header for empty .data section. 457 0x2e, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 459 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x40, 0x00, 0x00, 0x00, 0x00, 463 464 // Start of symbol table. 465 // C_File symbol. 466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 467 0xff, 0xfe, 0x00, 0x02, 0x67, 0x01, 468 // File Auxiliary Entry. 469 0x61, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 470 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 471 472 // Csect symbol. 473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 474 0x00, 0x01, 0x00, 0x00, 0x6b, 0x01, 475 // Csect auxiliary entry. 476 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x05, 477 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 478 479 // String table. 480 0x00, 0x00, 0x00, 0x10, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x2e, 0x64, 481 0x61, 0x74, 0x61, 0x00}; 482 483 ArrayRef<uint8_t> XCOFF64Ref(XCOFF64Binary, sizeof(XCOFF64Binary)); 484 Expected<std::unique_ptr<ObjectFile>> XCOFFObjOrErr = 485 object::ObjectFile::createObjectFile( 486 MemoryBufferRef(toStringRef(XCOFF64Ref), "dummyXCOFF"), 487 file_magic::xcoff_object_64); 488 ASSERT_THAT_EXPECTED(XCOFFObjOrErr, Succeeded()); 489 490 const XCOFFObjectFile &File = *cast<XCOFFObjectFile>((*XCOFFObjOrErr).get()); 491 DataRefImpl Ref; 492 Ref.p = File.getSymbolEntryAddressByIndex(2); 493 XCOFFSymbolRef SymRef = File.toSymbolRef(Ref); 494 Expected<XCOFFCsectAuxRef> CsectRefOrErr = SymRef.getXCOFFCsectAuxRef(); 495 ASSERT_THAT_EXPECTED(CsectRefOrErr, Succeeded()); 496 497 // Inject incorrect auxiliary type value. 498 XCOFF64Binary[167] = static_cast<uint8_t>(XCOFF::AUX_SYM); 499 Expected<XCOFFCsectAuxRef> NotFoundErr = SymRef.getXCOFFCsectAuxRef(); 500 EXPECT_THAT_ERROR( 501 NotFoundErr.takeError(), 502 FailedWithMessage("a csect auxiliary entry has not been found for symbol " 503 "\".data\" with index 2")); 504 505 // Set csect symbol's auxiliary entry count to 0. 506 XCOFF64Binary[149] = 0; 507 Expected<XCOFFCsectAuxRef> ExpectErr = SymRef.getXCOFFCsectAuxRef(); 508 EXPECT_THAT_ERROR( 509 ExpectErr.takeError(), 510 FailedWithMessage( 511 "csect symbol \".data\" with index 2 contains no auxiliary entry")); 512 } 513 514 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) { 515 const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01, 516 0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00, 517 0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64, 518 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00}; 519 uint64_t Size = 28; 520 Expected<XCOFFTracebackTable> TTOrErr = 521 XCOFFTracebackTable::create(TBTableData, Size); 522 523 EXPECT_THAT_ERROR( 524 TTOrErr.takeError(), 525 FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters " 526 "in parseParmsType.")); 527 } 528 529 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) { 530 const uint8_t TBTableData[] = { 531 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x10, 532 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00, 533 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 534 0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00}; 535 uint64_t Size = 44; 536 Expected<XCOFFTracebackTable> TTOrErr = 537 XCOFFTracebackTable::create(TBTableData, Size); 538 539 EXPECT_THAT_ERROR( 540 TTOrErr.takeError(), 541 FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters " 542 "in parseParmsTypeWithVecInfo.")); 543 } 544 545 TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) { 546 const uint8_t TBTableData[] = { 547 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00, 548 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00, 549 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c, 550 0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00}; 551 uint64_t Size = 44; 552 Expected<XCOFFTracebackTable> TTOrErr = 553 XCOFFTracebackTable::create(TBTableData, Size); 554 555 EXPECT_THAT_ERROR(TTOrErr.takeError(), 556 FailedWithMessage("ParmsType encodes more than ParmsNum " 557 "parameters in parseVectorParmsType.")); 558 } 559