Be consistent when deciding if a relocation is needed.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 6 Apr 2015 15:27:57 +0000 (15:27 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 6 Apr 2015 15:27:57 +0000 (15:27 +0000)
Before when deciding if we needed a relocation in A-B, we wore only checking
if A was weak.

This fixes the asymmetry.

The "InSet" argument should probably be renamed to "ForValue", since InSet is
very MachO specific, but doing so in this patch would make it hard to read.

This fixes PR22815.

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

include/llvm/MC/MCMachObjectWriter.h
include/llvm/MC/MCObjectWriter.h
lib/MC/ELFObjectWriter.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCObjectWriter.cpp
lib/MC/MachObjectWriter.cpp
lib/MC/WinCOFFObjectWriter.cpp
test/MC/ELF/weak-diff2.s [new file with mode: 0644]

index 3d270ce7e0d0a4be0bf83e7b1c705c57c1c29d21..eb2789b90f9a67153e475ffc656f126227e570a7 100644 (file)
@@ -262,6 +262,7 @@ public:
 
   bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
                                               const MCSymbolData &DataA,
+                                              const MCSymbolData *DataB,
                                               const MCFragment &FB,
                                               bool InSet,
                                               bool IsPCRel) const override;
index fcfa968362bedc925738e4ececcf8e6d54b2204e..2965ce21b82e2e2cf4d70a8746d9a3a540cf58fa 100644 (file)
@@ -91,12 +91,12 @@ public:
                                           const MCSymbolRefExpr *B,
                                           bool InSet) const;
 
-  virtual bool
-  IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
-                                         const MCSymbolData &DataA,
-                                         const MCFragment &FB,
-                                         bool InSet,
-                                         bool IsPCRel) const;
+  virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+                                                      const MCSymbolData &DataA,
+                                                      const MCSymbolData *DataB,
+                                                      const MCFragment &FB,
+                                                      bool InSet,
+                                                      bool IsPCRel) const;
 
   /// \brief True if this symbol (which is a variable) is weak. This is not
   /// just STB_WEAK, but more generally whether or not we can evaluate
index 2004b1b8a2de3a602f49acdba33c8c806ffc220a..6105b25b8bf6cf45b4ad57955645b19b57ee5b20 100644 (file)
@@ -300,6 +300,7 @@ class ELFObjectWriter : public MCObjectWriter {
     bool
     IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
                                            const MCSymbolData &DataA,
+                                           const MCSymbolData *DataB,
                                            const MCFragment &FB,
                                            bool InSet,
                                            bool IsPCRel) const override;
@@ -619,7 +620,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
 
   if (ESize) {
     int64_t Res;
-    if (!ESize->EvaluateAsAbsolute(Res, Layout))
+    if (!ESize->evaluateKnownAbsolute(Res, Layout))
       report_fatal_error("Size expression must be absolute.");
     Size = Res;
   }
@@ -1765,16 +1766,14 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
     WriteDataSectionData(Asm, Layout, *Sections[i]);
 }
 
