[llvm-commits] [llvm] r119152 - in /llvm/trunk: include/llvm/MC/MCSymbol.h lib/MC/ELFObjectWriter.cpp lib/MC/MCAssembler.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCExpr.cpp lib/MC/MCSymbol.cpp test/MC/ELF/alias-reloc.s

Rafael Espindola rafael.espindola at gmail.com
Mon Nov 15 08:33:49 PST 2010


Author: rafael
Date: Mon Nov 15 10:33:49 2010
New Revision: 119152

URL: http://llvm.org/viewvc/llvm-project?rev=119152&view=rev
Log:
Change MCExpr::EvaluateAsRelocatableImpl of variables to return the original
variable if recursing fails to simplify it.

Factor AliasedSymbol to be a method of MCSymbol.

Update MCAssembler::EvaluateFixup to match the change in
EvaluateAsRelocatableImpl.

Remove the WeakRefExpr hack, as the object writer now sees the weakref with
no extra effort needed.

Nothing else is using MCTargetExpr, but keep it for now.

Now that the ELF writer sees relocations with aliases, handle

    .weak    foo2
foo2:
    .weak    bar2
    .set    bar2,foo2
    .quad    bar2

the same way gas does and produce a relocation with bar2.

Modified:
    llvm/trunk/include/llvm/MC/MCSymbol.h
    llvm/trunk/lib/MC/ELFObjectWriter.cpp
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/lib/MC/MCELFStreamer.cpp
    llvm/trunk/lib/MC/MCExpr.cpp
    llvm/trunk/lib/MC/MCSymbol.cpp
    llvm/trunk/test/MC/ELF/alias-reloc.s

Modified: llvm/trunk/include/llvm/MC/MCSymbol.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSymbol.h?rev=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSymbol.h (original)
+++ llvm/trunk/include/llvm/MC/MCSymbol.h Mon Nov 15 10:33:49 2010
@@ -138,6 +138,11 @@
       return Value;
     }
 
+    // AliasedSymbol() - If this is an alias (a = b), return the symbol
+    // we ultimately point to. For a non alias, this just returns the symbol
+    // itself.
+    const MCSymbol &AliasedSymbol() const;
+
     void setVariableValue(const MCExpr *Value);
 
     /// @}

Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Mon Nov 15 10:33:49 2010
@@ -504,31 +504,6 @@
   return 0;
 }
 
