[lld] af16a45 - [LLD][ELF] - Allow relocation sections to appear before their target sections.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 04:00:14 PDT 2020


Author: Georgii Rymar
Date: 2020-07-13T13:59:54+03:00
New Revision: af16a45683cccc78925e71ac5d58d6cab8447840

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

LOG: [LLD][ELF] -  Allow relocation sections to appear before their target sections.

It allows handling cases when we have SHT_REL[A] sections before target
sections in objects.

This fixes https://bugs.llvm.org/show_bug.cgi?id=46632

which says: "Normally it is not what compilers would emit. We have to support it,
because some custom tools might want to use this feature, which is not restricted by ELF gABI"

Differential revision: https://reviews.llvm.org/D83469

Added: 
    lld/test/ELF/reloc-sec-before-relocated.test

Modified: 
    lld/ELF/InputFiles.cpp

Removed: 
    lld/test/ELF/invalid/reloc-section-reordered.test


################################################################################
diff  --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index e59bf626be50..c2f1830a981b 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -632,6 +632,8 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
       break;
     case SHT_SYMTAB:
     case SHT_STRTAB:
+    case SHT_REL:
+    case SHT_RELA:
     case SHT_NULL:
       break;
     default:
@@ -639,11 +641,21 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats) {
     }
   }
 
-  // This block handles SHF_LINK_ORDER.
+  // We have a second loop. It is used to:
+  // 1) handle SHF_LINK_ORDER sections.
+  // 2) create SHT_REL[A] sections. In some cases the section header index of a
+  //    relocation section may be smaller than that of the relocated section. In
+  //    such cases, the relocation section would attempt to reference a target
+  //    section that has not yet been created. For simplicity, delay creation of
+  //    relocation sections until now.
   for (size_t i = 0, e = objSections.size(); i < e; ++i) {
     if (this->sections[i] == &InputSection::discarded)
       continue;
     const Elf_Shdr &sec = objSections[i];
+
+    if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA)
+      this->sections[i] = createInputSection(sec);
+
     if (!(sec.sh_flags & SHF_LINK_ORDER))
       continue;
 

diff  --git a/lld/test/ELF/invalid/reloc-section-reordered.test b/lld/test/ELF/invalid/reloc-section-reordered.test
deleted file mode 100644
index 91f25f61b7e6..000000000000
--- a/lld/test/ELF/invalid/reloc-section-reordered.test
+++ /dev/null
@@ -1,33 +0,0 @@
-# REQUIRES: x86
-
-# RUN: yaml2obj %s -o %t.o
-# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
-# CHECK: unsupported relocation reference
-
-## YAML below lists .rela.text before .text, we do not support it.
-
-!ELF
-FileHeader:
-  Class:           ELFCLASS64
-  Data:            ELFDATA2LSB
-  OSABI:           ELFOSABI_FREEBSD
-  Type:            ET_REL
-  Machine:         EM_X86_64
-Sections:
-  - Type:            SHT_REL
-    Name:            .rela.text
-    Link:            .symtab
-    Info:            .text
-    AddressAlign:    0x04
-    Relocations:
-      - Symbol:          .text
-        Type:            R_X86_64_NONE
-  - Type:            SHT_PROGBITS
-    Name:            .text
-    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
-    AddressAlign:    0x04
-    Content:         "FFFFFFFFFFFFFFFF"
-Symbols:
-  - Name:    .text
-    Type:    STT_SECTION
-    Section: .text

diff  --git a/lld/test/ELF/reloc-sec-before-relocated.test b/lld/test/ELF/reloc-sec-before-relocated.test
new file mode 100644
index 000000000000..a56231294a0c
--- /dev/null
+++ b/lld/test/ELF/reloc-sec-before-relocated.test
@@ -0,0 +1,38 @@
+## If the section header index of a SHT_REL[A] section is smaller than the
+## section header index of the relocated section, we should handle it properly.
+## Normally it is not what compilers would emit, but some custom tools might
+## want to use this feature, which is not restricted by ELF gABI.
+## GNU ld supports this as well.
+
+# RUN: yaml2obj %s -DTYPE=SHT_RELA -o %t1.o
+# RUN: ld.lld -shared %t1.o -o %t1
+# RUN: llvm-readelf --relocs %t1 | FileCheck %s
+
+# RUN: yaml2obj %s -DTYPE=SHT_REL -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2
+# RUN: llvm-readelf --relocs %t2 | FileCheck %s
+
+## Check we handle the relocation properly.
+# CHECK:      Relocation section '.rela.dyn' at offset 0x238 contains 1 entries:
+# CHECK-NEXT:     Offset             Info             Type    Symbol's Value  Symbol's Name + Addend
+# CHECK-NEXT: 00000000000022f0  0000000100000001 R_X86_64_64 0000000000000000 foo + 0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:  .relx.data
+    Type:  [[TYPE]]
+    Info:  .data
+    Relocations:
+      - Symbol: foo
+        Type:   R_X86_64_64
+  - Name:  .data
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC, SHF_WRITE ]
+Symbols:
+  - Name:    foo
+    Binding: STB_GLOBAL


        


More information about the llvm-commits mailing list