-bool
-ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
-                                                      const MCSymbolData &DataA,
-                                                      const MCFragment &FB,
-                                                      bool InSet,
-                                                      bool IsPCRel) const {
-  if (::isWeak(DataA))
+bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+    const MCAssembler &Asm, const MCSymbolData &DataA,
+    const MCSymbolData *DataB, const MCFragment &FB, bool InSet,
+    bool IsPCRel) const {
+  if (!InSet && (::isWeak(DataA) || (DataB && ::isWeak(*DataB))))
     return false;
   return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
-                                                 Asm, DataA, FB,InSet, IsPCRel);
+      Asm, DataA, DataB, FB, InSet, IsPCRel);
 }
 
 bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const {
index 857eafc0b7e4585c9ecafcab234021c483e138e3..d7ca875f29738130efc55239118860838aa3f485 100644 (file)
@@ -502,9 +502,8 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
         IsResolved = false;
       } else {
         const MCSymbolData &DataA = getSymbolData(SA);
-        IsResolved =
-          getWriter().IsSymbolRefDifferenceFullyResolvedImpl(*this, DataA,
-                                                             *DF, false, true);
+        IsResolved = getWriter().IsSymbolRefDifferenceFullyResolvedImpl(
+            *this, DataA, nullptr, *DF, false, true);
       }
     }
   } else {
index 3c536ecc9fd6530e00b4339639ae4a0f11db9419..33e4556e102e2f52eccd74f3240923f59889e5d5 100644 (file)
@@ -35,18 +35,14 @@ bool MCObjectWriter::IsSymbolRefDifferenceFullyResolved(
   if(!DataA.getFragment() || !DataB.getFragment())
     return false;
 
-  return IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA,
-                                                *DataB.getFragment(),
-                                                InSet,
-                                                false);
+  return IsSymbolRefDifferenceFullyResolvedImpl(
+      Asm, DataA, &DataB, *DataB.getFragment(), InSet, false);
 }
 
-bool
-MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
-                                                      const MCSymbolData &DataA,
-                                                      const MCFragment &FB,
-                                                      bool InSet,
-                                                      bool IsPCRel) const {
+bool MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+    const MCAssembler &Asm, const MCSymbolData &DataA,
+    const MCSymbolData *DataB, const MCFragment &FB, bool InSet,
+    bool IsPCRel) const {
   const MCSection &SecA = DataA.getSymbol().AliasedSymbol().getSection();
   const MCSection &SecB = FB.getParent()->getSection();
   // On ELF and COFF  A - B is absolute if A and B are in the same section.
index 56cccab1d39f11ac9e82111208a36efc0454bf68..93ff75211c4371660dbd7a251efdfb7856785322 100644 (file)
@@ -660,6 +660,7 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
 bool MachObjectWriter::
 IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
                                        const MCSymbolData &DataA,
+                                       const MCSymbolData *DataB,
                                        const MCFragment &FB,
                                        bool InSet,
                                        bool IsPCRel) const {
index ff90b7c2cefa4ef88f7b257a77b51cade29e5f78..b62b342edd172e22d637b34c0b97ceb41af94d34 100644 (file)
@@ -172,6 +172,7 @@ public:
 
   bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
                                               const MCSymbolData &DataA,
+                                              const MCSymbolData *DataB,
                                               const MCFragment &FB, bool InSet,
                                               bool IsPCRel) const override;
 
@@ -649,16 +650,17 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
 }
 
 bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
-    const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB,
-    bool InSet, bool IsPCRel) const {
+    const MCAssembler &Asm, const MCSymbolData &DataA,
+    const MCSymbolData *DataB, const MCFragment &FB, bool InSet,
+    bool IsPCRel) const {
   // MS LINK expects to be able to replace all references to a function with a
   // thunk to implement their /INCREMENTAL feature.  Make sure we don't optimize
   // away any relocations to functions.
   if ((((DataA.getFlags() & COFF::SF_TypeMask) >> COFF::SF_TypeShift) >>
        COFF::SCT_COMPLEX_TYPE_SHIFT) == COFF::IMAGE_SYM_DTYPE_FUNCTION)
     return false;
-  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB,
-                                                                InSet, IsPCRel);
+  return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(
+      Asm, DataA, DataB, FB, InSet, IsPCRel);
 }
 
 bool WinCOFFObjectWriter::isWeak(const MCSymbolData &SD) const {
diff --git a/test/MC/ELF/weak-diff2.s b/test/MC/ELF/weak-diff2.s
new file mode 100644 (file)
index 0000000..daf64a4
--- /dev/null
@@ -0,0 +1,10 @@
+// RUN: not llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t 2>&1 | FileCheck %s
+
+// CHECK: error: Cannot represent a subtraction with a weak symbol
+
+.weak f
+f:
+    nop
+g:
+    nop
+.quad g - f