[lld] r322152 - Rename --icf-data and add a corresponding flag for functions.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 9 17:37:36 PST 2018


Author: rafael
Date: Tue Jan  9 17:37:36 2018
New Revision: 322152

URL: http://llvm.org/viewvc/llvm-project?rev=322152&view=rev
Log:
Rename --icf-data and add a corresponding flag for functions.

When we have --icf=safe we should be able to define --icf=all as a
shorthand for --icf=safe --ignore-function-address-equality.

For now --ignore-function-address-equality is used only to control
access to non preemptable symbols in shared libraries.

Added:
    lld/trunk/test/ELF/Inputs/protected-data-access.s
    lld/trunk/test/ELF/Inputs/protected-function-access.s
    lld/trunk/test/ELF/protected-data-access.s
    lld/trunk/test/ELF/protected-function-access.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/ICF.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/test/ELF/icf9.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=322152&r1=322151&r2=322152&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Jan  9 17:37:36 2018
@@ -126,7 +126,8 @@ struct Configuration {
   bool HasDynamicList = false;
   bool HasDynSymTab;
   bool ICF;
-  bool ICFData;
+  bool IgnoreDataAddressEquality;
+  bool IgnoreFunctionAddressEquality;
   bool MergeArmExidx;
   bool MipsN32Abi = false;
   bool NoGnuUnique;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=322152&r1=322151&r2=322152&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Jan  9 17:37:36 2018
@@ -618,7 +618,10 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->GcSections = Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, false);
   Config->GdbIndex = Args.hasFlag(OPT_gdb_index, OPT_no_gdb_index, false);
   Config->ICF = Args.hasFlag(OPT_icf_all, OPT_icf_none, false);
-  Config->ICFData = Args.hasArg(OPT_icf_data);
+  Config->IgnoreDataAddressEquality =
+      Args.hasArg(OPT_ignore_data_address_equality);
+  Config->IgnoreFunctionAddressEquality =
+      Args.hasArg(OPT_ignore_function_address_equality);
   Config->Init = Args.getLastArgValue(OPT_init, "_init");
   Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
   Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);

Modified: lld/trunk/ELF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=322152&r1=322151&r2=322152&view=diff
==============================================================================
--- lld/trunk/ELF/ICF.cpp (original)
+++ lld/trunk/ELF/ICF.cpp Tue Jan  9 17:37:36 2018
@@ -161,8 +161,9 @@ template <class ELFT> static uint32_t ge
 
 // Returns true if section S is subject of ICF.
 static bool isEligible(InputSection *S) {
-  // Don't merge read only data sections unless --icf-data was passed.
-  if (!(S->Flags & SHF_EXECINSTR) && !Config->ICFData)
+  // Don't merge read only data sections unless
+  // --ignore-data-address-equality was passed.
+  if (!(S->Flags & SHF_EXECINSTR) && !Config->IgnoreDataAddressEquality)
     return false;
 
   // .init and .fini contains instructions that must be executed to

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=322152&r1=322151&r2=322152&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Tue Jan  9 17:37:36 2018
@@ -143,11 +143,14 @@ def help: F<"help">, HelpText<"Print opt
 
 def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">;
 
-def icf_data: F<"icf-data">,
-  HelpText<"Enable ICF to also fold identical read only data">;
-
 def icf_none: F<"icf=none">, HelpText<"Disable identical code folding">;
 
+def ignore_function_address_equality: F<"ignore-function-address-equality">,
+  HelpText<"lld can break the address equality of functions">;
+
+def ignore_data_address_equality: F<"ignore-data-address-equality">,
+  HelpText<"lld can break the address equality of data">;
+
 defm image_base : Eq<"image-base">, HelpText<"Set the base address">;
 
 defm init: Eq<"init">, HelpText<"Specify an initializer function">,

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=322152&r1=322151&r2=322152&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Jan  9 17:37:36 2018
@@ -738,6 +738,23 @@ template <class ELFT> static void addGot
                          R_ABS, Target->GotRel);
 }
 
+// Return true if we can define a symbol in the executable that
+// contains the value/function of a symbol defined in a shared
+// library.
+static bool canDefineSymbolInExecutable(Symbol &Sym) {
+  // If the symbol has default visibility the symbol defined in the
+  // executable will preempt it.
+  if (Sym.getVisibility() == STV_DEFAULT)
+    return true;
+
+  // If we are allowed to break address equality of functions, defining
+  // a plt entry will allow the program to call the function in the
+  // .so, but the .so and the executable will no agree on the address
+  // of the function. Similar logic for objects.
+  return ((Sym.isFunc() && Config->IgnoreFunctionAddressEquality) ||
+          (Sym.isObject() && Config->IgnoreDataAddressEquality));
+}
+
 // The reason we have to do this early scan is as follows
 // * To mmap the output file, we need to know the size
 // * For that, we need to know how many dynamic relocs we will have.
