[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