-static const MCSymbol &AliasedSymbol(const MCSymbol &Symbol) {
-  const MCSymbol *S = &Symbol;
-  while (S->isVariable()) {
-    const MCExpr *Value = S->getVariableValue();
-    MCExpr::ExprKind Kind = Value->getKind();
-    switch (Kind) {
-    case MCExpr::SymbolRef: {
-      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Value);
-      S = &Ref->getSymbol();
-      break;
-    }
-    case MCExpr::Target: {
-      const MCTargetExpr *TExp = static_cast<const MCTargetExpr*>(Value);
-      MCValue Res;
-      TExp->EvaluateAsRelocatableImpl(Res, NULL);
-      S = &Res.getSymA()->getSymbol();
-      break;
-    }
-    default:
-      return *S;
-    }
-  }
-  return *S;
-}
-
 void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) {
   // The presence of symbol versions causes undefined symbols and
   // versions declared with @@@ to be renamed.
@@ -536,7 +511,7 @@
   for (MCAssembler::symbol_iterator it = Asm.symbol_begin(),
          ie = Asm.symbol_end(); it != ie; ++it) {
     const MCSymbol &Alias = it->getSymbol();
-    const MCSymbol &Symbol = AliasedSymbol(Alias);
+    const MCSymbol &Symbol = Alias.AliasedSymbol();
     MCSymbolData &SD = Asm.getSymbolData(Symbol);
 
     // Not an alias.
@@ -572,7 +547,7 @@
                                   const MCAsmLayout &Layout) {
   MCSymbolData &OrigData = *MSD.SymbolData;
   MCSymbolData &Data =
-    Layout.getAssembler().getSymbolData(AliasedSymbol(OrigData.getSymbol()));
+    Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol());
 
   bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
     Data.getSymbol().isVariable();
@@ -673,28 +648,24 @@
                                                const MCValue &Target,
                                                const MCFragment &F) const {
   const MCSymbol &Symbol = Target.getSymA()->getSymbol();
-  const MCSymbol &ASymbol = AliasedSymbol(Symbol);
-  const MCSymbol *RenamedP = Renames.lookup(&Symbol);
-
-  if (!RenamedP) {
-    if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None ||
-        Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref)
-      RenamedP = &ASymbol;
-    else
-      RenamedP = &Symbol;
+  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
+  const MCSymbol *Renamed = Renames.lookup(&Symbol);
+  const MCSymbolData &SD = Asm.getSymbolData(Symbol);
+
+  if (ASymbol.isUndefined()) {
+    if (Renamed)
+      return Renamed;
+    return &ASymbol;
   }
-  const MCSymbol &Renamed = *RenamedP;
-
-  MCSymbolData &SD = Asm.getSymbolData(Symbol);
-
-  if (Symbol.isUndefined())
-    return &Renamed;
 
-  if (SD.isExternal())
-    return &Renamed;
+  if (SD.isExternal()) {
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
+  }
 
   const MCSectionELF &Section =
-    static_cast<const MCSectionELF&>(Symbol.getSection());
+    static_cast<const MCSectionELF&>(ASymbol.getSection());
 
   if (Section.getKind().isBSS())
     return NULL;
@@ -706,13 +677,18 @@
   if (&Sec2 != &Section &&
       (Kind == MCSymbolRefExpr::VK_PLT ||
        Kind == MCSymbolRefExpr::VK_GOTPCREL ||
-       Kind == MCSymbolRefExpr::VK_GOTOFF))
-    return &Renamed;
+       Kind == MCSymbolRefExpr::VK_GOTOFF)) {
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
+  }
 
   if (Section.getFlags() & MCSectionELF::SHF_MERGE) {
-    if (Target.getConstant() != 0)
-      return &Renamed;
-    return NULL;
+    if (Target.getConstant() == 0)
+      return NULL;
+    if (Renamed)
+      return Renamed;
+    return &Symbol;
   }
 
   return NULL;
@@ -742,7 +718,7 @@
   if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
     return true;
 
-  const MCSymbol &A = AliasedSymbol(Symbol);
+  const MCSymbol &A = Symbol.AliasedSymbol();
   if (!A.isVariable() && A.isUndefined() && !Data.isCommon())
     return false;
 
@@ -761,7 +737,7 @@
     return false;
 
   const MCSymbol &Symbol = Data.getSymbol();
