summaryrefslogtreecommitdiffstats
path: root/lld/ELF/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF/Driver.cpp')
-rw-r--r--lld/ELF/Driver.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 0d6602b767e..c81efb3905d 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1163,6 +1163,18 @@ template <class ELFT> static void demoteSymbols() {
}
}
+// Record sections that define symbols mentioned in --keep-unique <symbol>
+// these sections are inelligible for ICF.
+static void findKeepUniqueSections(opt::InputArgList &Args) {
+ for (auto *Arg : Args.filtered(OPT_keep_unique)) {
+ StringRef Name = Arg->getValue();
+ if (auto *Sym = dyn_cast_or_null<Defined>(Symtab->find(Name)))
+ Sym->Section->KeepUnique = true;
+ else
+ warn("could not find symbol " + Name + " to keep unique");
+ }
+}
+
// Do actual linking. Note that when this function is called,
// all linker scripts have already been parsed.
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
@@ -1335,8 +1347,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
markLive<ELFT>();
demoteSymbols<ELFT>();
mergeSections();
- if (Config->ICF)
+ if (Config->ICF) {
+ findKeepUniqueSections(Args);
doIcf<ELFT>();
+ }
// Read the callgraph now that we know what was gced or icfed
if (auto *Arg = Args.getLastArg(OPT_call_graph_ordering_file))
OpenPOWER on IntegriCloud