[lld] 288082d - [ELF] Move SHT_REL/SHT_RELA handling from createInputSection to initializeSections

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 18 23:31:56 PST 2022


Author: Fangrui Song
Date: 2022-01-18T23:31:51-08:00
New Revision: 288082d45d6124a7f818f6a44feec7780fbc4c52

URL: https://github.com/llvm/llvm-project/commit/288082d45d6124a7f818f6a44feec7780fbc4c52
DIFF: https://github.com/llvm/llvm-project/commit/288082d45d6124a7f818f6a44feec7780fbc4c52.diff

LOG: [ELF] Move SHT_REL/SHT_RELA handling from createInputSection to initializeSections

This simplifies the code a bit. While here,

* change the `multiple relocation sections` diagnostic from `fatal` to `error` and include the relocated section name.
* drop less useful name from `getRelocTarget`. Without -r/--emit-relocs we don't need to get SHT_REL/SHT_RELA names.

Added: 
    

Modified: 
    lld/ELF/InputFiles.cpp
    lld/ELF/InputFiles.h
    lld/test/ELF/invalid/bad-reloc-target.test
    lld/test/ELF/invalid/multiple-relocations-sections.test

Removed: 
    


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index bad9cc169cd1f..64e64ff63b506 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -643,12 +643,52 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
       continue;
     const Elf_Shdr &sec = objSections[i];
 
-    if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA)
-      this->sections[i] = createInputSection(i, sec, shstrtab);
+    if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA) {
+      // Find a relocation target section and associate this section with that.
+      // Target may have been discarded if it is in a 
diff erent section group
+      // and the group is discarded, even though it's a violation of the spec.
+      // We handle that situation gracefully by discarding dangling relocation
+      // sections.
+      const uint32_t info = sec.sh_info;
+      InputSectionBase *s = getRelocTarget(i, sec, info);
+      if (!s)
+        continue;
+
+      // ELF spec allows mergeable sections with relocations, but they are rare,
+      // and it is in practice hard to merge such sections by contents, because
+      // applying relocations at end of linking changes section contents. So, we
+      // simply handle such sections as non-mergeable ones. Degrading like this
+      // is acceptable because section merging is optional.
+      if (auto *ms = dyn_cast<MergeInputSection>(s)) {
+        s = make<InputSection>(ms->file, ms->flags, ms->type, ms->alignment,
+                               ms->data(), ms->name);
+        sections[info] = s;
+      }
+
+      if (s->relSecIdx != 0)
+        error(
+            toString(s) +
+            ": multiple relocation sections to one section are not supported");
+      s->relSecIdx = i;
+
+      // Relocation sections are usually removed from the output, so return
+      // `nullptr` for the normal case. However, if -r or --emit-relocs is
+      // specified, we need to copy them to the output. (Some post link analysis
+      // tools specify --emit-relocs to obtain the information.)
+      if (config->copyRelocs) {
+        auto *isec = make<InputSection>(
+            *this, sec, check(obj.getSectionName(sec, shstrtab)));
+        // If the relocated section is discarded (due to /DISCARD/ or
+        // --gc-sections), the relocation section should be discarded as well.
+        s->dependentSections.push_back(isec);
+        sections[i] = isec;
+      }
+      continue;
+    }
 
     // A SHF_LINK_ORDER section with sh_link=0 is handled as if it did not have
     // the flag.
-    if (!(sec.sh_flags & SHF_LINK_ORDER) || !sec.sh_link)
+    if (!sec.sh_link || !(sec.sh_flags & SHF_LINK_ORDER))
       continue;
 
     InputSectionBase *linkSec = nullptr;
@@ -828,9 +868,9 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
 }
 
 template <class ELFT>
-InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, StringRef name,
-                                                const Elf_Shdr &sec) {
-  uint32_t info = sec.sh_info;
+InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx,
+                                                const Elf_Shdr &sec,
+                                                uint32_t info) {
   if (info < this->sections.size()) {
     InputSectionBase *target = this->sections[info];
 
@@ -844,18 +884,11 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx, StringRef name,
       return target;
   }
 
-  error(toString(this) + Twine(": relocation section ") + name + " (index " +
-        Twine(idx) + ") has invalid sh_info (" + Twine(info) + ")");
+  error(toString(this) + Twine(": relocation section (index ") + Twine(idx) +
+        ") has invalid sh_info (" + Twine(info) + ")");
   return nullptr;
 }
 
-// Create a regular InputSection class that has the same contents
-// as a given section.
-static InputSection *toRegularSection(MergeInputSection *sec) {
-  return make<InputSection>(sec->file, sec->flags, sec->type, sec->alignment,
-                            sec->data(), sec->name);
-}
-
 template <class ELFT>
 InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
                                                     const Elf_Shdr &sec,
@@ -908,10 +941,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
     }
   }
 
