diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2018-08-29 23:43:38 +0000 | 
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2018-08-29 23:43:38 +0000 | 
| commit | 6556e6b9290adc40cdcec7e844a1334dda8b7c50 (patch) | |
| tree | 611d0f801a3567e8c3915269acad5eb35184f343 | |
| parent | 7c57dac95598bd1aaa00b2f0df725d8980e50a38 (diff) | |
| download | bcm5719-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.cpp | 5 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/Symbols.h | 7 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/icf.s | 11 | 
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  | 

