diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-05-03 19:57:04 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-05-03 19:57:04 +0000 |
commit | 3d082fa50704f55a3c6d25c9d6b25d652e7d84ae (patch) | |
tree | a3aff89a7742699070c17f25e005b1f04fdeb4a7 /llvm/lib | |
parent | 834652ade026fa990a110c8bc572f988d94a18a5 (diff) | |
download | bcm5719-llvm-3d082fa50704f55a3c6d25c9d6b25d652e7d84ae.tar.gz bcm5719-llvm-3d082fa50704f55a3c6d25c9d6b25d652e7d84ae.zip |
Fix pr19645.
The fix itself is fairly simple: move getAccessVariant to MCValue so that we
replace the old weak expression evaluation with the far more general
EvaluateAsRelocatable.
This then requires that EvaluateAsRelocatable stop when it finds a non
trivial reference kind. And that in turn requires the ELF writer to look
harder for weak references.
Last but not least, this found a case where we were being bug by bug
compatible with gas and accepting an invalid input. I reported pr19647
to track it.
llvm-svn: 207920
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/CMakeLists.txt | 1 | ||||
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/MC/MCExpr.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCFixup.cpp | 42 | ||||
-rw-r--r-- | llvm/lib/MC/MCValue.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp | 2 |
9 files changed, 47 insertions, 53 deletions
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index 7b69c7a9e36..6a384c1a8e1 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -16,7 +16,6 @@ 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 3bce1211920..0a54627f8cd 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -787,6 +787,25 @@ bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, return false; } +static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { + const MCSymbol &Sym = Ref.getSymbol(); + + if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Sym; + + if (!Sym.isVariable()) + return nullptr; + + const MCExpr *Expr = Sym.getVariableValue(); + const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); + if (!Inner) + return nullptr; + + if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) + return &Inner->getSymbol(); + return nullptr; +} + void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, @@ -872,8 +891,8 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, if (const MCSymbol *R = Renames.lookup(SymA)) SymA = R; - if (RefA->getKind() == MCSymbolRefExpr::VK_WEAKREF) - WeakrefUsedInReloc.insert(SymA); + if (const MCSymbol *WeakRef = getWeakRef(*RefA)) + WeakrefUsedInReloc.insert(WeakRef); else UsedInReloc.insert(SymA); } diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index 60b14ad53ee..ff5009f0a20 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -658,12 +658,11 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, case SymbolRef: { const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this); - bool IsWeakRef = SRE->getKind() == MCSymbolRefExpr::VK_WEAKREF; const MCSymbol &Sym = SRE->getSymbol(); const MCAsmInfo &MCAsmInfo = SRE->getMCAsmInfo(); // Evaluate recursively if this is a variable. - if (Sym.isVariable() && !IsWeakRef) { + if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None) { if (Sym.getVariableValue()->EvaluateAsRelocatableImpl( Res, Asm, Layout, Addrs, true, ForceVarExpansion)) { const MCSymbolRefExpr *A = Res.getSymA(); diff --git a/llvm/lib/MC/MCFixup.cpp b/llvm/lib/MC/MCFixup.cpp deleted file mode 100644 index e41e67350c5..00000000000 --- a/llvm/lib/MC/MCFixup.cpp +++ /dev/null @@ -1,42 +0,0 @@ -//===- 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: { - assert(getAccessVariant(cast<MCUnaryExpr>(Expr)->getSubExpr()) == - MCSymbolRefExpr::VK_None); - return MCSymbolRefExpr::VK_None; - } - - 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()); - } - } - llvm_unreachable("unknown MCExpr kind"); -} - -MCSymbolRefExpr::VariantKind MCFixup::getAccessVariant() const { - return ::getAccessVariant(getValue()); -} diff --git a/llvm/lib/MC/MCValue.cpp b/llvm/lib/MC/MCValue.cpp index 21d9e2102e2..9dfc56ef23d 100644 --- a/llvm/lib/MC/MCValue.cpp +++ b/llvm/lib/MC/MCValue.cpp @@ -10,6 +10,7 @@ #include "llvm/MC/MCValue.h" #include "llvm/MC/MCExpr.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -41,3 +42,20 @@ void MCValue::dump() const { print(dbgs(), nullptr); } #endif + +MCSymbolRefExpr::VariantKind MCValue::getAccessVariant() const { + const MCSymbolRefExpr *B = getSymB(); + if (B) { + if (B->getKind() != MCSymbolRefExpr::VK_None) + llvm_unreachable("unsupported"); + } + + const MCSymbolRefExpr *A = getSymA(); + if (!A) + return MCSymbolRefExpr::VK_None; + + MCSymbolRefExpr::VariantKind Kind = A->getKind(); + if (Kind == MCSymbolRefExpr::VK_WEAKREF) + return MCSymbolRefExpr::VK_None; + return Kind; +} diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index a6f7258e651..1c842633f43 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -74,7 +74,7 @@ unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant(); + MCSymbolRefExpr::VariantKind Modifier = Target.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 d19f6a0214d..cd3b4f45359 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -41,11 +41,12 @@ PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) PPCELFObjectWriter::~PPCELFObjectWriter() { } -static MCSymbolRefExpr::VariantKind getAccessVariant(const MCFixup &Fixup) { +static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, + const MCFixup &Fixup) { const MCExpr *Expr = Fixup.getValue(); if (Expr->getKind() != MCExpr::Target) - return Fixup.getAccessVariant(); + return Target.getAccessVariant(); switch (cast<PPCMCExpr>(Expr)->getKind()) { case PPCMCExpr::VK_PPC_None: @@ -72,7 +73,7 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup); + MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); // determine the type of the relocation unsigned Type; diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp index 54c6987ca2f..c6a18165889 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp @@ -82,7 +82,7 @@ static unsigned getPLTReloc(unsigned Kind) { unsigned SystemZObjectWriter::GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant(); + MCSymbolRefExpr::VariantKind Modifier = Target.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 c4a1af86157..3fdec874cba 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -43,7 +43,7 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, bool IsPCRel) const { // determine the type of the relocation - MCSymbolRefExpr::VariantKind Modifier = Fixup.getAccessVariant(); + MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); unsigned Type; if (getEMachine() == ELF::EM_X86_64) { if (IsPCRel) { |