diff options
19 files changed, 317 insertions, 247 deletions
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h index a6d41392724..216271086a4 100644 --- a/llvm/include/llvm/MC/MCAsmBackend.h +++ b/llvm/include/llvm/MC/MCAsmBackend.h @@ -61,12 +61,6 @@ public:    /// markers. If not, data region directives will be ignored.    bool hasDataInCodeSupport() const { return HasDataInCodeSupport; } -  /// doesSectionRequireSymbols - Check whether the given section requires that -  /// all symbols (even temporaries) have symbol table entries. -  virtual bool doesSectionRequireSymbols(const MCSection &Section) const { -    return false; -  } -    /// @name Target Fixup Interfaces    /// @{ diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 681a3172879..31f29eb1f3f 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -11,6 +11,7 @@  #define LLVM_MC_MCASSEMBLER_H  #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h"  #include "llvm/ADT/PointerIntPair.h"  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/SmallString.h" @@ -881,6 +882,8 @@ private:    iplist<MCSymbolData> Symbols; +  DenseSet<const MCSymbol *> LocalsUsedInReloc; +    /// The map of sections to their associated assembler backend data.    //    // FIXME: Avoid this indirection? @@ -980,6 +983,9 @@ private:                                          MCFragment &F, const MCFixup &Fixup);  public: +  void addLocalUsedInReloc(const MCSymbol &Sym); +  bool isLocalUsedInReloc(const MCSymbol &Sym) const; +    /// Compute the effective fragment size assuming it is laid out at the given    /// \p SectionAddress and \p FragmentOffset.    uint64_t computeFragmentSize(const MCAsmLayout &Layout, diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h index 0c5aa8a1806..e4681c0a3dc 100644 --- a/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -68,12 +68,10 @@ public:    /// @name API    /// @{ -  virtual void RecordRelocation(MachObjectWriter *Writer, -                                const MCAssembler &Asm, +  virtual void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,                                  const MCAsmLayout &Layout,                                  const MCFragment *Fragment, -                                const MCFixup &Fixup, -                                MCValue Target, +                                const MCFixup &Fixup, MCValue Target,                                  uint64_t &FixedValue) = 0;    /// @} @@ -97,8 +95,14 @@ class MachObjectWriter : public MCObjectWriter {    /// @name Relocation Data    /// @{ -  llvm::DenseMap<const MCSectionData*, -                 std::vector<MachO::any_relocation_info> > Relocations; +  struct RelAndSymbol { +    const MCSymbolData *Sym; +    MachO::any_relocation_info MRE; +    RelAndSymbol(const MCSymbolData *Sym, const MachO::any_relocation_info &MRE) +        : Sym(Sym), MRE(MRE) {} +  }; + +  llvm::DenseMap<const MCSectionData *, std::vector<RelAndSymbol>> Relocations;    llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;    /// @} @@ -213,9 +217,15 @@ public:    //  - Input errors, where something cannot be correctly encoded. 'as' allows    //    these through in many cases. -  void addRelocation(const MCSectionData *SD, +  // Add a relocation to be output in the object file. At the time this is +  // called, the symbol indexes are not know, so if the relocation refers +  // to a symbol it should be passed as \p RelSymbol so that it can be updated +  // afterwards. If the relocation doesn't refer to a symbol, nullptr should be +  // used. +  void addRelocation(const MCSymbolData *RelSymbol, const MCSectionData *SD,                       MachO::any_relocation_info &MRE) { -    Relocations[SD].push_back(MRE); +    RelAndSymbol P(RelSymbol, MRE); +    Relocations[SD].push_back(P);    }    void RecordScatteredRelocation(const MCAssembler &Asm, @@ -231,7 +241,7 @@ public:                              const MCFixup &Fixup, MCValue Target,                              uint64_t &FixedValue); -  void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, +  void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,                          const MCFragment *Fragment, const MCFixup &Fixup,                          MCValue Target, bool &IsPCRel,                          uint64_t &FixedValue) override; diff --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h index 55c828c6c17..173ef416f2c 100644 --- a/llvm/include/llvm/MC/MCObjectWriter.h +++ b/llvm/include/llvm/MC/MCObjectWriter.h @@ -76,12 +76,10 @@ public:    /// post layout binding. The implementation is responsible for storing    /// information about the relocation so that it can be emitted during    /// WriteObject(). -  virtual void RecordRelocation(const MCAssembler &Asm, -                                const MCAsmLayout &Layout, +  virtual void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,                                  const MCFragment *Fragment,                                  const MCFixup &Fixup, MCValue Target, -                                bool &IsPCRel, -                                uint64_t &FixedValue) = 0; +                                bool &IsPCRel, uint64_t &FixedValue) = 0;    /// \brief Check whether the difference (A - B) between two symbol    /// references is fully resolved. diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index e4442e10a05..83a76dc2256 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -219,7 +219,7 @@ class ELFObjectWriter : public MCObjectWriter {                                    const MCSymbolData *SD, uint64_t C,                                    unsigned Type) const; -    void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, +    void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,                            const MCFragment *Fragment, const MCFixup &Fixup,                            MCValue Target, bool &IsPCRel,                            uint64_t &FixedValue) override; @@ -789,13 +789,11 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) {    return nullptr;  } -void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, +void ELFObjectWriter::RecordRelocation(MCAssembler &Asm,                                         const MCAsmLayout &Layout,                                         const MCFragment *Fragment, -                                       const MCFixup &Fixup, -                                       MCValue Target, -                                       bool &IsPCRel, -                                       uint64_t &FixedValue) { +                                       const MCFixup &Fixup, MCValue Target, +                                       bool &IsPCRel, uint64_t &FixedValue) {    const MCSectionData *FixupSection = Fragment->getParent();    uint64_t C = Target.getConstant();    uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); diff --git a/llvm/lib/MC/MCAsmInfoDarwin.cpp b/llvm/lib/MC/MCAsmInfoDarwin.cpp index 04cc0ff4a86..f7054902f24 100644 --- a/llvm/lib/MC/MCAsmInfoDarwin.cpp +++ b/llvm/lib/MC/MCAsmInfoDarwin.cpp @@ -27,22 +27,7 @@ bool MCAsmInfoDarwin::isSectionAtomizableBySymbols(    // contain.    // Sections holding 2 byte strings require symbols in order to be atomized.    // There is no dedicated section for 4 byte strings. -  if (SMO.getKind().isMergeable1ByteCString()) -    return false; - -  if (SMO.getSegmentName() == "__TEXT" && -      SMO.getSectionName() == "__objc_classname" && -      SMO.getType() == MachO::S_CSTRING_LITERALS) -    return false; - -  if (SMO.getSegmentName() == "__TEXT" && -      SMO.getSectionName() == "__objc_methname" && -      SMO.getType() == MachO::S_CSTRING_LITERALS) -    return false; - -  if (SMO.getSegmentName() == "__TEXT" && -      SMO.getSectionName() == "__objc_methtype" && -      SMO.getType() == MachO::S_CSTRING_LITERALS) +  if (SMO.getType() == MachO::S_CSTRING_LITERALS)      return false;    if (SMO.getSegmentName() == "__DATA" && SMO.getSectionName() == "__cfstring") diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 459488bfe15..a4af21efee1 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -425,6 +425,16 @@ bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {    return true;  } +void MCAssembler::addLocalUsedInReloc(const MCSymbol &Sym) { +  assert(Sym.isTemporary()); +  LocalsUsedInReloc.insert(&Sym); +} + +bool MCAssembler::isLocalUsedInReloc(const MCSymbol &Sym) const { +  assert(Sym.isTemporary()); +  return LocalsUsedInReloc.count(&Sym); +} +  bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {    // Non-temporary labels should always be visible to the linker.    if (!Symbol.isTemporary()) @@ -434,8 +444,10 @@ bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {    if (!Symbol.isInSection())      return false; -  // Otherwise, check if the section requires symbols even for temporary labels. -  return getBackend().doesSectionRequireSymbols(Symbol.getSection()); +  if (isLocalUsedInReloc(Symbol)) +    return true; + +  return false;  }  const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index d3751bd9ba5..588d424120c 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -448,14 +448,11 @@ void MachObjectWriter::WriteLinkerOptionsLoadCommand(    assert(OS.tell() - Start == Size);  } - -void MachObjectWriter::RecordRelocation(const MCAssembler &Asm, +void MachObjectWriter::RecordRelocation(MCAssembler &Asm,                                          const MCAsmLayout &Layout,                                          const MCFragment *Fragment, -                                        const MCFixup &Fixup, -                                        MCValue Target, -                                        bool &IsPCRel, -                                        uint64_t &FixedValue) { +                                        const MCFixup &Fixup, MCValue Target, +                                        bool &IsPCRel, uint64_t &FixedValue) {    TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup,                                         Target, FixedValue);  } @@ -616,6 +613,22 @@ void MachObjectWriter::ComputeSymbolTable(      ExternalSymbolData[i].SymbolData->setIndex(Index++);    for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i)      UndefinedSymbolData[i].SymbolData->setIndex(Index++); + +  for (const MCSectionData &SD : Asm) { +    std::vector<RelAndSymbol> &Relocs = Relocations[&SD]; +    for (RelAndSymbol &Rel : Relocs) { +      if (!Rel.Sym) +        continue; + +      // Set the Index and the IsExtern bit. +      unsigned Index = Rel.Sym->getIndex(); +      assert(isInt<24>(Index)); +      if (IsLittleEndian) +        Rel.MRE.r_word1 = (Rel.MRE.r_word1 & (-1 << 24)) | Index | (1 << 27); +      else +        Rel.MRE.r_word1 = (Rel.MRE.r_word1 & 0xff) | Index << 8 | (1 << 4); +    } +  }  }  void MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, @@ -662,10 +675,6 @@ void MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,    // Mark symbol difference expressions in variables (from .set or = directives)    // as absolute.    markAbsoluteVariableSymbols(Asm, Layout); - -  // Compute symbol table information and bind symbol indices. -  ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData, -                     UndefinedSymbolData);  }  bool MachObjectWriter:: @@ -749,6 +758,10 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,  void MachObjectWriter::WriteObject(MCAssembler &Asm,                                     const MCAsmLayout &Layout) { +  // Compute symbol table information and bind symbol indices. +  ComputeSymbolTable(Asm, LocalSymbolData, ExternalSymbolData, +                     UndefinedSymbolData); +    unsigned NumSections = Asm.size();    const MCAssembler::VersionMinInfoType &VersionInfo =      Layout.getAssembler().getVersionMinInfo(); @@ -839,7 +852,7 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,    uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;    for (MCAssembler::const_iterator it = Asm.begin(),           ie = Asm.end(); it != ie; ++it) { -    std::vector<MachO::any_relocation_info> &Relocs = Relocations[it]; +    std::vector<RelAndSymbol> &Relocs = Relocations[it];      unsigned NumRelocs = Relocs.size();      uint64_t SectionStart = SectionDataStart + getSectionAddress(it);      WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs); @@ -933,10 +946,10 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,           ie = Asm.end(); it != ie; ++it) {      // Write the section relocation entries, in reverse order to match 'as'      // (approximately, the exact algorithm is more complicated than this). -    std::vector<MachO::any_relocation_info> &Relocs = Relocations[it]; +    std::vector<RelAndSymbol> &Relocs = Relocations[it];      for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { -      Write32(Relocs[e - i - 1].r_word0); -      Write32(Relocs[e - i - 1].r_word1); +      Write32(Relocs[e - i - 1].MRE.r_word0); +      Write32(Relocs[e - i - 1].MRE.r_word1);      }    } diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 2180b42bcb5..2cb247a7a90 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -175,7 +175,7 @@ public:                                                const MCFragment &FB, bool InSet,                                                bool IsPCRel) const override; -  void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, +  void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,                          const MCFragment *Fragment, const MCFixup &Fixup,                          MCValue Target, bool &IsPCRel,                          uint64_t &FixedValue) override; @@ -661,13 +661,9 @@ bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(                                                                  InSet, IsPCRel);  } -void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, -                                           const MCAsmLayout &Layout, -                                           const MCFragment *Fragment, -                                           const MCFixup &Fixup, -                                           MCValue Target, -                                           bool &IsPCRel, -                                           uint64_t &FixedValue) { +void WinCOFFObjectWriter::RecordRelocation( +    MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, +    const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) {    assert(Target.getSymA() && "Relocation must reference a symbol!");    const MCSymbol &Symbol = Target.getSymA()->getSymbol(); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp index 458ba3c2f54..05db044dfe6 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -317,42 +317,6 @@ public:                                           MachO::CPU_SUBTYPE_ARM64_ALL);    } -  bool doesSectionRequireSymbols(const MCSection &Section) const override { -    // Any section for which the linker breaks things into atoms needs to -    // preserve symbols, including assembler local symbols, to identify -    // those atoms. These sections are: -    // Sections of type: -    // -    //    S_CSTRING_LITERALS  (e.g. __cstring) -    //    S_LITERAL_POINTERS  (e.g.  objc selector pointers) -    //    S_16BYTE_LITERALS, S_8BYTE_LITERALS, S_4BYTE_LITERALS -    // -    // Sections named: -    // -    //    __TEXT,__eh_frame -    //    __TEXT,__ustring -    //    __DATA,__cfstring -    //    __DATA,__objc_classrefs -    //    __DATA,__objc_catlist -    // -    // FIXME: It would be better if the compiler used actual linker local -    // symbols for each of these sections rather than preserving what -    // are ostensibly assembler local symbols. -    const MCSectionMachO &SMO = static_cast<const MCSectionMachO &>(Section); -    return (SMO.getType() == MachO::S_CSTRING_LITERALS || -            SMO.getType() == MachO::S_4BYTE_LITERALS || -            SMO.getType() == MachO::S_8BYTE_LITERALS || -            SMO.getType() == MachO::S_16BYTE_LITERALS || -            SMO.getType() == MachO::S_LITERAL_POINTERS || -            (SMO.getSegmentName() == "__TEXT" && -             (SMO.getSectionName() == "__eh_frame" || -              SMO.getSectionName() == "__ustring")) || -            (SMO.getSegmentName() == "__DATA" && -             (SMO.getSectionName() == "__cfstring" || -              SMO.getSectionName() == "__objc_classrefs" || -              SMO.getSectionName() == "__objc_catlist"))); -  } -    /// \brief Generate the compact unwind encoding from the CFI directives.    uint32_t generateCompactUnwindEncoding(                               ArrayRef<MCCFIInstruction> Instrs) const override { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp index e12a24be0a6..f6fab5d6b6f 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp @@ -10,6 +10,7 @@  #include "MCTargetDesc/AArch64FixupKinds.h"  #include "MCTargetDesc/AArch64MCTargetDesc.h"  #include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCAsmLayout.h"  #include "llvm/MC/MCAssembler.h"  #include "llvm/MC/MCContext.h" @@ -33,7 +34,7 @@ public:        : MCMachObjectTargetWriter(true /* is64Bit */, CPUType, CPUSubtype,                                   /*UseAggressiveSymbolFolding=*/true) {} -  void RecordRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, +  void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,                          const MCAsmLayout &Layout, const MCFragment *Fragment,                          const MCFixup &Fixup, MCValue Target,                          uint64_t &FixedValue) override; @@ -112,8 +113,25 @@ bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo(    }  } +static bool canUseLocalRelocation(const MCSectionMachO &Section, +                                  const MCSymbol &Symbol, unsigned Log2Size) { +  // Debug info sections can use local relocations. +  if (Section.hasAttribute(MachO::S_ATTR_DEBUG)) +    return true; + +  // Otherwise, only pointer sized relocations are supported. +  if (Log2Size != 3) +    return false; + +  // But only if they don't point to a cstring. +  if (!Symbol.isInSection()) +    return true; +  const MCSectionMachO &RefSec = cast<MCSectionMachO>(Symbol.getSection()); +  return RefSec.getType() != MachO::S_CSTRING_LITERALS; +} +  void AArch64MachObjectWriter::RecordRelocation( -    MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, +    MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout,      const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target,      uint64_t &FixedValue) {    unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); @@ -123,9 +141,9 @@ void AArch64MachObjectWriter::RecordRelocation(    unsigned Log2Size = 0;    int64_t Value = 0;    unsigned Index = 0; -  unsigned IsExtern = 0;    unsigned Type = 0;    unsigned Kind = Fixup.getKind(); +  const MCSymbolData *RelSymbol = nullptr;    FixupOffset += Fixup.getOffset(); @@ -171,10 +189,8 @@ void AArch64MachObjectWriter::RecordRelocation(      // FIXME: Should this always be extern?      // SymbolNum of 0 indicates the absolute section.      Type = MachO::ARM64_RELOC_UNSIGNED; -    Index = 0;      if (IsPCRel) { -      IsExtern = 1;        Asm.getContext().FatalError(Fixup.getLoc(),                                    "PC relative absolute relocation!"); @@ -198,15 +214,12 @@ void AArch64MachObjectWriter::RecordRelocation(          Layout.getSymbolOffset(&B_SD) ==              Layout.getFragmentOffset(Fragment) + Fixup.getOffset()) {        // SymB is the PC, so use a PC-rel pointer-to-GOT relocation. -      Index = A_Base->getIndex(); -      IsExtern = 1;        Type = MachO::ARM64_RELOC_POINTER_TO_GOT;        IsPCRel = 1;        MachO::any_relocation_info MRE;        MRE.r_word0 = FixupOffset; -      MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | -                     (IsExtern << 27) | (Type << 28)); -      Writer->addRelocation(Fragment->getParent(), MRE); +      MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); +      Writer->addRelocation(A_Base, Fragment->getParent(), MRE);        return;      } else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None ||                 Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) @@ -252,26 +265,31 @@ void AArch64MachObjectWriter::RecordRelocation(                    ? 0                    : Writer->getSymbolAddress(B_Base, Layout)); -    Index = A_Base->getIndex(); -    IsExtern = 1;      Type = MachO::ARM64_RELOC_UNSIGNED;      MachO::any_relocation_info MRE;      MRE.r_word0 = FixupOffset; -    MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | -                   (IsExtern << 27) | (Type << 28)); -    Writer->addRelocation(Fragment->getParent(), MRE); +    MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); +    Writer->addRelocation(A_Base, Fragment->getParent(), MRE); -    Index = B_Base->getIndex(); -    IsExtern = 1; +    RelSymbol = B_Base;      Type = MachO::ARM64_RELOC_SUBTRACTOR;    } else { // A + constant      const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); -    const MCSymbolData &SD = Asm.getSymbolData(*Symbol); -    const MCSymbolData *Base = Asm.getAtom(&SD);      const MCSectionMachO &Section = static_cast<const MCSectionMachO &>(          Fragment->getParent()->getSection()); +    bool CanUseLocalRelocation = +        canUseLocalRelocation(Section, *Symbol, Log2Size); +    if (Symbol->isTemporary() && (Value || !CanUseLocalRelocation)) { +      const MCSection &Sec = Symbol->getSection(); +      if (!Asm.getContext().getAsmInfo()->isSectionAtomizableBySymbols(Sec)) +        Asm.addLocalUsedInReloc(*Symbol); +    } + +    const MCSymbolData &SD = Asm.getSymbolData(*Symbol); +    const MCSymbolData *Base = Asm.getAtom(&SD); +      // If the symbol is a variable and we weren't able to get a Base for it      // (i.e., it's not in the symbol table associated with a section) resolve      // the relocation based its expansion instead. @@ -310,16 +328,13 @@ void AArch64MachObjectWriter::RecordRelocation(      // sections, and for pointer-sized relocations (.quad), we allow section      // relocations.  It's code sections that run into trouble.      if (Base) { -      Index = Base->getIndex(); -      IsExtern = 1; +      RelSymbol = Base;        // Add the local offset, if needed.        if (Base != &SD)          Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base);      } else if (Symbol->isInSection()) { -      // Pointer-sized relocations can use a local relocation. Otherwise, -      // we have to be in a debug info section. -      if (!Section.hasAttribute(MachO::S_ATTR_DEBUG) && Log2Size != 3) +      if (!CanUseLocalRelocation)          Asm.getContext().FatalError(              Fixup.getLoc(),              "unsupported relocation of local symbol '" + Symbol->getName() + @@ -329,7 +344,6 @@ void AArch64MachObjectWriter::RecordRelocation(        const MCSectionData &SymSD =            Asm.getSectionData(SD.getSymbol().getSection());        Index = SymSD.getOrdinal() + 1; -      IsExtern = 0;        Value += Writer->getSymbolAddress(&SD, Layout);        if (IsPCRel) @@ -362,16 +376,16 @@ void AArch64MachObjectWriter::RecordRelocation(      MachO::any_relocation_info MRE;      MRE.r_word0 = FixupOffset; -    MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | -                   (IsExtern << 27) | (Type << 28)); -    Writer->addRelocation(Fragment->getParent(), MRE); +    MRE.r_word1 = +        (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); +    Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);      // Now set up the Addend relocation.      Type = MachO::ARM64_RELOC_ADDEND;      Index = Value; +    RelSymbol = nullptr;      IsPCRel = 0;      Log2Size = 2; -    IsExtern = 0;      // Put zero into the instruction itself. The addend is in the relocation.      Value = 0; @@ -383,9 +397,9 @@ void AArch64MachObjectWriter::RecordRelocation(    // struct relocation_info (8 bytes)    MachO::any_relocation_info MRE;    MRE.r_word0 = FixupOffset; -  MRE.r_word1 = ((Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | -                 (IsExtern << 27) | (Type << 28)); -  Writer->addRelocation(Fragment->getParent(), MRE); +  MRE.r_word1 = +      (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); +  Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);  }  MCObjectWriter *llvm::createAArch64MachObjectWriter(raw_ostream &OS, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp index 7da500390ed..3187d36f751 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -54,10 +54,10 @@ public:      : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,                                 /*UseAggressiveSymbolFolding=*/true) {} -  void RecordRelocation(MachObjectWriter *Writer, -                        const MCAssembler &Asm, const MCAsmLayout &Layout, -                        const MCFragment *Fragment, const MCFixup &Fixup, -                        MCValue Target, uint64_t &FixedValue) override; +  void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, +                        const MCAsmLayout &Layout, const MCFragment *Fragment, +                        const MCFixup &Fixup, MCValue Target, +                        uint64_t &FixedValue) override;  };  } @@ -232,7 +232,7 @@ RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,                     (IsPCRel               << 30) |                     MachO::R_SCATTERED);      MRE.r_word1 = Value2; -    Writer->addRelocation(Fragment->getParent(), MRE); +    Writer->addRelocation(nullptr, Fragment->getParent(), MRE);    }    MachO::any_relocation_info MRE; @@ -243,7 +243,7 @@ RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,                   (IsPCRel     << 30) |                   MachO::R_SCATTERED);    MRE.r_word1 = Value; -  Writer->addRelocation(Fragment->getParent(), MRE); +  Writer->addRelocation(nullptr, Fragment->getParent(), MRE);  }  void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer, @@ -297,7 +297,7 @@ void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer,                     (IsPCRel               << 30) |                     MachO::R_SCATTERED);      MRE.r_word1 = Value2; -    Writer->addRelocation(Fragment->getParent(), MRE); +    Writer->addRelocation(nullptr, Fragment->getParent(), MRE);    }    MachO::any_relocation_info MRE; @@ -307,7 +307,7 @@ void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer,                   (IsPCRel     << 30) |                   MachO::R_SCATTERED);    MRE.r_word1 = Value; -  Writer->addRelocation(Fragment->getParent(), MRE); +  Writer->addRelocation(nullptr, Fragment->getParent(), MRE);  }  bool ARMMachObjectWriter::requiresExternRelocation(MachObjectWriter *Writer, @@ -351,11 +351,10 @@ bool ARMMachObjectWriter::requiresExternRelocation(MachObjectWriter *Writer,  }  void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer, -                                           const MCAssembler &Asm, +                                           MCAssembler &Asm,                                             const MCAsmLayout &Layout,                                             const MCFragment *Fragment, -                                           const MCFixup &Fixup, -                                           MCValue Target, +                                           const MCFixup &Fixup, MCValue Target,                                             uint64_t &FixedValue) {    unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());    unsigned Log2Size; @@ -401,8 +400,8 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,    // See <reloc.h>.    uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();    unsigned Index = 0; -  unsigned IsExtern = 0;    unsigned Type = 0; +  const MCSymbolData *RelSymbol = nullptr;    if (Target.isAbsolute()) { // constant      // FIXME! @@ -422,8 +421,7 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,      // Check whether we need an external or internal relocation.      if (requiresExternRelocation(Writer, Asm, *Fragment, RelocType, SD,                                   FixedValue)) { -      IsExtern = 1; -      Index = SD->getIndex(); +      RelSymbol = SD;        // For external relocations, make sure to offset the fixup value to        // compensate for the addend of the symbol address, if it was @@ -447,11 +445,8 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,    // struct relocation_info (8 bytes)    MachO::any_relocation_info MRE;    MRE.r_word0 = FixupOffset; -  MRE.r_word1 = ((Index     <<  0) | -                 (IsPCRel   << 24) | -                 (Log2Size  << 25) | -                 (IsExtern  << 27) | -                 (Type      << 28)); +  MRE.r_word1 = +      (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);    // Even when it's not a scattered relocation, movw/movt always uses    // a PAIR relocation. @@ -476,10 +471,10 @@ void ARMMachObjectWriter::RecordRelocation(MachObjectWriter *Writer,                         (Log2Size              << 25) |                         (MachO::ARM_RELOC_PAIR << 28)); -    Writer->addRelocation(Fragment->getParent(), MREPair); +    Writer->addRelocation(nullptr, Fragment->getParent(), MREPair);    } -  Writer->addRelocation(Fragment->getParent(), MRE); +  Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);  }  MCObjectWriter *llvm::createARMMachObjectWriter(raw_ostream &OS, diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp index df2f14a91a7..f7259b9a098 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp @@ -41,7 +41,7 @@ public:        : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,                                   /*UseAggressiveSymbolFolding=*/Is64Bit) {} -  void RecordRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, +  void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,                          const MCAsmLayout &Layout, const MCFragment *Fragment,                          const MCFixup &Fixup, MCValue Target,                          uint64_t &FixedValue) override { @@ -282,7 +282,7 @@ bool PPCMachObjectWriter::RecordScatteredRelocation(      MachO::any_relocation_info MRE;      makeScatteredRelocationInfo(MRE, other_half, MachO::GENERIC_RELOC_PAIR,                                  Log2Size, IsPCRel, Value2); -    Writer->addRelocation(Fragment->getParent(), MRE); +    Writer->addRelocation(nullptr, Fragment->getParent(), MRE);    } else {      // If the offset is more than 24-bits, it won't fit in a scattered      // relocation offset field, so we fall back to using a non-scattered @@ -296,7 +296,7 @@ bool PPCMachObjectWriter::RecordScatteredRelocation(    }    MachO::any_relocation_info MRE;    makeScatteredRelocationInfo(MRE, FixupOffset, Type, Log2Size, IsPCRel, Value); -  Writer->addRelocation(Fragment->getParent(), MRE); +  Writer->addRelocation(nullptr, Fragment->getParent(), MRE);    return true;  } @@ -331,9 +331,9 @@ void PPCMachObjectWriter::RecordPPCRelocation(    // See <reloc.h>.    const uint32_t FixupOffset = getFixupOffset(Layout, Fragment, Fixup);    unsigned Index = 0; -  unsigned IsExtern = 0;    unsigned Type = RelocType; +  const MCSymbolData *RelSymbol = nullptr;    if (Target.isAbsolute()) { // constant                               // SymbolNum of 0 indicates the absolute section.                               // @@ -355,8 +355,7 @@ void PPCMachObjectWriter::RecordPPCRelocation(      // Check whether we need an external or internal relocation.      if (Writer->doesSymbolRequireExternRelocation(SD)) { -      IsExtern = 1; -      Index = SD->getIndex(); +      RelSymbol = SD;        // For external relocations, make sure to offset the fixup value to        // compensate for the addend of the symbol address, if it was        // undefined. This occurs with weak definitions, for example. @@ -375,9 +374,8 @@ void PPCMachObjectWriter::RecordPPCRelocation(    // struct relocation_info (8 bytes)    MachO::any_relocation_info MRE; -  makeRelocationInfo(MRE, FixupOffset, Index, IsPCRel, Log2Size, IsExtern, -                     Type); -  Writer->addRelocation(Fragment->getParent(), MRE); +  makeRelocationInfo(MRE, FixupOffset, Index, IsPCRel, Log2Size, false, Type); +  Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);  }  MCObjectWriter *llvm::createPPCMachObjectWriter(raw_ostream &OS, bool Is64Bit, diff --git a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp index 5fb311b3016..d0c634fb7e4 100644 --- a/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp +++ b/llvm/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -29,7 +29,7 @@ public:                                  const MCAsmLayout &Layout) override {      //XXX: Implement if necessary.    } -  void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, +  void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,                          const MCFragment *Fragment, const MCFixup &Fixup,                          MCValue Target, bool &IsPCRel,                          uint64_t &FixedValue) override { diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index 164b4192ae6..719b761084f 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -777,19 +777,6 @@ public:                                       MachO::CPU_TYPE_X86_64, Subtype);    } -  bool doesSectionRequireSymbols(const MCSection &Section) const override { -    // Temporary labels in the string literals sections require symbols. The -    // issue is that the x86_64 relocation format does not allow symbol + -    // offset, and so the linker does not have enough information to resolve the -    // access to the appropriate atom unless an external relocation is used. For -    // non-cstring sections, we expect the compiler to use a non-temporary label -    // for anything that could have an addend pointing outside the symbol. -    // -    // See <rdar://problem/4765733>. -    const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); -    return SMO.getType() == MachO::S_CSTRING_LITERALS; -  } -    /// \brief Generate the compact unwind encoding for the CFI instructions.    uint32_t generateCompactUnwindEncoding(                               ArrayRef<MCCFIInstruction> Instrs) const override { diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp index 67b0c890085..7a83f4c64e6 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @@ -10,6 +10,7 @@  #include "MCTargetDesc/X86MCTargetDesc.h"  #include "MCTargetDesc/X86FixupKinds.h"  #include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCAsmLayout.h"  #include "llvm/MC/MCAssembler.h"  #include "llvm/MC/MCContext.h" @@ -47,23 +48,21 @@ class X86MachObjectWriter : public MCMachObjectTargetWriter {                                const MCFixup &Fixup,                                MCValue Target,                                uint64_t &FixedValue); -  void RecordX86_64Relocation(MachObjectWriter *Writer, -                              const MCAssembler &Asm, +  void RecordX86_64Relocation(MachObjectWriter *Writer, MCAssembler &Asm,                                const MCAsmLayout &Layout, -                              const MCFragment *Fragment, -                              const MCFixup &Fixup, -                              MCValue Target, -                              uint64_t &FixedValue); +                              const MCFragment *Fragment, const MCFixup &Fixup, +                              MCValue Target, uint64_t &FixedValue); +  public:    X86MachObjectWriter(bool Is64Bit, uint32_t CPUType,                        uint32_t CPUSubtype)      : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,                                 /*UseAggressiveSymbolFolding=*/Is64Bit) {} -  void RecordRelocation(MachObjectWriter *Writer, -                        const MCAssembler &Asm, const MCAsmLayout &Layout, -                        const MCFragment *Fragment, const MCFixup &Fixup, -                        MCValue Target, uint64_t &FixedValue) override { +  void RecordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, +                        const MCAsmLayout &Layout, const MCFragment *Fragment, +                        const MCFixup &Fixup, MCValue Target, +                        uint64_t &FixedValue) override {      if (Writer->is64Bit())        RecordX86_64Relocation(Writer, Asm, Layout, Fragment, Fixup, Target,                               FixedValue); @@ -97,13 +96,10 @@ static unsigned getFixupKindLog2Size(unsigned Kind) {    }  } -void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer, -                                                 const MCAssembler &Asm, -                                                 const MCAsmLayout &Layout, -                                                 const MCFragment *Fragment, -                                                 const MCFixup &Fixup, -                                                 MCValue Target, -                                                 uint64_t &FixedValue) { +void X86MachObjectWriter::RecordX86_64Relocation( +    MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, +    const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, +    uint64_t &FixedValue) {    unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());    unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind());    unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); @@ -117,6 +113,7 @@ void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,    unsigned Index = 0;    unsigned IsExtern = 0;    unsigned Type = 0; +  const MCSymbolData *RelSymbol = nullptr;    Value = Target.getConstant(); @@ -132,7 +129,6 @@ void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,    if (Target.isAbsolute()) { // constant      // SymbolNum of 0 indicates the absolute section.      Type = MachO::X86_64_RELOC_UNSIGNED; -    Index = 0;      // FIXME: I believe this is broken, I don't think the linker can understand      // it. I think it would require a local relocation, but I'm not sure if that @@ -193,36 +189,30 @@ void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,      Value -= Writer->getSymbolAddress(&B_SD, Layout) -        (!B_Base ? 0 : Writer->getSymbolAddress(B_Base, Layout)); -    if (A_Base) { -      Index = A_Base->getIndex(); -      IsExtern = 1; -    } else { +    if (!A_Base)        Index = A_SD.getFragment()->getParent()->getOrdinal() + 1; -      IsExtern = 0; -    }      Type = MachO::X86_64_RELOC_UNSIGNED;      MachO::any_relocation_info MRE;      MRE.r_word0 = FixupOffset; -    MRE.r_word1 = ((Index     <<  0) | -                   (IsPCRel   << 24) | -                   (Log2Size  << 25) | -                   (IsExtern  << 27) | -                   (Type      << 28)); -    Writer->addRelocation(Fragment->getParent(), MRE); - -    if (B_Base) { -      Index = B_Base->getIndex(); -      IsExtern = 1; -    } else { +    MRE.r_word1 = +        (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); +    Writer->addRelocation(A_Base, Fragment->getParent(), MRE); + +    if (B_Base) +      RelSymbol = B_Base; +    else        Index = B_SD.getFragment()->getParent()->getOrdinal() + 1; -      IsExtern = 0; -    }      Type = MachO::X86_64_RELOC_SUBTRACTOR;    } else {      const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); +    if (Symbol->isTemporary() && Value) { +      const MCSection &Sec = Symbol->getSection(); +      if (!Asm.getContext().getAsmInfo()->isSectionAtomizableBySymbols(Sec)) +        Asm.addLocalUsedInReloc(*Symbol); +    }      const MCSymbolData &SD = Asm.getSymbolData(*Symbol); -    const MCSymbolData *Base = Asm.getAtom(&SD); +    RelSymbol = Asm.getAtom(&SD);      // Relocations inside debug sections always use local relocations when      // possible. This seems to be done because the debugger doesn't fully @@ -232,23 +222,20 @@ void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,        const MCSectionMachO &Section = static_cast<const MCSectionMachO&>(          Fragment->getParent()->getSection());        if (Section.hasAttribute(MachO::S_ATTR_DEBUG)) -        Base = nullptr; +        RelSymbol = nullptr;      }      // x86_64 almost always uses external relocations, except when there is no      // symbol to use as a base address (a local symbol with no preceding      // non-local symbol). -    if (Base) { -      Index = Base->getIndex(); -      IsExtern = 1; - +    if (RelSymbol) {        // Add the local offset, if needed. -      if (Base != &SD) -        Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base); +      if (RelSymbol != &SD) +        Value += +            Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(RelSymbol);      } else if (Symbol->isInSection() && !Symbol->isVariable()) {        // The index is the section ordinal (1-based).        Index = SD.getFragment()->getParent()->getOrdinal() + 1; -      IsExtern = 0;        Value += Writer->getSymbolAddress(&SD, Layout);        if (IsPCRel) @@ -347,12 +334,9 @@ void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,    // struct relocation_info (8 bytes)    MachO::any_relocation_info MRE;    MRE.r_word0 = FixupOffset; -  MRE.r_word1 = ((Index     <<  0) | -                 (IsPCRel   << 24) | -                 (Log2Size  << 25) | -                 (IsExtern  << 27) | -                 (Type      << 28)); -  Writer->addRelocation(Fragment->getParent(), MRE); +  MRE.r_word1 = (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | +                (IsExtern << 27) | (Type << 28); +  Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);  }  bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer, @@ -424,7 +408,7 @@ bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer,                     (IsPCRel                   << 30) |                     MachO::R_SCATTERED);      MRE.r_word1 = Value2; -    Writer->addRelocation(Fragment->getParent(), MRE); +    Writer->addRelocation(nullptr, Fragment->getParent(), MRE);    } else {      // If the offset is more than 24-bits, it won't fit in a scattered      // relocation offset field, so we fall back to using a non-scattered @@ -446,7 +430,7 @@ bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer,                   (IsPCRel     << 30) |                   MachO::R_SCATTERED);    MRE.r_word1 = Value; -  Writer->addRelocation(Fragment->getParent(), MRE); +  Writer->addRelocation(nullptr, Fragment->getParent(), MRE);    return true;  } @@ -467,7 +451,6 @@ void X86MachObjectWriter::RecordTLVPRelocation(MachObjectWriter *Writer,    // Get the symbol data.    const MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol()); -  unsigned Index = SD_A->getIndex();    // We're only going to have a second symbol in pic mode and it'll be a    // subtraction from the picbase. For 32-bit pic the addend is the difference @@ -490,12 +473,9 @@ void X86MachObjectWriter::RecordTLVPRelocation(MachObjectWriter *Writer,    // struct relocation_info (8 bytes)    MachO::any_relocation_info MRE;    MRE.r_word0 = Value; -  MRE.r_word1 = ((Index                    <<  0) | -                 (IsPCRel                  << 24) | -                 (Log2Size                 << 25) | -                 (1                        << 27) | // r_extern -                 (MachO::GENERIC_RELOC_TLV << 28)); // r_type -  Writer->addRelocation(Fragment->getParent(), MRE); +  MRE.r_word1 = +      (IsPCRel << 24) | (Log2Size << 25) | (MachO::GENERIC_RELOC_TLV << 28); +  Writer->addRelocation(SD_A, Fragment->getParent(), MRE);  }  void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer, @@ -546,8 +526,8 @@ void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,    // See <reloc.h>.    uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();    unsigned Index = 0; -  unsigned IsExtern = 0;    unsigned Type = 0; +  const MCSymbolData *RelSymbol = nullptr;    if (Target.isAbsolute()) { // constant      // SymbolNum of 0 indicates the absolute section. @@ -568,8 +548,7 @@ void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,      // Check whether we need an external or internal relocation.      if (Writer->doesSymbolRequireExternRelocation(SD)) { -      IsExtern = 1; -      Index = SD->getIndex(); +      RelSymbol = SD;        // For external relocations, make sure to offset the fixup value to        // compensate for the addend of the symbol address, if it was        // undefined. This occurs with weak definitions, for example. @@ -591,12 +570,9 @@ void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,    // struct relocation_info (8 bytes)    MachO::any_relocation_info MRE;    MRE.r_word0 = FixupOffset; -  MRE.r_word1 = ((Index     <<  0) | -                 (IsPCRel   << 24) | -                 (Log2Size  << 25) | -                 (IsExtern  << 27) | -                 (Type      << 28)); -  Writer->addRelocation(Fragment->getParent(), MRE); +  MRE.r_word1 = +      (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); +  Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);  }  MCObjectWriter *llvm::createX86MachObjectWriter(raw_ostream &OS, diff --git a/llvm/test/MC/MachO/AArch64/mergeable.s b/llvm/test/MC/MachO/AArch64/mergeable.s new file mode 100644 index 00000000000..fc6ec04f37b --- /dev/null +++ b/llvm/test/MC/MachO/AArch64/mergeable.s @@ -0,0 +1,59 @@ +// RUN: llvm-mc -triple aarch64-apple-darwin14 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s + +// Test that we "S + K" produce a relocation with a symbol, but just S produces +// a relocation with the section. + +	.section	__TEXT,__literal4,4byte_literals +L0: +	.long	42 + +	.section	__TEXT,__cstring,cstring_literals +L1: +	.asciz	"42" + +	.section	__DATA,__data +	.quad	L0 +	.quad	L0 + 1 +	.quad	L1 +	.quad	L1 + 1 + +// CHECK:      Relocations [ +// CHECK-NEXT:   Section __data { +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x18 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 1 +// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: L1 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x10 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 1 +// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: L1 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x8 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 1 +// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: L0 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x0 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 0 +// CHECK-NEXT:       Type: ARM64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: 0x2 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:   } +// CHECK-NEXT: ] diff --git a/llvm/test/MC/MachO/x86_64-mergeable.s b/llvm/test/MC/MachO/x86_64-mergeable.s new file mode 100644 index 00000000000..972477693ed --- /dev/null +++ b/llvm/test/MC/MachO/x86_64-mergeable.s @@ -0,0 +1,59 @@ +// RUN: llvm-mc -triple x86_64-apple-darwin14 %s -filetype=obj -o - | llvm-readobj -r --expand-relocs | FileCheck %s + +// Test that we "S + K" produce a relocation with a symbol, but just S produces +// a relocation with the section. + +	.section	__TEXT,__literal4,4byte_literals +L0: +	.long	42 + +	.section	__TEXT,__cstring,cstring_literals +L1: +	.asciz	"42" + +	.section	__DATA,__data +	.quad	L0 +	.quad	L0 + 1 +	.quad	L1 +	.quad	L1 + 1 + +// CHECK:      Relocations [ +// CHECK-NEXT:   Section __data { +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x18 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 1 +// CHECK-NEXT:       Type: X86_64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: L1 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x10 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 0 +// CHECK-NEXT:       Type: X86_64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: 0x3 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x8 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 1 +// CHECK-NEXT:       Type: X86_64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: L0 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:     Relocation { +// CHECK-NEXT:       Offset: 0x0 +// CHECK-NEXT:       PCRel: 0 +// CHECK-NEXT:       Length: 3 +// CHECK-NEXT:       Extern: 0 +// CHECK-NEXT:       Type: X86_64_RELOC_UNSIGNED (0) +// CHECK-NEXT:       Symbol: 0x2 +// CHECK-NEXT:       Scattered: 0 +// CHECK-NEXT:     } +// CHECK-NEXT:   } +// CHECK-NEXT: ] diff --git a/llvm/test/MC/MachO/x86_64-symbols.s b/llvm/test/MC/MachO/x86_64-symbols.s index e2dcc440fb5..f40183df853 100644 --- a/llvm/test/MC/MachO/x86_64-symbols.s +++ b/llvm/test/MC/MachO/x86_64-symbols.s @@ -121,6 +121,12 @@ D38:  //L39:  //D39: +        .section foo, bar +        .long L4 + 1 +        .long L35 + 1 +        .long L36 + 1 +        .long L37 + 1 +        .long L38 + 1  // CHECK: Symbols [  // CHECK-NEXT:   Symbol {  | 

