[llvm] r204294 - Look through variables when computing relocations.

Rafael Espindola rafael.espindola at gmail.com
Wed Mar 19 19:12:02 PDT 2014


Author: rafael
Date: Wed Mar 19 21:12:01 2014
New Revision: 204294

URL: http://llvm.org/viewvc/llvm-project?rev=204294&view=rev
Log:
Look through variables when computing relocations.

Given

bar = foo + 4
	.long bar

MC would eat the 4. GNU as includes it in the relocation. The rule seems to be
that a variable that defines a symbol is used in the relocation and one that
does not define a symbol is evaluated and the result included in the relocation.

Fixing this unfortunately required some other changes:

* Since the variable is now evaluated, it would prevent the ELF writer from
  noticing the weakref marker the elf streamer uses. This patch then replaces
  that with a VariantKind in MCSymbolRefExpr.

* Using VariantKind then requires us to look past other VariantKind to see

	.weakref	bar,foo
	call	bar at PLT

  doing this also fixes

	zed = foo +2
	call zed at PLT

  so that is a good thing.

* Looking past VariantKind means that the relocation selection has to use
  the fixup instead of the target.

This is a reboot of the previous fixes for MC. I will watch the sanitizer
buildbot and wait for a build before adding back the previous fixes.

Added:
    llvm/trunk/lib/MC/MCFixup.cpp
    llvm/trunk/test/MC/X86/reloc-undef-global.s
Modified:
    llvm/trunk/include/llvm/MC/MCELFSymbolFlags.h
    llvm/trunk/include/llvm/MC/MCExpr.h
    llvm/trunk/include/llvm/MC/MCFixup.h
    llvm/trunk/lib/MC/CMakeLists.txt
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MCELFStreamer.cpp
    llvm/trunk/lib/MC/MCExpr.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
    llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
    llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
    llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
    llvm/trunk/test/MC/ELF/relocation.s

Modified: llvm/trunk/include/llvm/MC/MCELFSymbolFlags.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCELFSymbolFlags.h?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCELFSymbolFlags.h (original)
+++ llvm/trunk/include/llvm/MC/MCELFSymbolFlags.h Wed Mar 19 21:12:01 2014
@@ -51,8 +51,7 @@ namespace llvm {
       ELF_STV_Hidden    = (ELF::STV_HIDDEN    << ELF_STV_Shift),
       ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift),
 
-      ELF_Other_Weakref = (1                  << ELF_Other_Shift),
-      ELF_Other_ThumbFunc = (2                << ELF_Other_Shift)
+      ELF_Other_ThumbFunc = (1                << ELF_Other_Shift)
   };
 
 } // end namespace llvm

Modified: llvm/trunk/include/llvm/MC/MCExpr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCExpr.h?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCExpr.h (original)
+++ llvm/trunk/include/llvm/MC/MCExpr.h Wed Mar 19 21:12:01 2014
@@ -160,6 +160,7 @@ public:
     VK_DTPOFF,
     VK_TLVP,      // Mach-O thread local variable relocation
     VK_SECREL,
+    VK_WEAKREF,   // The link between the symbols in .weakref foo, bar
 
     VK_ARM_NONE,
     VK_ARM_TARGET1,

Modified: llvm/trunk/include/llvm/MC/MCFixup.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFixup.h?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCFixup.h (original)
+++ llvm/trunk/include/llvm/MC/MCFixup.h Wed Mar 19 21:12:01 2014
@@ -10,6 +10,7 @@
 #ifndef LLVM_MC_MCFIXUP_H
 #define LLVM_MC_MCFIXUP_H
 
+#include "llvm/MC/MCExpr.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/SMLoc.h"
@@ -87,6 +88,8 @@ public:
 
   MCFixupKind getKind() const { return MCFixupKind(Kind); }
 
+  MCSymbolRefExpr::VariantKind getAccessVariant() const;
+
   uint32_t getOffset() const { return Offset; }
   void setOffset(uint32_t Value) { Offset = Value; }
 

