Ejemplo n.º 1
0
void ARM64AsmPrinter::EmitEndOfAsmFile(Module &M) {
  if (Subtarget->isTargetMachO()) {
    // Funny Darwin hack: This flag tells the linker that no global symbols
    // contain code that falls through to other global symbols (e.g. the obvious
    // implementation of multiple entry points).  If this doesn't occur, the
    // linker can safely perform dead code stripping.  Since LLVM never
    // generates code that does this, it is always safe to set.
    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
    SM.serializeToStackMapSection();
  }

  // Emit a .data.rel section containing any stubs that were created.
  if (Subtarget->isTargetELF()) {
    const TargetLoweringObjectFileELF &TLOFELF =
      static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());

    MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();

    // Output stubs for external and common global variables.
    MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
    if (!Stubs.empty()) {
      OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
      const DataLayout *TD = TM.getDataLayout();

      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
        OutStreamer.EmitLabel(Stubs[i].first);
        OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
                                    TD->getPointerSize(0));
      }
      Stubs.clear();
    }
  }

}
Ejemplo n.º 2
0
void SparcAsmPrinter::EmitEndOfAsmFile(Module &M) {
  const TargetLoweringObjectFileELF &TLOFELF =
    static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
  MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();

  // Generate stubs for global variables.
  MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
  if (!Stubs.empty()) {
    OutStreamer.SwitchSection(TLOFELF.getDataSection());
    unsigned PtrSize = TM.getDataLayout()->getPointerSize(0);
    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
      OutStreamer.EmitLabel(Stubs[i].first);
      OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), PtrSize);
    }
  }
}
Ejemplo n.º 3
0
bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
  const DataLayout *TD = TM.getDataLayout();

  bool isPPC64 = TD->getPointerSizeInBits() == 64;

  if (isPPC64 && !TOC.empty()) {
    const MCSectionELF *Section = OutStreamer.getContext().getELFSection(".toc",
        ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC,
        SectionKind::getReadOnly());
    OutStreamer.SwitchSection(Section);

    for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
         E = TOC.end(); I != E; ++I) {
      OutStreamer.EmitLabel(I->second);
      MCSymbol *S = OutContext.GetOrCreateSymbol(I->first->getName());
      OutStreamer.EmitTCEntry(*S);
    }
  }

  MachineModuleInfoELF &MMIELF =
    MMI->getObjFileInfo<MachineModuleInfoELF>();

  MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
  if (!Stubs.empty()) {
    OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
    for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
      // L_foo$stub:
      OutStreamer.EmitLabel(Stubs[i].first);
      //   .long _foo
      OutStreamer.EmitValue(MCSymbolRefExpr::Create(Stubs[i].second.getPointer(),
                                                    OutContext),
                            isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/);
    }

    Stubs.clear();
    OutStreamer.AddBlankLine();
  }

  return AsmPrinter::doFinalization(M);
}
Ejemplo n.º 4
0
void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
  if (Subtarget->isTargetELF()) {
    auto &TLOFELF =
      static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());

    MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();

    // Output stubs for external and common global variables.
    MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
    if (!Stubs.empty()) {
      OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
      const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout();

      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
        OutStreamer.EmitLabel(Stubs[i].first);
        OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
                                    TD->getPointerSize(0));
      }
      Stubs.clear();
    }
  }
}
Ejemplo n.º 5
0
void Cse523AsmPrinter::EmitEndOfAsmFile(Module &M) {
    if (Subtarget->isTargetMacho()) {
        // All darwin targets use mach-o.
        MachineModuleInfoMachO &MMIMacho =
            MMI->getObjFileInfo<MachineModuleInfoMachO>();

        // Output stubs for dynamically-linked functions.
        MachineModuleInfoMachO::SymbolListTy Stubs;

        Stubs = MMIMacho.GetFnStubList();
        if (!Stubs.empty()) {
            const MCSection *TheSection =
                OutContext.getMachOSection("__IMPORT", "__jump_table",
                        MCSectionMachO::S_SYMBOL_STUBS |
                        MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE |
                        MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
                        5, SectionKind::getMetadata());
            OutStreamer.SwitchSection(TheSection);

            for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
                // L_foo$stub:
                OutStreamer.EmitLabel(Stubs[i].first);
                //   .indirect_symbol _foo
                OutStreamer.EmitSymbolAttribute(Stubs[i].second.getPointer(),
                        MCSA_IndirectSymbol);
                // hlt; hlt; hlt; hlt; hlt     hlt = 0xf4.
                const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4";
                OutStreamer.EmitBytes(StringRef(HltInsts, 5));
            }

            Stubs.clear();
            OutStreamer.AddBlankLine();
        }

        // Output stubs for external and common global variables.
        Stubs = MMIMacho.GetGVStubList();
        if (!Stubs.empty()) {
            const MCSection *TheSection =
                OutContext.getMachOSection("__IMPORT", "__pointers",
                        MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
                        SectionKind::getMetadata());
            OutStreamer.SwitchSection(TheSection);

            for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
                // L_foo$non_lazy_ptr:
                OutStreamer.EmitLabel(Stubs[i].first);
                // .indirect_symbol _foo
                MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
                OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),
                        MCSA_IndirectSymbol);
                // .long 0
                if (MCSym.getInt())
                    // External to current translation unit.
                    OutStreamer.EmitIntValue(0, 4/*size*/);
                else
                    // Internal to current translation unit.
                    //
                    // When we place the LSDA into the TEXT section, the type info
                    // pointers need to be indirect and pc-rel. We accomplish this by
                    // using NLPs.  However, sometimes the types are local to the file. So
                    // we need to fill in the value for the NLP in those cases.
                    OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
                                OutContext), 4/*size*/);
            }
            Stubs.clear();
            OutStreamer.AddBlankLine();
        }

        Stubs = MMIMacho.GetHiddenGVStubList();
        if (!Stubs.empty()) {
            OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
            EmitAlignment(2);

            for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
                // L_foo$non_lazy_ptr:
                OutStreamer.EmitLabel(Stubs[i].first);
                // .long _foo
                OutStreamer.EmitValue(MCSymbolRefExpr::
                        Create(Stubs[i].second.getPointer(),
                            OutContext), 4/*size*/);
            }
            Stubs.clear();
            OutStreamer.AddBlankLine();
        }

        SM.serializeToStackMapSection();

        // Funny Darwin hack: This flag tells the linker that no global symbols
        // contain code that falls through to other global symbols (e.g. the obvious
        // implementation of multiple entry points).  If this doesn't occur, the
        // linker can safely perform dead code stripping.  Since LLVM never
        // generates code that does this, it is always safe to set.
        OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
    }

    if (Subtarget->isTargetWindows() && !Subtarget->isTargetCygMing() &&
            MMI->usesVAFloatArgument()) {
        StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused";
        MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName);
        OutStreamer.EmitSymbolAttribute(S, MCSA_Global);
    }

    if (Subtarget->isTargetCOFF()) {
        Cse523COFFMachineModuleInfo &COFFMMI =
            MMI->getObjFileInfo<Cse523COFFMachineModuleInfo>();

        // Emit type information for external functions
        typedef Cse523COFFMachineModuleInfo::externals_iterator externals_iterator;
        for (externals_iterator I = COFFMMI.externals_begin(),
                E = COFFMMI.externals_end();
                I != E; ++I) {
            OutStreamer.BeginCOFFSymbolDef(CurrentFnSym);
            OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_EXTERNAL);
            OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
                    << COFF::SCT_COMPLEX_TYPE_SHIFT);
            OutStreamer.EndCOFFSymbolDef();
        }

        // Necessary for dllexport support
        std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;

        for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
            if (I->hasDLLExportStorageClass())
                DLLExportedFns.push_back(getSymbol(I));

        for (Module::const_global_iterator I = M.global_begin(),
                E = M.global_end(); I != E; ++I)
            if (I->hasDLLExportStorageClass())
                DLLExportedGlobals.push_back(getSymbol(I));

        for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
                I != E; ++I) {
            const GlobalValue *GV = I;
            if (!GV->hasDLLExportStorageClass())
                continue;

            while (const GlobalAlias *A = dyn_cast<GlobalAlias>(GV))
                GV = A->getAliasedGlobal();

            if (isa<Function>(GV))
                DLLExportedFns.push_back(getSymbol(I));
            else if (isa<GlobalVariable>(GV))
                DLLExportedGlobals.push_back(getSymbol(I));
        }

        // Output linker support code for dllexported globals on windows.
        if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
            const TargetLoweringObjectFileCOFF &TLOFCOFF =
                static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());

            OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());
            SmallString<128> name;
            for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) {
                if (Subtarget->isTargetWindows())
                    name = " /EXPORT:";
                else
                    name = " -export:";
                name += DLLExportedGlobals[i]->getName();
                if (Subtarget->isTargetWindows())
                    name += ",DATA";
                else
                    name += ",data";
                OutStreamer.EmitBytes(name);
            }

            for (unsigned i = 0, e = DLLExportedFns.size(); i != e; ++i) {
                if (Subtarget->isTargetWindows())
                    name = " /EXPORT:";
                else
                    name = " -export:";
                name += DLLExportedFns[i]->getName();
                OutStreamer.EmitBytes(name);
            }
        }
    }

    if (Subtarget->isTargetELF()) {
        const TargetLoweringObjectFileELF &TLOFELF =
            static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());

        MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();

        // Output stubs for external and common global variables.
        MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
        if (!Stubs.empty()) {
            OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
            const DataLayout *TD = TM.getDataLayout();

            for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
                OutStreamer.EmitLabel(Stubs[i].first);
                OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
                        TD->getPointerSize());
            }
            Stubs.clear();
        }
    }
}
Ejemplo n.º 6
0
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
  if (Subtarget->isTargetMacho()) {
    // All darwin targets use mach-o.
    MachineModuleInfoMachO &MMIMacho =
      MMI->getObjFileInfo<MachineModuleInfoMachO>();

    // Output stubs for dynamically-linked functions.
    MachineModuleInfoMachO::SymbolListTy Stubs;

    Stubs = MMIMacho.GetFnStubList();
    if (!Stubs.empty()) {
      const MCSection *TheSection =
        OutContext.getMachOSection("__IMPORT", "__jump_table",
                                   MachO::S_SYMBOL_STUBS |
                                   MachO::S_ATTR_SELF_MODIFYING_CODE |
                                   MachO::S_ATTR_PURE_INSTRUCTIONS,
                                   5, SectionKind::getMetadata());
      OutStreamer.SwitchSection(TheSection);

      for (const auto &Stub : Stubs) {
        // L_foo$stub:
        OutStreamer.EmitLabel(Stub.first);
        //   .indirect_symbol _foo
        OutStreamer.EmitSymbolAttribute(Stub.second.getPointer(),
                                        MCSA_IndirectSymbol);
        // hlt; hlt; hlt; hlt; hlt     hlt = 0xf4.
        const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4";
        OutStreamer.EmitBytes(StringRef(HltInsts, 5));
      }

      Stubs.clear();
      OutStreamer.AddBlankLine();
    }

    // Output stubs for external and common global variables.
    Stubs = MMIMacho.GetGVStubList();
    if (!Stubs.empty()) {
      const MCSection *TheSection =
        OutContext.getMachOSection("__IMPORT", "__pointers",
                                   MachO::S_NON_LAZY_SYMBOL_POINTERS,
                                   SectionKind::getMetadata());
      OutStreamer.SwitchSection(TheSection);

      for (auto &Stub : Stubs)
        emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);

      Stubs.clear();
      OutStreamer.AddBlankLine();
    }

    Stubs = MMIMacho.GetHiddenGVStubList();
    if (!Stubs.empty()) {
      const MCSection *TheSection =
        OutContext.getMachOSection("__IMPORT", "__pointers",
                                   MachO::S_NON_LAZY_SYMBOL_POINTERS,
                                   SectionKind::getMetadata());
      OutStreamer.SwitchSection(TheSection);

      for (auto &Stub : Stubs)
        emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);

      Stubs.clear();
      OutStreamer.AddBlankLine();
    }

    SM.serializeToStackMapSection();

    // Funny Darwin hack: This flag tells the linker that no global symbols
    // contain code that falls through to other global symbols (e.g. the obvious
    // implementation of multiple entry points).  If this doesn't occur, the
    // linker can safely perform dead code stripping.  Since LLVM never
    // generates code that does this, it is always safe to set.
    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
  }

  if (Subtarget->isTargetKnownWindowsMSVC() && MMI->usesVAFloatArgument()) {
    StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused";
    MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName);
    OutStreamer.EmitSymbolAttribute(S, MCSA_Global);
  }

  if (Subtarget->isTargetCOFF()) {
    // Necessary for dllexport support
    std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals;

    for (const auto &Function : M)
      if (Function.hasDLLExportStorageClass())
        DLLExportedFns.push_back(getSymbol(&Function));

    for (const auto &Global : M.globals())
      if (Global.hasDLLExportStorageClass())
        DLLExportedGlobals.push_back(getSymbol(&Global));

    for (const auto &Alias : M.aliases()) {
      if (!Alias.hasDLLExportStorageClass())
        continue;

      if (Alias.getType()->getElementType()->isFunctionTy())
        DLLExportedFns.push_back(getSymbol(&Alias));
      else
        DLLExportedGlobals.push_back(getSymbol(&Alias));
    }

    // Output linker support code for dllexported globals on windows.
    if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) {
      const TargetLoweringObjectFileCOFF &TLOFCOFF =
        static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());

      OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection());

      for (auto & Symbol : DLLExportedGlobals)
        GenerateExportDirective(Symbol, /*IsData=*/true);
      for (auto & Symbol : DLLExportedFns)
        GenerateExportDirective(Symbol, /*IsData=*/false);
    }
  }

  if (Subtarget->isTargetELF()) {
    const TargetLoweringObjectFileELF &TLOFELF =
      static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());

    MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();

    // Output stubs for external and common global variables.
    MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
    if (!Stubs.empty()) {
      OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
      const DataLayout *TD = TM.getDataLayout();

      for (const auto &Stub : Stubs) {
        OutStreamer.EmitLabel(Stub.first);
        OutStreamer.EmitSymbolValue(Stub.second.getPointer(),
                                    TD->getPointerSize());
      }
      Stubs.clear();
    }
  }
}