-
Notifications
You must be signed in to change notification settings - Fork 12.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix issues with GlobalMerge on Mach-O. (#110046)
As a side-effect of PR #101222, GlobalMerge started making transforms which are unsafe on Mach-O platforms. Two issues, in particular, are fixed here: 1. We must never merge symbols in the `__cfstring` section, as the linker assumes each object in this section is only ever referenced directly, and that it can split the section as it likes. Previously, we avoided this problem because CFString literals are identified by private-linkage symbols. This patch adds a list of section-names with special behavior, to avoid merging under Mach-O. 2. When GlobalMerge code was originally written, it had to be careful about emitting symbol aliases, due to issues with Mach-O's subsection splitting in the linker with `-dead_strip` enabled. The underlying cause of this problem was fixed in 2016, via creation of the `.alt_entry` assembler directive, which allows a symbol to not also imply the start of a new subsection. GlobalMerge's workaround for that issue was never removed. In the meantime, Apple's new ld-prime linker was written, and has a bug in `.alt_entry` handling. Therefore, even though the original issue was fixed, we must _continue_ to be careful not to emit any such symbol aliases. The existing workaround avoided it for InternalLinkage symbols, but after the above-mentioned PR, we also must avoid emitting aliases for PrivateLinkage symbols. I will file an Apple bug-report about this issue, so that it can be fixed in a future version of ld-prime. But, in the meantime, the workaround is sufficient for GlobalMerge, unless `-global-merge-on-externals` is enabled (which it is already not by default, on MachO platforms, due to the original issue). Fixes #104625
- Loading branch information
Showing
3 changed files
with
87 additions
and
6 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
; RUN: opt -global-merge -global-merge-max-offset=100 -S -o - %s | FileCheck %s | ||
; RUN: opt -passes='global-merge<max-offset=100>' -S -o - %s | FileCheck %s | ||
|
||
;; Check that we do _not_ merge globals which are in certain special | ||
;; sections under Mach-O. | ||
|
||
target datalayout = "e-p:64:64" | ||
target triple = "x86_64-apple-macos11" | ||
|
||
; CHECK: @cfstring1 = private global i32 1, section "__DATA,__cfstring" | ||
@cfstring1 = private global i32 1, section "__DATA,__cfstring" | ||
; CHECK: @cfstring2 = private global i32 2, section "__DATA,__cfstring" | ||
@cfstring2 = private global i32 2, section "__DATA,__cfstring" | ||
; CHECK: @objcclassrefs1 = private global i32 3, section "__DATA,__objc_classrefs,regular,no_dead_strip" | ||
@objcclassrefs1 = private global i32 3, section "__DATA,__objc_classrefs,regular,no_dead_strip" | ||
; CHECK: @objcclassrefs2 = private global i32 4, section "__DATA,__objc_classrefs,regular,no_dead_strip" | ||
@objcclassrefs2 = private global i32 4, section "__DATA,__objc_classrefs,regular,no_dead_strip" | ||
; CHECK: @objcselrefs1 = private global i32 5, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip" | ||
@objcselrefs1 = private global i32 5, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip" | ||
; CHECK: @objcselrefs2 = private global i32 6, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip" | ||
@objcselrefs2 = private global i32 6, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip" | ||
|
||
define void @use() { | ||
load ptr, ptr @cfstring1 | ||
load ptr, ptr @cfstring2 | ||
load ptr, ptr @objcclassrefs1 | ||
load ptr, ptr @objcclassrefs2 | ||
load ptr, ptr @objcselrefs1 | ||
load ptr, ptr @objcselrefs2 | ||
ret void | ||
} |
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,28 @@ | ||
; RUN: opt -global-merge -global-merge-max-offset=100 -S -o - %s | FileCheck %s | ||
; RUN: opt -passes='global-merge<max-offset=100>' -S -o - %s | FileCheck %s | ||
|
||
;; For Mach-O, we do not expect any alias symbols to be created for | ||
;; internal/private symbols by GlobalMerge. | ||
|
||
target datalayout = "e-p:64:64" | ||
target triple = "x86_64-apple-macos11" | ||
|
||
@a = private global i32 1 | ||
@b = private global i32 2 | ||
@c = internal global i32 3 | ||
@d = internal global i32 4 | ||
|
||
; CHECK: @_MergedGlobals = internal global <{ i32, i32, i32, i32 }> <{ i32 1, i32 2, i32 3, i32 4 }>, align 4 | ||
; CHECK-NOT: alias | ||
|
||
define void @use() { | ||
; CHECK: load i32, ptr @_MergedGlobals, | ||
%x = load i32, ptr @a | ||
; CHECK: load i32, ptr getelementptr inbounds (<{ i32, i32, i32, i32 }>, ptr @_MergedGlobals, i32 0, i32 1) | ||
%y = load i32, ptr @b | ||
; CHECK: load i32, ptr getelementptr inbounds (<{ i32, i32, i32, i32 }>, ptr @_MergedGlobals, i32 0, i32 2) | ||
%z1 = load i32, ptr @c | ||
; CHECK: load i32, ptr getelementptr inbounds (<{ i32, i32, i32, i32 }>, ptr @_MergedGlobals, i32 0, i32 3) | ||
%z2 = load i32, ptr @d | ||
ret void | ||
} |