Modified: llvm/trunk/lib/MC/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/CMakeLists.txt?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/MC/CMakeLists.txt (original)
+++ llvm/trunk/lib/MC/CMakeLists.txt Wed Mar 19 21:12:01 2014
@@ -16,6 +16,7 @@ add_llvm_library(LLVMMC
   MCELF.cpp
   MCELFObjectTargetWriter.cpp
   MCELFStreamer.cpp
+  MCFixup.cpp
   MCFunction.cpp
   MCExpr.cpp
   MCExternalSymbolizer.cpp

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed Mar 19 21:12:01 2014
@@ -778,7 +778,7 @@ void ELFObjectWriter::RecordRelocation(c
         Index = 0;
       }
     } else {
-      if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
+      if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_WEAKREF)
         WeakrefUsedInReloc.insert(RelocSymbol);
       else
         UsedInReloc.insert(RelocSymbol);
@@ -823,8 +823,14 @@ ELFObjectWriter::getSymbolIndexInSymbolT
 bool ELFObjectWriter::isInSymtab(const MCAssembler &Asm,
                                  const MCSymbolData &Data,
                                  bool Used, bool Renamed) {
-  if (Data.getFlags() & ELF_Other_Weakref)
-    return false;
+  const MCSymbol &Symbol = Data.getSymbol();
+  if (Symbol.isVariable()) {
+    const MCExpr *Expr = Symbol.getVariableValue();
+    if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
+      if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
+        return false;
+    }
+  }
 
   if (Used)
     return true;
@@ -832,8 +838,6 @@ bool ELFObjectWriter::isInSymtab(const M
   if (Renamed)
     return false;
 
-  const MCSymbol &Symbol = Data.getSymbol();
-
   if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
     return true;
 

Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Wed Mar 19 21:12:01 2014
@@ -99,9 +99,8 @@ void MCELFStreamer::ChangeSection(const
 
 void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
   getAssembler().getOrCreateSymbolData(*Symbol);
-  MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
-  AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
-  const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, getContext());
+  const MCExpr *Value = MCSymbolRefExpr::Create(
+      Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
   Alias->setVariableValue(Value);
 }
 

Modified: llvm/trunk/lib/MC/MCExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCExpr.cpp (original)
+++ llvm/trunk/lib/MC/MCExpr.cpp Wed Mar 19 21:12:01 2014
@@ -180,6 +180,7 @@ StringRef MCSymbolRefExpr::getVariantKin
   case VK_DTPOFF: return "DTPOFF";
   case VK_TLVP: return "TLVP";
   case VK_SECREL: return "SECREL32";
+  case VK_WEAKREF: return "WEAKREF";
   case VK_ARM_NONE: return "none";
   case VK_ARM_TARGET1: return "target1";
   case VK_ARM_TARGET2: return "target2";
@@ -630,17 +631,31 @@ bool MCExpr::EvaluateAsRelocatableImpl(M
   case SymbolRef: {
     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
     const MCSymbol &Sym = SRE->getSymbol();
+    const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo();
 
     // Evaluate recursively if this is a variable.
-    if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
-      bool Ret = Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm,
-                                                                   Layout,
-                                                                   Addrs,
-                                                                   true);
-      // If we failed to simplify this to a constant, let the target
-      // handle it.
-      if (Ret && !Res.getSymA() && !Res.getSymB())
-        return true;
+    if (Sym.isVariable()) {
+      if (Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Asm, Layout,
+                                                            Addrs, true)) {
+        const MCSymbolRefExpr *A = Res.getSymA();
+        const MCSymbolRefExpr *B = Res.getSymB();
+
+        if (MCAsmInfo.hasSubsectionsViaSymbols()) {
+          // FIXME: This is small hack. Given
+          // a = b + 4
+          // .long a
+          // the OS X assembler will completely drop the 4. We should probably
+          // include it in the relocation or produce an error if that is not
+          // possible.
+          if (!A && !B)
+            return true;
+        } else {
+          bool IsSymbol = A && A->getSymbol().isDefined();
+          bool IsWeakRef = SRE->getKind() == MCSymbolRefExpr::VK_WEAKREF;
+          if (!IsSymbol && !IsWeakRef)
+            return true;
+        }
+      }
     }
 
     Res = MCValue::get(SRE, 0, 0);

Added: llvm/trunk/lib/MC/MCFixup.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCFixup.cpp?rev=204294&view=auto
==============================================================================
--- llvm/trunk/lib/MC/MCFixup.cpp (added)
+++ llvm/trunk/lib/MC/MCFixup.cpp Wed Mar 19 21:12:01 2014
@@ -0,0 +1,36 @@
+//===- MCFixup.cpp - Assembly Fixup Implementation ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCFixup.h"
+using namespace llvm;
+
+static MCSymbolRefExpr::VariantKind getAccessVariant(const MCExpr *Expr) {
+  switch (Expr->getKind()) {
+  case MCExpr::Unary:
+  case MCExpr::Target:
+    llvm_unreachable("unsupported");
+
+  case MCExpr::Constant:
+    return MCSymbolRefExpr::VK_None;
+
+  case MCExpr::SymbolRef: {
+    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
+    return SRE->getKind();
+  }
+  case MCExpr::Binary: {
+    const MCBinaryExpr *ABE = cast<MCBinaryExpr>(Expr);
+    assert(getAccessVariant(ABE->getRHS()) == MCSymbolRefExpr::VK_None);
+    return getAccessVariant(ABE->getLHS());
+  }
+  }
+}
+
+MCSymbolRefExpr::VariantKind MCFixup::getAccessVariant() const {
+  return ::getAccessVariant(getValue());
+}

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp Wed Mar 19 21:12:01 2014
@@ -71,17 +71,16 @@ const MCSymbol *ARMELFObjectWriter::Expl
   bool InNormalSection = true;
   unsigned RelocType = 0;
   RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel);
