diff options
Diffstat (limited to 'llvm/unittests/Object/ELFObjectFileTest.cpp')
-rw-r--r-- | llvm/unittests/Object/ELFObjectFileTest.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp index 30be24c..aabb07c 100644 --- a/llvm/unittests/Object/ELFObjectFileTest.cpp +++ b/llvm/unittests/Object/ELFObjectFileTest.cpp @@ -397,3 +397,75 @@ ProgramHeaders: EXPECT_EQ((const char *)Data - Buf.getBufferStart(), 0x4000); EXPECT_EQ(Data[0], 0x99); } + +// This is a test for API that is related to symbols. +// We check that errors are properly reported here. +TEST(ELFObjectFileTest, InvalidSymbolTest) { + SmallString<0> Storage; + Expected<ELFObjectFile<ELF64LE>> ElfOrErr = toBinary<ELF64LE>(Storage, R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB +)"); + + ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded()); + const ELFFile<ELF64LE> &Elf = ElfOrErr->getELFFile(); + const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr; + + Expected<const typename ELF64LE::Shdr *> SymtabSecOrErr = Elf.getSection(1); + ASSERT_THAT_EXPECTED(SymtabSecOrErr, Succeeded()); + ASSERT_EQ((*SymtabSecOrErr)->sh_type, ELF::SHT_SYMTAB); + + // We create a symbol with an index that is too large to exist in the object. + constexpr unsigned BrokenSymIndex = 0xFFFFFFFF; + ELFSymbolRef BrokenSym = Obj.toSymbolRef(*SymtabSecOrErr, BrokenSymIndex); + + const char *ErrMsg = "unable to access section [index 1] data at " + "0x1800000028: offset goes past the end of file"; + // 1) Check the behavior of ELFObjectFile<ELFT>::getSymbolName(). + // SymbolRef::getName() calls it internally. We can't test it directly, + // because it is protected. + EXPECT_THAT_ERROR(BrokenSym.getName().takeError(), FailedWithMessage(ErrMsg)); + + // 2) Check the behavior of ELFObjectFile<ELFT>::getSymbol(). + EXPECT_THAT_ERROR(Obj.getSymbol(BrokenSym.getRawDataRefImpl()).takeError(), + FailedWithMessage(ErrMsg)); + + // 3) Check the behavior of ELFObjectFile<ELFT>::getSymbolSection(). + // SymbolRef::getSection() calls it internally. We can't test it directly, + // because it is protected. + EXPECT_THAT_ERROR(BrokenSym.getSection().takeError(), + FailedWithMessage(ErrMsg)); + + // 4) Check the behavior of ELFObjectFile<ELFT>::getSymbolFlags(). + // SymbolRef::getFlags() calls it internally. We can't test it directly, + // because it is protected. + EXPECT_THAT_ERROR(BrokenSym.getFlags().takeError(), + FailedWithMessage(ErrMsg)); + + // 5) Check the behavior of ELFObjectFile<ELFT>::getSymbolType(). + // SymbolRef::getType() calls it internally. We can't test it directly, + // because it is protected. + EXPECT_THAT_ERROR(BrokenSym.getType().takeError(), FailedWithMessage(ErrMsg)); + + // 6) Check the behavior of ELFObjectFile<ELFT>::getSymbolAddress(). + // SymbolRef::getAddress() calls it internally. We can't test it directly, + // because it is protected. + EXPECT_THAT_ERROR(BrokenSym.getAddress().takeError(), + FailedWithMessage(ErrMsg)); + + // Finally, check the `ELFFile<ELFT>::getEntry` API. This is an underlying + // method that generates errors for all cases above. + EXPECT_THAT_EXPECTED(Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, 0), + Succeeded()); + EXPECT_THAT_ERROR( + Elf.getEntry<typename ELF64LE::Sym>(**SymtabSecOrErr, BrokenSymIndex) + .takeError(), + FailedWithMessage(ErrMsg)); +} |