summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/MC/MCAssembler.h13
-rw-r--r--llvm/include/llvm/MC/MCExpr.h5
-rw-r--r--llvm/include/llvm/MC/MCMachObjectWriter.h5
-rw-r--r--llvm/include/llvm/MC/MCObjectWriter.h5
-rw-r--r--llvm/include/llvm/MC/MCSection.h6
-rw-r--r--llvm/include/llvm/MC/MCStreamer.h2
-rw-r--r--llvm/include/llvm/MC/MCSymbol.h63
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp3
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp4
-rw-r--r--llvm/lib/MC/MCAssembler.cpp16
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp10
-rw-r--r--llvm/lib/MC/MCExpr.cpp45
-rw-r--r--llvm/lib/MC/MCMachOStreamer.cpp7
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp4
-rw-r--r--llvm/lib/MC/MCObjectWriter.cpp10
-rw-r--r--llvm/lib/MC/MCSection.cpp2
-rw-r--r--llvm/lib/MC/MCStreamer.cpp9
-rw-r--r--llvm/lib/MC/MCSymbol.cpp5
-rw-r--r--llvm/lib/MC/MachObjectWriter.cpp12
-rw-r--r--llvm/lib/MC/WinCOFFStreamer.cpp2
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp2
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h2
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h4
-rw-r--r--llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp2
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h4
-rw-r--r--llvm/lib/Target/NVPTX/NVPTXMCExpr.h4
-rw-r--r--llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h4
-rw-r--r--llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h4
-rw-r--r--llvm/test/MC/COFF/alias.s4
-rw-r--r--llvm/test/MC/ELF/relocation.s8
30 files changed, 153 insertions, 113 deletions
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 6becda88ebf..d69472bf2ec 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -52,7 +52,8 @@ public:
FT_Dwarf,
FT_DwarfFrame,
FT_LEB,
- FT_SafeSEH
+ FT_SafeSEH,
+ FT_Dummy
};
private:
@@ -136,9 +137,19 @@ public:
/// and only some fragments have a meaningful implementation.
void setBundlePadding(uint8_t N) { BundlePadding = N; }
+ /// \brief Return true if given frgment has FT_Dummy type.
+ bool isDummy() const { return Kind == FT_Dummy; }
+
void dump();
};
+class MCDummyFragment : public MCFragment {
+public:
+ explicit MCDummyFragment(MCSection *Sec)
+ : MCFragment(FT_Dummy, false, 0, Sec){};
+ static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
+};
+
/// Interface implemented by fragments that contain encoded instructions and/or
/// data.
///
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index b3a607351a8..76da86cd7d6 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -20,6 +20,7 @@ class MCAsmLayout;
class MCAssembler;
class MCContext;
class MCFixup;
+class MCFragment;
class MCSection;
class MCStreamer;
class MCSymbol;
@@ -115,7 +116,7 @@ public:
/// currently defined as the absolute section for constants, or
/// otherwise the section associated with the first defined symbol in the
/// expression.
- MCSection *findAssociatedSection() const;
+ MCFragment *findAssociatedFragment() const;
/// @}
};
@@ -556,7 +557,7 @@ public:
const MCAsmLayout *Layout,
const MCFixup *Fixup) const = 0;
virtual void visitUsedExpr(MCStreamer& Streamer) const = 0;
- virtual MCSection *findAssociatedSection() const = 0;
+ virtual MCFragment *findAssociatedFragment() const = 0;
virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h
index 7eccd562af3..fe1227fe3dd 100644
--- a/llvm/include/llvm/MC/MCMachObjectWriter.h
+++ b/llvm/include/llvm/MC/MCMachObjectWriter.h
@@ -248,6 +248,11 @@ public:
const MCAsmLayout &Layout) override;
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &A,
+ const MCSymbol &B,
+ bool InSet) const override;
+
+ bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &SymA,
const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
diff --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h
index 406831aae81..ed1f493d74e 100644
--- a/llvm/include/llvm/MC/MCObjectWriter.h
+++ b/llvm/include/llvm/MC/MCObjectWriter.h
@@ -93,6 +93,11 @@ public:
bool InSet) const;
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbol &A,
+ const MCSymbol &B,
+ bool InSet) const;
+
+ virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
const MCSymbol &SymA,
const MCFragment &FB,
bool InSet,
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index 2d0d4dfc591..f5490fcd173 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Compiler.h"
@@ -92,6 +93,8 @@ private:
unsigned IsRegistered : 1;
+ MCDummyFragment DummyFragment;
+
FragmentListType Fragments;
/// Mapping from subsection number to insertion point for subsection numbers
@@ -152,6 +155,9 @@ public:
return const_cast<MCSection *>(this)->getFragmentList();
}
+ const MCDummyFragment &getDummyFragment() const { return DummyFragment; }
+ MCDummyFragment &getDummyFragment() { return DummyFragment; }
+
MCSection::iterator begin();
MCSection::const_iterator begin() const {
return const_cast<MCSection *>(this)->begin();
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 6beeaa9dd77..209bfe5801f 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -358,7 +358,7 @@ public:
///
/// Each emitted symbol will be tracked in the ordering table,
/// so we can sort on them later.
- void AssignSection(MCSymbol *Symbol, MCSection *Section);
+ void AssignFragment(MCSymbol *Symbol, MCFragment *Fragment);
/// \brief Emit a label for \p Symbol into the current section.
///
diff --git a/llvm/include/llvm/MC/MCSymbol.h b/llvm/include/llvm/MC/MCSymbol.h
index 563fa803b0e..c51ecfcb0c5 100644
--- a/llvm/include/llvm/MC/MCSymbol.h
+++ b/llvm/include/llvm/MC/MCSymbol.h
@@ -56,19 +56,17 @@ protected:
SymContentsCommon,
};
- // Special sentinal value for the absolute pseudo section.
- //
- // FIXME: Use a PointerInt wrapper for this?
- static MCSection *AbsolutePseudoSection;
+ // Special sentinal value for the absolute pseudo fragment.
+ static MCFragment *AbsolutePseudoFragment;
/// If a symbol has a Fragment, the section is implied, so we only need
/// one pointer.
+ /// The special AbsolutePseudoFragment value is for absolute symbols.
+ /// If this is a variable symbol, this caches the variable value's fragment.
/// FIXME: We might be able to simplify this by having the asm streamer create
/// dummy fragments.
/// If this is a section, then it gives the symbol is defined in. This is null
- /// for undefined symbols, and the special AbsolutePseudoSection value for
- /// absolute symbols. If this is a variable symbol, this caches the variable
- /// value's section.
+ /// for undefined symbols.
///
/// If this is a fragment, then it gives the fragment this symbol's value is
/// relative to, if any.
@@ -76,8 +74,7 @@ protected:
/// For the 'HasName' integer, this is true if this symbol is named.
/// A named symbol will have a pointer to the name allocated in the bytes
/// immediately prior to the MCSymbol.
- mutable PointerIntPair<PointerUnion<MCSection *, MCFragment *>, 1>
- SectionOrFragmentAndHasName;
+ mutable PointerIntPair<MCFragment *, 1> FragmentAndHasName;
/// IsTemporary - True if this is an assembler temporary label, which
/// typically does not survive in the .o file's symbol table. Usually
@@ -155,7 +152,7 @@ protected: // MCContext creates and uniques these.
Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset),
CommonAlignLog2(0), Flags(0) {
Offset = 0;
- SectionOrFragmentAndHasName.setInt(!!Name);
+ FragmentAndHasName.setInt(!!Name);
if (Name)
getNameEntryPtr() = Name;
}
@@ -180,19 +177,16 @@ private:
MCSymbol(const MCSymbol &) = delete;
void operator=(const MCSymbol &) = delete;
MCSection *getSectionPtr(bool SetUsed = true) const {
- if (MCFragment *F = getFragment())
+ if (MCFragment *F = getFragment(SetUsed)) {
+ assert(F != AbsolutePseudoFragment);
return F->getParent();
- const auto &SectionOrFragment = SectionOrFragmentAndHasName.getPointer();
- assert(!SectionOrFragment.is<MCFragment *>() && "Section or null expected");
- MCSection *Section = SectionOrFragment.dyn_cast<MCSection *>();
- if (Section || !isVariable())
- return Section;
- return Section = getVariableValue(SetUsed)->findAssociatedSection();
+ }
+ return nullptr;
}
/// \brief Get a reference to the name field. Requires that we have a name
const StringMapEntry<bool> *&getNameEntryPtr() {
- assert(SectionOrFragmentAndHasName.getInt() && "Name is required");
+ assert(FragmentAndHasName.getInt() && "Name is required");
NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this);
return (*(Name - 1)).NameEntry;
}
@@ -203,7 +197,7 @@ private:
public:
/// getName - Get the symbol name.
StringRef getName() const {
- if (!SectionOrFragmentAndHasName.getInt())
+ if (!FragmentAndHasName.getInt())
return StringRef();
return getNameEntryPtr()->first();
@@ -249,7 +243,7 @@ public:
///
/// Defined symbols are either absolute or in some section.
bool isDefined(bool SetUsed = true) const {
- return getSectionPtr(SetUsed) != nullptr;
+ return getFragment(SetUsed) != nullptr;
}
/// isInSection - Check if this symbol is defined in some section (i.e., it
@@ -263,7 +257,7 @@ public:
/// isAbsolute - Check if this is an absolute symbol.
bool isAbsolute(bool SetUsed = true) const {
- return getSectionPtr(SetUsed) == AbsolutePseudoSection;
+ return getFragment(SetUsed) == AbsolutePseudoFragment;
}
/// Get the section associated with a defined, non-absolute symbol.
@@ -272,19 +266,14 @@ public:
return *getSectionPtr(SetUsed);
}
- /// Mark the symbol as defined in the section \p S.
- void setSection(MCSection &S) {
- assert(!isVariable() && "Cannot set section of variable");
- assert(!SectionOrFragmentAndHasName.getPointer().is<MCFragment *>() &&
- "Section or null expected");
- SectionOrFragmentAndHasName.setPointer(&S);
+ /// Mark the symbol as defined in the fragment \p F.
+ void setFragment(MCFragment *F) const {
+ assert(!isVariable() && "Cannot set fragment of variable");
+ FragmentAndHasName.setPointer(F);
}
/// Mark the symbol as undefined.
- void setUndefined() {
- SectionOrFragmentAndHasName.setPointer(
- PointerUnion<MCSection *, MCFragment *>());
- }
+ void setUndefined() { FragmentAndHasName.setPointer(nullptr); }
bool isELF() const { return Kind == SymbolKindELF; }
@@ -385,11 +374,13 @@ public:
return SymbolContents == SymContentsCommon;
}
- MCFragment *getFragment() const {
- return SectionOrFragmentAndHasName.getPointer().dyn_cast<MCFragment *>();
- }
- void setFragment(MCFragment *Value) const {
- SectionOrFragmentAndHasName.setPointer(Value);
+ MCFragment *getFragment(bool SetUsed = true) const {
+ MCFragment *Fragment = FragmentAndHasName.getPointer();
+ if (Fragment || !isVariable())
+ return Fragment;
+ Fragment = getVariableValue(SetUsed)->findAssociatedFragment();
+ FragmentAndHasName.setPointer(Fragment);
+ return Fragment;
}
bool isExternal() const { return IsExternal; }
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index 16f299c8fd8..f1acc1d75fb 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -447,9 +447,6 @@ void ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer,
uint32_t StringIndex, ELFSymbolData &MSD,
const MCAsmLayout &Layout) {
const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
- assert((!Symbol.getFragment() ||
- (Symbol.getFragment()->getParent() == &Symbol.getSection())) &&
- "The symbol's section doesn't match the fragment's symbol");
const MCSymbolELF *Base =
cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 7a30075bac9..f9dbd5ad3f0 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -575,7 +575,7 @@ void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
if (Symbol)
- AssignSection(Symbol, Section);
+ AssignFragment(Symbol, &Section->getDummyFragment());
// Note: a .zerofill directive does not switch sections.
OS << ".zerofill ";
@@ -599,7 +599,7 @@ void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
// e.g. _a.
void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
- AssignSection(Symbol, Section);
+ AssignFragment(Symbol, &Section->getDummyFragment());
assert(Symbol && "Symbol shouldn't be NULL!");
// Instead of using the Section we'll just use the shortcut.
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index d93bf44928d..143d284897f 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -277,7 +277,7 @@ MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
: Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr),
Offset(~UINT64_C(0)) {
- if (Parent)
+ if (Parent && !isDummy())
Parent->getFragmentList().push_back(this);
}
@@ -319,6 +319,9 @@ void MCFragment::destroy() {
case FT_SafeSEH:
delete cast<MCSafeSEHFragment>(this);
return;
+ case FT_Dummy:
+ delete cast<MCDummyFragment>(this);
+ return;
}
}
@@ -411,7 +414,7 @@ const MCSymbol *MCAssembler::getAtom(const MCSymbol &S) const {
return &S;
// Absolute and undefined symbols have no defining atom.
- if (!S.getFragment())
+ if (!S.isInSection())
return nullptr;
// Non-linker visible symbols in sections which can't be atomized have no
@@ -547,6 +550,8 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
return cast<MCDwarfLineAddrFragment>(F).getContents().size();
case MCFragment::FT_DwarfFrame:
return cast<MCDwarfCallFrameFragment>(F).getContents().size();
+ case MCFragment::FT_Dummy:
+ llvm_unreachable("Should not have been added");
}
llvm_unreachable("invalid fragment kind");
@@ -780,6 +785,8 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
OW->writeBytes(CF.getContents());
break;
}
+ case MCFragment::FT_Dummy:
+ llvm_unreachable("Should not have been added");
}
assert(OW->getStream().tell() - Start == FragmentSize &&
@@ -1147,6 +1154,9 @@ void MCFragment::dump() {
case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
case MCFragment::FT_LEB: OS << "MCLEBFragment"; break;
case MCFragment::FT_SafeSEH: OS << "MCSafeSEHFragment"; break;
+ case MCFragment::FT_Dummy:
+ OS << "MCDummyFragment";
+ break;
}
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
@@ -1245,6 +1255,8 @@ void MCFragment::dump() {
OS << " Sym:" << F->getSymbol();
break;
}
+ case MCFragment::FT_Dummy:
+ break;
}
OS << ">";
}
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index f0b3ec699fe..fc4f8a6281b 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -111,7 +111,7 @@ void MCELFStreamer::EmitLabel(MCSymbol *S) {
MCObjectStreamer::EmitLabel(Symbol);
const MCSectionELF &Section =
- static_cast<const MCSectionELF&>(Symbol->getSection());
+ static_cast<const MCSectionELF &>(*getCurrentSectionOnly());
if (Section.getFlags() & ELF::SHF_TLS)
Symbol->setType(ELF::STT_TLS);
}
@@ -311,11 +311,6 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
Symbol->setType(ELF::STT_OBJECT);
if (Symbol->getBinding() == ELF::STB_LOCAL) {
- MCSection *Section = getAssembler().getContext().getELFSection(
- ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
-
- AssignSection(Symbol, Section);
-
struct LocalCommon L = {Symbol, Size, ByteAlignment};
LocalCommons.push_back(L);
} else {
@@ -630,7 +625,8 @@ void MCELFStreamer::Flush() {
const MCSymbol &Symbol = *i->Symbol;
uint64_t Size = i->Size;
unsigned ByteAlignment = i->ByteAlignment;
- MCSection &Section = Symbol.getSection();
+ MCSection &Section = *getAssembler().getContext().getELFSection(
+ ".bss", ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
getAssembler().registerSection(Section);
new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &Section);
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 042fd1c72a2..916e505c4b9 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -477,7 +477,8 @@ static void AttemptToFoldSymbolOffsetDifference(
if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
return;
- if (SA.getFragment() == SB.getFragment()) {
+ if (SA.getFragment() == SB.getFragment() && !SA.isVariable() &&
+ !SB.isVariable()) {
Addend += (SA.getOffset() - SB.getOffset());
// Pointers to Thumb symbols need to have their low-bit set to allow
@@ -606,7 +607,7 @@ bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const {
true);
}
-static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) {
+static bool canExpand(const MCSymbol &Sym, bool InSet) {
const MCExpr *Expr = Sym.getVariableValue();
const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
if (Inner) {
@@ -616,9 +617,7 @@ static bool canExpand(const MCSymbol &Sym, const MCAssembler *Asm, bool InSet) {
if (InSet)
return true;
- if (!Asm)
- return false;
- return !Asm->getWriter().isWeak(Sym);
+ return !Sym.isInSection();
}
bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
@@ -643,7 +642,7 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
// Evaluate recursively if this is a variable.
if (Sym.isVariable() && SRE->getKind() == MCSymbolRefExpr::VK_None &&
- canExpand(Sym, Asm, InSet)) {
+ canExpand(Sym, InSet)) {
bool IsMachO = SRE->hasSubsectionsViaSymbols();
if (Sym.getVariableValue()->evaluateAsRelocatableImpl(
Res, Asm, Layout, Fixup, Addrs, InSet || IsMachO)) {
@@ -775,45 +774,41 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
llvm_unreachable("Invalid assembly expression kind!");
}
-MCSection *MCExpr::findAssociatedSection() const {
+MCFragment *MCExpr::findAssociatedFragment() const {
switch (getKind()) {
case Target:
// We never look through target specific expressions.
- return cast<MCTargetExpr>(this)->findAssociatedSection();
+ return cast<MCTargetExpr>(this)->findAssociatedFragment();
case Constant:
- return MCSymbol::AbsolutePseudoSection;
+ return MCSymbol::AbsolutePseudoFragment;
case SymbolRef: {
const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
const MCSymbol &Sym = SRE->getSymbol();
-
- if (Sym.isDefined())
- return &Sym.getSection();
-
- return nullptr;
+ return Sym.getFragment();
}
case Unary:
- return cast<MCUnaryExpr>(this)->getSubExpr()->findAssociatedSection();
+ return cast<MCUnaryExpr>(this)->getSubExpr()->findAssociatedFragment();
case Binary: {
const MCBinaryExpr *BE = cast<MCBinaryExpr>(this);
- MCSection *LHS_S = BE->getLHS()->findAssociatedSection();
- MCSection *RHS_S = BE->getRHS()->findAssociatedSection();
+ MCFragment *LHS_F = BE->getLHS()->findAssociatedFragment();
+ MCFragment *RHS_F = BE->getRHS()->findAssociatedFragment();
- // If either section is absolute, return the other.
- if (LHS_S == MCSymbol::AbsolutePseudoSection)
- return RHS_S;
- if (RHS_S == MCSymbol::AbsolutePseudoSection)
- return LHS_S;
+ // If either is absolute, return the other.
+ if (LHS_F == MCSymbol::AbsolutePseudoFragment)
+ return RHS_F;
+ if (RHS_F == MCSymbol::AbsolutePseudoFragment)
+ return LHS_F;
// Not always correct, but probably the best we can do without more context.
if (BE->getOpcode() == MCBinaryExpr::Sub)
- return MCSymbol::AbsolutePseudoSection;
+ return MCSymbol::AbsolutePseudoFragment;
- // Otherwise, return the first non-null section.
- return LHS_S ? LHS_S : RHS_S;
+ // Otherwise, return the first non-null fragment.
+ return LHS_F ? LHS_F : RHS_F;
}
}
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 0f65d51bb73..50ee08fa1f9 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -180,8 +180,6 @@ void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
- // isSymbolLinkerVisible uses the section.
- AssignSection(Symbol, getCurrentSection().first);
// We have to create a new fragment if this is an atom defining symbol,
// fragments cannot span atoms.
if (getAssembler().isSymbolLinkerVisible(*Symbol))
@@ -415,8 +413,6 @@ void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
if (ByteAlignment != 1)
new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section);
- AssignSection(Symbol, Section);
-
MCFragment *F = new MCFillFragment(0, 0, Size, Section);
Symbol->setFragment(F);
@@ -460,7 +456,8 @@ void MCMachOStreamer::FinishImpl() {
// defining symbols.
DenseMap<const MCFragment *, const MCSymbol *> DefiningSymbolMap;
for (const MCSymbol &Symbol : getAssembler().symbols()) {
- if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.getFragment()) {
+ if (getAssembler().isSymbolLinkerVisible(Symbol) && Symbol.isInSection() &&
+ !Symbol.isVariable()) {
// An atom defining symbol should never be internal to a fragment.
assert(Symbol.getOffset() == 0 &&
"Invalid offset in atom defining symbol!");
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index caee5da47a0..992b2cfe359 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -58,7 +58,8 @@ void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
const MCSymbol *Lo,
unsigned Size) {
// If not assigned to the same (valid) fragment, fallback.
- if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment()) {
+ if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
+ Hi->isVariable() || Lo->isVariable()) {
MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
return;
}
@@ -155,7 +156,6 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
MCStreamer::EmitLabel(Symbol);
getAssembler().registerSymbol(*Symbol);
- assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
// If there is a current fragment, mark the symbol as pointing into it.
// Otherwise queue the label and set its fragment pointer when we emit the
diff --git a/llvm/lib/MC/MCObjectWriter.cpp b/llvm/lib/MC/MCObjectWriter.cpp
index 34790340873..e84f74ae81d 100644
--- a/llvm/lib/MC/MCObjectWriter.cpp
+++ b/llvm/lib/MC/MCObjectWriter.cpp
@@ -33,8 +33,14 @@ bool MCObjectWriter::isSymbolRefDifferenceFullyResolved(
if (!SA.getFragment() || !SB.getFragment())
return false;
- return isSymbolRefDifferenceFullyResolvedImpl(Asm, SA, *SB.getFragment(),
- InSet, false);
+ return isSymbolRefDifferenceFullyResolvedImpl(Asm, SA, SB, InSet);
+}
+
+bool MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
+ const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B,
+ bool InSet) const {
+ return isSymbolRefDifferenceFullyResolvedImpl(Asm, A, *B.getFragment(), InSet,
+ false);
}
bool MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp
index 9152f2b42a4..e0d29bbd660 100644
--- a/llvm/lib/MC/MCSection.cpp
+++ b/llvm/lib/MC/MCSection.cpp
@@ -21,7 +21,7 @@ using namespace llvm;
MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
: Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
- IsRegistered(false), Variant(V), Kind(K) {}
+ IsRegistered(false), DummyFragment(this), Variant(V), Kind(K) {}
MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
if (!End)
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index d6b44a0297d..5d7685177b2 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -188,9 +188,9 @@ void MCStreamer::InitSections(bool NoExecStack) {
SwitchSection(getContext().getObjectFileInfo()->getTextSection());
}
-void MCStreamer::AssignSection(MCSymbol *Symbol, MCSection *Section) {
- assert(Section);
- Symbol->setSection(*Section);
+void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
+ assert(Fragment);
+ Symbol->setFragment(Fragment);
// As we emit symbols into a section, track the order so that they can
// be sorted upon later. Zero is reserved to mean 'unemitted'.
@@ -200,7 +200,8 @@ void MCStreamer::AssignSection(MCSymbol *Symbol, MCSection *Section) {
void MCStreamer::EmitLabel(MCSymbol *Symbol) {
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSection().first && "Cannot emit before setting section!");
- AssignSection(Symbol, getCurrentSection().first);
+ assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
+ Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
MCTargetStreamer *TS = getTargetStreamer();
if (TS)
diff --git a/llvm/lib/MC/MCSymbol.cpp b/llvm/lib/MC/MCSymbol.cpp
index 125380a9d14..c7d6213bc19 100644
--- a/llvm/lib/MC/MCSymbol.cpp
+++ b/llvm/lib/MC/MCSymbol.cpp
@@ -16,8 +16,9 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-// Sentinel value for the absolute pseudo section.
-MCSection *MCSymbol::AbsolutePseudoSection = reinterpret_cast<MCSection *>(1);
+// Sentinel value for the absolute pseudo fragment.
+MCFragment *MCSymbol::AbsolutePseudoFragment =
+ reinterpret_cast<MCFragment *>(4);
void *MCSymbol::operator new(size_t s, const StringMapEntry<bool> *Name,
MCContext &Ctx) {
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index 94d71f1116d..d5184f1d9a4 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -626,6 +626,18 @@ void MachObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
}
bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
+ const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B,
+ bool InSet) const {
+ // FIXME: We don't handle things like
+ // foo = .
+ // creating atoms.
+ if (A.isVariable() || B.isVariable())
+ return false;
+ return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, A, B,
+ InSet);
+}
+
+bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
const MCAssembler &Asm, const MCSymbol &SymA, const MCFragment &FB,
bool InSet, bool IsPCRel) const {
if (InSet)
diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp
index 40c242ce866..02814fa7d28 100644
--- a/llvm/lib/MC/WinCOFFStreamer.cpp
+++ b/llvm/lib/MC/WinCOFFStreamer.cpp
@@ -245,8 +245,6 @@ void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
getAssembler().registerSymbol(*Symbol);
Symbol->setExternal(false);
- AssignSection(Symbol, Section);
-
if (ByteAlignment != 1)
new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0,
ByteAlignment, Section);
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
index 29a903fd9f1..a540f49866a 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
@@ -85,7 +85,7 @@ void AArch64MCExpr::visitUsedExpr(MCStreamer &Streamer) const {
Streamer.visitUsedExpr(*getSubExpr());
}
-MCSection *AArch64MCExpr::findAssociatedSection() const {
+MCFragment *AArch64MCExpr::findAssociatedFragment() const {
llvm_unreachable("FIXME: what goes here?");
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
index b111e7c2ded..db36a65564c 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
@@ -149,7 +149,7 @@ public:
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *findAssociatedSection() const override;
+ MCFragment *findAssociatedFragment() const override;
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h
index 9146d4def75..75dde8008fc 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCExpr.h
@@ -63,8 +63,8 @@ public:
return false;
}
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *findAssociatedSection() const override {
- return getSubExpr()->findAssociatedSection();
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
}
// There are no TLS ARMMCExprs at the moment.
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp
index bf51c3515e9..1bec375f33e 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.cpp
@@ -114,7 +114,7 @@ void HexagonMCELFStreamer::HexagonMCEmitCommonSymbol(MCSymbol *Symbol,
MCSection *Section = getAssembler().getContext().getELFSection(
SectionName, ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
SwitchSection(Section);
- AssignSection(Symbol, Section);
+ AssignFragment(Symbol, getCurrentFragment());
MCELFStreamer::EmitCommonSymbol(Symbol, Size, ByteAlignment);
SwitchSection(CrntSection);
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
index fd2ed17ee78..e889972c5c0 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCExpr.h
@@ -51,8 +51,8 @@ public:
const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *findAssociatedSection() const override {
- return getSubExpr()->findAssociatedSection();
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
}
// There are no TLS MipsMCExprs at the moment.
diff --git a/llvm/lib/Target/NVPTX/NVPTXMCExpr.h b/llvm/lib/Target/NVPTX/NVPTXMCExpr.h
index 46b4b33e7e4..81a606d7535 100644
--- a/llvm/lib/Target/NVPTX/NVPTXMCExpr.h
+++ b/llvm/lib/Target/NVPTX/NVPTXMCExpr.h
@@ -68,7 +68,7 @@ public:
return false;
}
void visitUsedExpr(MCStreamer &Streamer) const override {};
- MCSection *findAssociatedSection() const override { return nullptr; }
+ MCFragment *findAssociatedFragment() const override { return nullptr; }
// There are no TLS NVPTXMCExprs at the moment.
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
@@ -110,7 +110,7 @@ public:
return false;
}
void visitUsedExpr(MCStreamer &Streamer) const override {};
- MCSection *findAssociatedSection() const override { return nullptr; }
+ MCFragment *findAssociatedFragment() const override { return nullptr; }
// There are no TLS NVPTXMCExprs at the moment.
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override {}
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
index a641780516b..d42a111cc43 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h
@@ -82,8 +82,8 @@ public:
const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *findAssociatedSection() const override {
- return getSubExpr()->findAssociatedSection();
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
}
// There are no TLS PPCMCExprs at the moment.
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
index d08ad86dbe0..13f08195c76 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
@@ -90,8 +90,8 @@ public:
const MCAsmLayout *Layout,
const MCFixup *Fixup) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
- MCSection *findAssociatedSection() const override {
- return getSubExpr()->findAssociatedSection();
+ MCFragment *findAssociatedFragment() const override {
+ return getSubExpr()->findAssociatedFragment();
}
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
diff --git a/llvm/test/MC/COFF/alias.s b/llvm/test/MC/COFF/alias.s
index 2293d43c575..369bbe8d844 100644
--- a/llvm/test/MC/COFF/alias.s
+++ b/llvm/test/MC/COFF/alias.s
@@ -21,9 +21,9 @@ weak_aliased_to_external = external2
.long weak_aliased_to_external
// CHECK: Relocations [
-// CHECK: 0x0 IMAGE_REL_I386_DIR32 local1
+// CHECK: 0x0 IMAGE_REL_I386_DIR32 external_aliased_to_local
// CHECK: 0x4 IMAGE_REL_I386_DIR32 external1
-// CHECK: 0x8 IMAGE_REL_I386_DIR32 local2
+// CHECK: 0x8 IMAGE_REL_I386_DIR32 global_aliased_to_local
// CHECK: 0xC IMAGE_REL_I386_DIR32 external2
// CHECK: ]
// CHECK: Symbols [
diff --git a/llvm/test/MC/ELF/relocation.s b/llvm/test/MC/ELF/relocation.s
index 34f1a403813..0fec7679281 100644
--- a/llvm/test/MC/ELF/relocation.s
+++ b/llvm/test/MC/ELF/relocation.s
@@ -55,6 +55,11 @@ bar:
.quad pr23272_2 - pr23272
.quad pr23272_3 - pr23272
+ .global pr24486
+pr24486:
+ pr24486_alias = pr24486
+ .long pr24486_alias
+
.code16
call pr23771
@@ -94,6 +99,7 @@ bar:
// CHECK-NEXT: 0xD4 R_X86_64_SIZE32 blah 0xFFFFFFFFFFFFFFE0
// CHECK-NEXT: 0xD8 R_X86_64_GOTPCREL foo 0x0
// CHECK-NEXT: 0xDC R_X86_64_PLT32 foo 0x0
-// CHECK-NEXT: 0xF1 R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
+// CHECK-NEXT: 0xF0 R_X86_64_32 .text 0xF0
+// CHECK-NEXT: 0xF5 R_X86_64_PC16 pr23771 0xFFFFFFFFFFFFFFFE
// CHECK-NEXT: ]
// CHECK-NEXT: }
OpenPOWER on IntegriCloud