@@ -37,7 +37,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
3737 unsafe {
3838 llvm:: LLVMRustSetLinkage ( g, base:: linkage_to_llvm ( linkage) ) ;
3939 llvm:: LLVMRustSetVisibility ( g, base:: visibility_to_llvm ( visibility) ) ;
40- if self . should_assume_dso_local ( linkage , visibility ) {
40+ if self . should_assume_dso_local ( g , false ) {
4141 llvm:: LLVMRustSetDSOLocal ( g, true ) ;
4242 }
4343 }
@@ -85,7 +85,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
8585 attributes:: from_fn_attrs ( self , lldecl, instance) ;
8686
8787 unsafe {
88- if self . should_assume_dso_local ( linkage , visibility ) {
88+ if self . should_assume_dso_local ( lldecl , false ) {
8989 llvm:: LLVMRustSetDSOLocal ( lldecl, true ) ;
9090 }
9191 }
@@ -95,28 +95,48 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
9595}
9696
9797impl CodegenCx < ' ll , ' tcx > {
98- /// Whether a definition (NB: not declaration!) can be assumed to be local to a group of
98+ /// Whether a definition or declaration can be assumed to be local to a group of
9999 /// libraries that form a single DSO or executable.
100100 pub ( crate ) unsafe fn should_assume_dso_local (
101101 & self ,
102- linkage : Linkage ,
103- visibility : Visibility ,
102+ llval : & llvm :: Value ,
103+ is_declaration : bool ,
104104 ) -> bool {
105- if matches ! ( linkage, Linkage :: Internal | Linkage :: Private ) {
105+ let linkage = llvm:: LLVMRustGetLinkage ( llval) ;
106+ let visibility = llvm:: LLVMRustGetVisibility ( llval) ;
107+
108+ if matches ! ( linkage, llvm:: Linkage :: InternalLinkage | llvm:: Linkage :: PrivateLinkage ) {
106109 return true ;
107110 }
108111
109- if visibility != Visibility :: Default && linkage != Linkage :: ExternalWeak {
112+ if visibility != llvm:: Visibility :: Default && linkage != llvm:: Linkage :: ExternalWeakLinkage
113+ {
110114 return true ;
111115 }
112116
113- // Static relocation model should force copy relocations everywhere.
114- if self . tcx . sess . relocation_model ( ) == RelocModel :: Static {
117+ // Symbols from executables can't really be imported any further.
118+ let all_exe = self . tcx . sess . crate_types ( ) . iter ( ) . all ( |ty| * ty == CrateType :: Executable ) ;
119+ let is_declaration_for_linker =
120+ is_declaration || linkage == llvm:: Linkage :: AvailableExternallyLinkage ;
121+ if all_exe && !is_declaration_for_linker {
115122 return true ;
116123 }
117124
118- // Symbols from executables can't really be imported any further.
119- if self . tcx . sess . crate_types ( ) . iter ( ) . all ( |ty| * ty == CrateType :: Executable ) {
125+ // PowerPC64 prefers TOC indirection to avoid copy relocations.
126+ if matches ! ( & * self . tcx. sess. target. arch, "powerpc64" | "powerpc64le" ) {
127+ return false ;
128+ }
129+
130+ // Thread-local variables generally don't support copy relocations.
131+ let is_thread_local_var = llvm:: LLVMIsAGlobalVariable ( llval)
132+ . map ( |v| llvm:: LLVMIsThreadLocal ( v) == llvm:: True )
133+ . unwrap_or ( false ) ;
134+ if is_thread_local_var {
135+ return false ;
136+ }
137+
138+ // Static relocation model should force copy relocations everywhere.
139+ if self . tcx . sess . relocation_model ( ) == RelocModel :: Static {
120140 return true ;
121141 }
122142
0 commit comments