1 //===- GOFFObjectFileTest.cpp - Tests for GOFFObjectFile ------------------===// 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/GOFFObjectFile.h" 10 #include "llvm/Support/MemoryBuffer.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::GOFF; 17 18 namespace { 19 char GOFFData[GOFF::RecordLength * 3] = {0x00}; 20 21 void constructValidGOFF(size_t Size) { 22 StringRef ValidSize(GOFFData, Size); 23 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 24 object::ObjectFile::createGOFFObjectFile( 25 MemoryBufferRef(ValidSize, "dummyGOFF")); 26 27 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 28 } 29 30 void constructInvalidGOFF(size_t Size) { 31 // Construct GOFFObject with record of length != multiple of 80. 32 StringRef InvalidData(GOFFData, Size); 33 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 34 object::ObjectFile::createGOFFObjectFile( 35 MemoryBufferRef(InvalidData, "dummyGOFF")); 36 37 ASSERT_THAT_EXPECTED( 38 GOFFObjOrErr, 39 FailedWithMessage("object file is not the right size. Must be a multiple " 40 "of 80 bytes, but is " + 41 std::to_string(Size) + " bytes")); 42 } 43 } // namespace 44 45 TEST(GOFFObjectFileTest, ConstructGOFFObjectValidSize) { 46 GOFFData[0] = (char)0x03; 47 GOFFData[1] = (char)0xF0; 48 GOFFData[80] = (char)0x03; 49 GOFFData[81] = (char)0x40; 50 constructValidGOFF(160); 51 constructValidGOFF(0); 52 } 53 54 TEST(GOFFObjectFileTest, ConstructGOFFObjectInvalidSize) { 55 constructInvalidGOFF(70); 56 constructInvalidGOFF(79); 57 constructInvalidGOFF(81); 58 } 59 60 TEST(GOFFObjectFileTest, MissingHDR) { 61 char GOFFData[GOFF::RecordLength * 2] = {0x00}; 62 63 // ESD record. 64 GOFFData[0] = (char)0x03; 65 66 // END record. 67 GOFFData[GOFF::RecordLength] = (char)0x03; 68 GOFFData[GOFF::RecordLength + 1] = (char)0x40; 69 70 StringRef Data(GOFFData, GOFF::RecordLength * 2); 71 72 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 73 object::ObjectFile::createGOFFObjectFile( 74 MemoryBufferRef(Data, "dummyGOFF")); 75 76 ASSERT_THAT_EXPECTED( 77 GOFFObjOrErr, 78 FailedWithMessage("object file must start with HDR record")); 79 } 80 81 TEST(GOFFObjectFileTest, MissingEND) { 82 char GOFFData[GOFF::RecordLength * 2] = {0x00}; 83 84 // HDR record. 85 GOFFData[0] = (char)0x03; 86 GOFFData[1] = (char)0xF0; 87 88 // ESD record. 89 GOFFData[GOFF::RecordLength] = (char)0x03; 90 91 StringRef Data(GOFFData, GOFF::RecordLength * 2); 92 93 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 94 object::ObjectFile::createGOFFObjectFile( 95 MemoryBufferRef(Data, "dummyGOFF")); 96 97 ASSERT_THAT_EXPECTED( 98 GOFFObjOrErr, FailedWithMessage("object file must end with END record")); 99 } 100 101 TEST(GOFFObjectFileTest, GetSymbolName) { 102 char GOFFData[GOFF::RecordLength * 3] = {0x00}; 103 104 // HDR record. 105 GOFFData[0] = (char)0x03; 106 GOFFData[1] = (char)0xF0; 107 108 // ESD record. 109 GOFFData[GOFF::RecordLength] = (char)0x03; 110 GOFFData[GOFF::RecordLength + 3] = (char)0x02; 111 GOFFData[GOFF::RecordLength + 7] = (char)0x01; 112 GOFFData[GOFF::RecordLength + 11] = (char)0x01; 113 GOFFData[GOFF::RecordLength + 71] = (char)0x05; // Size of symbol name. 114 GOFFData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is Hello. 115 GOFFData[GOFF::RecordLength + 73] = (char)0x85; 116 GOFFData[GOFF::RecordLength + 74] = (char)0x93; 117 GOFFData[GOFF::RecordLength + 75] = (char)0x93; 118 GOFFData[GOFF::RecordLength + 76] = (char)0x96; 119 120 // END record. 121 GOFFData[GOFF::RecordLength * 2] = 0x03; 122 GOFFData[GOFF::RecordLength * 2 + 1] = 0x40; 123 124 StringRef Data(GOFFData, GOFF::RecordLength * 3); 125 126 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 127 object::ObjectFile::createGOFFObjectFile( 128 MemoryBufferRef(Data, "dummyGOFF")); 129 130 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 131 132 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 133 134 for (SymbolRef Symbol : GOFFObj->symbols()) { 135 Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); 136 ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); 137 StringRef SymbolName = SymbolNameOrErr.get(); 138 139 EXPECT_EQ(SymbolName, "Hello"); 140 } 141 } 142 143 TEST(GOFFObjectFileTest, ConcatenatedGOFFFile) { 144 char GOFFData[GOFF::RecordLength * 6] = {0x00}; 145 146 // HDR record. 147 GOFFData[0] = (char)0x03; 148 GOFFData[1] = (char)0xF0; 149 // ESD record. 150 GOFFData[GOFF::RecordLength] = (char)0x03; 151 // END record. 152 GOFFData[GOFF::RecordLength * 2] = (char)0x03; 153 GOFFData[GOFF::RecordLength * 2 + 1] = (char)0x40; 154 // HDR record. 155 GOFFData[GOFF::RecordLength * 3] = (char)0x03; 156 GOFFData[GOFF::RecordLength * 3 + 1] = (char)0xF0; 157 // ESD record. 158 GOFFData[GOFF::RecordLength * 4] = (char)0x03; 159 // END record. 160 GOFFData[GOFF::RecordLength * 5] = (char)0x03; 161 GOFFData[GOFF::RecordLength * 5 + 1] = (char)0x40; 162 163 StringRef Data(GOFFData, GOFF::RecordLength * 6); 164 165 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 166 object::ObjectFile::createGOFFObjectFile( 167 MemoryBufferRef(Data, "dummyGOFF")); 168 169 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 170 } 171 172 TEST(GOFFObjectFileTest, ContinuationGetSymbolName) { 173 char GOFFContData[GOFF::RecordLength * 4] = {0x00}; 174 175 // HDR record. 176 GOFFContData[0] = (char)0x03; 177 GOFFContData[1] = (char)0xF0; 178 179 // ESD record. 180 GOFFContData[GOFF::RecordLength] = (char)0x03; 181 GOFFContData[GOFF::RecordLength + 1] = (char)0x01; 182 GOFFContData[GOFF::RecordLength + 3] = (char)0x02; 183 GOFFContData[GOFF::RecordLength + 7] = (char)0x01; 184 GOFFContData[GOFF::RecordLength + 11] = (char)0x01; 185 GOFFContData[GOFF::RecordLength + 71] = (char)0x0A; // Size of symbol name. 186 GOFFContData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is HelloWorld. 187 GOFFContData[GOFF::RecordLength + 73] = (char)0x85; 188 GOFFContData[GOFF::RecordLength + 74] = (char)0x93; 189 GOFFContData[GOFF::RecordLength + 75] = (char)0x93; 190 GOFFContData[GOFF::RecordLength + 76] = (char)0x96; 191 GOFFContData[GOFF::RecordLength + 77] = (char)0xA6; 192 GOFFContData[GOFF::RecordLength + 78] = (char)0x96; 193 GOFFContData[GOFF::RecordLength + 79] = (char)0x99; 194 195 // ESD continuation record. 196 GOFFContData[GOFF::RecordLength * 2] = (char)0x03; 197 GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x02; // No further continuations. 198 GOFFContData[GOFF::RecordLength * 2 + 3] = (char)0x93; 199 GOFFContData[GOFF::RecordLength * 2 + 4] = (char)0x84; 200 201 // END record. 202 GOFFContData[GOFF::RecordLength * 3] = (char)0x03; 203 GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; 204 205 StringRef Data(GOFFContData, GOFF::RecordLength * 4); 206 207 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 208 object::ObjectFile::createGOFFObjectFile( 209 MemoryBufferRef(Data, "dummyGOFF")); 210 211 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 212 213 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 214 215 for (SymbolRef Symbol : GOFFObj->symbols()) { 216 Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); 217 ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); 218 StringRef SymbolName = SymbolNameOrErr.get(); 219 EXPECT_EQ(SymbolName, "Helloworld"); 220 } 221 } 222 223 TEST(GOFFObjectFileTest, ContinuationBitNotSet) { 224 char GOFFContData[GOFF::RecordLength * 4] = {0x00}; 225 226 // HDR record. 227 GOFFContData[0] = (char)0x03; 228 GOFFContData[1] = (char)0xF0; 229 230 // ESD record. 231 GOFFContData[GOFF::RecordLength] = (char)0x03; 232 GOFFContData[GOFF::RecordLength + 1] = (char)0x01; 233 GOFFContData[GOFF::RecordLength + 3] = (char)0x02; 234 GOFFContData[GOFF::RecordLength + 7] = (char)0x01; 235 GOFFContData[GOFF::RecordLength + 11] = (char)0x01; 236 GOFFContData[GOFF::RecordLength + 71] = (char)0x0A; // Size of symbol name. 237 GOFFContData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is HelloWorld. 238 GOFFContData[GOFF::RecordLength + 73] = (char)0x85; 239 GOFFContData[GOFF::RecordLength + 74] = (char)0x93; 240 GOFFContData[GOFF::RecordLength + 75] = (char)0x93; 241 GOFFContData[GOFF::RecordLength + 76] = (char)0x96; 242 GOFFContData[GOFF::RecordLength + 77] = (char)0xA6; 243 GOFFContData[GOFF::RecordLength + 78] = (char)0x96; 244 GOFFContData[GOFF::RecordLength + 79] = (char)0x99; 245 246 // ESD continuation record. 247 GOFFContData[GOFF::RecordLength * 2] = (char)0x03; 248 GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x00; 249 GOFFContData[GOFF::RecordLength * 2 + 3] = (char)0x93; 250 GOFFContData[GOFF::RecordLength * 2 + 4] = (char)0x84; 251 252 // END record. 253 GOFFContData[GOFF::RecordLength * 3] = (char)0x03; 254 GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; 255 256 StringRef Data(GOFFContData, GOFF::RecordLength * 4); 257 258 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 259 object::ObjectFile::createGOFFObjectFile( 260 MemoryBufferRef(Data, "dummyGOFF")); 261 EXPECT_THAT_EXPECTED( 262 GOFFObjOrErr, 263 FailedWithMessage("record 2 is not a continuation record but the " 264 "preceding record is continued")); 265 } 266 267 TEST(GOFFObjectFileTest, ContinuationRecordNotTerminated) { 268 char GOFFContData[GOFF::RecordLength * 4] = {0x00}; 269 270 // HDR record. 271 GOFFContData[0] = (char)0x03; 272 GOFFContData[1] = (char)0xF0; 273 274 // ESD record. 275 GOFFContData[GOFF::RecordLength] = (char)0x03; 276 GOFFContData[GOFF::RecordLength + 1] = (char)0x01; 277 GOFFContData[GOFF::RecordLength + 3] = (char)0x02; 278 GOFFContData[GOFF::RecordLength + 7] = (char)0x01; 279 GOFFContData[GOFF::RecordLength + 11] = (char)0x01; 280 GOFFContData[GOFF::RecordLength + 71] = (char)0x0A; // Size of symbol name. 281 GOFFContData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name is HelloWorld. 282 GOFFContData[GOFF::RecordLength + 73] = (char)0x85; 283 GOFFContData[GOFF::RecordLength + 74] = (char)0x93; 284 GOFFContData[GOFF::RecordLength + 75] = (char)0x93; 285 GOFFContData[GOFF::RecordLength + 76] = (char)0x96; 286 GOFFContData[GOFF::RecordLength + 77] = (char)0xA6; 287 GOFFContData[GOFF::RecordLength + 78] = (char)0x96; 288 GOFFContData[GOFF::RecordLength + 79] = (char)0x99; 289 290 // ESD continuation record. 291 GOFFContData[GOFF::RecordLength * 2] = (char)0x03; 292 GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x03; // Continued bit set. 293 GOFFContData[GOFF::RecordLength * 2 + 3] = (char)0x93; 294 GOFFContData[GOFF::RecordLength * 2 + 4] = (char)0x84; 295 296 // END record. 297 GOFFContData[GOFF::RecordLength * 3] = (char)0x03; 298 GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; 299 300 StringRef Data(GOFFContData, GOFF::RecordLength * 4); 301 302 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 303 object::ObjectFile::createGOFFObjectFile( 304 MemoryBufferRef(Data, "dummyGOFF")); 305 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 306 307 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 308 309 for (SymbolRef Symbol : GOFFObj->symbols()) { 310 Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); 311 EXPECT_THAT_EXPECTED(SymbolNameOrErr, 312 FailedWithMessage("continued bit should not be set")); 313 } 314 } 315 316 TEST(GOFFObjectFileTest, PrevNotContinued) { 317 char GOFFContData[GOFF::RecordLength * 4] = {0x00}; 318 319 // HDR record. 320 GOFFContData[0] = (char)0x03; 321 GOFFContData[1] = (char)0xF0; 322 323 // ESD record, with continued bit not set. 324 GOFFContData[GOFF::RecordLength] = (char)0x03; 325 326 // ESD continuation record. 327 GOFFContData[GOFF::RecordLength * 2] = (char)0x03; 328 GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x02; 329 330 // END record. 331 GOFFContData[GOFF::RecordLength * 3] = (char)0x03; 332 GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; 333 334 StringRef Data(GOFFContData, GOFF::RecordLength * 4); 335 336 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 337 object::ObjectFile::createGOFFObjectFile( 338 MemoryBufferRef(Data, "dummyGOFF")); 339 340 ASSERT_THAT_EXPECTED( 341 GOFFObjOrErr, 342 FailedWithMessage("record 2 is a continuation record that is not " 343 "preceded by a continued record")); 344 } 345 346 TEST(GOFFObjectFileTest, ContinuationTypeMismatch) { 347 char GOFFContData[GOFF::RecordLength * 4] = {0x00}; 348 349 // HDR record. 350 GOFFContData[0] = (char)0x03; 351 GOFFContData[1] = (char)0xF0; 352 353 // ESD record. 354 GOFFContData[GOFF::RecordLength] = (char)0x03; 355 GOFFContData[GOFF::RecordLength + 1] = (char)0x01; // Continued to next record. 356 357 // END continuation record. 358 GOFFContData[GOFF::RecordLength * 2] = (char)0x03; 359 GOFFContData[GOFF::RecordLength * 2 + 1] = (char)0x42; 360 361 // END record. 362 GOFFContData[GOFF::RecordLength * 3] = (char)0x03; 363 GOFFContData[GOFF::RecordLength * 3 + 1] = (char)0x40; 364 365 StringRef Data(GOFFContData, GOFF::RecordLength * 4); 366 367 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 368 object::ObjectFile::createGOFFObjectFile( 369 MemoryBufferRef(Data, "dummyGOFF")); 370 371 ASSERT_THAT_EXPECTED( 372 GOFFObjOrErr, 373 FailedWithMessage("record 2 is a continuation record that does not match " 374 "the type of the previous record")); 375 } 376 377 TEST(GOFFObjectFileTest, TwoSymbols) { 378 char GOFFData[GOFF::RecordLength * 4] = {0x00}; 379 380 // HDR record. 381 GOFFData[0] = (char)0x03; 382 GOFFData[1] = (char)0xF0; 383 384 // ESD record 1. 385 GOFFData[GOFF::RecordLength] = (char)0x03; 386 GOFFData[GOFF::RecordLength + 3] = (char)0x00; 387 GOFFData[GOFF::RecordLength + 7] = (char)0x01; // ESDID. 388 GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name. 389 GOFFData[GOFF::RecordLength + 72] = (char)0xa7; // Symbol name is x. 390 391 // ESD record 2. 392 GOFFData[GOFF::RecordLength * 2] = (char)0x03; 393 GOFFData[GOFF::RecordLength * 2 + 3] = (char)0x03; 394 GOFFData[GOFF::RecordLength * 2 + 7] = (char)0x02; // ESDID. 395 GOFFData[GOFF::RecordLength * 2 + 11] = (char)0x01; // Parent ESDID. 396 GOFFData[GOFF::RecordLength * 2 + 71] = (char)0x05; // Size of symbol name. 397 GOFFData[GOFF::RecordLength * 2 + 72] = (char)0xC8; // Symbol name is Hello. 398 GOFFData[GOFF::RecordLength * 2 + 73] = (char)0x85; 399 GOFFData[GOFF::RecordLength * 2 + 74] = (char)0x93; 400 GOFFData[GOFF::RecordLength * 2 + 75] = (char)0x93; 401 GOFFData[GOFF::RecordLength * 2 + 76] = (char)0x96; 402 403 // END record. 404 GOFFData[GOFF::RecordLength * 3] = (char)0x03; 405 GOFFData[GOFF::RecordLength * 3 + 1] = (char)0x40; 406 407 StringRef Data(GOFFData, GOFF::RecordLength * 4); 408 409 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 410 object::ObjectFile::createGOFFObjectFile( 411 MemoryBufferRef(Data, "dummyGOFF")); 412 413 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 414 415 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 416 417 for (SymbolRef Symbol : GOFFObj->symbols()) { 418 Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); 419 ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); 420 StringRef SymbolName = SymbolNameOrErr.get(); 421 EXPECT_EQ(SymbolName, "Hello"); 422 } 423 } 424 425 TEST(GOFFObjectFileTest, InvalidSymbolType) { 426 char GOFFData[GOFF::RecordLength * 3] = {0x00}; 427 428 // HDR record. 429 GOFFData[0] = (char)0x03; 430 GOFFData[1] = (char)0xF0; 431 432 // ESD record. 433 GOFFData[GOFF::RecordLength] = (char)0x03; 434 GOFFData[GOFF::RecordLength + 3] = (char)0x05; 435 GOFFData[GOFF::RecordLength + 7] = (char)0x01; 436 GOFFData[GOFF::RecordLength + 11] = (char)0x01; 437 GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name. 438 GOFFData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name. 439 440 // END record. 441 GOFFData[GOFF::RecordLength * 2] = (char)0x03; 442 GOFFData[GOFF::RecordLength * 2 + 1] = (char)0x40; 443 444 StringRef Data(GOFFData, GOFF::RecordLength * 3); 445 446 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 447 object::ObjectFile::createGOFFObjectFile( 448 MemoryBufferRef(Data, "dummyGOFF")); 449 450 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 451 452 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 453 454 for (SymbolRef Symbol : GOFFObj->symbols()) { 455 Expected<SymbolRef::Type> SymbolType = Symbol.getType(); 456 EXPECT_THAT_EXPECTED( 457 SymbolType, 458 FailedWithMessage("ESD record 1 has invalid symbol type 0x05")); 459 460 Expected<section_iterator> SymSI = Symbol.getSection(); 461 ASSERT_THAT_EXPECTED( 462 SymSI, 463 FailedWithMessage( 464 "symbol with ESD id 1 refers to invalid section with ESD id 1")); 465 } 466 } 467 468 TEST(GOFFObjectFileTest, InvalidERSymbolType) { 469 char GOFFData[GOFF::RecordLength * 3] = {0x00}; 470 471 // HDR record. 472 GOFFData[0] = (char)0x03; 473 GOFFData[1] = (char)0xF0; 474 475 // ESD record. 476 GOFFData[GOFF::RecordLength] = (char)0x03; 477 GOFFData[GOFF::RecordLength + 3] = (char)0x04; 478 GOFFData[GOFF::RecordLength + 7] = (char)0x01; 479 GOFFData[GOFF::RecordLength + 11] = (char)0x01; 480 GOFFData[GOFF::RecordLength + 63] = (char)0x03; // Unknown executable type. 481 GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name. 482 GOFFData[GOFF::RecordLength + 72] = (char)0xC8; // Symbol name. 483 484 // END record. 485 GOFFData[GOFF::RecordLength * 2] = (char)0x03; 486 GOFFData[GOFF::RecordLength * 2 + 1] = (char)0x40; 487 488 StringRef Data(GOFFData, GOFF::RecordLength * 3); 489 490 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 491 object::ObjectFile::createGOFFObjectFile( 492 MemoryBufferRef(Data, "dummyGOFF")); 493 494 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 495 496 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 497 498 for (SymbolRef Symbol : GOFFObj->symbols()) { 499 Expected<SymbolRef::Type> SymbolType = Symbol.getType(); 500 EXPECT_THAT_EXPECTED( 501 SymbolType, 502 FailedWithMessage("ESD record 1 has unknown Executable type 0x03")); 503 } 504 } 505 506 TEST(GOFFObjectFileTest, TXTConstruct) { 507 char GOFFData[GOFF::RecordLength * 6] = {}; 508 509 // HDR record. 510 GOFFData[0] = (char)0x03; 511 GOFFData[1] = (char)0xF0; 512 GOFFData[50] = (char)0x01; 513 514 // ESD record. 515 GOFFData[GOFF::RecordLength] = (char)0x03; 516 GOFFData[GOFF::RecordLength + 7] = (char)0x01; // ESDID. 517 GOFFData[GOFF::RecordLength + 71] = (char)0x05; // Size of symbol name. 518 GOFFData[GOFF::RecordLength + 72] = (char)0xa5; // Symbol name is v. 519 GOFFData[GOFF::RecordLength + 73] = (char)0x81; // Symbol name is a. 520 GOFFData[GOFF::RecordLength + 74] = (char)0x99; // Symbol name is r. 521 GOFFData[GOFF::RecordLength + 75] = (char)0x7b; // Symbol name is #. 522 GOFFData[GOFF::RecordLength + 76] = (char)0x83; // Symbol name is c. 523 524 // ESD record. 525 GOFFData[GOFF::RecordLength * 2] = (char)0x03; 526 GOFFData[GOFF::RecordLength * 2 + 3] = (char)0x01; 527 GOFFData[GOFF::RecordLength * 2 + 7] = (char)0x02; // ESDID. 528 GOFFData[GOFF::RecordLength * 2 + 11] = (char)0x01; // Parent ESDID. 529 GOFFData[GOFF::RecordLength * 2 + 27] = (char)0x08; // Length. 530 GOFFData[GOFF::RecordLength * 2 + 40] = (char)0x01; // Name Space ID. 531 GOFFData[GOFF::RecordLength * 2 + 41] = (char)0x80; 532 GOFFData[GOFF::RecordLength * 2 + 60] = (char)0x04; // Size of symbol name. 533 GOFFData[GOFF::RecordLength * 2 + 61] = (char)0x04; // Size of symbol name. 534 GOFFData[GOFF::RecordLength * 2 + 63] = (char)0x0a; // Size of symbol name. 535 GOFFData[GOFF::RecordLength * 2 + 66] = (char)0x03; // Size of symbol name. 536 GOFFData[GOFF::RecordLength * 2 + 71] = (char)0x08; // Size of symbol name. 537 GOFFData[GOFF::RecordLength * 2 + 72] = (char)0xc3; // Symbol name is c. 538 GOFFData[GOFF::RecordLength * 2 + 73] = (char)0x6d; // Symbol name is _. 539 GOFFData[GOFF::RecordLength * 2 + 74] = (char)0xc3; // Symbol name is c. 540 GOFFData[GOFF::RecordLength * 2 + 75] = (char)0xd6; // Symbol name is o. 541 GOFFData[GOFF::RecordLength * 2 + 76] = (char)0xc4; // Symbol name is D. 542 GOFFData[GOFF::RecordLength * 2 + 77] = (char)0xc5; // Symbol name is E. 543 GOFFData[GOFF::RecordLength * 2 + 78] = (char)0xf6; // Symbol name is 6. 544 GOFFData[GOFF::RecordLength * 2 + 79] = (char)0xf4; // Symbol name is 4. 545 546 // ESD record. 547 GOFFData[GOFF::RecordLength * 3] = (char)0x03; 548 GOFFData[GOFF::RecordLength * 3 + 3] = (char)0x02; 549 GOFFData[GOFF::RecordLength * 3 + 7] = (char)0x03; // ESDID. 550 GOFFData[GOFF::RecordLength * 3 + 11] = (char)0x02; // Parent ESDID. 551 GOFFData[GOFF::RecordLength * 3 + 71] = (char)0x05; // Size of symbol name. 552 GOFFData[GOFF::RecordLength * 3 + 72] = (char)0xa5; // Symbol name is v. 553 GOFFData[GOFF::RecordLength * 3 + 73] = (char)0x81; // Symbol name is a. 554 GOFFData[GOFF::RecordLength * 3 + 74] = (char)0x99; // Symbol name is r. 555 GOFFData[GOFF::RecordLength * 3 + 75] = (char)0x7b; // Symbol name is #. 556 GOFFData[GOFF::RecordLength * 3 + 76] = (char)0x83; // Symbol name is c. 557 558 // TXT record. 559 GOFFData[GOFF::RecordLength * 4] = (char)0x03; 560 GOFFData[GOFF::RecordLength * 4 + 1] = (char)0x10; 561 GOFFData[GOFF::RecordLength * 4 + 7] = (char)0x02; 562 GOFFData[GOFF::RecordLength * 4 + 23] = (char)0x08; // Data Length. 563 GOFFData[GOFF::RecordLength * 4 + 24] = (char)0x12; 564 GOFFData[GOFF::RecordLength * 4 + 25] = (char)0x34; 565 GOFFData[GOFF::RecordLength * 4 + 26] = (char)0x56; 566 GOFFData[GOFF::RecordLength * 4 + 27] = (char)0x78; 567 GOFFData[GOFF::RecordLength * 4 + 28] = (char)0x9a; 568 GOFFData[GOFF::RecordLength * 4 + 29] = (char)0xbc; 569 GOFFData[GOFF::RecordLength * 4 + 30] = (char)0xde; 570 GOFFData[GOFF::RecordLength * 4 + 31] = (char)0xf0; 571 572 // END record. 573 GOFFData[GOFF::RecordLength * 5] = (char)0x03; 574 GOFFData[GOFF::RecordLength * 5 + 1] = (char)0x40; 575 GOFFData[GOFF::RecordLength * 5 + 11] = (char)0x06; 576 577 StringRef Data(GOFFData, GOFF::RecordLength * 6); 578 579 Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr = 580 object::ObjectFile::createGOFFObjectFile( 581 MemoryBufferRef(Data, "dummyGOFF")); 582 583 ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded()); 584 585 GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get()); 586 auto Symbols = GOFFObj->symbols(); 587 ASSERT_EQ(std::distance(Symbols.begin(), Symbols.end()), 1); 588 SymbolRef Symbol = *Symbols.begin(); 589 Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(Symbol); 590 ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded()); 591 StringRef SymbolName = SymbolNameOrErr.get(); 592 EXPECT_EQ(SymbolName, "var#c"); 593 594 auto Sections = GOFFObj->sections(); 595 ASSERT_EQ(std::distance(Sections.begin(), Sections.end()), 1); 596 SectionRef Section = *Sections.begin(); 597 Expected<StringRef> SectionContent = Section.getContents(); 598 ASSERT_THAT_EXPECTED(SectionContent, Succeeded()); 599 StringRef Contents = SectionContent.get(); 600 EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0"); 601 } 602