aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests/Object/ELFObjectFileTest.cpp
diff options
context:
space:
mode:
authorGeorgii Rymar <grimar@accesssoftek.com>2020-12-15 15:45:15 +0300
committerGeorgii Rymar <grimar@accesssoftek.com>2020-12-16 13:14:23 +0300
commit407d42002904ce541f732ce4300913ef57cff232 (patch)
treeab845530cd316fa895087a054f337a13a7a983d5 /llvm/unittests/Object/ELFObjectFileTest.cpp
parent78aea98308a85c061a87952e9842bf1e6fe097d5 (diff)
downloadllvm-407d42002904ce541f732ce4300913ef57cff232.zip
llvm-407d42002904ce541f732ce4300913ef57cff232.tar.gz
llvm-407d42002904ce541f732ce4300913ef57cff232.tar.bz2
[lib/Object] - Make ELFObjectFile::getSymbol() return Expected<>.
This was requested in comments for D93209: https://reviews.llvm.org/D93209#inline-871192 D93209 fixes an issue with `ELFFile<ELFT>::getEntry`, after what `getSymbol` starts calling `report_fatal_error` for previously missed invalid cases. This patch makes it return `Expected<>` and updates callers. For few of them I had to add new `report_fatal_error` calls. But I see no way to avoid it currently. The change would affects too many places, e.g: `getSymbolBinding` and other methods are used from `ELFSymbolRef` which is used in too many places across LLVM. Differential revision: https://reviews.llvm.org/D93297
Diffstat (limited to 'llvm/unittests/Object/ELFObjectFileTest.cpp')
-rw-r--r--llvm/unittests/Object/ELFObjectFileTest.cpp72
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));
+}