summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2018-08-29 23:43:38 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2018-08-29 23:43:38 +0000
commit6556e6b9290adc40cdcec7e844a1334dda8b7c50 (patch)
tree611d0f801a3567e8c3915269acad5eb35184f343
parent7c57dac95598bd1aaa00b2f0df725d8980e50a38 (diff)
downloadbcm5719-llvm-6556e6b9290adc40cdcec7e844a1334dda8b7c50.tar.gz
bcm5719-llvm-6556e6b9290adc40cdcec7e844a1334dda8b7c50.zip
ELF: Don't examine values of linker script symbols during ICF.
These symbols are declared early with the same value, so they otherwise appear identical to ICF. Differential Revision: https://reviews.llvm.org/D51376 llvm-svn: 340998
-rw-r--r--lld/ELF/ICF.cpp5
-rw-r--r--lld/ELF/LinkerScript.cpp1
-rw-r--r--lld/ELF/Symbols.h7
-rw-r--r--lld/test/ELF/linkerscript/icf.s11
4 files changed, 22 insertions, 2 deletions
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index 075938bd16b..7c6440a410e 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -252,7 +252,10 @@ bool ICF<ELFT>::constantEq(const InputSection *SecA, ArrayRef<RelTy> RA,
auto *DA = dyn_cast<Defined>(&SA);
auto *DB = dyn_cast<Defined>(&SB);
- if (!DA || !DB)
+
+ // Placeholder symbols generated by linker scripts look the same now but
+ // may have different values later.
+ if (!DA || !DB || DA->ScriptDefined || DB->ScriptDefined)
return false;
// Relocations referring to absolute symbols are constant-equal if their
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index c865e9bd6b1..9c35bb78ce1 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -209,6 +209,7 @@ static void declareSymbol(SymbolAssignment *Cmd) {
STT_NOTYPE, 0, 0, nullptr);
Cmd->Sym = cast<Defined>(Sym);
Cmd->Provide = false;
+ Sym->ScriptDefined = true;
}
// This method is used to handle INSERT AFTER statement. Here we rebuild
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index c3a958df2a1..dcfeb7f813e 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -164,7 +164,8 @@ protected:
: File(File), NameData(Name.Data), NameSize(Name.Size), Binding(Binding),
Type(Type), StOther(StOther), SymbolKind(K), NeedsPltAddr(false),
IsInIplt(false), IsInIgot(false), IsPreemptible(false),
- Used(!Config->GcSections), NeedsTocRestore(false) {}
+ Used(!Config->GcSections), NeedsTocRestore(false),
+ ScriptDefined(false) {}
public:
// True the symbol should point to its PLT entry.
@@ -187,6 +188,9 @@ public:
// PPC64 toc pointer.
unsigned NeedsTocRestore : 1;
+ // True if this symbol is defined by a linker script.
+ unsigned ScriptDefined : 1;
+
// The Type field may also have this value. It means that we have not yet seen
// a non-Lazy symbol with this name, so we don't know what its type is. The
// Type field is normally set to this value for Lazy symbols unless we saw a
@@ -376,6 +380,7 @@ void replaceSymbol(Symbol *S, ArgT &&... Arg) {
S->ExportDynamic = Sym.ExportDynamic;
S->CanInline = Sym.CanInline;
S->Traced = Sym.Traced;
+ S->ScriptDefined = Sym.ScriptDefined;
// Print out a log message if --trace-symbol was specified.
// This is for debugging.
diff --git a/lld/test/ELF/linkerscript/icf.s b/lld/test/ELF/linkerscript/icf.s
new file mode 100644
index 00000000000..7c74458232a
--- /dev/null
+++ b/lld/test/ELF/linkerscript/icf.s
@@ -0,0 +1,11 @@
+# REQUIRES: x86
+
+# RUN: echo "foo = 1; bar = 2;" > %t.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o %t.script -o %t --icf=all --print-icf-sections | count 0
+
+.section .text.foo,"ax",@progbits
+jmp foo
+
+.section .text.bar,"ax",@progbits
+jmp bar
OpenPOWER on IntegriCloud