-
Notifications
You must be signed in to change notification settings - Fork 12k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[COFF] Emit embedded -exclude-symbols: directives for hidden visibili…
…ty for MinGW This works with the automatic export of all symbols; in MinGW mode, when a DLL has no explicit dllexports, it exports all symbols (except for some that are hardcoded to be excluded, including some toolchain libraries). By hooking up the hidden visibility to the -exclude-symbols: directive, the automatic export of all symbols can be controlled in an easier way (with a mechanism that doesn't require strict annotation of every single symbol, but which allows gradually marking more unnecessary symbols as hidden). The primary use case is dylib builds of LLVM/Clang. These can be done in MinGW mode but not in MSVC mode, as MinGW builds can export all symbols (and the calling code can use APIs without corresponding dllimport directives). However, as all symbols are exported, it can easily overflow the max number of exported symbols in a DLL (65536). In the llvm-mingw distribution, only the X86, ARM and AArch64 backends are enabled; for the LLVM 13.0.0 release, libLLVM-13.dll ended up with 58112 exported symbols. For LLVM 14.0.0, it was 62015 symbols. Current builds of the 15.x branch end up at around 64650 symbols - i.e. extremely close to the limit. The msys2 packages of LLVM have had to progressively disable more of their backends in their builds, to be able to keep building with a dylib. This allows improving the current mingw dylib situation significantly, by using the same hidden visibility options and attributes as on Unix. With those in place, a current build of LLVM git main ends up at 35142 symbols instead of 64650. For code using hidden visibility, this now requires linking with either a current git lld or ld.bfd. (Older lld error out on the unknown directives, older ld.bfd will successfully link, but will print huge amounts of warnings.) Differential Revision: https://reviews.llvm.org/D130121
- Loading branch information
Showing
3 changed files
with
129 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
; RUN: llc -mtriple i386-pc-win32 < %s \ | ||
; RUN: | FileCheck --check-prefixes=CHECK,CHECK-MSVC %s | ||
; RUN: llc -mtriple i386-pc-mingw32 < %s \ | ||
; RUN: | FileCheck --check-prefixes=CHECK,CHECK-MINGW %s | ||
; RUN: llc -mtriple i386-pc-mingw32 < %s \ | ||
; RUN: | FileCheck --check-prefix=NOTEXPORTED %s | ||
|
||
; CHECK: .text | ||
|
||
; CHECK: .globl _notHidden | ||
define void @notHidden() { | ||
ret void | ||
} | ||
|
||
; CHECK: .globl _f1 | ||
define hidden void @f1() { | ||
ret void | ||
} | ||
|
||
; CHECK: .globl _f2 | ||
define hidden void @f2() unnamed_addr { | ||
ret void | ||
} | ||
|
||
declare hidden void @notDefined() | ||
|
||
; CHECK: .globl _stdfun@0 | ||
define hidden x86_stdcallcc void @stdfun() nounwind { | ||
ret void | ||
} | ||
|
||
; CHECK: .globl _lnk1 | ||
$lnk1 = comdat any | ||
|
||
define linkonce_odr hidden void @lnk1() comdat { | ||
ret void | ||
} | ||
|
||
; CHECK: .globl _lnk2 | ||
$lnk2 = comdat any | ||
|
||
define linkonce_odr hidden void @lnk2() alwaysinline comdat { | ||
ret void | ||
} | ||
|
||
; CHECK: .data | ||
; CHECK: .globl _Var1 | ||
@Var1 = hidden global i32 1, align 4 | ||
|
||
; CHECK: .rdata,"dr" | ||
; CHECK: .globl _Var2 | ||
@Var2 = hidden unnamed_addr constant i32 1 | ||
|
||
; CHECK: .comm _Var3 | ||
@Var3 = common hidden global i32 0, align 4 | ||
|
||
; CHECK: .globl "_complex-name" | ||
@"complex-name" = hidden global i32 1, align 4 | ||
|
||
; CHECK: .globl _complex.name | ||
@"complex.name" = hidden global i32 1, align 4 | ||
|
||
|
||
; Verify items that should not be marked hidden do not appear in the directives. | ||
; We use a separate check prefix to avoid confusion between -NOT and -SAME. | ||
; NOTEXPORTED: .section .drectve | ||
; NOTEXPORTED-NOT: :notHidden | ||
; NOTEXPORTED-NOT: :notDefined | ||
|
||
; CHECK-MSVC-NOT: .section .drectve | ||
; CHECK-MINGW: .section .drectve | ||
; CHECK-MINGW: .ascii " -exclude-symbols:f1" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:f2" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:stdfun@0" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:lnk1" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:lnk2" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:Var1" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:Var2" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:Var3" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:\"complex-name\"" | ||
; CHECK-MINGW: .ascii " -exclude-symbols:\"complex.name\"" |