aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/gold
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2021-07-20 13:22:00 -0700
committerFangrui Song <i@maskray.me>2021-07-20 13:22:00 -0700
commitdb5e0786900e53843f87c4169c404f8c7831eb8c (patch)
tree35da5fa3a9c42965f2504fdae276b09481ead698 /llvm/tools/gold
parentce8024e8ff76e7be8b9ffa1a39d1dc9310bf74c7 (diff)
downloadllvm-db5e0786900e53843f87c4169c404f8c7831eb8c.zip
llvm-db5e0786900e53843f87c4169c404f8c7831eb8c.tar.gz
llvm-db5e0786900e53843f87c4169c404f8c7831eb8c.tar.bz2
[LTO] Add SelectionKind to IRSymtab and use it in ld.lld/LLVMgold
In PGO, a C++ external linkage function `foo` has a private counter `__profc_foo` and a private `__profd_foo` in a `comdat nodeduplicate`. A `__attribute__((weak))` function `foo` has a weak hidden counter `__profc_foo` and a private `__profd_foo` in a `comdat nodeduplicate`. In `ld.lld a.o b.o`, say a.o defines an external linkage `foo` and b.o defines a weak `foo`. Currently we treat `comdat nodeduplicate` as `comdat any`, ld.lld will incorrectly consider `b.o:__profc_foo` non-prevailing. In the worst case when `b.o:__profd_foo` is retained and `b.o:__profc_foo` isn't, there will be dangling reference causing an `undefined hidden symbol` error. Add SelectionKind to `Comdat` in IRSymtab and let linkers ignore nodeduplicate comdat. Differential Revision: https://reviews.llvm.org/D106228
Diffstat (limited to 'llvm/tools/gold')
-rw-r--r--llvm/tools/gold/gold-plugin.cpp6
1 files changed, 4 insertions, 2 deletions
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index 9870f3a..6bcb1e4 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -623,8 +623,10 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
sym.comdat_key = nullptr;
int CI = Sym.getComdatIndex();
if (CI != -1) {
- StringRef C = Obj->getComdatTable()[CI];
- sym.comdat_key = strdup(C.str().c_str());
+ // Not setting comdat_key for nodeduplicate ensuress we don't deduplicate.
+ std::pair<StringRef, Comdat::SelectionKind> C = Obj->getComdatTable()[CI];
+ if (C.second != Comdat::NoDeduplicate)
+ sym.comdat_key = strdup(C.first.str().c_str());
}
sym.resolution = LDPR_UNKNOWN;