-  const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
+  const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
 
   if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) {
     if (isSignature && !isUsedInReloc)
@@ -830,7 +806,7 @@
 
     ELFSymbolData MSD;
     MSD.SymbolData = it;
-    const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
+    const MCSymbol &RefSymbol = Symbol.AliasedSymbol();
 
     // Undefined symbols are global, but this is the first place we
     // are able to set it.
@@ -1104,13 +1080,13 @@
   const MCSection *SectionA = 0;
   const MCSymbol *SymbolA = 0;
   if (const MCSymbolRefExpr *A = Target.getSymA()) {
-    SymbolA = &A->getSymbol();
+    SymbolA = &A->getSymbol().AliasedSymbol();
     SectionA = &SymbolA->getSection();
   }
 
   const MCSection *SectionB = 0;
   if (const MCSymbolRefExpr *B = Target.getSymB()) {
-    SectionB = &B->getSymbol().getSection();
+    SectionB = &B->getSymbol().AliasedSymbol().getSection();
   }
 
   if (!BaseSection)
@@ -1413,6 +1389,7 @@
   int Index = 0;
   int64_t Value = Target.getConstant();
   const MCSymbol &Symbol = Target.getSymA()->getSymbol();
+  const MCSymbol &ASymbol = Symbol.AliasedSymbol();
   const MCSymbol *RelocSymbol = SymbolToReloc(Asm, Target, *Fragment);
 
   bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
@@ -1432,7 +1409,7 @@
     }
 
     if (!RelocSymbol) {
-      MCSymbolData &SD = Asm.getSymbolData(Symbol);
+      MCSymbolData &SD = Asm.getSymbolData(ASymbol);
       MCFragment *F = SD.getFragment();
 
       Index = F->getParent()->getOrdinal();

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Nov 15 10:33:49 2010
@@ -285,14 +285,16 @@
     Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;
   bool IsResolved = true;
   if (const MCSymbolRefExpr *A = Target.getSymA()) {
-    if (A->getSymbol().isDefined())
-      Value += Layout.getSymbolAddress(&getSymbolData(A->getSymbol()));
+    const MCSymbol &Sym = A->getSymbol().AliasedSymbol();
+    if (Sym.isDefined())
+      Value += Layout.getSymbolAddress(&getSymbolData(Sym));
     else
       IsResolved = false;
   }
   if (const MCSymbolRefExpr *B = Target.getSymB()) {
-    if (B->getSymbol().isDefined())
-      Value -= Layout.getSymbolAddress(&getSymbolData(B->getSymbol()));
+    const MCSymbol &Sym = B->getSymbol().AliasedSymbol();
+    if (Sym.isDefined())
+      Value -= Layout.getSymbolAddress(&getSymbolData(Sym));
     else
       IsResolved = false;
   }

Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Mon Nov 15 10:33:49 2010
@@ -240,49 +240,6 @@
   Symbol->setVariableValue(AddValueSymbols(Value));
 }
 
-// This is a hack. To be able to implement weakrefs the writer has to be able
-// to distinguish
-//    .weakref foo, bar
-//    .long foo
-// from
-//   .weakref foo, bar
-//   .long bar
-// since the first case should produce a weak undefined reference and the second
-// one a strong one.
-// If we created foo as a regular alias pointing to bar (foo = bar), then
-// MCExpr::EvaluateAsRelocatable would recurse on foo and the writer would
-// never see it used in a relocation.
-// What we do is create a MCTargetExpr that when evaluated produces a symbol
-// ref to a temporary symbol. This temporary symbol in turn is a variable
-// that equals the original symbol (tmp = bar). With this hack the writer
-// gets a relocation with tmp and can correctly implement weak references.
-
-namespace {
-class WeakRefExpr : public MCTargetExpr {
-private:
-  const MCSymbolRefExpr *Alias;
-
-  explicit WeakRefExpr(const MCSymbolRefExpr *Alias_)
-    : MCTargetExpr(), Alias(Alias_) {}
-
-public:
-  virtual void PrintImpl(raw_ostream &OS) const {
-    llvm_unreachable("Unimplemented");
-  }
-
-  virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
-                                         const MCAsmLayout *Layout) const {
-    Res = MCValue::get(Alias, 0, 0);
-    return true;
-  }
-
-  static const WeakRefExpr *Create(const MCSymbol *Alias, MCContext &Ctx) {
-    const MCSymbolRefExpr *A = MCSymbolRefExpr::Create(Alias, Ctx);
-    return new (Ctx) WeakRefExpr(A);
-  }
-};
-} // end anonymous namespace
-
 void MCELFStreamer::SwitchSection(const MCSection *Section) {
   const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
   if (Grp)
@@ -294,16 +251,7 @@
   getAssembler().getOrCreateSymbolData(*Symbol);
   MCSymbolData &AliasSD = getAssembler().getOrCreateSymbolData(*Alias);
   AliasSD.setFlags(AliasSD.getFlags() | ELF_Other_Weakref);
-
-  // Create the alias that actually points to Symbol
-  const MCSymbolRefExpr *SymRef = MCSymbolRefExpr::Create(Symbol, getContext());
-  MCSymbol *RealAlias = getContext().CreateTempSymbol();
-  RealAlias->setVariableValue(SymRef);
-
-  MCSymbolData &RealAliasSD = getAssembler().getOrCreateSymbolData(*RealAlias);
-  RealAliasSD.setFlags(RealAliasSD.getFlags() | ELF_Other_Weakref);
-
-  const MCExpr *Value = WeakRefExpr::Create(RealAlias, getContext());
+  const MCExpr *Value = MCSymbolRefExpr::Create(Symbol, 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=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCExpr.cpp (original)
+++ llvm/trunk/lib/MC/MCExpr.cpp Mon Nov 15 10:33:49 2010
@@ -336,9 +336,14 @@
     const MCSymbol &Sym = SRE->getSymbol();
 
     // Evaluate recursively if this is a variable.
-    if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None)
-      return Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Layout,
-                                                               true);
+    if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) {
+      bool Ret = Sym.getVariableValue()->EvaluateAsRelocatableImpl(Res, Layout,
+                                                                   true);
+      // If we failed to simplify this to a constant, let the target
+      // handle it.
+      if (Ret && !Res.getSymA() && !Res.getSymB())
+        return true;
+    }
 
     Res = MCValue::get(SRE, 0, 0);
     return true;

