summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/CMakeLists.txt1
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp14
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp5
-rw-r--r--llvm/lib/MC/MCExpr.cpp33
-rw-r--r--llvm/lib/MC/MCFixup.cpp36
5 files changed, 72 insertions, 17 deletions
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 06099640a1a..eb3f9e52d73 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -16,6 +16,7 @@ add_llvm_library(LLVMMC
MCELF.cpp
MCELFObjectTargetWriter.cpp
MCELFStreamer.cpp
+ MCFixup.cpp
MCFunction.cpp
MCExpr.cpp
MCExternalSymbolizer.cpp
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 909ea800830..1dae2f467d3 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -778,7 +778,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
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::getSymbolIndexInSymbolTable(const MCAssembler &Asm,
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 MCAssembler &Asm,
if (Renamed)
return false;
- const MCSymbol &Symbol = Data.getSymbol();
-
if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_")
return true;
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 5f6a889769d..d07ef9e698e 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -99,9 +99,8 @@ void MCELFStreamer::ChangeSection(const MCSection *Section,
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);
}
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 9a4c41699e1..673913f0b82 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -180,6 +180,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
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(MCValue &Res,
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);
diff --git a/llvm/lib/MC/MCFixup.cpp b/llvm/lib/MC/MCFixup.cpp
new file mode 100644
index 00000000000..d0a4fed28f9
--- /dev/null
+++ b/llvm/lib/MC/MCFixup.cpp
@@ -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());
+}
OpenPOWER on IntegriCloud