[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