-  switch (sec.sh_type) {
-  case SHT_LLVM_DEPENDENT_LIBRARIES: {
-    if (config->relocatable)
-      break;
+  if (sec.sh_type == SHT_LLVM_DEPENDENT_LIBRARIES && !config->relocatable) {
     ArrayRef<char> data =
         CHECK(this->getObj().template getSectionContentsAsArray<char>(sec), this);
     if (!data.empty() && data.back() != '\0') {
@@ -927,45 +957,6 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
     }
     return &InputSection::discarded;
   }
-  case SHT_RELA:
-  case SHT_REL: {
-    // Find a relocation target section and associate this section with that.
-    // Target may have been discarded if it is in a 
diff erent section group
-    // and the group is discarded, even though it's a violation of the
-    // spec. We handle that situation gracefully by discarding dangling
-    // relocation sections.
-    InputSectionBase *target = getRelocTarget(idx, name, sec);
-    if (!target)
-      return nullptr;
-
-    // ELF spec allows mergeable sections with relocations, but they are
-    // rare, and it is in practice hard to merge such sections by contents,
-    // because applying relocations at end of linking changes section
-    // contents. So, we simply handle such sections as non-mergeable ones.
-    // Degrading like this is acceptable because section merging is optional.
-    if (auto *ms = dyn_cast<MergeInputSection>(target)) {
-      target = toRegularSection(ms);
-      this->sections[sec.sh_info] = target;
-    }
-
-    if (target->relSecIdx != 0)
-      fatal(toString(this) +
-            ": multiple relocation sections to one section are not supported");
-    target->relSecIdx = idx;
-
-    // Relocation sections are usually removed from the output, so return
-    // `nullptr` for the normal case. However, if -r or --emit-relocs is
-    // specified, we need to copy them to the output. (Some post link analysis
-    // tools specify --emit-relocs to obtain the information.)
-    if (!config->copyRelocs)
-      return nullptr;
-    InputSection *relocSec = make<InputSection>(*this, sec, name);
-    // If the relocated section is discarded (due to /DISCARD/ or
-    // --gc-sections), the relocation section should be discarded as well.
-    target->dependentSections.push_back(relocSec);
-    return relocSec;
-  }
-  }
 
   if (name.startswith(".n")) {
     // The GNU linker uses .note.GNU-stack section as a marker indicating

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 1084cf94313b5..6febea3f437d4 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -286,8 +286,8 @@ template <class ELFT> class ObjFile : public ELFFileBase {
   void initializeSymbols();
   void initializeJustSymbols();
 
-  InputSectionBase *getRelocTarget(uint32_t idx, StringRef name,
-                                   const Elf_Shdr &sec);
+  InputSectionBase *getRelocTarget(uint32_t idx, const Elf_Shdr &sec,
+                                   uint32_t info);
   InputSectionBase *createInputSection(uint32_t idx, const Elf_Shdr &sec,
                                        StringRef shstrtab);
 

diff  --git a/lld/test/ELF/invalid/bad-reloc-target.test b/lld/test/ELF/invalid/bad-reloc-target.test
index 6177910d881ef..88b4cdf96779f 100644
--- a/lld/test/ELF/invalid/bad-reloc-target.test
+++ b/lld/test/ELF/invalid/bad-reloc-target.test
@@ -1,6 +1,6 @@
 # RUN: yaml2obj --docnum=1 %s -o %t1.o
 # RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck %s
-# CHECK: error: {{.*}}.o: relocation section .rela.text (index 2) has invalid sh_info (0)
+# CHECK: error: {{.*}}.o: relocation section (index 2) has invalid sh_info (0)
 
 --- !ELF
 FileHeader:
@@ -25,7 +25,7 @@ Symbols:
 
 # RUN: yaml2obj --docnum=2 %s -o %t2.o
 # RUN: not ld.lld %t2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2
-# ERR2: error: {{.*}}.o: relocation section .rela.text (index 2) has invalid sh_info (99)
+# ERR2: error: {{.*}}.o: relocation section (index 2) has invalid sh_info (99)
 
 --- !ELF
 FileHeader:

diff  --git a/lld/test/ELF/invalid/multiple-relocations-sections.test b/lld/test/ELF/invalid/multiple-relocations-sections.test
index 3f8f663073756..673113f026917 100644
--- a/lld/test/ELF/invalid/multiple-relocations-sections.test
+++ b/lld/test/ELF/invalid/multiple-relocations-sections.test
@@ -1,6 +1,6 @@
 # RUN: yaml2obj %s -o %t1.o
 # RUN: not ld.lld %t1.o -o /dev/null 2>&1 | FileCheck %s
-# CHECK: error: {{.*}}1.o: multiple relocation sections to one section are not supported
+# CHECK: error: {{.*}}1.o:(.text): multiple relocation sections to one section are not supported
 
 ## The file has two relocation sections referring to a single target section.
 ## Multiple relocation sections to one section are not supported, check we report this case.


        


More information about the llvm-commits mailing list