[llvm] 8ec73e9 - [ELF] getRelocatedSection: remove the check for ET_REL object file
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 7 13:17:07 PDT 2021
Author: Amir Ayupov
Date: 2021-06-07T13:17:00-07:00
New Revision: 8ec73e96b72d04787ed606cfbb62a7a2a05b3711
URL: https://github.com/llvm/llvm-project/commit/8ec73e96b72d04787ed606cfbb62a7a2a05b3711
DIFF: https://github.com/llvm/llvm-project/commit/8ec73e96b72d04787ed606cfbb62a7a2a05b3711.diff
LOG: [ELF] getRelocatedSection: remove the check for ET_REL object file
getRelocatedSection interface should not check that the object file is
relocatable, as executable files may have relocations preserved with
`--emit-relocs` linker flag. The relocations are useful in context of post-link
binary analysis for function reference identification. For example, BOLT relies
on relocations to perform function reordering.
Reviewed By: MaskRay, jhenderson
Differential Revision: https://reviews.llvm.org/D102296
Added:
Modified:
llvm/include/llvm/Object/ELFObjectFile.h
llvm/include/llvm/Object/ObjectFile.h
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/Object/XCOFFObjectFile.cpp
llvm/unittests/Object/ELFObjectFileTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 97bc076c09c8..c87a09f86fae 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -975,9 +975,6 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
template <class ELFT>
Expected<section_iterator>
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
- if (EF.getHeader().e_type != ELF::ET_REL)
- return section_end();
-
const Elf_Shdr *EShdr = getSection(Sec);
uintX_t Type = EShdr->sh_type;
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
diff --git a/llvm/include/llvm/Object/ObjectFile.h b/llvm/include/llvm/Object/ObjectFile.h
index c3f5fd18dba6..267fe3046738 100644
--- a/llvm/include/llvm/Object/ObjectFile.h
+++ b/llvm/include/llvm/Object/ObjectFile.h
@@ -132,6 +132,9 @@ class SectionRef {
iterator_range<relocation_iterator> relocations() const {
return make_range(relocation_begin(), relocation_end());
}
+
+ /// Returns the related section if this section contains relocations. The
+ /// returned section may or may not have applied its relocations.
Expected<section_iterator> getRelocatedSection() const;
DataRefImpl getRawDataRefImpl() const;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index efdf91597064..4e1cafeb2126 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1687,7 +1687,8 @@ class DWARFObjInMemory final : public DWARFObject {
// Try to obtain an already relocated version of this section.
// Else use the unrelocated section from the object file. We'll have to
// apply relocations ourselves later.
- section_iterator RelocatedSection = *SecOrErr;
+ section_iterator RelocatedSection =
+ Obj.isRelocatableObject() ? *SecOrErr : Obj.section_end();
if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
Expected<StringRef> E = Section.getContents();
if (E)
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 86815539a033..6e54e4ac7982 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -440,7 +440,7 @@ SubtargetFeatures XCOFFObjectFile::getFeatures() const {
bool XCOFFObjectFile::isRelocatableObject() const {
if (is64Bit())
- report_fatal_error("64-bit support not implemented yet");
+ return !(fileHeader64()->Flags & NoRelMask);
return !(fileHeader32()->Flags & NoRelMask);
}
diff --git a/llvm/unittests/Object/ELFObjectFileTest.cpp b/llvm/unittests/Object/ELFObjectFileTest.cpp
index bf59d4aa705b..246406ef6e43 100644
--- a/llvm/unittests/Object/ELFObjectFileTest.cpp
+++ b/llvm/unittests/Object/ELFObjectFileTest.cpp
@@ -590,3 +590,68 @@ TEST(ELFObjectFileTest, InvalidBBAddrMap) {
DoCheck(OverLimitNumBlocks,
"ULEB128 value at offset 0x8 exceeds UINT32_MAX (0x100000000)");
}
+
+// Test for ObjectFile::getRelocatedSection: check that it returns a relocated
+// section for executable and relocatable files.
+TEST(ELFObjectFileTest, ExecutableWithRelocs) {
+ StringRef HeaderString(R"(
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+)");
+ StringRef ContentsString(R"(
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ - Name: .rela.text
+ Type: SHT_RELA
+ Flags: [ SHF_INFO_LINK ]
+ Info: .text
+)");
+
+ auto DoCheck = [&](StringRef YamlString) {
+ SmallString<0> Storage;
+ Expected<ELFObjectFile<ELF64LE>> ElfOrErr =
+ toBinary<ELF64LE>(Storage, YamlString);
+ ASSERT_THAT_EXPECTED(ElfOrErr, Succeeded());
+ const ELFObjectFile<ELF64LE> &Obj = *ElfOrErr;
+
+ bool FoundRela;
+
+ for (SectionRef Sec : Obj.sections()) {
+ Expected<StringRef> SecNameOrErr = Sec.getName();
+ ASSERT_THAT_EXPECTED(SecNameOrErr, Succeeded());
+ StringRef SecName = *SecNameOrErr;
+ if (SecName != ".rela.text")
+ continue;
+ FoundRela = true;
+ Expected<section_iterator> RelSecOrErr = Sec.getRelocatedSection();
+ ASSERT_THAT_EXPECTED(RelSecOrErr, Succeeded());
+ section_iterator RelSec = *RelSecOrErr;
+ ASSERT_NE(RelSec, Obj.section_end());
+ Expected<StringRef> TextSecNameOrErr = RelSec->getName();
+ ASSERT_THAT_EXPECTED(TextSecNameOrErr, Succeeded());
+ StringRef TextSecName = *TextSecNameOrErr;
+ EXPECT_EQ(TextSecName, ".text");
+ }
+ ASSERT_TRUE(FoundRela);
+ };
+
+ // Check ET_EXEC file (`ld --emit-relocs` use-case).
+ SmallString<128> ExecFileYamlString(HeaderString);
+ ExecFileYamlString += R"(
+ Type: ET_EXEC
+)";
+ ExecFileYamlString += ContentsString;
+ DoCheck(ExecFileYamlString);
+
+ // Check ET_REL file.
+ SmallString<128> RelocatableFileYamlString(HeaderString);
+ RelocatableFileYamlString += R"(
+ Type: ET_REL
+)";
+ RelocatableFileYamlString += ContentsString;
+ DoCheck(RelocatableFileYamlString);
+}
More information about the llvm-commits
mailing list