@@ -823,7 +840,7 @@ static RelExpr processRelocAux(InputSect
     return Expr;
   }
 
-  if (Sym.getVisibility() != STV_DEFAULT) {
+  if (!canDefineSymbolInExecutable(Sym)) {
     error("cannot preempt symbol: " + toString(Sym) +
           getLocation(Sec, Sym, Offset));
     return Expr;

Added: lld/trunk/test/ELF/Inputs/protected-data-access.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/protected-data-access.s?rev=322152&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/protected-data-access.s (added)
+++ lld/trunk/test/ELF/Inputs/protected-data-access.s Tue Jan  9 17:37:36 2018
@@ -0,0 +1,7 @@
+        .section .rodata,"a"
+        .global foo
+        .protected foo
+        .type foo, @object
+        .size foo, 8
+foo:
+        .quad 42

Added: lld/trunk/test/ELF/Inputs/protected-function-access.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/protected-function-access.s?rev=322152&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/protected-function-access.s (added)
+++ lld/trunk/test/ELF/Inputs/protected-function-access.s Tue Jan  9 17:37:36 2018
@@ -0,0 +1,5 @@
+        .global foo
+        .protected foo
+        .type foo, @function
+foo:
+        ret

Modified: lld/trunk/test/ELF/icf9.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/icf9.s?rev=322152&r1=322151&r2=322152&view=diff
==============================================================================
--- lld/trunk/test/ELF/icf9.s (original)
+++ lld/trunk/test/ELF/icf9.s Tue Jan  9 17:37:36 2018
@@ -11,7 +11,7 @@
 # CHECK-NOT: selected .rodata.d2
 
 # We do merge rodata if passed --icf-data
-# RUN: ld.lld %t -o %t2 --icf=all --verbose --icf-data 2>&1 | FileCheck --check-prefix=DATA %s
+# RUN: ld.lld %t -o %t2 --icf=all --verbose --ignore-data-address-equality 2>&1 | FileCheck --check-prefix=DATA %s
 # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s
 
 # DATA: selected .rodata.d1

Added: lld/trunk/test/ELF/protected-data-access.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/protected-data-access.s?rev=322152&view=auto
==============================================================================
--- lld/trunk/test/ELF/protected-data-access.s (added)
+++ lld/trunk/test/ELF/protected-data-access.s Tue Jan  9 17:37:36 2018
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %p/Inputs/protected-data-access.s -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t.o
+
+# RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: error: cannot preempt symbol: foo
+
+# RUN: ld.lld --ignore-data-address-equality %t.o %t2.so -o %t
+# RUN: llvm-readobj --dyn-symbols --relocations %t | FileCheck %s
+
+# Check that we have a copy relocation.
+
+# CHECK: R_X86_64_COPY foo 0x0
+
+# CHECK:      Name: foo
+# CHECK-NEXT: Value:
+# CHECK-NEXT: Size: 8
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Object
+# CHECK-NEXT: Other:
+# CHECK-NEXT: Section: .bss.rel.ro
+
+.global _start
+_start:
+  .quad foo
+

Added: lld/trunk/test/ELF/protected-function-access.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/protected-function-access.s?rev=322152&view=auto
==============================================================================
--- lld/trunk/test/ELF/protected-function-access.s (added)
+++ lld/trunk/test/ELF/protected-function-access.s Tue Jan  9 17:37:36 2018
@@ -0,0 +1,27 @@
+# REQUIRES: x86
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %p/Inputs/protected-function-access.s -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t.o
+
+# RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck --check-prefix=ERR %s
+# ERR: error: cannot preempt symbol: foo
+
+# RUN: ld.lld --ignore-function-address-equality %t.o %t2.so -o %t
+# RUN: llvm-readobj --dyn-symbols --relocations %t | FileCheck %s
+
+# Check that we have a relocation and an undefined symbol with a non zero address
+
+# CHECK: R_X86_64_JUMP_SLOT foo 0x0
+
+# CHECK:      Name: foo
+# CHECK-NEXT: Value: 0x201020
+# CHECK-NEXT: Size:
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other:
+# CHECK-NEXT: Section: Undefined
+
+.global _start
+_start:
+  .quad foo
+




More information about the llvm-commits mailing list