/// Initialize - this method must be called before any actual lowering is /// done. This specifies the current context for codegen, and gives the /// lowering implementations a chance to set up their default sections. void TargetLoweringObjectFile::Initialize(MCContext &ctx, const TargetMachine &TM) { Ctx = &ctx; DL = TM.getDataLayout(); InitMCObjectFileInfo(TM.getTargetTriple(), TM.getRelocationModel(), TM.getCodeModel(), *Ctx); }
unsigned char X86Subtarget::classifyGlobalFunctionReference( const GlobalValue *GV, const TargetMachine &TM) const { // On ELF targets, in both X86-64 and X86-32 mode, direct calls to // external symbols most go through the PLT in PIC mode. If the symbol // has hidden or protected visibility, or if it is static or local, then // we don't need to use the PLT - we can directly call it. // In PIE mode, calls to global functions don't need to go through PLT if (isTargetELF() && TM.getRelocationModel() == Reloc::PIC_ && !isGlobalDefinedInPIE(GV, TM) && GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) { return X86II::MO_PLT; } else if (isPICStyleStubAny() && !GV->isStrongDefinitionForLinker() && (!getTargetTriple().isMacOSX() || getTargetTriple().isMacOSXVersionLT(10, 5))) { // PC-relative references to external symbols should go through $stub, // unless we're building with the leopard linker or later, which // automatically synthesizes these stubs. return X86II::MO_DARWIN_STUB; } else if (isPICStyleRIPRel() && isa<Function>(GV) && cast<Function>(GV)->hasFnAttribute(Attribute::NonLazyBind)) { // If the function is marked as non-lazy, generate an indirect call // which loads from the GOT directly. This avoids runtime overhead // at the cost of eager binding (and one extra byte of encoding). return X86II::MO_GOTPCREL; } return X86II::MO_NO_FLAG; }
/// Return true if the subtarget allows calls to immediate address. bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const { // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32 // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does, // the following check for Win32 should be removed. if (In64BitMode || isTargetWin32()) return false; return isTargetELF() || TM.getRelocationModel() == Reloc::Static; }
/// hasLazyResolverStub - Return true if accesses to the specified global have /// to go through a dyld lazy resolution stub. This means that an extra load /// is required to get the address of the global. bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV, const TargetMachine &TM) const { // We never have stubs if HasLazyResolverStubs=false or if in static mode. if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) return false; bool isDecl = GV->isDeclaration(); if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage()) return false; return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() || isDecl; }
/// ClassifyGlobalReference - Find the target operand flags that describe /// how a global value should be referenced for the current subtarget. unsigned char AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { bool isDecl = GV->isDeclarationForLinker(); // MachO large model always goes via a GOT, simply to get a single 8-byte // absolute relocation on all global addresses. if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) return AArch64II::MO_GOT; // The small code mode's direct accesses use ADRP, which cannot necessarily // produce the value 0 (if the code is above 4GB). if (TM.getCodeModel() == CodeModel::Small && GV->isWeakForLinker() && isDecl) { // In PIC mode use the GOT, but in absolute mode use a constant pool load. if (TM.getRelocationModel() == Reloc::Static) return AArch64II::MO_CONSTPOOL; else return AArch64II::MO_GOT; } // If symbol visibility is hidden, the extra load is not needed if // the symbol is definitely defined in the current translation unit. // The handling of non-hidden symbols in PIC mode is rather target-dependent: // + On MachO, if the symbol is defined in this module the GOT can be // skipped. // + On ELF, the R_AARCH64_COPY relocation means that even symbols actually // defined could end up in unexpected places. Use a GOT. if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) { if (isTargetMachO()) return (isDecl || GV->isWeakForLinker()) ? AArch64II::MO_GOT : AArch64II::MO_NO_FLAG; else // No need to go through the GOT for local symbols on ELF. return GV->hasLocalLinkage() ? AArch64II::MO_NO_FLAG : AArch64II::MO_GOT; } return AArch64II::MO_NO_FLAG; }
/// hasLazyResolverStub - Return true if accesses to the specified global have /// to go through a dyld lazy resolution stub. This means that an extra load /// is required to get the address of the global. bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV, const TargetMachine &TM) const { // We never have stubs if HasLazyResolverStubs=false or if in static mode. if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) return false; // If symbol visibility is hidden, the extra load is not needed if // the symbol is definitely defined in the current translation unit. bool isDecl = GV->isDeclaration() && !GV->isMaterializable(); if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage()) return false; return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() || isDecl; }
/// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls /// to immediate address. bool X86Subtarget::IsLegalToCallImmediateAddr(const TargetMachine &TM) const { // FIXME: I386 PE/COFF supports PC relative calls using IMAGE_REL_I386_REL32 // but WinCOFFObjectWriter::RecordRelocation cannot emit them. Once it does, // the following check for Win32 should be removed. if (In64BitMode || isTargetWin32()) return false; // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2367 // For NaCl dynamic linking we do not want to generate a text relocation to // an absolute address in PIC mode. Such a situation arises from // test/CodeGen/X86/call-imm.ll with the default implementation. // For other platforms we retain the default behavior. return (isTargetELF() && !isTargetNaCl()) || TM.getRelocationModel() == Reloc::Static; }
void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, const TargetMachine &TM) { TargetLoweringObjectFile::Initialize(Ctx, TM); if (TM.getRelocationModel() == Reloc::Static) { StaticCtorSection = Ctx.getMachOSection("__TEXT", "__constructor", 0, SectionKind::getData()); StaticDtorSection = Ctx.getMachOSection("__TEXT", "__destructor", 0, SectionKind::getData()); } else { StaticCtorSection = Ctx.getMachOSection("__DATA", "__mod_init_func", MachO::S_MOD_INIT_FUNC_POINTERS, SectionKind::getData()); StaticDtorSection = Ctx.getMachOSection("__DATA", "__mod_term_func", MachO::S_MOD_TERM_FUNC_POINTERS, SectionKind::getData()); } }
/// ClassifyGlobalReference - Find the target operand flags that describe /// how a global value should be referenced for the current subtarget. unsigned char ARM64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { // Determine whether this is a reference to a definition or a declaration. // Materializable GVs (in JIT lazy compilation mode) do not require an extra // load from stub. bool isDecl = GV->hasAvailableExternallyLinkage(); if (GV->isDeclaration() && !GV->isMaterializable()) isDecl = true; // MachO large model always goes via a GOT, simply to get a single 8-byte // absolute relocation on all global addresses. if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) return ARM64II::MO_GOT; // The small code mode's direct accesses use ADRP, which cannot necessarily // produce the value 0 (if the code is above 4GB). Therefore they must use the // GOT. if (TM.getCodeModel() == CodeModel::Small && GV->isWeakForLinker() && isDecl) return ARM64II::MO_GOT; // If symbol visibility is hidden, the extra load is not needed if // the symbol is definitely defined in the current translation unit. // The handling of non-hidden symbols in PIC mode is rather target-dependent: // + On MachO, if the symbol is defined in this module the GOT can be // skipped. // + On ELF, the R_AARCH64_COPY relocation means that even symbols actually // defined could end up in unexpected places. Use a GOT. if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) { if (isTargetMachO()) return (isDecl || GV->isWeakForLinker()) ? ARM64II::MO_GOT : ARM64II::MO_NO_FLAG; else // No need to go through the GOT for local symbols on ELF. return GV->hasLocalLinkage() ? ARM64II::MO_NO_FLAG : ARM64II::MO_GOT; } return ARM64II::MO_NO_FLAG; }
/// Find the target operand flags that describe how a global value should be /// referenced for the current subtarget. unsigned char AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const { // MachO large model always goes via a GOT, simply to get a single 8-byte // absolute relocation on all global addresses. if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) return AArch64II::MO_GOT; Reloc::Model RM = TM.getRelocationModel(); if (!shouldAssumeDSOLocal(RM, TargetTriple, *GV->getParent(), GV)) return AArch64II::MO_GOT; // The small code mode's direct accesses use ADRP, which cannot necessarily // produce the value 0 (if the code is above 4GB). if (TM.getCodeModel() == CodeModel::Small && GV->hasExternalWeakLinkage()) { // In PIC mode use the GOT, but in absolute mode use a constant pool load. if (RM == Reloc::Static) return AArch64II::MO_CONSTPOOL; else return AArch64II::MO_GOT; } return AArch64II::MO_NO_FLAG; }
/// getKindForGlobal - This is a top-level target-independent classifier for /// a global variable. Given an global variable and information from TM, it /// classifies the global in a variety of ways that make various target /// implementations simpler. The target implementation is free to ignore this /// extra info of course. SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, const TargetMachine &TM){ assert(!GV->isDeclaration() && !GV->hasAvailableExternallyLinkage() && "Can only be used for global definitions"); Reloc::Model ReloModel = TM.getRelocationModel(); // Early exit - functions should be always in text sections. const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); if (!GVar) return SectionKind::getText(); // Handle thread-local data first. if (GVar->isThreadLocal()) { if (isSuitableForBSS(GVar, TM.Options.NoZerosInBSS)) return SectionKind::getThreadBSS(); return SectionKind::getThreadData(); } // Variables with common linkage always get classified as common. if (GVar->hasCommonLinkage()) return SectionKind::getCommon(); // Variable can be easily put to BSS section. if (isSuitableForBSS(GVar, TM.Options.NoZerosInBSS)) { if (GVar->hasLocalLinkage()) return SectionKind::getBSSLocal(); else if (GVar->hasExternalLinkage()) return SectionKind::getBSSExtern(); return SectionKind::getBSS(); } const Constant *C = GVar->getInitializer(); // If the global is marked constant, we can put it into a mergable section, // a mergable string section, or general .data if it contains relocations. if (GVar->isConstant()) { // If the initializer for the global contains something that requires a // relocation, then we may have to drop this into a writable data section // even though it is marked const. switch (C->getRelocationInfo()) { case Constant::NoRelocation: // If the global is required to have a unique address, it can't be put // into a mergable section: just drop it into the general read-only // section instead. if (!GVar->hasUnnamedAddr()) return SectionKind::getReadOnly(); // If initializer is a null-terminated string, put it in a "cstring" // section of the right width. if (ArrayType *ATy = dyn_cast<ArrayType>(C->getType())) { if (IntegerType *ITy = dyn_cast<IntegerType>(ATy->getElementType())) { if ((ITy->getBitWidth() == 8 || ITy->getBitWidth() == 16 || ITy->getBitWidth() == 32) && IsNullTerminatedString(C)) { if (ITy->getBitWidth() == 8) return SectionKind::getMergeable1ByteCString(); if (ITy->getBitWidth() == 16) return SectionKind::getMergeable2ByteCString(); assert(ITy->getBitWidth() == 32 && "Unknown width"); return SectionKind::getMergeable4ByteCString(); } } } // Otherwise, just drop it into a mergable constant section. If we have // a section for this size, use it, otherwise use the arbitrary sized // mergable section. switch (TM.getDataLayout()->getTypeAllocSize(C->getType())) { case 4: return SectionKind::getMergeableConst4(); case 8: return SectionKind::getMergeableConst8(); case 16: return SectionKind::getMergeableConst16(); default: return SectionKind::getMergeableConst(); } case Constant::LocalRelocation: // In static relocation model, the linker will resolve all addresses, so // the relocation entries will actually be constants by the time the app // starts up. However, we can't put this into a mergable section, because // the linker doesn't take relocations into consideration when it tries to // merge entries in the section. if (ReloModel == Reloc::Static) return SectionKind::getReadOnly(); // Otherwise, the dynamic linker needs to fix it up, put it in the // writable data.rel.local section. return SectionKind::getReadOnlyWithRelLocal(); case Constant::GlobalRelocations: // In static relocation model, the linker will resolve all addresses, so // the relocation entries will actually be constants by the time the app // starts up. However, we can't put this into a mergable section, because // the linker doesn't take relocations into consideration when it tries to // merge entries in the section. if (ReloModel == Reloc::Static) return SectionKind::getReadOnly(); // Otherwise, the dynamic linker needs to fix it up, put it in the // writable data.rel section. return SectionKind::getReadOnlyWithRel(); } } // Okay, this isn't a constant. If the initializer for the global is going // to require a runtime relocation by the dynamic linker, put it into a more // specific section to improve startup time of the app. This coalesces these // globals together onto fewer pages, improving the locality of the dynamic // linker. if (ReloModel == Reloc::Static) return SectionKind::getDataNoRel(); switch (C->getRelocationInfo()) { case Constant::NoRelocation: return SectionKind::getDataNoRel(); case Constant::LocalRelocation: return SectionKind::getDataRelLocal(); case Constant::GlobalRelocations: return SectionKind::getDataRel(); } llvm_unreachable("Invalid relocation"); }
int LLVMTargetMachineAssembleToOutputStream(LLVMTargetMachineRef TM, LLVMMemoryBufferRef Mem, void *JOStream, LLVMBool RelaxAll, LLVMBool NoExecStack, char **ErrorMessage) { *ErrorMessage = NULL; #if !defined(WIN32) locale_t loc = newlocale(LC_ALL_MASK, "C", 0); locale_t oldLoc = uselocale(loc); #endif TargetMachine *TheTargetMachine = unwrap(TM); const Target *TheTarget = &(TheTargetMachine->getTarget()); std::string TripleName = TheTargetMachine->getTargetTriple().str(); std::string MCPU = TheTargetMachine->getTargetCPU().str(); std::string FeaturesStr = TheTargetMachine->getTargetFeatureString().str(); Reloc::Model RelocModel = TheTargetMachine->getRelocationModel(); CodeModel::Model CMModel = TheTargetMachine->getCodeModel(); std::unique_ptr<MemoryBuffer> Buffer(unwrap(Mem)); std::string DiagStr; raw_string_ostream DiagStream(DiagStr); SourceMgr SrcMgr; SrcMgr.setDiagHandler(assembleDiagHandler, &DiagStream); // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); // Record the location of the include directories so that the lexer can find // it later. // SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); raw_java_ostream& Out = *((raw_java_ostream*) JOStream); std::unique_ptr<MCStreamer> Str; MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, Out, CE, *STI, RelaxAll != 0)); if (NoExecStack != 0) Str->InitSections(true); MCTargetOptions MCOptions; std::unique_ptr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, *Str, *MAI)); std::unique_ptr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); if (!TAP) { *ErrorMessage = strdup("this target does not support assembly parsing"); goto done; } Parser->setTargetParser(*TAP.get()); if (Parser->Run(false)) { *ErrorMessage = strdup(DiagStream.str().c_str()); goto done; } Out.flush(); done: #if !defined(WIN32) uselocale(oldLoc); freelocale(loc); #endif return *ErrorMessage ? 1 : 0; }