1 //===- ELFObjectFileTest.cpp - Tests for ELFObjectFile --------------------===// 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/ADT/STLExtras.h" 11 #include "llvm/ObjectYAML/yaml2obj.h" 12 #include "llvm/Support/MemoryBuffer.h" 13 #include "llvm/Support/YAMLTraits.h" 14 #include "llvm/Testing/Support/Error.h" 15 #include "gtest/gtest.h" 16 17 #include "llvm/Support/thread.h" 18 #include "llvm/TargetParser/Host.h" 19 20 using namespace llvm; 21 using namespace llvm::object; 22 23 // Used to skip LLVM_BB_ADDR_MAP tests on windows platforms due to 24 // https://github.com/llvm/llvm-project/issues/60013. 25 bool IsHostWindows() { 26 Triple Host(Triple::normalize(sys::getProcessTriple())); 27 return Host.isOSWindows(); 28 } 29 30 namespace { 31 32 // A struct to initialize a buffer to represent an ELF object file. 33 struct DataForTest { 34 std::vector<uint8_t> Data; 35 36 template <typename T> 37 std::vector<uint8_t> makeElfData(uint8_t Class, uint8_t Encoding, 38 uint16_t Machine) { 39 T Ehdr{}; // Zero-initialise the header. 40 Ehdr.e_ident[ELF::EI_MAG0] = 0x7f; 41 Ehdr.e_ident[ELF::EI_MAG1] = 'E'; 42 Ehdr.e_ident[ELF::EI_MAG2] = 'L'; 43 Ehdr.e_ident[ELF::EI_MAG3] = 'F'; 44 Ehdr.e_ident[ELF::EI_CLASS] = Class; 45 Ehdr.e_ident[ELF::EI_DATA] = Encoding; 46 Ehdr.e_ident[ELF::EI_VERSION] = 1; 47 Ehdr.e_type = ELF::ET_REL; 48 Ehdr.e_machine = Machine; 49 Ehdr.e_version = 1; 50 Ehdr.e_ehsize = sizeof(T); 51 52 bool IsLittleEndian = Encoding == ELF::ELFDATA2LSB; 53 if (sys::IsLittleEndianHost != IsLittleEndian) { 54 sys::swapByteOrder(Ehdr.e_type); 55 sys::swapByteOrder(Ehdr.e_machine); 56 sys::swapByteOrder(Ehdr.e_version); 57 sys::swapByteOrder(Ehdr.e_ehsize); 58 } 59 60 uint8_t *EhdrBytes = reinterpret_cast<uint8_t *>(&Ehdr); 61 std::vector<uint8_t> Bytes; 62 std::copy(EhdrBytes, EhdrBytes + sizeof(Ehdr), std::back_inserter(Bytes)); 63 return Bytes; 64 } 65 66 DataForTest(uint8_t Class, uint8_t Encoding, uint16_t Machine) { 67 if (Class == ELF::ELFCLASS64) 68 Data = makeElfData<ELF::Elf64_Ehdr>(Class, Encoding, Machine); 69 else { 70 assert(Class == ELF::ELFCLASS32); 71 Data = makeElfData<ELF::Elf32_Ehdr>(Class, Encoding, Machine); 72 } 73 } 74 }; 75 76 void checkFormatAndArch(const DataForTest &D, StringRef Fmt, 77 Triple::ArchType Arch) { 78 Expected<std::unique_ptr<ObjectFile>> ELFObjOrErr = 79 object::ObjectFile::createELFObjectFile( 80 MemoryBufferRef(toStringRef(D.Data), "dummyELF")); 81 ASSERT_THAT_EXPECTED(ELFObjOrErr, Succeeded()); 82 83 const ObjectFile &File = *(*ELFObjOrErr).get(); 84 EXPECT_EQ(Fmt, File.getFileFormatName()); 85 EXPECT_EQ(Arch, File.getArch()); 86 } 87 88 std::array<DataForTest, 4> generateData(uint16_t Machine) { 89 return {DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2LSB, Machine), 90 DataForTest(ELF::ELFCLASS32, ELF::ELFDATA2MSB, Machine), 91 DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2LSB, Machine), 92 DataForTest(ELF::ELFCLASS64, ELF::ELFDATA2MSB, Machine)}; 93 } 94 95 } // namespace 96 97 TEST(ELFObjectFileTest, MachineTestForNoneOrUnused) { 98 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 99 "elf64-unknown", "elf64-unknown"}; 100 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_NONE))) 101 checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch); 102 103 // Test an arbitrary unused EM_* value (255). 104 for (auto [Idx, Data] : enumerate(generateData(255))) 105 checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch); 106 } 107 108 TEST(ELFObjectFileTest, MachineTestForVE) { 109 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 110 "elf64-ve", "elf64-ve"}; 111 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_VE))) 112 checkFormatAndArch(Data, Formats[Idx], Triple::ve); 113 } 114 115 TEST(ELFObjectFileTest, MachineTestForX86_64) { 116 std::array<StringRef, 4> Formats = {"elf32-x86-64", "elf32-x86-64", 117 "elf64-x86-64", "elf64-x86-64"}; 118 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_X86_64))) 119 checkFormatAndArch(Data, Formats[Idx], Triple::x86_64); 120 } 121 122 TEST(ELFObjectFileTest, MachineTestFor386) { 123 std::array<StringRef, 4> Formats = {"elf32-i386", "elf32-i386", "elf64-i386", 124 "elf64-i386"}; 125 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_386))) 126 checkFormatAndArch(Data, Formats[Idx], Triple::x86); 127 } 128 129 TEST(ELFObjectFileTest, MachineTestForMIPS) { 130 std::array<StringRef, 4> Formats = {"elf32-mips", "elf32-mips", "elf64-mips", 131 "elf64-mips"}; 132 std::array<Triple::ArchType, 4> Archs = {Triple::mipsel, Triple::mips, 133 Triple::mips64el, Triple::mips64}; 134 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_MIPS))) 135 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 136 } 137 138 TEST(ELFObjectFileTest, MachineTestForAMDGPU) { 139 std::array<StringRef, 4> Formats = {"elf32-amdgpu", "elf32-amdgpu", 140 "elf64-amdgpu", "elf64-amdgpu"}; 141 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AMDGPU))) 142 checkFormatAndArch(Data, Formats[Idx], Triple::UnknownArch); 143 } 144 145 TEST(ELFObjectFileTest, MachineTestForIAMCU) { 146 std::array<StringRef, 4> Formats = {"elf32-iamcu", "elf32-iamcu", 147 "elf64-unknown", "elf64-unknown"}; 148 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_IAMCU))) 149 checkFormatAndArch(Data, Formats[Idx], Triple::x86); 150 } 151 152 TEST(ELFObjectFileTest, MachineTestForAARCH64) { 153 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 154 "elf64-littleaarch64", 155 "elf64-bigaarch64"}; 156 std::array<Triple::ArchType, 4> Archs = {Triple::aarch64, Triple::aarch64_be, 157 Triple::aarch64, Triple::aarch64_be}; 158 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AARCH64))) 159 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 160 } 161 162 TEST(ELFObjectFileTest, MachineTestForPPC64) { 163 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 164 "elf64-powerpcle", "elf64-powerpc"}; 165 std::array<Triple::ArchType, 4> Archs = {Triple::ppc64le, Triple::ppc64, 166 Triple::ppc64le, Triple::ppc64}; 167 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_PPC64))) 168 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 169 } 170 171 TEST(ELFObjectFileTest, MachineTestForPPC) { 172 std::array<StringRef, 4> Formats = {"elf32-powerpcle", "elf32-powerpc", 173 "elf64-unknown", "elf64-unknown"}; 174 std::array<Triple::ArchType, 4> Archs = {Triple::ppcle, Triple::ppc, 175 Triple::ppcle, Triple::ppc}; 176 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_PPC))) 177 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 178 } 179 180 TEST(ELFObjectFileTest, MachineTestForRISCV) { 181 std::array<StringRef, 4> Formats = {"elf32-littleriscv", "elf32-littleriscv", 182 "elf64-littleriscv", "elf64-littleriscv"}; 183 std::array<Triple::ArchType, 4> Archs = {Triple::riscv32, Triple::riscv32, 184 Triple::riscv64, Triple::riscv64}; 185 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_RISCV))) 186 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 187 } 188 189 TEST(ELFObjectFileTest, MachineTestForARM) { 190 std::array<StringRef, 4> Formats = {"elf32-littlearm", "elf32-bigarm", 191 "elf64-unknown", "elf64-unknown"}; 192 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_ARM))) 193 checkFormatAndArch(Data, Formats[Idx], Triple::arm); 194 } 195 196 TEST(ELFObjectFileTest, MachineTestForS390) { 197 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 198 "elf64-s390", "elf64-s390"}; 199 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_S390))) 200 checkFormatAndArch(Data, Formats[Idx], Triple::systemz); 201 } 202 203 TEST(ELFObjectFileTest, MachineTestForSPARCV9) { 204 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 205 "elf64-sparc", "elf64-sparc"}; 206 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARCV9))) 207 checkFormatAndArch(Data, Formats[Idx], Triple::sparcv9); 208 } 209 210 TEST(ELFObjectFileTest, MachineTestForSPARC) { 211 std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc", 212 "elf64-unknown", "elf64-unknown"}; 213 std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc, 214 Triple::sparcel, Triple::sparc}; 215 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARC))) 216 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 217 } 218 219 TEST(ELFObjectFileTest, MachineTestForSPARC32PLUS) { 220 std::array<StringRef, 4> Formats = {"elf32-sparc", "elf32-sparc", 221 "elf64-unknown", "elf64-unknown"}; 222 std::array<Triple::ArchType, 4> Archs = {Triple::sparcel, Triple::sparc, 223 Triple::sparcel, Triple::sparc}; 224 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_SPARC32PLUS))) 225 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 226 } 227 228 TEST(ELFObjectFileTest, MachineTestForBPF) { 229 std::array<StringRef, 4> Formats = {"elf32-unknown", "elf32-unknown", 230 "elf64-bpf", "elf64-bpf"}; 231 std::array<Triple::ArchType, 4> Archs = {Triple::bpfel, Triple::bpfeb, 232 Triple::bpfel, Triple::bpfeb}; 233 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_BPF))) 234 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 235 } 236 237 TEST(ELFObjectFileTest, MachineTestForAVR) { 238 std::array<StringRef, 4> Formats = {"elf32-avr", "elf32-avr", "elf64-unknown", 239 "elf64-unknown"}; 240 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_AVR))) 241 checkFormatAndArch(Data, Formats[Idx], Triple::avr); 242 } 243 244 TEST(ELFObjectFileTest, MachineTestForHEXAGON) { 245 std::array<StringRef, 4> Formats = {"elf32-hexagon", "elf32-hexagon", 246 "elf64-unknown", "elf64-unknown"}; 247 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_HEXAGON))) 248 checkFormatAndArch(Data, Formats[Idx], Triple::hexagon); 249 } 250 251 TEST(ELFObjectFileTest, MachineTestForLANAI) { 252 std::array<StringRef, 4> Formats = {"elf32-lanai", "elf32-lanai", 253 "elf64-unknown", "elf64-unknown"}; 254 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LANAI))) 255 checkFormatAndArch(Data, Formats[Idx], Triple::lanai); 256 } 257 258 TEST(ELFObjectFileTest, MachineTestForMSP430) { 259 std::array<StringRef, 4> Formats = {"elf32-msp430", "elf32-msp430", 260 "elf64-unknown", "elf64-unknown"}; 261 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_MSP430))) 262 checkFormatAndArch(Data, Formats[Idx], Triple::msp430); 263 } 264 265 TEST(ELFObjectFileTest, MachineTestForLoongArch) { 266 std::array<StringRef, 4> Formats = {"elf32-loongarch", "elf32-loongarch", 267 "elf64-loongarch", "elf64-loongarch"}; 268 std::array<Triple::ArchType, 4> Archs = { 269 Triple::loongarch32, Triple::loongarch32, Triple::loongarch64, 270 Triple::loongarch64}; 271 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_LOONGARCH))) 272 checkFormatAndArch(Data, Formats[Idx], Archs[Idx]); 273 } 274 275 TEST(ELFObjectFileTest, MachineTestForCSKY) { 276 std::array<StringRef, 4> Formats = {"elf32-csky", "elf32-csky", 277 "elf64-unknown", "elf64-unknown"}; 278 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_CSKY))) 279 checkFormatAndArch(Data, Formats[Idx], Triple::csky); 280 } 281 282 TEST(ELFObjectFileTest, MachineTestForXtensa) { 283 std::array<StringRef, 4> Formats = {"elf32-xtensa", "elf32-xtensa", 284 "elf64-unknown", "elf64-unknown"}; 285 for (auto [Idx, Data] : enumerate(generateData(ELF::EM_XTENSA))) 286 checkFormatAndArch(Data, Formats[Idx], Triple::xtensa); 287 } 288 289 // ELF relative relocation type test. 290 TEST(ELFObjectFileTest, RelativeRelocationTypeTest) { 291 EXPECT_EQ(ELF::R_CKCORE_RELATIVE, getELFRelativeRelocationType(ELF::EM_CSKY)); 292 } 293 294 template <class ELFT> 295 static Expected<ELFObjectFile<ELFT>> toBinary(SmallVectorImpl<char> &Storage, 296 StringRef Yaml) { 297 raw_svector_ostream OS(Storage); 298 yaml::Input YIn(Yaml); 299 if (!yaml::convertYAML(YIn, OS, [](const Twine &Msg) {})) 300 return createStringError(std::errc::invalid_argument, 301 "unable to convert YAML"); 302 return ELFObjectFile<ELFT>::create(MemoryBufferRef(OS.str(), "dummyELF")); 303 } 304 305 // Check we are able to create an ELFObjectFile even when the content of the 306 // SHT_SYMTAB_SHNDX section can't be read properly. 307 TEST(ELFObjectFileTest, InvalidSymtabShndxTest) { 308 SmallString<0> Storage; 309 Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"( 310 --- !ELF 311 FileHeader: 312 Class: ELFCLASS64 313 Data: ELFDATA2LSB 314 Type: ET_REL 315 Sections: 316 - Name: .symtab_shndx 317 Type: SHT_SYMTAB_SHNDX 318 Entries: [ 0 ] 319 ShSize: 0xFFFFFFFF 320 )"); 321 322 ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded()); 323 } 324 325 // Test that we are able to create an ELFObjectFile even when loadable segments 326 // are unsorted by virtual address. 327 // Test that ELFFile<ELFT>::toMappedAddr works properly in this case. 328 329 TEST(ELFObjectFileTest, InvalidLoadSegmentsOrderTest) { 330 SmallString<0> Storage; 331 Expected<ELFObjectFile<ELF64LE>> ExpectedFile = toBinary<ELF64LE>(Storage, R"( 332 --- !ELF 333 FileHeader: 334 Class: ELFCLASS64 335 Data: ELFDATA2LSB 336 Type: ET_EXEC 337 Sections: 338 - Name: .foo 339 Type: SHT_PROGBITS 340 Address: 0x1000 341 Offset: 0x3000 342 ContentArray: [ 0x11 ] 343 - Name: .bar 344 Type: SHT_PROGBITS 345 Address: 0x2000 346 Offset: 0x4000 347 ContentArray: [ 0x99 ] 348 ProgramHeaders: 349 - Type: PT_LOAD 350 VAddr: 0x2000 351 FirstSec: .bar 352 LastSec: .bar 353 - Type: PT_LOAD 354 VAddr: 0x1000 355 FirstSec: .foo 356 LastSec: .foo 357 )"); 358 359 ASSERT_THAT_EXPECTED(ExpectedFile, Succeeded()); 360 361 std::string WarnString; 362 auto ToMappedAddr = [&](uint64_t Addr) -> const uint8_t * { 363 Expected<const uint8_t *> DataOrErr = 364 ExpectedFile->getELFFile().toMappedAddr(Addr, [&](const Twine &Msg) { 365 EXPECT_TRUE(WarnString.empty()); 366 WarnString = Msg.str(); 367 return Error::success(); 368 }); 369 370 if (!DataOrErr) { 371 ADD_FAILURE() << toString(DataOrErr.takeError()); 372 return nullptr; 373 } 374 375 EXPECT_TRUE(WarnString == 376 "loadable segments are unsorted by virtual address"); 377 WarnString = ""; 378 return *DataOrErr; 379 }; 380 381 const uint8_t *Data = ToMappedAddr(0x1000); 382 ASSERT_TRUE(Data); 383 MemoryBufferRef Buf = ExpectedFile->getMemoryBufferRef(); 384 EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x3000); 385 EXPECT_EQ(Data[0], 0x11); 386 387 Data = ToMappedAddr(0x2000); 388 ASSERT_TRUE(Data); 389 Buf = ExpectedFile->getMemoryBufferRef(); 390 EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x4000); 391 EXPECT_EQ(Data[0], 0x99); 392 } 393 394 // This is a test for API that is related to symbols. 395 // We check that errors are properly reported here. 396 TEST(ELFObjectFileTest, InvalidSymbolTest) { 397 SmallString<0> Storage; 398 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"( 399 --- !ELF 400 FileHeader: 401 Class: ELFCLASS64 402 Data: ELFDATA2LSB 403 Type: ET_DYN 404 Machine: EM_X86_64 405 Sections: 406 - Name: .symtab 407 Type: SHT_SYMTAB 408 )"); 409 410 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 411 const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile(); 412 const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr; 413 414 Expected<const typename ELF64LE::Shdr *> SymtabSecOrErr = Elf.getSection(1); 415 ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded()); 416 ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB); 417 418 auto DoCheck = [&](unsigned BrokenSymIndex, const char *ErrMsg) { 419 ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex); 420 421 // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName(). 422 // SymbolRef::getName() calls it internally. We can't test it directly, 423 // because it is protected. 424 EXPECT_THAT_ERROR(BrokenSym.getName().takeError(), 425 FailedWithMessage(ErrMsg)); 426 427 // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol(). 428 EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(), 429 FailedWithMessage(ErrMsg)); 430 431 // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection(). 432 // SymbolRef::getSection() calls it internally. We can't test it 433 // directly, because it is protected. 434 EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(), 435 FailedWithMessage(ErrMsg)); 436 437 // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags(). 438 // SymbolRef::getFlags() calls it internally. We can't test it directly, 439 // because it is protected. 440 EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(), 441 FailedWithMessage(ErrMsg)); 442 443 // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType(). 444 // SymbolRef::getType() calls it internally. We can't test it directly, 445 // because it is protected. 446 EXPECT_THAT_ERROR(BrokenSym.getType().takeError(), 447 FailedWithMessage(ErrMsg)); 448 449 // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress(). 450 // SymbolRef::getAddress() calls it internally. We can't test it 451 // directly, because it is protected. 452 EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(), 453 FailedWithMessage(ErrMsg)); 454 455 // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying 456 // method that generates errors for all cases above. 457 EXPECT_THAT_EXPECTED( 458 Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), Succeeded()); 459 EXPECT_THAT_ERROR( 460 Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex) 461 .takeError(), 462 FailedWithMessage(ErrMsg)); 463 }; 464 465 // We create a symbol with an index that is too large to exist in the symbol 466 // table. 467 DoCheck(0x1, "can't read an entry at 0x18: it goes past the end of the " 468 "section (0x18)"); 469 470 // We create a symbol with an index that is too large to exist in the object. 471 DoCheck(0xFFFFFFFF, "can't read an entry at 0x17ffffffe8: it goes past the " 472 "end of the section (0x18)"); 473 } 474 475 // Tests for error paths of the ELFFile::decodeBBAddrMap API. 476 TEST(ELFObjectFileTest, InvalidDecodeBBAddrMap) { 477 if (IsHostWindows()) 478 GTEST_SKIP(); 479 StringRef CommonYamlString(R"( 480 --- !ELF 481 FileHeader: 482 Class: ELFCLASS64 483 Data: ELFDATA2LSB 484 Type: ET_EXEC 485 Sections: 486 - Type: SHT_LLVM_BB_ADDR_MAP 487 Name: .llvm_bb_addr_map 488 Entries: 489 - Address: 0x11111 490 )"); 491 492 auto DoCheck = [&](StringRef YamlString, const char *ErrMsg) { 493 SmallString<0> Storage; 494 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = 495 toBinary<ELF64LE>(Storage, YamlString); 496 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 497 const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile(); 498 499 Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr = 500 Elf.getSection(1); 501 ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded()); 502 EXPECT_THAT_ERROR(Elf.decodeBBAddrMap(**BBAddrMapSecOrErr).takeError(), 503 FailedWithMessage(ErrMsg)); 504 }; 505 506 // Check that we can detect unsupported versions. 507 SmallString<128> UnsupportedVersionYamlString(CommonYamlString); 508 UnsupportedVersionYamlString += R"( 509 Version: 3 510 BBEntries: 511 - AddressOffset: 0x0 512 Size: 0x1 513 Metadata: 0x2 514 )"; 515 516 DoCheck(UnsupportedVersionYamlString, 517 "unsupported SHT_LLVM_BB_ADDR_MAP version: 3"); 518 519 SmallString<128> CommonVersionedYamlString(CommonYamlString); 520 CommonVersionedYamlString += R"( 521 Version: 2 522 BBEntries: 523 - ID: 1 524 AddressOffset: 0x0 525 Size: 0x1 526 Metadata: 0x2 527 )"; 528 529 // Check that we can detect the malformed encoding when the section is 530 // truncated. 531 SmallString<128> TruncatedYamlString(CommonVersionedYamlString); 532 TruncatedYamlString += R"( 533 ShSize: 0xb 534 )"; 535 DoCheck(TruncatedYamlString, "unable to decode LEB128 at offset 0x0000000b: " 536 "malformed uleb128, extends past end"); 537 538 // Check that we can detect when the encoded BB entry fields exceed the UINT32 539 // limit. 540 SmallVector<SmallString<128>, 3> OverInt32LimitYamlStrings( 541 3, CommonVersionedYamlString); 542 OverInt32LimitYamlStrings[0] += R"( 543 - ID: 1 544 AddressOffset: 0x100000000 545 Size: 0xFFFFFFFF 546 Metadata: 0xFFFFFFFF 547 )"; 548 549 OverInt32LimitYamlStrings[1] += R"( 550 - ID: 2 551 AddressOffset: 0xFFFFFFFF 552 Size: 0x100000000 553 Metadata: 0xFFFFFFFF 554 )"; 555 556 OverInt32LimitYamlStrings[2] += R"( 557 - ID: 3 558 AddressOffset: 0xFFFFFFFF 559 Size: 0xFFFFFFFF 560 Metadata: 0x100000000 561 )"; 562 563 DoCheck(OverInt32LimitYamlStrings[0], 564 "ULEB128 value at offset 0x10 exceeds UINT32_MAX (0x100000000)"); 565 DoCheck(OverInt32LimitYamlStrings[1], 566 "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)"); 567 DoCheck(OverInt32LimitYamlStrings[2], 568 "ULEB128 value at offset 0x1a exceeds UINT32_MAX (0x100000000)"); 569 570 // Check the proper error handling when the section has fields exceeding 571 // UINT32 and is also truncated. This is for checking that we don't generate 572 // unhandled errors. 573 SmallVector<SmallString<128>, 3> OverInt32LimitAndTruncated( 574 3, OverInt32LimitYamlStrings[1]); 575 // Truncate before the end of the 5-byte field. 576 OverInt32LimitAndTruncated[0] += R"( 577 ShSize: 0x19 578 )"; 579 // Truncate at the end of the 5-byte field. 580 OverInt32LimitAndTruncated[1] += R"( 581 ShSize: 0x1a 582 )"; 583 // Truncate after the end of the 5-byte field. 584 OverInt32LimitAndTruncated[2] += R"( 585 ShSize: 0x1b 586 )"; 587 588 DoCheck(OverInt32LimitAndTruncated[0], 589 "unable to decode LEB128 at offset 0x00000015: malformed uleb128, " 590 "extends past end"); 591 DoCheck(OverInt32LimitAndTruncated[1], 592 "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)"); 593 DoCheck(OverInt32LimitAndTruncated[2], 594 "ULEB128 value at offset 0x15 exceeds UINT32_MAX (0x100000000)"); 595 596 // Check for proper error handling when the 'NumBlocks' field is overridden 597 // with an out-of-range value. 598 SmallString<128> OverLimitNumBlocks(CommonVersionedYamlString); 599 OverLimitNumBlocks += R"( 600 NumBlocks: 0x100000000 601 )"; 602 603 DoCheck(OverLimitNumBlocks, 604 "ULEB128 value at offset 0xa exceeds UINT32_MAX (0x100000000)"); 605 } 606 607 // Test for the ELFObjectFile::readBBAddrMap API. 608 TEST(ELFObjectFileTest, ReadBBAddrMap) { 609 if (IsHostWindows()) 610 GTEST_SKIP(); 611 StringRef CommonYamlString(R"( 612 --- !ELF 613 FileHeader: 614 Class: ELFCLASS64 615 Data: ELFDATA2LSB 616 Type: ET_EXEC 617 Sections: 618 - Name: .llvm_bb_addr_map_1 619 Type: SHT_LLVM_BB_ADDR_MAP 620 Link: 1 621 Entries: 622 - Version: 2 623 Address: 0x11111 624 BBEntries: 625 - ID: 1 626 AddressOffset: 0x0 627 Size: 0x1 628 Metadata: 0x2 629 - Name: .llvm_bb_addr_map_2 630 Type: SHT_LLVM_BB_ADDR_MAP 631 Link: 1 632 Entries: 633 - Version: 2 634 Address: 0x22222 635 BBEntries: 636 - ID: 2 637 AddressOffset: 0x0 638 Size: 0x2 639 Metadata: 0x4 640 - Name: .llvm_bb_addr_map_3 641 Type: SHT_LLVM_BB_ADDR_MAP 642 Link: 2 643 Entries: 644 - Version: 1 645 Address: 0x33333 646 BBEntries: 647 - ID: 0 648 AddressOffset: 0x0 649 Size: 0x3 650 Metadata: 0x6 651 - Name: .llvm_bb_addr_map_4 652 Type: SHT_LLVM_BB_ADDR_MAP_V0 653 # Link: 0 (by default, can be overriden) 654 Entries: 655 - Version: 0 656 Address: 0x44444 657 BBEntries: 658 - ID: 0 659 AddressOffset: 0x0 660 Size: 0x4 661 Metadata: 0x18 662 )"); 663 664 BBAddrMap E1 = {0x11111, {{1, 0x0, 0x1, {false, true, false, false, false}}}}; 665 BBAddrMap E2 = {0x22222, {{2, 0x0, 0x2, {false, false, true, false, false}}}}; 666 BBAddrMap E3 = {0x33333, {{0, 0x0, 0x3, {false, true, true, false, false}}}}; 667 BBAddrMap E4 = {0x44444, {{0, 0x0, 0x4, {false, false, false, true, true}}}}; 668 669 std::vector<BBAddrMap> Section0BBAddrMaps = {E4}; 670 std::vector<BBAddrMap> Section1BBAddrMaps = {E3}; 671 std::vector<BBAddrMap> Section2BBAddrMaps = {E1, E2}; 672 std::vector<BBAddrMap> AllBBAddrMaps = {E1, E2, E3, E4}; 673 674 auto DoCheckSucceeds = [&](StringRef YamlString, 675 std::optional<unsigned> TextSectionIndex, 676 std::vector<BBAddrMap> ExpectedResult) { 677 SmallString<0> Storage; 678 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = 679 toBinary<ELF64LE>(Storage, YamlString); 680 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 681 682 Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr = 683 ElfOrErr->getELFFile().getSection(1); 684 ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded()); 685 auto BBAddrMaps = ElfOrErr->readBBAddrMap(TextSectionIndex); 686 EXPECT_THAT_EXPECTED(BBAddrMaps, Succeeded()); 687 EXPECT_EQ(*BBAddrMaps, ExpectedResult); 688 }; 689 690 auto DoCheckFails = [&](StringRef YamlString, 691 std::optional<unsigned> TextSectionIndex, 692 const char *ErrMsg) { 693 SmallString<0> Storage; 694 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = 695 toBinary<ELF64LE>(Storage, YamlString); 696 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 697 698 Expected<const typename ELF64LE::Shdr *> BBAddrMapSecOrErr = 699 ElfOrErr->getELFFile().getSection(1); 700 ASSERT_THAT_EXPECTED(BBAddrMapSecOrErr, Succeeded()); 701 EXPECT_THAT_ERROR(ElfOrErr->readBBAddrMap(TextSectionIndex).takeError(), 702 FailedWithMessage(ErrMsg)); 703 }; 704 705 // Check that we can retrieve the data in the normal case. 706 DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/std::nullopt, 707 AllBBAddrMaps); 708 DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/0, Section0BBAddrMaps); 709 DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/2, Section1BBAddrMaps); 710 DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/1, Section2BBAddrMaps); 711 // Check that when no bb-address-map section is found for a text section, 712 // we return an empty result. 713 DoCheckSucceeds(CommonYamlString, /*TextSectionIndex=*/3, {}); 714 715 // Check that we detect when a bb-addr-map section is linked to an invalid 716 // (not present) section. 717 SmallString<128> InvalidLinkedYamlString(CommonYamlString); 718 InvalidLinkedYamlString += R"( 719 Link: 10 720 )"; 721 722 DoCheckFails(InvalidLinkedYamlString, /*TextSectionIndex=*/4, 723 "unable to get the linked-to section for " 724 "SHT_LLVM_BB_ADDR_MAP_V0 section with index 4: invalid section " 725 "index: 10"); 726 // Linked sections are not checked when we don't target a specific text 727 // section. 728 DoCheckSucceeds(InvalidLinkedYamlString, /*TextSectionIndex=*/std::nullopt, 729 AllBBAddrMaps); 730 731 // Check that we can detect when bb-address-map decoding fails. 732 SmallString<128> TruncatedYamlString(CommonYamlString); 733 TruncatedYamlString += R"( 734 ShSize: 0x8 735 )"; 736 737 DoCheckFails(TruncatedYamlString, /*TextSectionIndex=*/std::nullopt, 738 "unable to read SHT_LLVM_BB_ADDR_MAP_V0 section with index 4: " 739 "unable to decode LEB128 at offset 0x00000008: malformed " 740 "uleb128, extends past end"); 741 // Check that we can read the other section's bb-address-maps which are 742 // valid. 743 DoCheckSucceeds(TruncatedYamlString, /*TextSectionIndex=*/2, 744 Section1BBAddrMaps); 745 } 746 747 // Test for ObjectFile::getRelocatedSection: check that it returns a relocated 748 // section for executable and relocatable files. 749 TEST(ELFObjectFileTest, ExecutableWithRelocs) { 750 StringRef HeaderString(R"( 751 --- !ELF 752 FileHeader: 753 Class: ELFCLASS64 754 Data: ELFDATA2LSB 755 )"); 756 StringRef ContentsString(R"( 757 Sections: 758 - Name: .text 759 Type: SHT_PROGBITS 760 Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 761 - Name: .rela.text 762 Type: SHT_RELA 763 Flags: [ SHF_INFO_LINK ] 764 Info: .text 765 )"); 766 767 auto DoCheck = [&](StringRef YamlString) { 768 SmallString<0> Storage; 769 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = 770 toBinary<ELF64LE>(Storage, YamlString); 771 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 772 const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr; 773 774 bool FoundRela; 775 776 for (SectionRef Sec : Obj.sections()) { 777 Expected<StringRef> SecNameOrErr = Sec.getName(); 778 ASSERT_THAT_EXPECTED(SecNameOrErr, Succeeded()); 779 StringRef SecName = *SecNameOrErr; 780 if (SecName != ".rela.text") 781 continue; 782 FoundRela = true; 783 Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection(); 784 ASSERT_THAT_EXPECTED(RelSecOrErr, Succeeded()); 785 section_iterator RelSec = *RelSecOrErr; 786 ASSERT_NE(RelSec, Obj.section_end()); 787 Expected<StringRef> TextSecNameOrErr = RelSec->getName(); 788 ASSERT_THAT_EXPECTED(TextSecNameOrErr, Succeeded()); 789 StringRef TextSecName = *TextSecNameOrErr; 790 EXPECT_EQ(TextSecName, ".text"); 791 } 792 ASSERT_TRUE(FoundRela); 793 }; 794 795 // Check ET_EXEC file (`ld --emit-relocs` use-case). 796 SmallString<128> ExecFileYamlString(HeaderString); 797 ExecFileYamlString += R"( 798 Type: ET_EXEC 799 )"; 800 ExecFileYamlString += ContentsString; 801 DoCheck(ExecFileYamlString); 802 803 // Check ET_REL file. 804 SmallString<128> RelocatableFileYamlString(HeaderString); 805 RelocatableFileYamlString += R"( 806 Type: ET_REL 807 )"; 808 RelocatableFileYamlString += ContentsString; 809 DoCheck(RelocatableFileYamlString); 810 } 811 812 TEST(ELFObjectFileTest, GetSectionAndRelocations) { 813 StringRef HeaderString(R"( 814 --- !ELF 815 FileHeader: 816 Class: ELFCLASS64 817 Data: ELFDATA2LSB 818 Type: ET_EXEC 819 )"); 820 821 using Elf_Shdr = Elf_Shdr_Impl<ELF64LE>; 822 823 auto DoCheckSucceeds = [&](StringRef ContentsString, 824 std::function<Expected<bool>(const Elf_Shdr &)> 825 Matcher) { 826 SmallString<0> Storage; 827 SmallString<128> FullYamlString(HeaderString); 828 FullYamlString += ContentsString; 829 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = 830 toBinary<ELF64LE>(Storage, FullYamlString); 831 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 832 833 Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr = 834 ElfOrErr->getELFFile().getSectionAndRelocations(Matcher); 835 ASSERT_THAT_EXPECTED(SecToRelocMapOrErr, Succeeded()); 836 837 // Basic verification to make sure we have the correct section types. 838 for (auto const &[Sec, RelaSec] : *SecToRelocMapOrErr) { 839 ASSERT_EQ(Sec->sh_type, ELF::SHT_PROGBITS); 840 ASSERT_EQ(RelaSec->sh_type, ELF::SHT_RELA); 841 } 842 }; 843 844 auto DoCheckFails = [&](StringRef ContentsString, 845 std::function<Expected<bool>(const Elf_Shdr &)> 846 Matcher, 847 const char *ErrorMessage) { 848 SmallString<0> Storage; 849 SmallString<128> FullYamlString(HeaderString); 850 FullYamlString += ContentsString; 851 Expected<ELFObjectFile<ELF64LE>> ElfOrErr = 852 toBinary<ELF64LE>(Storage, FullYamlString); 853 ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); 854 855 Expected<MapVector<const Elf_Shdr *, const Elf_Shdr *>> SecToRelocMapOrErr = 856 ElfOrErr->getELFFile().getSectionAndRelocations(Matcher); 857 ASSERT_THAT_ERROR(SecToRelocMapOrErr.takeError(), 858 FailedWithMessage(ErrorMessage)); 859 }; 860 861 auto DefaultMatcher = [](const Elf_Shdr &Sec) -> bool { 862 return Sec.sh_type == ELF::SHT_PROGBITS; 863 }; 864 865 StringRef TwoTextSections = R"( 866 Sections: 867 - Name: .text 868 Type: SHT_PROGBITS 869 Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 870 - Name: .rela.text 871 Type: SHT_RELA 872 Flags: [ SHF_INFO_LINK ] 873 Info: .text 874 - Name: .text2 875 Type: SHT_PROGBITS 876 Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 877 - Name: .rela.text2 878 Type: SHT_RELA 879 Flags: [ SHF_INFO_LINK ] 880 Info: .text2 881 )"; 882 DoCheckSucceeds(TwoTextSections, DefaultMatcher); 883 884 StringRef OneTextSection = R"( 885 Sections: 886 - Name: .text 887 Type: SHT_PROGBITS 888 Flags: [ SHF_ALLOC, SHF_EXECINSTR ] 889 )"; 890 891 auto ErroringMatcher = [](const Elf_Shdr &Sec) -> Expected<bool> { 892 if(Sec.sh_type == ELF::SHT_PROGBITS) 893 return createError("This was supposed to fail."); 894 return false; 895 }; 896 897 DoCheckFails(OneTextSection, ErroringMatcher, 898 "This was supposed to fail."); 899 900 StringRef MissingRelocatableContent = R"( 901 Sections: 902 - Name: .rela.text 903 Type: SHT_RELA 904 Flags: [ SHF_INFO_LINK ] 905 Info: 0xFF 906 )"; 907 908 DoCheckFails(MissingRelocatableContent, DefaultMatcher, 909 "SHT_RELA section with index 1: failed to get a " 910 "relocated section: invalid section index: 255"); 911 } 912