[LLD][COFF] Enable linking of __declspec(selectany) symbols from Clang and GCC

When annotating a symbol with __declspec(selectany), Clang assigns it
comdat 2 while GCC assigns it comdat 3. This patch enables two object
files that contain a __declspec(selectany) symbol, one created by gcc
and the other by clang, to be linked together instead of issuing a
duplicate symbol error.

Differential Revision: https://reviews.llvm.org/D73139
This commit is contained in:
Markus Böck 2020-01-23 10:43:56 +02:00 committed by Martin Storsjö
parent 4a8dbc617d
commit 9dbc1ab232
2 changed files with 24 additions and 0 deletions

View File

@ -500,6 +500,17 @@ void ObjFile::handleComdatSelection(COFFSymbolRef sym, COMDATType &selection,
leaderSelection = selection = IMAGE_COMDAT_SELECT_LARGEST;
}
// GCCs __declspec(selectany) doesn't actually pick "any" but "same size as".
// Clang on the other hand picks "any". To be able to link two object files
// with a __declspec(selectany) declaration, one compiled with gcc and the
// other with clang, we merge them as proper "same size as"
if (config->mingw && ((selection == IMAGE_COMDAT_SELECT_ANY &&
leaderSelection == IMAGE_COMDAT_SELECT_SAME_SIZE) ||
(selection == IMAGE_COMDAT_SELECT_SAME_SIZE &&
leaderSelection == IMAGE_COMDAT_SELECT_ANY))) {
leaderSelection = selection = IMAGE_COMDAT_SELECT_SAME_SIZE;
}
// Other than that, comdat selections must match. This is a bit more
// strict than link.exe which allows merging "any" and "largest" if "any"
// is the first symbol the linker sees, and it allows merging "largest"

View File

@ -0,0 +1,13 @@
# REQUIRES: x86
# RUN: llvm-mc %s -triple x86_64-pc-win32 -defsym obj=0 -filetype=obj -o %t1.obj
# RUN: llvm-mc %s -triple x86_64-pc-win32 -defsym obj=1 -filetype=obj -o %t2.obj
# RUN: lld-link /lldmingw /noentry /dll %t1.obj %t2.obj /out:%t3.dll
# RUN: not lld-link /noentry /dll %t1.obj %t2.obj /out:%t3.dll
.if obj==0
.section .text$nm, "", discard, symbol
.else
.section .text$nm, "", same_size, symbol
.endif
.globl symbol
symbol:
.long 1