[lld] r324221 - [ELF] Implement --[no-]apply-dynamic-relocs option.

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 5 02:15:08 PST 2018


Author: psmith
Date: Mon Feb  5 02:15:08 2018
New Revision: 324221

URL: http://llvm.org/viewvc/llvm-project?rev=324221&view=rev
Log:
[ELF] Implement --[no-]apply-dynamic-relocs option.

When resolving dynamic RELA relocations the addend is taken from the
relocation and not the place being relocated. Accordingly lld does not
write the addend field to the place like it would for a REL relocation.
Unfortunately there is some system software, in particlar dynamic loaders
such as Bionic's linker64 that use the value of the place prior to
relocation to find the offset that they have been loaded at. Both gold
and bfd control this behavior with the --[no-]apply-dynamic-relocs option.
This change implements the option and defaults it to true for compatibility
with gold and bfd.

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


Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/test/ELF/dynamic-got-rela.s
    lld/trunk/test/ELF/relocation-non-alloc.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=324221&r1=324220&r2=324221&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Mon Feb  5 02:15:08 2018
@@ -106,6 +106,7 @@ struct Configuration {
   std::vector<uint8_t> BuildIdVector;
   bool AllowMultipleDefinition;
   bool AndroidPackDynRelocs = false;
+  bool ApplyDynamicRelocs;
   bool ARMHasBlx = false;
   bool ARMHasMovtMovw = false;
   bool ARMJ1J2BranchEncoding = false;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=324221&r1=324220&r2=324221&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Feb  5 02:15:08 2018
@@ -597,6 +597,8 @@ static int parseInt(StringRef S, opt::Ar
 void LinkerDriver::readConfigs(opt::InputArgList &Args) {
   Config->AllowMultipleDefinition =
       Args.hasArg(OPT_allow_multiple_definition) || hasZOption(Args, "muldefs");
+  Config->ApplyDynamicRelocs = Args.hasFlag(OPT_apply_dynamic_relocs,
+                                            OPT_no_apply_dynamic_relocs, true);
   Config->AuxiliaryList = args::getStrings(Args, OPT_auxiliary);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=324221&r1=324220&r2=324221&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Mon Feb  5 02:15:08 2018
@@ -57,6 +57,10 @@ defm Ttext: Eq<"Ttext">,
 def allow_multiple_definition: F<"allow-multiple-definition">,
   HelpText<"Allow multiple definitions">;
 
+defm apply_dynamic_relocs: B<"apply-dynamic-relocs",
+    "Apply dynamic relocations to place",
+    "Do not apply dynamic relocations to place">;
+
 defm as_needed: B<"as-needed",
     "Only set DT_NEEDED for shared libraries if used",
     "Always set DT_NEEDED for shared libraries">;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=324221&r1=324220&r2=324221&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Feb  5 02:15:08 2018
@@ -1207,10 +1207,11 @@ void RelocationBaseSection::addReloc(uin
                                      uint64_t OffsetInSec, bool UseSymVA,
                                      Symbol *Sym, int64_t Addend, RelExpr Expr,
                                      RelType Type) {
-  // REL type relocations don't have addend fields unlike RELAs, and
-  // their addends are stored to the section to which they are applied.
-  // So, store addends if we need to.
-  if (!Config->IsRela && UseSymVA)
+  // 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->IsRela || Config->ApplyDynamicRelocs) && UseSymVA)
     InputSec->Relocations.push_back({Expr, Type, OffsetInSec, Addend, Sym});
   addReloc({DynType, InputSec, OffsetInSec, UseSymVA, Sym, Addend});
 }

Modified: lld/trunk/test/ELF/dynamic-got-rela.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/dynamic-got-rela.s?rev=324221&r1=324220&r2=324221&view=diff
==============================================================================
--- lld/trunk/test/ELF/dynamic-got-rela.s (original)
+++ lld/trunk/test/ELF/dynamic-got-rela.s Mon Feb  5 02:15:08 2018
@@ -1,24 +1,43 @@
 // REQUIRES: x86
 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
 // RUN: ld.lld %t.o -o %t.so -shared
-// RUN: llvm-readobj -r -s -l -section-data %t.so | FileCheck %s
+// RUN: llvm-readobj -r -s -l -section-data %t.so | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s
+// RUN: ld.lld %t.o -o %t2.so -shared --no-apply-dynamic-relocs
+// RUN: llvm-readobj -r -s -l -section-data %t2.so | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
 
-// CHECK:      Name: .got
-// CHECK-NEXT: Type: SHT_PROGBITS
-// CHECK-NEXT: Flags [
-// CHECK-NEXT:   SHF_ALLOC
-// CHECK-NEXT:   SHF_WRITE
-// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x[[GOT:.*]]
-// CHECK-NEXT: Offset:
-// CHECK-NEXT: Size:
-// CHECK-NEXT: Link:
-// CHECK-NEXT: Info:
-// CHECK-NEXT: AddressAlignment:
-// CHECK-NEXT: EntrySize:
-// CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 00000000 00000000                |
-// CHECK-NEXT: )
+// APPLYDYNREL:      Name: .got
+// APPLYDYNREL-NEXT: Type: SHT_PROGBITS
+// APPLYDYNREL-NEXT: Flags [
+// APPLYDYNREL-NEXT:   SHF_ALLOC
+// APPLYDYNREL-NEXT:   SHF_WRITE
+// APPLYDYNREL-NEXT: ]
+// APPLYDYNREL-NEXT: Address: 0x[[GOT:.*]]
+// APPLYDYNREL-NEXT: Offset:
+// APPLYDYNREL-NEXT: Size:
+// APPLYDYNREL-NEXT: Link:
+// APPLYDYNREL-NEXT: Info:
+// APPLYDYNREL-NEXT: AddressAlignment:
+// APPLYDYNREL-NEXT: EntrySize:
+// APPLYDYNREL-NEXT: SectionData (
+// APPLYDYNREL-NEXT:   0000: 00200000 00000000                |
+// APPLYDYNREL-NEXT: )
+
+// NOAPPLYDYNREL:      Name: .got
+// NOAPPLYDYNREL-NEXT: Type: SHT_PROGBITS
+// NOAPPLYDYNREL-NEXT: Flags [
+// NOAPPLYDYNREL-NEXT:   SHF_ALLOC
+// NOAPPLYDYNREL-NEXT:   SHF_WRITE
+// NOAPPLYDYNREL-NEXT: ]
+// NOAPPLYDYNREL-NEXT: Address: 0x[[GOT:.*]]
+// NOAPPLYDYNREL-NEXT: Offset:
+// NOAPPLYDYNREL-NEXT: Size:
+// NOAPPLYDYNREL-NEXT: Link:
+// NOAPPLYDYNREL-NEXT: Info:
+// NOAPPLYDYNREL-NEXT: AddressAlignment:
+// NOAPPLYDYNREL-NEXT: EntrySize:
+// NOAPPLYDYNREL-NEXT: SectionData (
+// NOAPPLYDYNREL-NEXT:   0000: 00000000 00000000                |
+// NOAPPLYDYNREL-NEXT: )
 
 // CHECK:      Relocations [
 // CHECK-NEXT:   Section ({{.*}}) .rela.dyn {

Modified: lld/trunk/test/ELF/relocation-non-alloc.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-non-alloc.s?rev=324221&r1=324220&r2=324221&view=diff
==============================================================================
--- lld/trunk/test/ELF/relocation-non-alloc.s (original)
+++ lld/trunk/test/ELF/relocation-non-alloc.s Mon Feb  5 02:15:08 2018
@@ -2,24 +2,44 @@
 
 // RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
 // RUN: ld.lld %t -o %t2 -shared
-// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck %s
+// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix APPLYDYNREL %s
 
-// CHECK:      Name: .data
-// CHECK-NEXT: Type: SHT_PROGBITS
-// CHECK-NEXT: Flags [
-// CHECK-NEXT:   SHF_ALLOC
-// CHECK-NEXT:   SHF_WRITE
-// CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x1000
-// CHECK-NEXT: Offset: 0x1000
-// CHECK-NEXT: Size: 16
-// CHECK-NEXT: Link: 0
-// CHECK-NEXT: Info: 0
-// CHECK-NEXT: AddressAlignment: 1
-// CHECK-NEXT: EntrySize: 0
-// CHECK-NEXT: SectionData (
-// CHECK-NEXT:   0000: 00000000 00000000 00000000 00000000
-// CHECK-NEXT: )
+// RUN: ld.lld %t -o %t2 -shared --no-apply-dynamic-relocs
+// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck -check-prefix CHECK -check-prefix NOAPPLYDYNREL %s
+
+// APPLYDYNREL:      Name: .data
+// APPLYDYNREL-NEXT: Type: SHT_PROGBITS
+// APPLYDYNREL-NEXT: Flags [
+// APPLYDYNREL-NEXT:   SHF_ALLOC
+// APPLYDYNREL-NEXT:   SHF_WRITE
+// APPLYDYNREL-NEXT: ]
+// APPLYDYNREL-NEXT: Address: 0x1000
+// APPLYDYNREL-NEXT: Offset: 0x1000
+// APPLYDYNREL-NEXT: Size: 16
+// APPLYDYNREL-NEXT: Link: 0
+// APPLYDYNREL-NEXT: Info: 0
+// APPLYDYNREL-NEXT: AddressAlignment: 1
+// APPLYDYNREL-NEXT: EntrySize: 0
+// APPLYDYNREL-NEXT: SectionData (
+// APPLYDYNREL-NEXT:   0000: 00100000 00000000 00000000 00000000
+// APPLYDYNREL-NEXT: )
+
+// NOAPPLYDYNREL:      Name: .data
+// NOAPPLYDYNREL-NEXT: Type: SHT_PROGBITS
+// NOAPPLYDYNREL-NEXT: Flags [
+// NOAPPLYDYNREL-NEXT:   SHF_ALLOC
+// NOAPPLYDYNREL-NEXT:   SHF_WRITE
+// NOAPPLYDYNREL-NEXT: ]
+// NOAPPLYDYNREL-NEXT: Address: 0x1000
+// NOAPPLYDYNREL-NEXT: Offset: 0x1000
+// NOAPPLYDYNREL-NEXT: Size: 16
+// NOAPPLYDYNREL-NEXT: Link: 0
+// NOAPPLYDYNREL-NEXT: Info: 0
+// NOAPPLYDYNREL-NEXT: AddressAlignment: 1
+// NOAPPLYDYNREL-NEXT: EntrySize: 0
+// NOAPPLYDYNREL-NEXT: SectionData (
+// NOAPPLYDYNREL-NEXT:   0000: 00000000 00000000 00000000 00000000
+// NOAPPLYDYNREL-NEXT: )
 
 // CHECK:      Name: foo
 // CHECK-NEXT: Type: SHT_PROGBITS




More information about the llvm-commits mailing list