Modified: llvm/trunk/lib/MC/MCSymbol.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSymbol.cpp?rev=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSymbol.cpp (original)
+++ llvm/trunk/lib/MC/MCSymbol.cpp Mon Nov 15 10:33:49 2010
@@ -39,6 +39,18 @@
   return false;
 }
 
+const MCSymbol &MCSymbol::AliasedSymbol() const {
+  const MCSymbol *S = this;
+  while (S->isVariable()) {
+    const MCExpr *Value = S->getVariableValue();
+    if (Value->getKind() != MCExpr::SymbolRef)
+      return *S;
+    const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Value);
+    S = &Ref->getSymbol();
+  }
+  return *S;
+}
+
 void MCSymbol::setVariableValue(const MCExpr *Value) {
   assert(!IsUsed && "Cannot set a variable that has already been used.");
   assert(Value && "Invalid variable value!");

Modified: llvm/trunk/test/MC/ELF/alias-reloc.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/alias-reloc.s?rev=119152&r1=119151&r2=119152&view=diff
==============================================================================
--- llvm/trunk/test/MC/ELF/alias-reloc.s (original)
+++ llvm/trunk/test/MC/ELF/alias-reloc.s Mon Nov 15 10:33:49 2010
@@ -8,6 +8,15 @@
         .section zed, "", @progbits
         call bar at PLT
 
+
+// Test that this produres a relocation with bar2
+
+    .weak    foo2
+foo2:
+    .weak    bar2
+    .set    bar2,foo2
+    .quad    bar2
+
 // CHECK:       # Symbol 0x00000001
 // CHECK-NEXT:  (('st_name', 0x00000005) # 'bar'
 // CHECK-NEXT:   ('st_bind', 0x00000000)
@@ -18,9 +27,26 @@
 // CHECK-NEXT:   ('st_size', 0x00000000)
 // CHECK-NEXT:  ),
 
+// CHECK:      # Symbol 0x00000006
+// CHECK-NEXT: (('st_name', 0x0000000e) # 'bar2'
+// CHECK-NEXT:  ('st_bind', 0x00000002)
+// CHECK-NEXT:  ('st_type', 0x00000000)
+// CHECK-NEXT:  ('st_other', 0x00000000)
+// CHECK-NEXT:  ('st_shndx', 0x00000004)
+// CHECK-NEXT:  ('st_value', 0x00000005)
+// CHECK-NEXT:  ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+
 // CHECK:       # Relocation 0x00000000
 // CHECK-NEXT:  (('r_offset', 0x00000001)
 // CHECK-NEXT:   ('r_sym', 0x00000001)
 // CHECK-NEXT:   ('r_type', 0x00000004)
 // CHECK-NEXT:   ('r_addend', 0xfffffffc)
 // CHECK-NEXT:  ),
+
+// CHECK:      # Relocation 0x00000001
+// CHECK-NEXT: (('r_offset', 0x00000005)
+// CHECK-NEXT:  ('r_sym', 0x00000006)
+// CHECK-NEXT:  ('r_type', 0x00000001)
+// CHECK-NEXT:  ('r_addend', 0x00000000)
+// CHECK-NEXT: ),





More information about the llvm-commits mailing list