[lld] r325328 - Ensure that Elf_Rel addends are always written for dynamic relocations

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 16 02:01:18 PST 2018


Author: arichardson
Date: Fri Feb 16 02:01:17 2018
New Revision: 325328

URL: http://llvm.org/viewvc/llvm-project?rev=325328&view=rev
Log:
Ensure that Elf_Rel addends are always written for dynamic relocations

Summary:
This follows up on r321889 where writing of Elf_Rel addends was partially
moved to RelocationBaseSection. This patch ensures that the addends are
always written to the output section when a input section uses RELA but the
output is REL.

Differential Revision: https://reviews.llvm.org/D42843

Added:
    lld/trunk/test/ELF/rel-addend-with-rela-input.s
Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Relocations.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=325328&r1=325327&r2=325328&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Feb 16 02:01:17 2018
@@ -842,6 +842,11 @@ static void setConfigs(opt::InputArgList
       (Config->Is64 || IsX32 || Machine == EM_PPC) && Machine != EM_MIPS;
   Config->Pic = Config->Pie || Config->Shared;
   Config->Wordsize = Config->Is64 ? 8 : 4;
+  // If the output uses REL relocations we must store the dynamic relocation
+  // addends to the output sections. We also store addends for RELA relocations
+  // if --apply-dynamic-relocs is used.
+  // We default to not writing the addends when using RELA relocations since
+  // any standard conforming tool can find it in r_addend.
   Config->WriteAddends = Args.hasFlag(OPT_apply_dynamic_relocs,
                                       OPT_no_apply_dynamic_relocs, false) ||
                          !Config->IsRela;

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=325328&r1=325327&r2=325328&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Feb 16 02:01:17 2018
@@ -474,6 +474,8 @@ static uint64_t getRelocTargetVA(RelType
   case R_ABS:
   case R_RELAX_GOT_PC_NOPIC:
     return Sym.getVA(A);
+  case R_ADDEND:
+    return A;
   case R_ARM_SBREL:
     return Sym.getVA(A) - getARMStaticBase(Sym);
   case R_GOT:

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=325328&r1=325327&r2=325328&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Feb 16 02:01:17 2018
@@ -780,8 +780,8 @@ static RelExpr processRelocAux(InputSect
                              Addend, Expr, Type);
       return Expr;
     } else if (Target->isPicRel(Type)) {
-      InX::RelaDyn->addReloc(
-          {Target->getDynRel(Type), &Sec, Offset, false, &Sym, Addend});
+      InX::RelaDyn->addReloc(Target->getDynRel(Type), &Sec, Offset, false, &Sym,
+                             Addend, Expr, Type);
 
       // MIPS ABI turns using of GOT and dynamic relocations inside out.
       // While regular ABI uses dynamic relocations to fill up GOT entries

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=325328&r1=325327&r2=325328&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Fri Feb 16 02:01:17 2018
@@ -32,6 +32,7 @@ typedef uint32_t RelType;
 enum RelExpr {
   R_INVALID,
   R_ABS,
+  R_ADDEND,
   R_ARM_SBREL,
   R_GOT,
   R_GOTONLY_PC,

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=325328&r1=325327&r2=325328&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Feb 16 02:01:17 2018
@@ -1212,12 +1212,14 @@ void RelocationBaseSection::addReloc(Rel
                                      uint64_t OffsetInSec, bool UseSymVA,
                                      Symbol *Sym, int64_t Addend, RelExpr Expr,
                                      RelType Type) {
-  // We store the addends for dynamic relocations for both REL and RELA
-  // relocations for compatibility with GNU Linkers. There is some system
-  // software such as the Bionic dynamic linker that uses the addend prior
-  // to dynamic relocation resolution.
-  if (Config->WriteAddends && UseSymVA)
+  // Write the addends to the relocated address if required. We skip
+  // it if the written value would be zero.
+  if (Config->WriteAddends && (UseSymVA || Addend != 0)) {
+    // If UseSymVA is true we have to write the symbol address, otherwise just
+    // the addend.
+    Expr = UseSymVA ? Expr : R_ADDEND;
     InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
+  }
   addReloc({DynType, InputSec, OffsetInSec, UseSymVA, Sym, Addend});
 }
 

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=325328&r1=325327&r2=325328&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Feb 16 02:01:17 2018
@@ -363,6 +363,8 @@ public:
                         int32_t SizeDynamicTag);
   void addReloc(RelType DynType, InputSectionBase *IS, uint64_t OffsetInSec,
                 Symbol *Sym);
+  // Add a dynamic relocation that might need an addend. This takes care of
+  // writing the addend to the output section if needed.
   void addReloc(RelType DynType, InputSectionBase *InputSec,
                 uint64_t OffsetInSec, bool UseSymVA, Symbol *Sym,
                 int64_t Addend, RelExpr Expr, RelType Type);

Added: lld/trunk/test/ELF/rel-addend-with-rela-input.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/rel-addend-with-rela-input.s?rev=325328&view=auto
==============================================================================
--- lld/trunk/test/ELF/rel-addend-with-rela-input.s (added)
+++ lld/trunk/test/ELF/rel-addend-with-rela-input.s Fri Feb 16 02:01:17 2018
@@ -0,0 +1,43 @@
+# REQUIRES: mips
+# Check that we correctly write addends if the output use Elf_Rel but the input
+# uses Elf_Rela
+
+# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t-rela.o
+# RUN: llvm-readobj -h -s -section-data -relocations %t-rela.o | FileCheck -check-prefix INPUT-RELA %s
+# INPUT-RELA:  ElfHeader {
+# INPUT-RELA:     Class: 64-bit
+# INPUT-RELA:     DataEncoding: BigEndian
+# INPUT-RELA:   Section {
+# INPUT-RELA:       Name: .data
+# INPUT-RELA:       SectionData (
+# INPUT-RELA-NEXT:    0000: 00000000 00000000 ABCDEF00 12345678 |.............4Vx|
+#                              ^--- No addend here since it uses RELA
+# INPUT-RELA:     Relocations [
+# INPUT-RELA-NEXT:  Section ({{.+}}) .rela.data {
+# INPUT-RELA-NEXT:     0x0 R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE foo 0x5544
+# INPUT-RELA-NEXT:  }
+# INPUT-RELA-NEXT: ]
+
+# Previously the addend to the dynamic relocation in the .data section was not copied if
+# the input file used RELA and the output uses REL. Check that it works now:
+# RUN: ld.lld -shared -o %t.so %t-rela.o  -verbose
+# RUN: llvm-readobj -h -s -section-data -relocations %t.so | FileCheck -check-prefix RELA-TO-REL %s
+# RELA-TO-REL:  ElfHeader {
+# RELA-TO-REL:    Class: 64-bit
+# RELA-TO-REL:    DataEncoding: BigEndian
+# RELA-TO-REL:  Section {
+# RELA-TO-REL:       Name: .data
+# RELA-TO-REL:       SectionData (
+# RELA-TO-REL-NEXT:    0000: 00000000 00005544 ABCDEF00 12345678 |......UD.....4Vx|
+#                                        ^--- Addend for relocation in .rel.dyn
+# RELA-TO-REL:     Relocations [
+# RELA-TO-REL-NEXT:  Section ({{.+}}) .rel.dyn {
+# RELA-TO-REL-NEXT:     0x10000 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE foo 0x0
+# RELA-TO-REL-NEXT:  }
+# RELA-TO-REL-NEXT: ]
+
+.extern foo
+
+.data
+.quad foo + 0x5544
+.quad 0xabcdef0012345678




More information about the llvm-commits mailing list