diff options
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:   }  | 

