]> granicus.if.org Git - llvm/commitdiff
Handle undefined weak hidden symbols on all architectures.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 27 Oct 2017 21:18:48 +0000 (21:18 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 27 Oct 2017 21:18:48 +0000 (21:18 +0000)
We were handling the non-hidden case in lib/Target/TargetMachine.cpp,
but the hidden case was handled in architecture dependent code and
only X86_64 and AArch64 were covered.

While it is true that some code sequences in some ABIs might be able
to produce the correct value at runtime, that doesn't seem to be the
common case.

I left the AArch64 code in place since it also forces a got access for
non-pic code. It is not clear if that is needed, but it is probably
better to change that in another commit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316799 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/TargetMachine.cpp
lib/Target/X86/X86Subtarget.cpp
test/CodeGen/X86/global-access-pie-copyrelocs.ll
test/CodeGen/X86/weak-undef.ll

index dd6c288607cf67dd16d3681bb8b100f38eeec46a..1b05e6ce9f41215281c8b82abcf81b414aecb204 100644 (file)
@@ -128,6 +128,15 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
   if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
     return true;
 
+  // Most PIC code sequences that assume that a symbol is local cannot
+  // produce a 0 if it turns out the symbol is undefined. While this
+  // is ABI and relocation depended, it seems worth it to handle it
+  // here.
+  // FIXME: this is probably not ELF specific.
+  if (GV && isPositionIndependent() && TT.isOSBinFormatELF() &&
+      GV->hasExternalWeakLinkage())
+    return false;
+
   if (GV && (GV->hasLocalLinkage() || !GV->hasDefaultVisibility() ||
               GV->isDSOLocal()))
     return true;
@@ -149,9 +158,8 @@ bool TargetMachine::shouldAssumeDSOLocal(const Module &M,
       return true;
 
     bool IsTLS = GV && GV->isThreadLocal();
-    bool IsAccessViaCopyRelocs = Options.MCOptions.MCPIECopyRelocations && GV &&
-                                 isa<GlobalVariable>(GV) &&
-                                 !GV->hasExternalWeakLinkage();
+    bool IsAccessViaCopyRelocs =
+        Options.MCOptions.MCPIECopyRelocations && GV && isa<GlobalVariable>(GV);
     Triple::ArchType Arch = TT.getArch();
     bool IsPPC =
         Arch == Triple::ppc || Arch == Triple::ppc64 || Arch == Triple::ppc64le;
index 0de5619cff28dd17096acbee4d4f3e8f714f602d..b0ce1335bd37ddb3acd650f42d74e75dbf3d26d3 100644 (file)
@@ -99,22 +99,6 @@ X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {
   return X86II::MO_GOTOFF;
 }
 
-static bool shouldAssumeGlobalReferenceLocal(const X86Subtarget *ST,
-                                             const TargetMachine &TM,
-                                             const Module &M,
-                                             const GlobalValue *GV) {
-  if (!TM.shouldAssumeDSOLocal(M, GV))
-    return false;
-  // A weak reference can end up being 0. If the code can be more that 4g away
-  // from zero and we are using the small code model we have to treat it as non
-  // local.
-  if (GV && GV->hasExternalWeakLinkage() &&
-      TM.getCodeModel() == CodeModel::Small && TM.isPositionIndependent() &&
-      ST->is64Bit() && ST->isTargetELF())
-    return false;
-  return true;
-}
-
 unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
                                                     const Module &M) const {
   // Large model never uses stubs.
@@ -134,7 +118,7 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
     }
   }
 
-  if (shouldAssumeGlobalReferenceLocal(this, TM, M, GV))
+  if (TM.shouldAssumeDSOLocal(M, GV))
     return classifyLocalReference(GV);
 
   if (isTargetCOFF())
index b370c4eeca94c08e50f10e14bec9f90e41f4ed41..0918793a4d20ac3b2725758299fb3dfc874976d0 100644 (file)
@@ -77,6 +77,19 @@ entry:
   ret i32* @e
 }
 
+; ExternalWeak hidden Linkage
+@he = extern_weak hidden global i32, align 4
+
+define i32* @my_access_global_he() #0 {
+; X32-LABEL: my_access_global_he:
+; X32:       addl $_GLOBAL_OFFSET_TABLE_{{.*}}, %eax
+; X32:       movl he@GOT(%eax), %eax
+; X64-LABEL: my_access_global_he:
+; X64:       movq he@GOTPCREL(%rip), %rax
+  ret i32* @he
+}
+
+
 ; External Linkage, only declaration, store a value.
 
 define i32 @my_access_global_store_d() #0 {
index 7a71d980aaf75a49b85d2f9afc5f43c5df7495b8..863fea43b1624da3f668fb111046cd66f79dd3b4 100644 (file)
@@ -8,7 +8,7 @@ define i32* @bar1() {
 ; CHECK: bar1:
 ; CHECK: movq foo1@GOTPCREL(%rip), %rax
 ; I386: bar1:
-; I386: leal foo1@GOTOFF(%eax), %eax
+; I386: movl foo1@GOT(%eax), %eax
 
 @foo2 = external hidden global i32, align 4
 define i32* @bar2() {
@@ -46,7 +46,7 @@ define i32()* @bar5() {
 ; CHECK: bar5:
 ; CHECK: movq foo5@GOTPCREL(%rip), %rax
 ; I386: bar5:
-; I386: leal foo5@GOTOFF(%eax), %eax
+; I386: movl foo5@GOT(%eax), %eax
 
 declare external hidden i32 @foo6()
 define i32()* @bar6() {