summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-03-20 02:12:01 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-03-20 02:12:01 +0000
commit7fadc0ea7df49f4fef7da3797ea382d9486cc259 (patch)
treea240de0de7267b634fd4b36e1e7673f661941f53 /llvm/lib
parent05c152b5d134a878ae8781d6fc3b8619f387c9de (diff)
downloadbcm5719-llvm-7fadc0ea7df49f4fef7da3797ea382d9486cc259.tar.gz
bcm5719-llvm-7fadc0ea7df49f4fef7da3797ea382d9486cc259.zip
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@PLT doing this also fixes zed = foo +2 call zed@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. llvm-svn: 204294
Diffstat (limited to 'llvm/lib')
-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
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp12
-rw-r--r--llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp33
-rw-r--r--llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp4
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp3
9 files changed, 108 insertions, 33 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());
+}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
index 25efd67c69b..d829394e09e 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -71,17 +71,16 @@ const MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
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::GetRelocType(const MCValue &Target,
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) {
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
index 54de70eff71..1e3d4b71aef 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
@@ -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(bool Is64Bit, uint8_t OSABI)
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::ExplicitRelSym(const MCAssembler &Asm,
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) {
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
index 217a51cea49..ddc1379e340 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
@@ -88,9 +88,7 @@ unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target,
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:
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
index 7118a6f6dc5..618b0e6e1ed 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
@@ -46,8 +46,7 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target,
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) {
OpenPOWER on IntegriCloud