+  assert(!Target.getSymB() ||
+         Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None);
 
   DEBUG(
-      const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind();
-      MCSymbolRefExpr::VariantKind Kind2;
-      Kind2 = Target.getSymB() ?  Target.getSymB()->getKind() :
-        MCSymbolRefExpr::VK_None;
+      MCSymbolRefExpr::VariantKind Kind = Fixup.getAccessVariant();
       dbgs() << "considering symbol "
         << Section.getSectionName() << "/"
         << Symbol.getName() << "/"
         << " Rel:" << (unsigned)RelocType
-        << " Kind: " << (int)Kind << "/" << (int)Kind2
+        << " Kind: " << (int)Kind
         << " Tmp:"
         << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/"
         << Symbol.isVariable() << "/" << Symbol.isTemporary()
@@ -152,8 +151,7 @@ unsigned ARMELFObjectWriter::GetRelocTyp
 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
                                                const MCFixup &Fixup,
                                                bool IsPCRel) const  {
-  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
-    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+  MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
 
   unsigned Type = 0;
   if (IsPCRel) {

Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp Wed Mar 19 21:12:01 2014
@@ -9,6 +9,7 @@
 
 #include "MCTargetDesc/PPCMCTargetDesc.h"
 #include "MCTargetDesc/PPCFixupKinds.h"
+#include "MCTargetDesc/PPCMCExpr.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCExpr.h"
@@ -49,12 +50,37 @@ PPCELFObjectWriter::PPCELFObjectWriter(b
 PPCELFObjectWriter::~PPCELFObjectWriter() {
 }
 
+static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) {
+  const MCExpr *Expr = Fixup.getValue();
+
+  if (Expr->getKind() != MCExpr::Target)
+    return Fixup.getAccessVariant();
+
+  switch (cast<PPCMCExpr>(Expr)->getKind()) {
+  case PPCMCExpr::VK_PPC_None:
+    return MCSymbolRefExpr::VK_None;
+  case PPCMCExpr::VK_PPC_LO:
+    return MCSymbolRefExpr::VK_PPC_LO;
+  case PPCMCExpr::VK_PPC_HI:
+    return MCSymbolRefExpr::VK_PPC_HI;
+  case PPCMCExpr::VK_PPC_HA:
+    return MCSymbolRefExpr::VK_PPC_HA;
+  case PPCMCExpr::VK_PPC_HIGHERA:
+    return MCSymbolRefExpr::VK_PPC_HIGHERA;
+  case PPCMCExpr::VK_PPC_HIGHER:
+    return MCSymbolRefExpr::VK_PPC_HIGHER;
+  case PPCMCExpr::VK_PPC_HIGHEST:
+    return MCSymbolRefExpr::VK_PPC_HIGHEST;
+  case PPCMCExpr::VK_PPC_HIGHESTA:
+    return MCSymbolRefExpr::VK_PPC_HIGHESTA;
+  }
+}
+
 unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
                                                const MCFixup &Fixup,
                                                bool IsPCRel) const
 {
-  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
-    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+  MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup);
 
   // determine the type of the relocation
   unsigned Type;
@@ -368,8 +394,7 @@ const MCSymbol *PPCELFObjectWriter::Expl
                                                    const MCFixup &Fixup,
                                                    bool IsPCRel) const {
   assert(Target.getSymA() && "SymA cannot be 0");
-  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
-    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+  MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
 
   bool EmitThisSym;
   switch (Modifier) {

Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp Wed Mar 19 21:12:01 2014
@@ -88,9 +88,7 @@ unsigned SystemZObjectWriter::GetRelocTy
                                            bool IsPCRel,
                                            bool IsRelocWithSymbol,
                                            int64_t Addend) const {
-  MCSymbolRefExpr::VariantKind Modifier = (Target.isAbsolute() ?
-                                           MCSymbolRefExpr::VK_None :
-                                           Target.getSymA()->getKind());
+  MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
   unsigned Kind = Fixup.getKind();
   switch (Modifier) {
   case MCSymbolRefExpr::VK_None:

Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp Wed Mar 19 21:12:01 2014
@@ -46,8 +46,7 @@ unsigned X86ELFObjectWriter::GetRelocTyp
                                           int64_t Addend) const {
   // determine the type of the relocation
 
-  MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ?
-    MCSymbolRefExpr::VK_None : Target.getSymA()->getKind();
+  MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant();
   unsigned Type;
   if (getEMachine() == ELF::EM_X86_64) {
     if (IsPCRel) {

Modified: llvm/trunk/test/MC/ELF/relocation.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/relocation.s?rev=204294&r1=204293&r2=204294&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/relocation.s (original)
+++ llvm/trunk/test/MC/ELF/relocation.s Wed Mar 19 21:12:01 2014
@@ -25,6 +25,9 @@ bar:
 	.word   foo-bar
 	.byte   foo-bar
 
+	zed = foo +2
+	call zed at PLT
+
 // CHECK:        Section {
 // CHECK:          Name: .rela.text
 // CHECK:          Relocations [
@@ -49,6 +52,7 @@ bar:
 // CHECK-NEXT:       0x85 R_X86_64_TPOFF64 baz 0x0
 // CHECK-NEXT:       0x8D R_X86_64_PC16 foo 0x8D
 // CHECK-NEXT:       0x8F R_X86_64_PC8 foo 0x8F
+// CHECK-NEXT:       0x91 R_X86_64_PLT32 foo 0xFFFFFFFFFFFFFFFE
 // CHECK-NEXT:     ]
 // CHECK-NEXT:   }
 

Added: llvm/trunk/test/MC/X86/reloc-undef-global.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/X86/reloc-undef-global.s?rev=204294&view=auto
==============================================================================
--- llvm/trunk/test/MC/X86/reloc-undef-global.s (added)
+++ llvm/trunk/test/MC/X86/reloc-undef-global.s Wed Mar 19 21:12:01 2014
@@ -0,0 +1,20 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o - | llvm-readobj -r | FileCheck --check-prefix=ELF %s
+// RUN: llvm-mc -filetype=obj -triple x86_64-apple-darwin %s -o - | llvm-readobj -r | FileCheck --check-prefix=MACHO %s
+
+
+bar = foo + 4
+	.globl bar
+	.long bar
+
+// ELF:      Relocations [
+// ELF-NEXT:   Section (2) .rela.text {
+// ELF-NEXT:     0x0 R_X86_64_32 foo 0x4
+// ELF-NEXT:   }
+// ELF-NEXT: ]
+
+
+// MACHO: Relocations [
+// MACHO:   Section __text {
+// MACHO:     0x0 0 2 1 X86_64_RELOC_UNSIGNED 0 bar
+// MACHO:   }
+// MACHO: ]





More information about the llvm-commits mailing list