void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { const ARMTargetMachine &ARM_TM = static_cast<const ARMTargetMachine &>(TM); bool isAAPCS_ABI = ARM_TM.TargetABI == ARMTargetMachine::ARMABI::ARM_ABI_AAPCS; genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly(); TargetLoweringObjectFileELF::Initialize(Ctx, TM); InitializeELF(isAAPCS_ABI); if (isAAPCS_ABI) { LSDASection = nullptr; } AttributesSection = getContext().getELFSection(".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0); // Make code section unreadable when in execute-only mode if (genExecuteOnly) { unsigned Type = ELF::SHT_PROGBITS; unsigned Flags = ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_ARM_PURECODE; // Since we cannot modify flags for an existing section, we create a new // section with the right flags, and use 0 as the unique ID for // execute-only text TextSection = Ctx.getELFSection(".text", Type, Flags, 0, "", 0U); } }
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()); } }
MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, bool isVerboseAsm, bool useCFI, bool useDwarfDirectory, MCInstPrinter *printer, MCCodeEmitter *emitter, MCAsmBackend *asmbackend, bool showInst) : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm), ShowInst(showInst), UseCFI(useCFI), UseDwarfDirectory(useDwarfDirectory) { if (InstPrinter && IsVerboseAsm) InstPrinter->setCommentStream(CommentStream); }
static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI, MCStreamer &OutStreamer, MCContext &OutContext) { const MachineOperand &MO = MI->getOperand(0); MCSymbol *StartLabel = OutContext.CreateTempSymbol(); MCSymbol *EndLabel = OutContext.CreateTempSymbol(); MCSymbol *SethiLabel = OutContext.CreateTempSymbol(); MCSymbol *GOTLabel = OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_")); assert(MO.getReg() != SP::O7 && "%o7 is assigned as destination for getpcx!"); MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg()); MCOperand RegO7 = MCOperand::CreateReg(SP::O7); // <StartLabel>: // call <EndLabel> // <SethiLabel>: // sethi %hi(_GLOBAL_OFFSET_TABLE_+(<SethiLabel>-<StartLabel>)), <MO> // <EndLabel>: // or <MO>, %lo(_GLOBAL_OFFSET_TABLE_+(<EndLabel>-<StartLabel>))), <MO> // add <MO>, %o7, <MO> OutStreamer.EmitLabel(StartLabel); MCOperand Callee = createPCXCallOP(EndLabel, OutContext); EmitCall(OutStreamer, Callee); OutStreamer.EmitLabel(SethiLabel); MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI, GOTLabel, StartLabel, SethiLabel, OutContext); EmitSETHI(OutStreamer, hiImm, MCRegOP); OutStreamer.EmitLabel(EndLabel); MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO, GOTLabel, StartLabel, EndLabel, OutContext); EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP); EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP); }
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, const TargetMachine &TM) { TargetLoweringObjectFile::Initialize(Ctx, TM); const Triple &T = TM.getTargetTriple(); if (T.isKnownWindowsMSVCEnvironment() || T.isWindowsItaniumEnvironment()) { StaticCtorSection = Ctx.getCOFFSection(".CRT$XCU", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); StaticDtorSection = Ctx.getCOFFSection(".CRT$XTX", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); } else { StaticCtorSection = Ctx.getCOFFSection( ".ctors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, SectionKind::getData()); StaticDtorSection = Ctx.getCOFFSection( ".dtors", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE, SectionKind::getData()); } }
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) { // Add common CodeGen passes. MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, StartAfter, StopAfter); if (!Context) return true; if (StopAfter) { // FIXME: The intent is that this should eventually write out a YAML file, // containing the LLVM IR, the machine-level IR (when stopping after a // machine-level pass), and whatever other information is needed to // deserialize the code and resume compilation. For now, just write the // LLVM IR. PM.add(createPrintModulePass(&Out)); return false; } if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCRegisterInfo &MRI = *getRegisterInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); OwningPtr<MCStreamer> AsmStreamer; switch (FileType) { case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, *getInstrInfo(), Context->getRegisterInfo(), STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; MCAsmBackend *MAB = 0; if (ShowMCEncoding) { const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI, *Context); MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU); } MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, getVerboseAsm(), hasMCUseLoc(), hasMCUseCFI(), hasMCUseDwarfDirectory(), InstPrinter, MCE, MAB, ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI, STI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU); if (MCE == 0 || MAB == 0) return true; AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Context, *MAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); PM.add(createGCInfoDeleter()); return false; }
bool LLVMTargetMachine::addPassesToEmitFile( PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter, AnalysisID StopAfter, MachineFunctionInitializer *MFInitializer) { // Add common CodeGen passes. MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, StartBefore, StartAfter, StopAfter, MFInitializer); if (!Context) return true; if (StopAfter) { PM.add(createPrintMIRPass(outs())); return false; } if (Options.MCOptions.MCSaveTempLabels) Context->setAllowTemporaryLabels(false); const MCSubtargetInfo &STI = *getMCSubtargetInfo(); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCRegisterInfo &MRI = *getMCRegisterInfo(); const MCInstrInfo &MII = *getMCInstrInfo(); std::unique_ptr<MCStreamer> AsmStreamer; switch (FileType) { case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter( getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = nullptr; if (Options.MCOptions.ShowMCEncoding) MCE = getTarget().createMCCodeEmitter(MII, MRI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU); auto FOut = llvm::make_unique<formatted_raw_ostream>(Out); MCStreamer *S = getTarget().createAsmStreamer( *Context, std::move(FOut), Options.MCOptions.AsmVerbose, Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, Options.MCOptions.ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple().str(), TargetCPU); if (!MCE || !MAB) return true; // Don't waste memory on names of temp labels. Context->setUseNamesOnTempLabels(false); Triple T(getTargetTriple().str()); AsmStreamer.reset(getTarget().createMCObjectStreamer( T, *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll, /*DWARFMustBeAtTheEnd*/ true)); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(getTarget().createNullStreamer(*Context)); break; } // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); if (!Printer) return true; PM.add(Printer); return false; }
bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify) { // This is mostly based on LLVMTargetMachine::addPassesToEmitFile // Add common CodeGen passes. MCContext *Context = 0; if (addCommonCodeGenPasses(PM, DisableVerify, Context)) return true; assert(Context != 0 && "Failed to get MCContext"); if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); OwningPtr<MCStreamer> AsmStreamer; switch (FileType) { default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; MCAsmBackend *MAB = 0; MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, true, /* verbose asm */ hasMCUseLoc(), hasMCUseCFI(), hasMCUseDwarfDirectory(), InstPrinter, MCE, MAB, false /* show MC encoding */); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { llvm_unreachable("Object file emission is not supported with PTX"); } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } // MC Logging //AsmStreamer.reset(createLoggingStreamer(AsmStreamer.take(), errs())); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); PM.add(createGCInfoDeleter()); return false; }
unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsCrossSection, const MCAsmBackend &MAB) const { unsigned FixupKind = Fixup.getKind(); if (IsCrossSection) { if (FixupKind != FK_Data_4 && FixupKind != llvm::X86::reloc_signed_4byte) { Ctx.reportError(Fixup.getLoc(), "Cannot represent this expression"); return COFF::IMAGE_REL_AMD64_ADDR32; } FixupKind = FK_PCRel_4; } MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); if (getMachine() == COFF::IMAGE_FILE_MACHINE_AMD64) { switch (FixupKind) { case FK_PCRel_4: case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_movq_load: case X86::reloc_riprel_4byte_relax: case X86::reloc_riprel_4byte_relax_rex: case X86::reloc_branch_4byte_pcrel: return COFF::IMAGE_REL_AMD64_REL32; case FK_Data_4: case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) return COFF::IMAGE_REL_AMD64_ADDR32NB; if (Modifier == MCSymbolRefExpr::VK_SECREL) return COFF::IMAGE_REL_AMD64_SECREL; return COFF::IMAGE_REL_AMD64_ADDR32; case FK_Data_8: return COFF::IMAGE_REL_AMD64_ADDR64; case FK_SecRel_2: return COFF::IMAGE_REL_AMD64_SECTION; case FK_SecRel_4: return COFF::IMAGE_REL_AMD64_SECREL; default: Ctx.reportError(Fixup.getLoc(), "unsupported relocation type"); return COFF::IMAGE_REL_AMD64_ADDR32; } } else if (getMachine() == COFF::IMAGE_FILE_MACHINE_I386) { switch (FixupKind) { case FK_PCRel_4: case X86::reloc_riprel_4byte: case X86::reloc_riprel_4byte_movq_load: return COFF::IMAGE_REL_I386_REL32; case FK_Data_4: case X86::reloc_signed_4byte: case X86::reloc_signed_4byte_relax: if (Modifier == MCSymbolRefExpr::VK_COFF_IMGREL32) return COFF::IMAGE_REL_I386_DIR32NB; if (Modifier == MCSymbolRefExpr::VK_SECREL) return COFF::IMAGE_REL_AMD64_SECREL; return COFF::IMAGE_REL_I386_DIR32; case FK_SecRel_2: return COFF::IMAGE_REL_I386_SECTION; case FK_SecRel_4: return COFF::IMAGE_REL_I386_SECREL; default: Ctx.reportError(Fixup.getLoc(), "unsupported relocation type"); return COFF::IMAGE_REL_I386_DIR32; } } else llvm_unreachable("Unsupported COFF machine type."); }
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify, AnalysisID StartAfter, AnalysisID StopAfter) { // Passes to handle jumptable function annotations. These can't be handled at // JIT time, so we don't add them directly to addPassesToGenerateCode. PM.add(createJumpInstrTableInfoPass()); PM.add(createJumpInstrTablesPass(Options.JTType)); // Add common CodeGen passes. MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, StartAfter, StopAfter); if (!Context) return true; if (StopAfter) { // FIXME: The intent is that this should eventually write out a YAML file, // containing the LLVM IR, the machine-level IR (when stopping after a // machine-level pass), and whatever other information is needed to // deserialize the code and resume compilation. For now, just write the // LLVM IR. PM.add(createPrintModulePass(Out)); return false; } if (Options.MCOptions.MCSaveTempLabels) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCRegisterInfo &MRI = *getRegisterInfo(); const MCInstrInfo &MII = *getInstrInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); std::unique_ptr<MCStreamer> AsmStreamer; switch (FileType) { case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, MII, MRI, STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = nullptr; if (Options.MCOptions.ShowMCEncoding) MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), TargetCPU); MCStreamer *S = getTarget().createAsmStreamer( *Context, Out, Options.MCOptions.AsmVerbose, Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, Options.MCOptions.ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), TargetCPU); if (!MCE || !MAB) return true; AsmStreamer.reset(getTarget().createMCObjectStreamer( getTargetTriple(), *Context, *MAB, Out, MCE, STI, Options.MCOptions.MCRelaxAll, Options.MCOptions.MCNoExecStack)); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (!Printer) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.release(); PM.add(Printer); return false; }
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext &Ctx) { unsigned Kind = Fixup.getKind(); int64_t SignedValue = static_cast<int64_t>(Value); switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); case AArch64::fixup_aarch64_pcrel_adr_imm21: if (SignedValue > 2097151 || SignedValue < -2097152) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); return AdrImmBits(Value & 0x1fffffULL); case AArch64::fixup_aarch64_pcrel_adrp_imm21: return AdrImmBits((Value & 0x1fffff000ULL) >> 12); case AArch64::fixup_aarch64_ldr_pcrel_imm19: case AArch64::fixup_aarch64_pcrel_branch19: // Signed 21-bit immediate if (SignedValue > 2097151 || SignedValue < -2097152) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0x3) Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned"); // Low two bits are not encoded. return (Value >> 2) & 0x7ffff; case AArch64::fixup_aarch64_add_imm12: case AArch64::fixup_aarch64_ldst_imm12_scale1: // Unsigned 12-bit immediate if (Value >= 0x1000) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); return Value; case AArch64::fixup_aarch64_ldst_imm12_scale2: // Unsigned 12-bit immediate which gets multiplied by 2 if (Value >= 0x2000) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0x1) Ctx.reportError(Fixup.getLoc(), "fixup must be 2-byte aligned"); return Value >> 1; case AArch64::fixup_aarch64_ldst_imm12_scale4: // Unsigned 12-bit immediate which gets multiplied by 4 if (Value >= 0x4000) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0x3) Ctx.reportError(Fixup.getLoc(), "fixup must be 4-byte aligned"); return Value >> 2; case AArch64::fixup_aarch64_ldst_imm12_scale8: // Unsigned 12-bit immediate which gets multiplied by 8 if (Value >= 0x8000) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0x7) Ctx.reportError(Fixup.getLoc(), "fixup must be 8-byte aligned"); return Value >> 3; case AArch64::fixup_aarch64_ldst_imm12_scale16: // Unsigned 12-bit immediate which gets multiplied by 16 if (Value >= 0x10000) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0xf) Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned"); return Value >> 4; case AArch64::fixup_aarch64_movw: Ctx.reportError(Fixup.getLoc(), "no resolvable MOVZ/MOVK fixups supported yet"); return Value; case AArch64::fixup_aarch64_pcrel_branch14: // Signed 16-bit immediate if (SignedValue > 32767 || SignedValue < -32768) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); // Low two bits are not encoded (4-byte alignment assumed). if (Value & 0x3) Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned"); return (Value >> 2) & 0x3fff; case AArch64::fixup_aarch64_pcrel_branch26: case AArch64::fixup_aarch64_pcrel_call26: // Signed 28-bit immediate if (SignedValue > 134217727 || SignedValue < -134217728) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); // Low two bits are not encoded (4-byte alignment assumed). if (Value & 0x3) Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned"); return (Value >> 2) & 0x3ffffff; case FK_Data_1: case FK_Data_2: case FK_Data_4: case FK_Data_8: return Value; } }
void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ TargetLoweringObjectFileELF::Initialize(Ctx, TM); BSSSection = Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getBSS()); BSSSectionLarge = Ctx.getELFSection(".dp.bss.large", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getBSS()); DataSection = Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getDataRel()); DataSectionLarge = Ctx.getELFSection(".dp.data.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getDataRel()); DataRelROSection = Ctx.getELFSection(".dp.rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getReadOnlyWithRel()); DataRelROSectionLarge = Ctx.getELFSection(".dp.rodata.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getReadOnlyWithRel()); ReadOnlySection = Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); ReadOnlySectionLarge = Ctx.getELFSection(".cp.rodata.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); MergeableConst4Section = Ctx.getELFSection(".cp.rodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst4()); MergeableConst8Section = Ctx.getELFSection(".cp.rodata.cst8", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst8()); MergeableConst16Section = Ctx.getELFSection(".cp.rodata.cst16", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst16()); CStringSection = Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); // TextSection - see MObjectFileInfo.cpp // StaticCtorSection - see MObjectFileInfo.cpp // StaticDtorSection - see MObjectFileInfo.cpp }
bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, raw_pwrite_stream &Out, CodeGenFileType FileType, MCContext &Context) { if (Options.MCOptions.MCSaveTempLabels) Context.setAllowTemporaryLabels(false); const MCSubtargetInfo &STI = *getMCSubtargetInfo(); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCRegisterInfo &MRI = *getMCRegisterInfo(); const MCInstrInfo &MII = *getMCInstrInfo(); std::unique_ptr<MCStreamer> AsmStreamer; switch (FileType) { case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter( getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = nullptr; if (Options.MCOptions.ShowMCEncoding) MCE = getTarget().createMCCodeEmitter(MII, MRI, Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); auto FOut = llvm::make_unique<formatted_raw_ostream>(Out); MCStreamer *S = getTarget().createAsmStreamer( Context, std::move(FOut), Options.MCOptions.AsmVerbose, Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, Options.MCOptions.ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); if (!MCE || !MAB) return true; // Don't waste memory on names of temp labels. Context.setUseNamesOnTempLabels(false); Triple T(getTargetTriple().str()); AsmStreamer.reset(getTarget().createMCObjectStreamer( T, Context, std::unique_ptr<MCAsmBackend>(MAB), Out, std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, Options.MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ true)); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(getTarget().createNullStreamer(Context)); break; } // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); if (!Printer) return true; PM.add(Printer); return false; }
// assumes IsILP32 is true static bool isNonILP32reloc(const MCFixup &Fixup, AArch64MCExpr::VariantKind RefKind, MCContext &Ctx) { if ((unsigned)Fixup.getKind() != AArch64::fixup_aarch64_movw) return false; switch(RefKind) { case AArch64MCExpr::VK_ABS_G3: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G3)); return true; case AArch64MCExpr::VK_ABS_G2: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2)); return true; case AArch64MCExpr::VK_ABS_G2_S: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G2)); return true; case AArch64MCExpr::VK_ABS_G2_NC: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC)); return true; case AArch64MCExpr::VK_ABS_G1_S: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1)); return true; case AArch64MCExpr::VK_ABS_G1_NC: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC)); return true; case AArch64MCExpr::VK_DTPREL_G2: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2)); return true; case AArch64MCExpr::VK_DTPREL_G1_NC: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC)); return true; case AArch64MCExpr::VK_TPREL_G2: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2)); return true; case AArch64MCExpr::VK_TPREL_G1_NC: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC)); return true; case AArch64MCExpr::VK_GOTTPREL_G1: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1)); return true; case AArch64MCExpr::VK_GOTTPREL_G0_NC: Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC)); return true; default: return false; } return false; }
unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { AArch64MCExpr::VariantKind RefKind = static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind()); AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind); bool IsNC = AArch64MCExpr::isNotChecked(RefKind); assert((!Target.getSymA() || Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) && "Should only be expression-level modifiers here"); assert((!Target.getSymB() || Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) && "Should only be expression-level modifiers here"); if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; case FK_Data_2: return R_CLS(PREL16); case FK_Data_4: return R_CLS(PREL32); case FK_Data_8: if (IsILP32) { Ctx.reportError(Fixup.getLoc(), "ILP32 8 byte PC relative data " "relocation not supported (LP64 eqv: PREL64)"); return ELF::R_AARCH64_NONE; } else return ELF::R_AARCH64_PREL64; case AArch64::fixup_aarch64_pcrel_adr_imm21: assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation"); return R_CLS(ADR_PREL_LO21); case AArch64::fixup_aarch64_pcrel_adrp_imm21: if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC) return R_CLS(ADR_PREL_PG_HI21); if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) { if (IsILP32) { Ctx.reportError(Fixup.getLoc(), "invalid fixup for 32-bit pcrel ADRP instruction " "VK_ABS VK_NC"); return ELF::R_AARCH64_NONE; } else { return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC; } } if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) return R_CLS(ADR_GOT_PAGE); if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC) return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21); if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) return R_CLS(TLSDESC_ADR_PAGE21); Ctx.reportError(Fixup.getLoc(), "invalid symbol kind for ADRP relocation"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_pcrel_branch26: return R_CLS(JUMP26); case AArch64::fixup_aarch64_pcrel_call26: return R_CLS(CALL26); case AArch64::fixup_aarch64_ldr_pcrel_imm19: if (SymLoc == AArch64MCExpr::VK_GOTTPREL) return R_CLS(TLSIE_LD_GOTTPREL_PREL19); return R_CLS(LD_PREL_LO19); case AArch64::fixup_aarch64_pcrel_branch14: return R_CLS(TSTBR14); case AArch64::fixup_aarch64_pcrel_branch19: return R_CLS(CONDBR19); default: Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind"); return ELF::R_AARCH64_NONE; } } else { if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx)) return ELF::R_AARCH64_NONE; switch ((unsigned)Fixup.getKind()) { case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; case FK_Data_2: return R_CLS(ABS16); case FK_Data_4: return R_CLS(ABS32); case FK_Data_8: if (IsILP32) { Ctx.reportError(Fixup.getLoc(), "ILP32 8 byte absolute data " "relocation not supported (LP64 eqv: ABS64)"); return ELF::R_AARCH64_NONE; } else return ELF::R_AARCH64_ABS64; case AArch64::fixup_aarch64_add_imm12: if (RefKind == AArch64MCExpr::VK_DTPREL_HI12) return R_CLS(TLSLD_ADD_DTPREL_HI12); if (RefKind == AArch64MCExpr::VK_TPREL_HI12) return R_CLS(TLSLE_ADD_TPREL_HI12); if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC) return R_CLS(TLSLD_ADD_DTPREL_LO12_NC); if (RefKind == AArch64MCExpr::VK_DTPREL_LO12) return R_CLS(TLSLD_ADD_DTPREL_LO12); if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC) return R_CLS(TLSLE_ADD_TPREL_LO12_NC); if (RefKind == AArch64MCExpr::VK_TPREL_LO12) return R_CLS(TLSLE_ADD_TPREL_LO12); if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12) return R_CLS(TLSDESC_ADD_LO12); if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(ADD_ABS_LO12_NC); Ctx.reportError(Fixup.getLoc(), "invalid fixup for add (uimm12) instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale1: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(LDST8_ABS_LO12_NC); if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return R_CLS(TLSLD_LDST8_DTPREL_LO12); if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return R_CLS(TLSLE_LDST8_TPREL_LO12); if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return R_CLS(TLSLE_LDST8_TPREL_LO12_NC); Ctx.reportError(Fixup.getLoc(), "invalid fixup for 8-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale2: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(LDST16_ABS_LO12_NC); if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return R_CLS(TLSLD_LDST16_DTPREL_LO12); if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return R_CLS(TLSLE_LDST16_TPREL_LO12); if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return R_CLS(TLSLE_LDST16_TPREL_LO12_NC); Ctx.reportError(Fixup.getLoc(), "invalid fixup for 16-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale4: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(LDST32_ABS_LO12_NC); if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return R_CLS(TLSLD_LDST32_DTPREL_LO12); if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return R_CLS(TLSLE_LDST32_TPREL_LO12); if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return R_CLS(TLSLE_LDST32_TPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) { if (IsILP32) { return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC; } else { Ctx.reportError(Fixup.getLoc(), "LP64 4 byte unchecked GOT load/store relocation " "not supported (ILP32 eqv: LD32_GOT_LO12_NC"); return ELF::R_AARCH64_NONE; } } if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) { if (IsILP32) { Ctx.reportError(Fixup.getLoc(), "ILP32 4 byte checked GOT load/store relocation " "not supported (unchecked eqv: LD32_GOT_LO12_NC)"); } else { Ctx.reportError(Fixup.getLoc(), "LP64 4 byte checked GOT load/store relocation " "not supported (unchecked/ILP32 eqv: " "LD32_GOT_LO12_NC)"); } return ELF::R_AARCH64_NONE; } if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) { if (IsILP32) { return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC; } else { Ctx.reportError(Fixup.getLoc(), "LP64 32-bit load/store " "relocation not supported (ILP32 eqv: " "TLSIE_LD32_GOTTPREL_LO12_NC)"); return ELF::R_AARCH64_NONE; } } if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) { if (IsILP32) { return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12; } else { Ctx.reportError(Fixup.getLoc(), "LP64 4 byte TLSDESC load/store relocation " "not supported (ILP32 eqv: TLSDESC_LD64_LO12)"); return ELF::R_AARCH64_NONE; } } Ctx.reportError(Fixup.getLoc(), "invalid fixup for 32-bit load/store instruction " "fixup_aarch64_ldst_imm12_scale4"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale8: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(LDST64_ABS_LO12_NC); if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) { if (!IsILP32) { return ELF::R_AARCH64_LD64_GOT_LO12_NC; } else { Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " "relocation not supported (LP64 eqv: " "LD64_GOT_LO12_NC)"); return ELF::R_AARCH64_NONE; } } if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return R_CLS(TLSLD_LDST64_DTPREL_LO12); if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return R_CLS(TLSLE_LDST64_TPREL_LO12); if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return R_CLS(TLSLE_LDST64_TPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) { if (!IsILP32) { return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; } else { Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " "relocation not supported (LP64 eqv: " "TLSIE_LD64_GOTTPREL_LO12_NC)"); return ELF::R_AARCH64_NONE; } } if (SymLoc == AArch64MCExpr::VK_TLSDESC) { if (!IsILP32) { return ELF::R_AARCH64_TLSDESC_LD64_LO12; } else { Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " "relocation not supported (LP64 eqv: " "TLSDESC_LD64_LO12)"); return ELF::R_AARCH64_NONE; } } Ctx.reportError(Fixup.getLoc(), "invalid fixup for 64-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale16: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return R_CLS(LDST128_ABS_LO12_NC); if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return R_CLS(TLSLD_LDST128_DTPREL_LO12); if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC); if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return R_CLS(TLSLE_LDST128_TPREL_LO12); if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return R_CLS(TLSLE_LDST128_TPREL_LO12_NC); Ctx.reportError(Fixup.getLoc(), "invalid fixup for 128-bit load/store instruction"); return ELF::R_AARCH64_NONE; // ILP32 case not reached here, tested with isNonILP32reloc case AArch64::fixup_aarch64_movw: if (RefKind == AArch64MCExpr::VK_ABS_G3) return ELF::R_AARCH64_MOVW_UABS_G3; if (RefKind == AArch64MCExpr::VK_ABS_G2) return ELF::R_AARCH64_MOVW_UABS_G2; if (RefKind == AArch64MCExpr::VK_ABS_G2_S) return ELF::R_AARCH64_MOVW_SABS_G2; if (RefKind == AArch64MCExpr::VK_ABS_G2_NC) return ELF::R_AARCH64_MOVW_UABS_G2_NC; if (RefKind == AArch64MCExpr::VK_ABS_G1) return R_CLS(MOVW_UABS_G1); if (RefKind == AArch64MCExpr::VK_ABS_G1_S) return ELF::R_AARCH64_MOVW_SABS_G1; if (RefKind == AArch64MCExpr::VK_ABS_G1_NC) return ELF::R_AARCH64_MOVW_UABS_G1_NC; if (RefKind == AArch64MCExpr::VK_ABS_G0) return R_CLS(MOVW_UABS_G0); if (RefKind == AArch64MCExpr::VK_ABS_G0_S) return R_CLS(MOVW_SABS_G0); if (RefKind == AArch64MCExpr::VK_ABS_G0_NC) return R_CLS(MOVW_UABS_G0_NC); if (RefKind == AArch64MCExpr::VK_DTPREL_G2) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2; if (RefKind == AArch64MCExpr::VK_DTPREL_G1) return R_CLS(TLSLD_MOVW_DTPREL_G1); if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC; if (RefKind == AArch64MCExpr::VK_DTPREL_G0) return R_CLS(TLSLD_MOVW_DTPREL_G0); if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC) return R_CLS(TLSLD_MOVW_DTPREL_G0_NC); if (RefKind == AArch64MCExpr::VK_TPREL_G2) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2; if (RefKind == AArch64MCExpr::VK_TPREL_G1) return R_CLS(TLSLE_MOVW_TPREL_G1); if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC; if (RefKind == AArch64MCExpr::VK_TPREL_G0) return R_CLS(TLSLE_MOVW_TPREL_G0); if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC) return R_CLS(TLSLE_MOVW_TPREL_G0_NC); if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1) return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1; if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC) return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for movz/movk instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_tlsdesc_call: return R_CLS(TLSDESC_CALL); default: Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type"); return ELF::R_AARCH64_NONE; } } llvm_unreachable("Unimplemented fixup -> relocation"); }
bool AsmExpr::EvaluateAsRelocatable(MCContext &Ctx, MCValue &Res) const { switch (getKind()) { default: assert(0 && "Invalid assembly expression kind!"); case Constant: Res = MCValue::get(cast<AsmConstantExpr>(this)->getValue()); return true; case SymbolRef: { MCSymbol *Sym = cast<AsmSymbolRefExpr>(this)->getSymbol(); if (const MCValue *Value = Ctx.GetSymbolValue(Sym)) Res = *Value; else Res = MCValue::get(Sym, 0, 0); return true; } case Unary: { const AsmUnaryExpr *AUE = cast<AsmUnaryExpr>(this); MCValue Value; if (!AUE->getSubExpr()->EvaluateAsRelocatable(Ctx, Value)) return false; switch (AUE->getOpcode()) { case AsmUnaryExpr::LNot: if (!Value.isAbsolute()) return false; Res = MCValue::get(!Value.getConstant()); break; case AsmUnaryExpr::Minus: /// -(a - b + const) ==> (b - a - const) if (Value.getSymA() && !Value.getSymB()) return false; Res = MCValue::get(Value.getSymB(), Value.getSymA(), -Value.getConstant()); break; case AsmUnaryExpr::Not: if (!Value.isAbsolute()) return false; Res = MCValue::get(~Value.getConstant()); break; case AsmUnaryExpr::Plus: Res = Value; break; } return true; } case Binary: { const AsmBinaryExpr *ABE = cast<AsmBinaryExpr>(this); MCValue LHSValue, RHSValue; if (!ABE->getLHS()->EvaluateAsRelocatable(Ctx, LHSValue) || !ABE->getRHS()->EvaluateAsRelocatable(Ctx, RHSValue)) return false; // We only support a few operations on non-constant expressions, handle // those first. if (!LHSValue.isAbsolute() || !RHSValue.isAbsolute()) { switch (ABE->getOpcode()) { default: return false; case AsmBinaryExpr::Sub: // Negate RHS and add. return EvaluateSymbolicAdd(LHSValue, RHSValue.getSymB(), RHSValue.getSymA(), -RHSValue.getConstant(), Res); case AsmBinaryExpr::Add: return EvaluateSymbolicAdd(LHSValue, RHSValue.getSymA(), RHSValue.getSymB(), RHSValue.getConstant(), Res); } } // FIXME: We need target hooks for the evaluation. It may be limited in // width, and gas defines the result of comparisons differently from Apple // as (the result is sign extended). int64_t LHS = LHSValue.getConstant(), RHS = RHSValue.getConstant(); int64_t Result = 0; switch (ABE->getOpcode()) { case AsmBinaryExpr::Add: Result = LHS + RHS; break; case AsmBinaryExpr::And: Result = LHS & RHS; break; case AsmBinaryExpr::Div: Result = LHS / RHS; break; case AsmBinaryExpr::EQ: Result = LHS == RHS; break; case AsmBinaryExpr::GT: Result = LHS > RHS; break; case AsmBinaryExpr::GTE: Result = LHS >= RHS; break; case AsmBinaryExpr::LAnd: Result = LHS && RHS; break; case AsmBinaryExpr::LOr: Result = LHS || RHS; break; case AsmBinaryExpr::LT: Result = LHS < RHS; break; case AsmBinaryExpr::LTE: Result = LHS <= RHS; break; case AsmBinaryExpr::Mod: Result = LHS % RHS; break; case AsmBinaryExpr::Mul: Result = LHS * RHS; break; case AsmBinaryExpr::NE: Result = LHS != RHS; break; case AsmBinaryExpr::Or: Result = LHS | RHS; break; case AsmBinaryExpr::Shl: Result = LHS << RHS; break; case AsmBinaryExpr::Shr: Result = LHS >> RHS; break; case AsmBinaryExpr::Sub: Result = LHS - RHS; break; case AsmBinaryExpr::Xor: Result = LHS ^ RHS; break; } Res = MCValue::get(Result); return true; } } }
void AVRTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { Base::Initialize(Ctx, TM); ProgmemDataSection = Ctx.getELFSection(".progmem.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); }
static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc, MCSymbolRefExpr::VariantKind Modifier, X86_64RelType Type, bool IsPCRel, unsigned Kind) { switch (Modifier) { default: llvm_unreachable("Unimplemented"); case MCSymbolRefExpr::VK_None: switch (Type) { case RT64_64: return IsPCRel ? ELF::R_X86_64_PC64 : ELF::R_X86_64_64; case RT64_32: return IsPCRel ? ELF::R_X86_64_PC32 : ELF::R_X86_64_32; case RT64_32S: return ELF::R_X86_64_32S; case RT64_16: return IsPCRel ? ELF::R_X86_64_PC16 : ELF::R_X86_64_16; case RT64_8: return IsPCRel ? ELF::R_X86_64_PC8 : ELF::R_X86_64_8; } case MCSymbolRefExpr::VK_GOT: switch (Type) { case RT64_64: return IsPCRel ? ELF::R_X86_64_GOTPC64 : ELF::R_X86_64_GOT64; case RT64_32: return IsPCRel ? ELF::R_X86_64_GOTPC32 : ELF::R_X86_64_GOT32; case RT64_32S: case RT64_16: case RT64_8: llvm_unreachable("Unimplemented"); } case MCSymbolRefExpr::VK_GOTOFF: assert(Type == RT64_64); assert(!IsPCRel); return ELF::R_X86_64_GOTOFF64; case MCSymbolRefExpr::VK_TPOFF: assert(!IsPCRel); switch (Type) { case RT64_64: return ELF::R_X86_64_TPOFF64; case RT64_32: return ELF::R_X86_64_TPOFF32; case RT64_32S: case RT64_16: case RT64_8: llvm_unreachable("Unimplemented"); } case MCSymbolRefExpr::VK_DTPOFF: assert(!IsPCRel); switch (Type) { case RT64_64: return ELF::R_X86_64_DTPOFF64; case RT64_32: return ELF::R_X86_64_DTPOFF32; case RT64_32S: case RT64_16: case RT64_8: llvm_unreachable("Unimplemented"); } case MCSymbolRefExpr::VK_SIZE: assert(!IsPCRel); switch (Type) { case RT64_64: return ELF::R_X86_64_SIZE64; case RT64_32: return ELF::R_X86_64_SIZE32; case RT64_32S: case RT64_16: case RT64_8: llvm_unreachable("Unimplemented"); } case MCSymbolRefExpr::VK_TLSCALL: return ELF::R_X86_64_TLSDESC_CALL; case MCSymbolRefExpr::VK_TLSDESC: return ELF::R_X86_64_GOTPC32_TLSDESC; case MCSymbolRefExpr::VK_TLSGD: checkIs32(Ctx, Loc, Type); return ELF::R_X86_64_TLSGD; case MCSymbolRefExpr::VK_GOTTPOFF: checkIs32(Ctx, Loc, Type); return ELF::R_X86_64_GOTTPOFF; case MCSymbolRefExpr::VK_TLSLD: checkIs32(Ctx, Loc, Type); return ELF::R_X86_64_TLSLD; case MCSymbolRefExpr::VK_PLT: checkIs32(Ctx, Loc, Type); return ELF::R_X86_64_PLT32; case MCSymbolRefExpr::VK_GOTPCREL: checkIs32(Ctx, Loc, Type); // Older versions of ld.bfd/ld.gold/lld // do not support GOTPCRELX/REX_GOTPCRELX, // and we want to keep back-compatibility. if (!Ctx.getAsmInfo()->canRelaxRelocations()) return ELF::R_X86_64_GOTPCREL; switch (Kind) { default: return ELF::R_X86_64_GOTPCREL; case X86::reloc_riprel_4byte_relax: return ELF::R_X86_64_GOTPCRELX; case X86::reloc_riprel_4byte_relax_rex: case X86::reloc_riprel_4byte_movq_load: return ELF::R_X86_64_REX_GOTPCRELX; } } }
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext &Ctx) { unsigned Kind = Fixup.getKind(); switch (Kind) { default: llvm_unreachable("Unknown fixup kind!"); case RISCV::fixup_riscv_got_hi20: llvm_unreachable("Relocation should be unconditionally forced\n"); case FK_Data_1: case FK_Data_2: case FK_Data_4: case FK_Data_8: return Value; case RISCV::fixup_riscv_lo12_i: case RISCV::fixup_riscv_pcrel_lo12_i: case RISCV::fixup_riscv_tprel_lo12_i: return Value & 0xfff; case RISCV::fixup_riscv_lo12_s: case RISCV::fixup_riscv_pcrel_lo12_s: case RISCV::fixup_riscv_tprel_lo12_s: return (((Value >> 5) & 0x7f) << 25) | ((Value & 0x1f) << 7); case RISCV::fixup_riscv_hi20: case RISCV::fixup_riscv_pcrel_hi20: case RISCV::fixup_riscv_tprel_hi20: // Add 1 if bit 11 is 1, to compensate for low 12 bits being negative. return ((Value + 0x800) >> 12) & 0xfffff; case RISCV::fixup_riscv_jal: { if (!isInt<21>(Value)) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0x1) Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned"); // Need to produce imm[19|10:1|11|19:12] from the 21-bit Value. unsigned Sbit = (Value >> 20) & 0x1; unsigned Hi8 = (Value >> 12) & 0xff; unsigned Mid1 = (Value >> 11) & 0x1; unsigned Lo10 = (Value >> 1) & 0x3ff; // Inst{31} = Sbit; // Inst{30-21} = Lo10; // Inst{20} = Mid1; // Inst{19-12} = Hi8; Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8; return Value; } case RISCV::fixup_riscv_branch: { if (!isInt<13>(Value)) Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); if (Value & 0x1) Ctx.reportError(Fixup.getLoc(), "fixup value must be 2-byte aligned"); // Need to extract imm[12], imm[10:5], imm[4:1], imm[11] from the 13-bit // Value. unsigned Sbit = (Value >> 12) & 0x1; unsigned Hi1 = (Value >> 11) & 0x1; unsigned Mid6 = (Value >> 5) & 0x3f; unsigned Lo4 = (Value >> 1) & 0xf; // Inst{31} = Sbit; // Inst{30-25} = Mid6; // Inst{11-8} = Lo4; // Inst{7} = Hi1; Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7); return Value; } case RISCV::fixup_riscv_call: case RISCV::fixup_riscv_call_plt: { // Jalr will add UpperImm with the sign-extended 12-bit LowerImm, // we need to add 0x800ULL before extract upper bits to reflect the // effect of the sign extension. uint64_t UpperImm = (Value + 0x800ULL) & 0xfffff000ULL; uint64_t LowerImm = Value & 0xfffULL; return UpperImm | ((LowerImm << 20) << 32); } case RISCV::fixup_riscv_rvc_jump: { // Need to produce offset[11|4|9:8|10|6|7|3:1|5] from the 11-bit Value. unsigned Bit11 = (Value >> 11) & 0x1; unsigned Bit4 = (Value >> 4) & 0x1; unsigned Bit9_8 = (Value >> 8) & 0x3; unsigned Bit10 = (Value >> 10) & 0x1; unsigned Bit6 = (Value >> 6) & 0x1; unsigned Bit7 = (Value >> 7) & 0x1; unsigned Bit3_1 = (Value >> 1) & 0x7; unsigned Bit5 = (Value >> 5) & 0x1; Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) | (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5; return Value; } case RISCV::fixup_riscv_rvc_branch: { // Need to produce offset[8|4:3], [reg 3 bit], offset[7:6|2:1|5] unsigned Bit8 = (Value >> 8) & 0x1; unsigned Bit7_6 = (Value >> 6) & 0x3; unsigned Bit5 = (Value >> 5) & 0x1; unsigned Bit4_3 = (Value >> 3) & 0x3; unsigned Bit2_1 = (Value >> 1) & 0x3; Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) | (Bit5 << 2); return Value; } } }
static void checkIs32(MCContext &Ctx, SMLoc Loc, X86_64RelType Type) { if (Type != RT64_32) Ctx.reportError(Loc, "32 bit reloc applied to a field with a different size"); }
unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { AArch64MCExpr::VariantKind RefKind = static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind()); AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind); bool IsNC = AArch64MCExpr::isNotChecked(RefKind); assert((!Target.getSymA() || Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) && "Should only be expression-level modifiers here"); assert((!Target.getSymB() || Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) && "Should only be expression-level modifiers here"); if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; case FK_Data_2: return ELF::R_AARCH64_PREL16; case FK_Data_4: return ELF::R_AARCH64_PREL32; case FK_Data_8: return ELF::R_AARCH64_PREL64; case AArch64::fixup_aarch64_pcrel_adr_imm21: assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation"); return ELF::R_AARCH64_ADR_PREL_LO21; case AArch64::fixup_aarch64_pcrel_adrp_imm21: if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC) return ELF::R_AARCH64_ADR_PREL_PG_HI21; if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) return ELF::R_AARCH64_ADR_GOT_PAGE; if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC) return ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21; if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) return ELF::R_AARCH64_TLSDESC_ADR_PAGE21; Ctx.reportError(Fixup.getLoc(), "invalid symbol kind for ADRP relocation"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_pcrel_branch26: return ELF::R_AARCH64_JUMP26; case AArch64::fixup_aarch64_pcrel_call26: return ELF::R_AARCH64_CALL26; case AArch64::fixup_aarch64_ldr_pcrel_imm19: if (SymLoc == AArch64MCExpr::VK_GOTTPREL) return ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19; return ELF::R_AARCH64_LD_PREL_LO19; case AArch64::fixup_aarch64_pcrel_branch14: return ELF::R_AARCH64_TSTBR14; case AArch64::fixup_aarch64_pcrel_branch19: return ELF::R_AARCH64_CONDBR19; default: Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind"); return ELF::R_AARCH64_NONE; } } else { switch ((unsigned)Fixup.getKind()) { case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; case FK_Data_2: return ELF::R_AARCH64_ABS16; case FK_Data_4: return ELF::R_AARCH64_ABS32; case FK_Data_8: return ELF::R_AARCH64_ABS64; case AArch64::fixup_aarch64_add_imm12: if (RefKind == AArch64MCExpr::VK_DTPREL_HI12) return ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12; if (RefKind == AArch64MCExpr::VK_TPREL_HI12) return ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12; if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC) return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC; if (RefKind == AArch64MCExpr::VK_DTPREL_LO12) return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12; if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC) return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC; if (RefKind == AArch64MCExpr::VK_TPREL_LO12) return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12; if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12) return ELF::R_AARCH64_TLSDESC_ADD_LO12_NC; if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return ELF::R_AARCH64_ADD_ABS_LO12_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for add (uimm12) instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale1: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return ELF::R_AARCH64_LDST8_ABS_LO12_NC; if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12; if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC; if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12; if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for 8-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale2: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return ELF::R_AARCH64_LDST16_ABS_LO12_NC; if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12; if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC; if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12; if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for 16-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale4: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return ELF::R_AARCH64_LDST32_ABS_LO12_NC; if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12; if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC; if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12; if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for 32-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale8: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return ELF::R_AARCH64_LDST64_ABS_LO12_NC; if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) return ELF::R_AARCH64_LD64_GOT_LO12_NC; if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12; if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC; if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12; if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC; if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; if (SymLoc == AArch64MCExpr::VK_TLSDESC && IsNC) return ELF::R_AARCH64_TLSDESC_LD64_LO12_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for 64-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_ldst_imm12_scale16: if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) return ELF::R_AARCH64_LDST128_ABS_LO12_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for 128-bit load/store instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_movw: if (RefKind == AArch64MCExpr::VK_ABS_G3) return ELF::R_AARCH64_MOVW_UABS_G3; if (RefKind == AArch64MCExpr::VK_ABS_G2) return ELF::R_AARCH64_MOVW_UABS_G2; if (RefKind == AArch64MCExpr::VK_ABS_G2_S) return ELF::R_AARCH64_MOVW_SABS_G2; if (RefKind == AArch64MCExpr::VK_ABS_G2_NC) return ELF::R_AARCH64_MOVW_UABS_G2_NC; if (RefKind == AArch64MCExpr::VK_ABS_G1) return ELF::R_AARCH64_MOVW_UABS_G1; if (RefKind == AArch64MCExpr::VK_ABS_G1_S) return ELF::R_AARCH64_MOVW_SABS_G1; if (RefKind == AArch64MCExpr::VK_ABS_G1_NC) return ELF::R_AARCH64_MOVW_UABS_G1_NC; if (RefKind == AArch64MCExpr::VK_ABS_G0) return ELF::R_AARCH64_MOVW_UABS_G0; if (RefKind == AArch64MCExpr::VK_ABS_G0_S) return ELF::R_AARCH64_MOVW_SABS_G0; if (RefKind == AArch64MCExpr::VK_ABS_G0_NC) return ELF::R_AARCH64_MOVW_UABS_G0_NC; if (RefKind == AArch64MCExpr::VK_DTPREL_G2) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2; if (RefKind == AArch64MCExpr::VK_DTPREL_G1) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1; if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC; if (RefKind == AArch64MCExpr::VK_DTPREL_G0) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0; if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC) return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC; if (RefKind == AArch64MCExpr::VK_TPREL_G2) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2; if (RefKind == AArch64MCExpr::VK_TPREL_G1) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1; if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC; if (RefKind == AArch64MCExpr::VK_TPREL_G0) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0; if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC) return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC; if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1) return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1; if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC) return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC; Ctx.reportError(Fixup.getLoc(), "invalid fixup for movz/movk instruction"); return ELF::R_AARCH64_NONE; case AArch64::fixup_aarch64_tlsdesc_call: return ELF::R_AARCH64_TLSDESC_CALL; default: Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type"); return ELF::R_AARCH64_NONE; } } llvm_unreachable("Unimplemented fixup -> relocation"); }
bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, CodeGenOpt::Level OptLevel, bool DisableVerify) { // Add common CodeGen passes. MCContext *Context = 0; if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Context)) return true; assert(Context != 0 && "Failed to get MCContext"); if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); OwningPtr<MCStreamer> AsmStreamer; switch (FileType) { default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; MCAsmBackend *MAB = 0; if (ShowMCEncoding) { const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context); MAB = getTarget().createMCAsmBackend(getTargetTriple()); } MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, getVerboseAsm(), hasMCUseLoc(), hasMCUseCFI(), hasMCUseDwarfDirectory(), InstPrinter, MCE, MAB, ShowMCInst); AsmStreamer.reset(S); break; } case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context); MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple()); if (MCE == 0 || MAB == 0) return true; AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Context, *MAB, Out, MCE, hasMCRelaxAll(), hasMCNoExecStack())); AsmStreamer.get()->InitSections(); break; } case CGFT_Null: // The Null output is intended for use for performance analysis and testing, // not real users. AsmStreamer.reset(createNullStreamer(*Context)); break; } if (EnableMCLogging) AsmStreamer.reset(createLoggingStreamer(AsmStreamer.take(), errs())); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) return true; // If successful, createAsmPrinter took ownership of AsmStreamer. AsmStreamer.take(); PM.add(Printer); PM.add(createGCInfoDeleter()); return false; }
unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel, MCContext &Ctx) const { MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { default: Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol"); return ELF::R_ARM_NONE; case FK_Data_4: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_REL32; case MCSymbolRefExpr::VK_GOTTPOFF: return ELF::R_ARM_TLS_IE32; case MCSymbolRefExpr::VK_ARM_GOT_PREL: return ELF::R_ARM_GOT_PREL; case MCSymbolRefExpr::VK_ARM_PREL31: return ELF::R_ARM_PREL31; } case ARM::fixup_arm_blx: case ARM::fixup_arm_uncondbl: switch (Modifier) { case MCSymbolRefExpr::VK_PLT: return ELF::R_ARM_CALL; case MCSymbolRefExpr::VK_TLSCALL: return ELF::R_ARM_TLS_CALL; default: return ELF::R_ARM_CALL; } case ARM::fixup_arm_condbl: case ARM::fixup_arm_condbranch: case ARM::fixup_arm_uncondbranch: return ELF::R_ARM_JUMP24; case ARM::fixup_t2_condbranch: return ELF::R_ARM_THM_JUMP19; case ARM::fixup_t2_uncondbranch: return ELF::R_ARM_THM_JUMP24; case ARM::fixup_arm_movt_hi16: return ELF::R_ARM_MOVT_PREL; case ARM::fixup_arm_movw_lo16: return ELF::R_ARM_MOVW_PREL_NC; case ARM::fixup_t2_movt_hi16: return ELF::R_ARM_THM_MOVT_PREL; case ARM::fixup_t2_movw_lo16: return ELF::R_ARM_THM_MOVW_PREL_NC; case ARM::fixup_arm_thumb_br: return ELF::R_ARM_THM_JUMP11; case ARM::fixup_arm_thumb_bcc: return ELF::R_ARM_THM_JUMP8; case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: switch (Modifier) { case MCSymbolRefExpr::VK_TLSCALL: return ELF::R_ARM_THM_TLS_CALL; default: return ELF::R_ARM_THM_CALL; } } } switch ((unsigned)Fixup.getKind()) { default: Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol"); return ELF::R_ARM_NONE; case FK_Data_1: switch (Modifier) { default: llvm_unreachable("unsupported Modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_ABS8; } case FK_Data_2: switch (Modifier) { default: llvm_unreachable("unsupported modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_ABS16; } case FK_Data_4: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_ARM_NONE: return ELF::R_ARM_NONE; case MCSymbolRefExpr::VK_GOT: return ELF::R_ARM_GOT_BREL; case MCSymbolRefExpr::VK_TLSGD: return ELF::R_ARM_TLS_GD32; case MCSymbolRefExpr::VK_TPOFF: return ELF::R_ARM_TLS_LE32; case MCSymbolRefExpr::VK_GOTTPOFF: return ELF::R_ARM_TLS_IE32; case MCSymbolRefExpr::VK_None: return ELF::R_ARM_ABS32; case MCSymbolRefExpr::VK_GOTOFF: return ELF::R_ARM_GOTOFF32; case MCSymbolRefExpr::VK_ARM_GOT_PREL: return ELF::R_ARM_GOT_PREL; case MCSymbolRefExpr::VK_ARM_TARGET1: return ELF::R_ARM_TARGET1; case MCSymbolRefExpr::VK_ARM_TARGET2: return ELF::R_ARM_TARGET2; case MCSymbolRefExpr::VK_ARM_PREL31: return ELF::R_ARM_PREL31; case MCSymbolRefExpr::VK_ARM_SBREL: return ELF::R_ARM_SBREL32; case MCSymbolRefExpr::VK_ARM_TLSLDO: return ELF::R_ARM_TLS_LDO32; case MCSymbolRefExpr::VK_TLSCALL: return ELF::R_ARM_TLS_CALL; case MCSymbolRefExpr::VK_TLSDESC: return ELF::R_ARM_TLS_GOTDESC; case MCSymbolRefExpr::VK_TLSLDM: return ELF::R_ARM_TLS_LDM32; case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ: return ELF::R_ARM_TLS_DESCSEQ; } case ARM::fixup_arm_condbranch: case ARM::fixup_arm_uncondbranch: return ELF::R_ARM_JUMP24; case ARM::fixup_arm_movt_hi16: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_MOVT_ABS; case MCSymbolRefExpr::VK_ARM_SBREL: return ELF::R_ARM_MOVT_BREL; } case ARM::fixup_arm_movw_lo16: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_MOVW_ABS_NC; case MCSymbolRefExpr::VK_ARM_SBREL: return ELF::R_ARM_MOVW_BREL_NC; } case ARM::fixup_t2_movt_hi16: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_THM_MOVT_ABS; case MCSymbolRefExpr::VK_ARM_SBREL: return ELF::R_ARM_THM_MOVT_BREL; } case ARM::fixup_t2_movw_lo16: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_None: return ELF::R_ARM_THM_MOVW_ABS_NC; case MCSymbolRefExpr::VK_ARM_SBREL: return ELF::R_ARM_THM_MOVW_BREL_NC; } } }