static void writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &Strings, uint32_t &StringOffset, MCSection *StrSection, MCSection *StrOffsetSection, StringRef CurStrSection, StringRef CurStrOffsetSection) { // Could possibly produce an error or warning if one of these was non-null but // the other was null. if (CurStrSection.empty() || CurStrOffsetSection.empty()) return; DenseMap<uint32_t, uint32_t> OffsetRemapping; DataExtractor Data(CurStrSection, true, 0); uint32_t LocalOffset = 0; uint32_t PrevOffset = 0; while (const char *s = Data.getCStr(&LocalOffset)) { StringRef Str(s, LocalOffset - PrevOffset - 1); auto Pair = Strings.insert(std::make_pair(Str, StringOffset)); if (Pair.second) { Out.SwitchSection(StrSection); Out.EmitBytes( StringRef(Pair.first->getKeyData(), Pair.first->getKeyLength() + 1)); StringOffset += Str.size() + 1; } OffsetRemapping[PrevOffset] = Pair.first->second; PrevOffset = LocalOffset; } Data = DataExtractor(CurStrOffsetSection, true, 0); Out.SwitchSection(StrOffsetSection); uint32_t Offset = 0; uint64_t Size = CurStrOffsetSection.size(); while (Offset < Size) { auto OldOffset = Data.getU32(&Offset); auto NewOffset = OffsetRemapping[OldOffset]; Out.EmitIntValue(NewOffset, 4); } }
bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, unsigned &ErrorInfo, bool MatchingInlineAsm) { MCInst Inst; unsigned MatchResult; MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); switch (MatchResult) { default: break; case Match_Success: Inst.setLoc(IDLoc); Out.EmitInstruction(Inst, STI); return false; case Match_MissingFeature: { assert(ErrorInfo && "Unknown missing feature!"); // Special case the error message for the very common case where only // a single subtarget feature is missing std::string Msg = "instruction requires:"; unsigned Mask = 1; for (unsigned I = 0; I < sizeof(ErrorInfo) * 8 - 1; ++I) { if (ErrorInfo & Mask) { Msg += " "; Msg += getSubtargetFeatureName(ErrorInfo & Mask); } Mask <<= 1; } return Error(IDLoc, Msg); } case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; if (ErrorInfo != ~0U) { if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); ErrorLoc = ((SystemZOperand &)*Operands[ErrorInfo]).getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } return Error(ErrorLoc, "invalid operand for instruction"); } case Match_MnemonicFail: return Error(IDLoc, "invalid instruction"); } llvm_unreachable("Unexpected match type"); }
static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym) { // L_foo$stub: OutStreamer.EmitLabel(StubLabel); // .indirect_symbol _foo OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 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. // We need to fill in the value for the NLP in those cases. OutStreamer.EmitValue( MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()), 4 /*size*/); }
static void EmitRet(const MCOperand *AmtOp, bool Is64Bit, MCStreamer &Out) { MCInst POPInst; POPInst.setOpcode(Is64Bit ? X86::POP64r : X86::POP32r); POPInst.addOperand(MCOperand::CreateReg(Is64Bit ? X86::RCX : X86::ECX)); Out.EmitInstruction(POPInst); if (AmtOp) { assert(!Is64Bit); MCInst ADDInst; unsigned ADDReg = X86::ESP; ADDInst.setOpcode(X86::ADD32ri); ADDInst.addOperand(MCOperand::CreateReg(ADDReg)); ADDInst.addOperand(MCOperand::CreateReg(ADDReg)); ADDInst.addOperand(*AmtOp); Out.EmitInstruction(ADDInst); } MCInst JMPInst; JMPInst.setOpcode(Is64Bit ? X86::NACL_JMP64r : X86::NACL_JMP32r); JMPInst.addOperand(MCOperand::CreateReg(X86::ECX)); Out.EmitInstruction(JMPInst); }
static void writeIndex(MCStreamer &Out, MCSection *Section, ArrayRef<unsigned> ContributionOffsets, ArrayRef<UnitIndexEntry> IndexEntries) { unsigned Columns = 0; for (auto &C : ContributionOffsets) if (C) ++Columns; std::vector<unsigned> Buckets(NextPowerOf2(3 * IndexEntries.size() / 2)); uint64_t Mask = Buckets.size() - 1; for (size_t i = 0; i != IndexEntries.size(); ++i) { auto S = IndexEntries[i].Signature; auto H = S & Mask; while (Buckets[H]) { assert(S != IndexEntries[Buckets[H] - 1].Signature && "Duplicate type unit"); H += ((S >> 32) & Mask) | 1; } Buckets[H] = i + 1; } Out.SwitchSection(Section); Out.EmitIntValue(2, 4); // Version Out.EmitIntValue(Columns, 4); // Columns Out.EmitIntValue(IndexEntries.size(), 4); // Num Units Out.EmitIntValue(Buckets.size(), 4); // Num Buckets // Write the signatures. for (const auto &I : Buckets) Out.EmitIntValue(I ? IndexEntries[I - 1].Signature : 0, 8); // Write the indexes. for (const auto &I : Buckets) Out.EmitIntValue(I, 4); // Write the column headers (which sections will appear in the table) for (size_t i = 0; i != ContributionOffsets.size(); ++i) if (ContributionOffsets[i]) Out.EmitIntValue(i + DW_SECT_INFO, 4); // Write the offsets. writeIndexTable(Out, ContributionOffsets, IndexEntries, &DWARFUnitIndex::Entry::SectionContribution::Offset); // Write the lengths. writeIndexTable(Out, ContributionOffsets, IndexEntries, &DWARFUnitIndex::Entry::SectionContribution::Length); }
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) { MCInst Inst; SmallVector<MCInst, 8> Instructions; unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); switch (MatchResult) { case Match_Success: { switch (Inst.getOpcode()) { default: Inst.setLoc(IDLoc); Instructions.push_back(Inst); break; case SP::SET: if (expandSET(Inst, IDLoc, Instructions)) return true; break; } for (const MCInst &I : Instructions) { Out.EmitInstruction(I, getSTI()); } return false; } case Match_MissingFeature: return Error(IDLoc, "instruction requires a CPU feature not currently enabled"); case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; if (ErrorInfo != ~0ULL) { if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } return Error(ErrorLoc, "invalid operand for instruction"); } case Match_MnemonicFail: return Error(IDLoc, "invalid instruction mnemonic"); } llvm_unreachable("Implement any new match types added!"); }
static void LowerSTATEPOINT(MCStreamer &OS, StackMaps &SM, const MachineInstr &MI, bool Is64Bit, const TargetMachine& TM, const MCSubtargetInfo& STI, X86MCInstLower &MCInstLowering) { assert(Is64Bit && "Statepoint currently only supports X86-64"); // Lower call target and choose correct opcode const MachineOperand &call_target = StatepointOpers(&MI).getCallTarget(); MCOperand call_target_mcop; unsigned call_opcode; switch (call_target.getType()) { case MachineOperand::MO_GlobalAddress: case MachineOperand::MO_ExternalSymbol: call_target_mcop = MCInstLowering.LowerSymbolOperand( call_target, MCInstLowering.GetSymbolFromOperand(call_target)); call_opcode = X86::CALL64pcrel32; // Currently, we only support relative addressing with statepoints. // Otherwise, we'll need a scratch register to hold the target // address. You'll fail asserts during load & relocation if this // symbol is to far away. (TODO: support non-relative addressing) break; case MachineOperand::MO_Immediate: call_target_mcop = MCOperand::CreateImm(call_target.getImm()); call_opcode = X86::CALL64pcrel32; // Currently, we only support relative addressing with statepoints. // Otherwise, we'll need a scratch register to hold the target // immediate. You'll fail asserts during load & relocation if this // address is to far away. (TODO: support non-relative addressing) break; case MachineOperand::MO_Register: call_target_mcop = MCOperand::CreateReg(call_target.getReg()); call_opcode = X86::CALL64r; break; default: llvm_unreachable("Unsupported operand type in statepoint call target"); break; } // Emit call MCInst call_inst; call_inst.setOpcode(call_opcode); call_inst.addOperand(call_target_mcop); OS.EmitInstruction(call_inst, STI); // Record our statepoint node in the same section used by STACKMAP // and PATCHPOINT SM.recordStatepoint(MI); }
static void addAllTypes(MCStreamer &Out, std::vector<UnitIndexEntry> &TypeIndexEntries, MCSection *OutputTypes, StringRef Types, const UnitIndexEntry &CUEntry, uint32_t &TypesOffset) { if (Types.empty()) return; Out.SwitchSection(OutputTypes); uint32_t Offset = 0; DataExtractor Data(Types, true, 0); while (Data.isValidOffset(Offset)) { UnitIndexEntry Entry = CUEntry; // Zero out the debug_info contribution Entry.Contributions[0] = {}; auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO]; C.Offset = TypesOffset; auto PrevOffset = Offset; // Length of the unit, including the 4 byte length field. C.Length = Data.getU32(&Offset) + 4; Data.getU16(&Offset); // Version Data.getU32(&Offset); // Abbrev offset Data.getU8(&Offset); // Address size Entry.Signature = Data.getU64(&Offset); Offset = PrevOffset + C.Length; if (any_of(TypeIndexEntries, [&](const UnitIndexEntry &E) { return E.Signature == Entry.Signature; })) continue; Out.EmitBytes(Types.substr(PrevOffset, C.Length)); TypesOffset += C.Length; TypeIndexEntries.push_back(Entry); } }
static void EmitDirectCall(const MCOperand &Op, bool Is64Bit, MCStreamer &Out) { const bool HideSandboxBase = (FlagHideSandboxBase && Is64Bit && !FlagUseZeroBasedSandbox); if (HideSandboxBase) { // For NaCl64, the sequence // call target // return_addr: // is changed to // push return_addr // jmp target // .align 32 // return_addr: // This avoids exposing the sandbox base address via the return // address on the stack. MCContext &Context = Out.getContext(); // Generate a label for the return address. MCSymbol *RetTarget = CreateTempLabel(Context, "DirectCallRetAddr"); const MCExpr *RetTargetExpr = MCSymbolRefExpr::Create(RetTarget, Context); // push return_addr MCInst PUSHInst; PUSHInst.setOpcode(X86::PUSH64i32); PUSHInst.addOperand(MCOperand::CreateExpr(RetTargetExpr)); Out.EmitInstruction(PUSHInst); // jmp target MCInst JMPInst; JMPInst.setOpcode(X86::JMP_4); JMPInst.addOperand(Op); Out.EmitInstruction(JMPInst); Out.EmitCodeAlignment(kNaClX86InstructionBundleSize); Out.EmitLabel(RetTarget); } else { Out.EmitBundleLock(true); MCInst CALLInst; CALLInst.setOpcode(Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32); CALLInst.addOperand(Op); Out.EmitInstruction(CALLInst); Out.EmitBundleUnlock(); } }
// Fix a register after being truncated to 32-bits. static void EmitRegFix(unsigned Reg64, MCStreamer &Out) { // lea (%rsp, %r15, 1), %rsp // We do not need to add the R15 base for the zero-based sandbox model if (!FlagUseZeroBasedSandbox) { MCInst Tmp; Tmp.setOpcode(X86::LEA64r); Tmp.addOperand(MCOperand::CreateReg(Reg64)); // DestReg Tmp.addOperand(MCOperand::CreateReg(Reg64)); // BaseReg Tmp.addOperand(MCOperand::CreateImm(1)); // Scale Tmp.addOperand(MCOperand::CreateReg(X86::R15)); // IndexReg Tmp.addOperand(MCOperand::CreateImm(0)); // Offset Tmp.addOperand(MCOperand::CreateReg(0)); // SegmentReg Out.EmitInstruction(Tmp); } }
static void EmitTST(MCStreamer &Out, unsigned Reg) { // tst \reg, #\MASK typically 0xc0000000 const unsigned Mask = 0xC0000000; MCInst TSTInst; TSTInst.setOpcode(ARM::TSTri); TSTInst.addOperand(MCOperand::CreateReg(Reg)); // rS if (FlagSfiZeroMask) { TSTInst.addOperand(MCOperand::CreateImm(0)); // imm } else { TSTInst.addOperand(MCOperand::CreateImm(Mask)); // imm } TSTInst.addOperand(MCOperand::CreateImm((int64_t)ARMCC::AL)); // Always TSTInst.addOperand(MCOperand::CreateImm(0)); // flag out Out.EmitInstruction(TSTInst); }
static void EmitTLSAddr32(const MCInst &Inst, MCStreamer &Out) { Out.EmitBundleLock(true); MCInst LeaInst; LeaInst.setOpcode(X86::LEA32r); LeaInst.addOperand(MCOperand::CreateReg(X86::EAX)); // DestReg LeaInst.addOperand(Inst.getOperand(0)); // BaseReg LeaInst.addOperand(Inst.getOperand(1)); // Scale LeaInst.addOperand(Inst.getOperand(2)); // IndexReg LeaInst.addOperand(Inst.getOperand(3)); // Offset LeaInst.addOperand(Inst.getOperand(4)); // SegmentReg Out.EmitInstruction(LeaInst); MCInst CALLInst; CALLInst.setOpcode(X86::CALLpcrel32); MCContext &context = Out.getContext(); const MCSymbolRefExpr *expr = MCSymbolRefExpr::Create( context.GetOrCreateSymbol(StringRef("___tls_get_addr")), MCSymbolRefExpr::VK_PLT, context); CALLInst.addOperand(MCOperand::CreateExpr(expr)); Out.EmitInstruction(CALLInst); Out.EmitBundleUnlock(); }
static void EmitTrap(bool Is64Bit, MCStreamer &Out) { // Rewrite to: // X86-32: mov $0, 0 // X86-64: mov $0, (%r15) unsigned BaseReg = Is64Bit && !FlagUseZeroBasedSandbox ? X86::R15 : 0; MCInst Tmp; Tmp.setOpcode(X86::MOV32mi); Tmp.addOperand(MCOperand::CreateReg(BaseReg)); // BaseReg Tmp.addOperand(MCOperand::CreateImm(1)); // Scale Tmp.addOperand(MCOperand::CreateReg(0)); // IndexReg Tmp.addOperand(MCOperand::CreateImm(0)); // Offset Tmp.addOperand(MCOperand::CreateReg(0)); // SegmentReg Tmp.addOperand(MCOperand::CreateImm(0)); // Value Out.EmitInstruction(Tmp); }
static void EmitBICMask(MCStreamer &Out, unsigned Addr, int64_t Pred, unsigned Mask) { // bic\Pred \Addr, \Addr, #Mask MCInst BICInst; BICInst.setOpcode(ARM::BICri); BICInst.addOperand(MCOperand::CreateReg(Addr)); // rD BICInst.addOperand(MCOperand::CreateReg(Addr)); // rS if (FlagSfiZeroMask) { BICInst.addOperand(MCOperand::CreateImm(0)); // imm } else { BICInst.addOperand(MCOperand::CreateImm(Mask)); // imm } BICInst.addOperand(MCOperand::CreateImm(Pred)); // predicate BICInst.addOperand(MCOperand::CreateReg(ARM::CPSR)); // CPSR BICInst.addOperand(MCOperand::CreateReg(0)); // flag out Out.EmitInstruction(BICInst); }
static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, SourceMgr &SM, raw_ostream &Out, MCStreamer &Streamer, bool InAtomicBlock, const MCSubtargetInfo &STI) { ArrayRef<uint8_t> Data(Bytes.first.data(), Bytes.first.size()); // Disassemble it to strings. uint64_t Size; uint64_t Index; for (Index = 0; Index < Bytes.first.size(); Index += Size) { MCInst Inst; MCDisassembler::DecodeStatus S; S = DisAsm.getInstruction(Inst, Size, Data.slice(Index), Index, /*REMOVE*/ nulls(), nulls()); switch (S) { case MCDisassembler::Fail: SM.PrintMessage(SMLoc::getFromPointer(Bytes.second[Index]), SourceMgr::DK_Warning, "invalid instruction encoding"); // Don't try to resynchronise the stream in a block if (InAtomicBlock) return true; if (Size == 0) Size = 1; // skip illegible bytes break; case MCDisassembler::SoftFail: SM.PrintMessage(SMLoc::getFromPointer(Bytes.second[Index]), SourceMgr::DK_Warning, "potentially undefined instruction encoding"); LLVM_FALLTHROUGH; case MCDisassembler::Success: Streamer.EmitInstruction(Inst, STI); break; } } return false; }
void TargetLoweringObjectFileELF::emitPersonalityValue( MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); MCSymbolELF *Label = cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), ELF::SHT_PROGBITS, Flags, 0); unsigned Size = DL.getPointerSize(); Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::create(Size, getContext()); Streamer.emitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); }
static void EmitLoad(bool Is64Bit, unsigned DestReg, unsigned BaseReg, unsigned Scale, unsigned IndexReg, unsigned Offset, unsigned SegmentReg, MCStreamer &Out) { // Load DestReg from address BaseReg + Scale * IndexReg + Offset MCInst Load; Load.setOpcode(Is64Bit ? X86::MOV64rm : X86::MOV32rm); Load.addOperand(MCOperand::CreateReg(DestReg)); Load.addOperand(MCOperand::CreateReg(BaseReg)); Load.addOperand(MCOperand::CreateImm(Scale)); Load.addOperand(MCOperand::CreateReg(IndexReg)); Load.addOperand(MCOperand::CreateImm(Offset)); Load.addOperand(MCOperand::CreateReg(SegmentReg)); Out.EmitInstruction(Load); }
bool SparcAsmParser:: MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, SmallVectorImpl<MCParsedAsmOperand*> &Operands, MCStreamer &Out, unsigned &ErrorInfo, bool MatchingInlineAsm) { MCInst Inst; SmallVector<MCInst, 8> Instructions; unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); switch (MatchResult) { default: break; case Match_Success: { Inst.setLoc(IDLoc); Out.EmitInstruction(Inst); return false; } case Match_MissingFeature: return Error(IDLoc, "instruction requires a CPU feature not currently enabled"); case Match_InvalidOperand: { SMLoc ErrorLoc = IDLoc; if (ErrorInfo != ~0U) { if (ErrorInfo >= Operands.size()) return Error(IDLoc, "too few operands for instruction"); ErrorLoc = ((SparcOperand*) Operands[ErrorInfo])->getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } return Error(ErrorLoc, "invalid operand for instruction"); } case Match_MnemonicFail: return Error(IDLoc, "invalid instruction"); } return true; }
static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, SourceMgr &SM, raw_ostream &Out, MCStreamer &Streamer) { // Wrap the vector in a MemoryObject. VectorMemoryObject memoryObject(Bytes); // Disassemble it to strings. uint64_t Size; uint64_t Index; for (Index = 0; Index < Bytes.size(); Index += Size) { MCInst Inst; MCDisassembler::DecodeStatus S; S = DisAsm.getInstruction(Inst, Size, memoryObject, Index, /*REMOVE*/ nulls(), nulls()); switch (S) { case MCDisassembler::Fail: SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), SourceMgr::DK_Warning, "invalid instruction encoding"); if (Size == 0) Size = 1; // skip illegible bytes break; case MCDisassembler::SoftFail: SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), SourceMgr::DK_Warning, "potentially undefined instruction encoding"); // Fall through case MCDisassembler::Success: Streamer.EmitInstruction(Inst); break; } } return false; }
bool BPFAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm) { MCInst Inst; SMLoc ErrorLoc; if (PreMatchCheck(Operands)) return Error(IDLoc, "additional inst constraint not met"); switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { default: break; case Match_Success: Inst.setLoc(IDLoc); Out.EmitInstruction(Inst, getSTI()); return false; case Match_MissingFeature: return Error(IDLoc, "instruction use requires an option to be enabled"); case Match_MnemonicFail: return Error(IDLoc, "unrecognized instruction mnemonic"); case Match_InvalidOperand: ErrorLoc = IDLoc; if (ErrorInfo != ~0U) { if (ErrorInfo >= Operands.size()) return Error(ErrorLoc, "too few operands for instruction"); ErrorLoc = ((BPFOperand &)*Operands[ErrorInfo]).getStartLoc(); if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; } return Error(ErrorLoc, "invalid operand for instruction"); } llvm_unreachable("Unknown match type detected!"); }
void X86::X86MCNaClExpander::doExpandInst(const MCInst &Inst, MCStreamer &Out, const MCSubtargetInfo &STI) { if (isPrefix(Inst)) { Prefixes.push_back(Inst); } else { switch (Inst.getOpcode()) { case X86::CALL16r: case X86::CALL32r: case X86::CALL16m: case X86::CALL32m: case X86::JMP16r: case X86::JMP32r: case X86::JMP16m: case X86::JMP32m: return expandIndirectBranch(Inst, Out, STI); case X86::RETL: case X86::RETIL: return expandReturn(Inst, Out, STI); default: emitPrefixes(Out, STI); Out.EmitInstruction(Inst, STI); } } }
void TargetLoweringObjectFileMachO::emitModuleMetadata( MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { // Emit the linker options if present. if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { for (const auto &Option : LinkerOptions->operands()) { SmallVector<std::string, 4> StrOptions; for (const auto &Piece : cast<MDNode>(Option)->operands()) StrOptions.push_back(cast<MDString>(Piece)->getString()); Streamer.EmitLinkerOptions(StrOptions); } } unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; StringRef SectionVal; GetObjCImageInfo(M, VersionVal, ImageInfoFlags, SectionVal); // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, TAA, TAAParsed, StubSize); if (!ErrorCode.empty()) // If invalid, report the error with report_fatal_error. report_fatal_error("Invalid section specifier '" + Section + "': " + ErrorCode + "."); // Get the section. MCSectionMachO *S = getContext().getMachOSection( Segment, Section, TAA, StubSize, SectionKind::getData()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); }
void TargetLoweringObjectFileCOFF::emitModuleMetadata( MCStreamer &Streamer, Module &M, const TargetMachine &TM) const { if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { // Emit the linker options to the linker .drectve section. According to the // spec, this section is a space-separated string containing flags for // linker. MCSection *Sec = getDrectveSection(); Streamer.SwitchSection(Sec); for (const auto &Option : LinkerOptions->operands()) { for (const auto &Piece : cast<MDNode>(Option)->operands()) { // Lead with a space for consistency with our dllexport implementation. std::string Directive(" "); Directive.append(cast<MDString>(Piece)->getString()); Streamer.EmitBytes(Directive); } } } unsigned Version = 0; unsigned Flags = 0; StringRef Section; GetObjCImageInfo(M, Version, Flags, Section); if (Section.empty()) return; auto &C = getContext(); auto *S = C.getCOFFSection( Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); Streamer.SwitchSection(S); Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(Version, 4); Streamer.EmitIntValue(Flags, 4); Streamer.AddBlankLine(); }
static void EmitIndirectBranch(const MCOperand &Op, bool Is64Bit, bool IsCall, MCStreamer &Out) { const bool UseZeroBasedSandbox = FlagUseZeroBasedSandbox; const int JmpMask = FlagSfiX86JmpMask; const unsigned Reg32 = Op.getReg(); const unsigned Reg64 = getX86SubSuperRegister_(Reg32, MVT::i64); Out.EmitBundleLock(IsCall); MCInst ANDInst; ANDInst.setOpcode(X86::AND32ri8); ANDInst.addOperand(MCOperand::CreateReg(Reg32)); ANDInst.addOperand(MCOperand::CreateReg(Reg32)); ANDInst.addOperand(MCOperand::CreateImm(JmpMask)); Out.EmitInstruction(ANDInst); if (Is64Bit && !UseZeroBasedSandbox) { MCInst InstADD; InstADD.setOpcode(X86::ADD64rr); InstADD.addOperand(MCOperand::CreateReg(Reg64)); InstADD.addOperand(MCOperand::CreateReg(Reg64)); InstADD.addOperand(MCOperand::CreateReg(X86::R15)); Out.EmitInstruction(InstADD); } if (IsCall) { MCInst CALLInst; CALLInst.setOpcode(Is64Bit ? X86::CALL64r : X86::CALL32r); CALLInst.addOperand(MCOperand::CreateReg(Is64Bit ? Reg64 : Reg32)); Out.EmitInstruction(CALLInst); } else { MCInst JMPInst; JMPInst.setOpcode(Is64Bit ? X86::JMP64r : X86::JMP32r); JMPInst.addOperand(MCOperand::CreateReg(Is64Bit ? Reg64 : Reg32)); Out.EmitInstruction(JMPInst); } Out.EmitBundleUnlock(); }
MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) { S.setTargetStreamer(this); }
/// emitModuleFlags - Perform code emission for module flags. void TargetLoweringObjectFileMachO:: emitModuleFlags(MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, Mangler &Mang, const TargetMachine &TM) const { unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; MDNode *LinkerOptions = nullptr; StringRef SectionVal; for (ArrayRef<Module::ModuleFlagEntry>::iterator i = ModuleFlags.begin(), e = ModuleFlags.end(); i != e; ++i) { const Module::ModuleFlagEntry &MFE = *i; // Ignore flags with 'Require' behavior. if (MFE.Behavior == Module::Require) continue; StringRef Key = MFE.Key->getString(); Value *Val = MFE.Val; if (Key == "Objective-C Image Info Version") { VersionVal = cast<ConstantInt>(Val)->getZExtValue(); } else if (Key == "Objective-C Garbage Collection" || Key == "Objective-C GC Only" || Key == "Objective-C Is Simulated") { ImageInfoFlags |= cast<ConstantInt>(Val)->getZExtValue(); } else if (Key == "Objective-C Image Info Section") { SectionVal = cast<MDString>(Val)->getString(); } else if (Key == "Linker Options") { LinkerOptions = cast<MDNode>(Val); } } // Emit the linker options if present. if (LinkerOptions) { for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { MDNode *MDOptions = cast<MDNode>(LinkerOptions->getOperand(i)); SmallVector<std::string, 4> StrOptions; // Convert to strings. for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { MDString *MDOption = cast<MDString>(MDOptions->getOperand(ii)); StrOptions.push_back(MDOption->getString()); } Streamer.EmitLinkerOptions(StrOptions); } } // The section is mandatory. If we don't have it, then we don't have GC info. if (SectionVal.empty()) return; StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, TAA, TAAParsed, StubSize); if (!ErrorCode.empty()) // If invalid, report the error with report_fatal_error. report_fatal_error("Invalid section specifier '" + Section + "': " + ErrorCode + "."); // Get the section. const MCSectionMachO *S = getContext().getMachOSection(Segment, Section, TAA, StubSize, SectionKind::getDataNoRel()); Streamer.SwitchSection(S); Streamer.EmitLabel(getContext(). GetOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); Streamer.EmitIntValue(VersionVal, 4); Streamer.EmitIntValue(ImageInfoFlags, 4); Streamer.AddBlankLine(); }
static void LowerTlsAddr(MCStreamer &OutStreamer, X86MCInstLower &MCInstLowering, const MachineInstr &MI, const MCSubtargetInfo& STI) { bool is64Bits = MI.getOpcode() == X86::TLS_addr64 || MI.getOpcode() == X86::TLS_base_addr64; bool needsPadding = MI.getOpcode() == X86::TLS_addr64; MCContext &context = OutStreamer.getContext(); if (needsPadding) OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX), STI); MCSymbolRefExpr::VariantKind SRVK; switch (MI.getOpcode()) { case X86::TLS_addr32: case X86::TLS_addr64: SRVK = MCSymbolRefExpr::VK_TLSGD; break; case X86::TLS_base_addr32: SRVK = MCSymbolRefExpr::VK_TLSLDM; break; case X86::TLS_base_addr64: SRVK = MCSymbolRefExpr::VK_TLSLD; break; default: llvm_unreachable("unexpected opcode"); } MCSymbol *sym = MCInstLowering.GetSymbolFromOperand(MI.getOperand(3)); const MCSymbolRefExpr *symRef = MCSymbolRefExpr::Create(sym, SRVK, context); MCInst LEA; if (is64Bits) { LEA.setOpcode(X86::LEA64r); LEA.addOperand(MCOperand::CreateReg(X86::RDI)); // dest LEA.addOperand(MCOperand::CreateReg(X86::RIP)); // base LEA.addOperand(MCOperand::CreateImm(1)); // scale LEA.addOperand(MCOperand::CreateReg(0)); // index LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp LEA.addOperand(MCOperand::CreateReg(0)); // seg } else if (SRVK == MCSymbolRefExpr::VK_TLSLDM) { LEA.setOpcode(X86::LEA32r); LEA.addOperand(MCOperand::CreateReg(X86::EAX)); // dest LEA.addOperand(MCOperand::CreateReg(X86::EBX)); // base LEA.addOperand(MCOperand::CreateImm(1)); // scale LEA.addOperand(MCOperand::CreateReg(0)); // index LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp LEA.addOperand(MCOperand::CreateReg(0)); // seg } else { LEA.setOpcode(X86::LEA32r); LEA.addOperand(MCOperand::CreateReg(X86::EAX)); // dest LEA.addOperand(MCOperand::CreateReg(0)); // base LEA.addOperand(MCOperand::CreateImm(1)); // scale LEA.addOperand(MCOperand::CreateReg(X86::EBX)); // index LEA.addOperand(MCOperand::CreateExpr(symRef)); // disp LEA.addOperand(MCOperand::CreateReg(0)); // seg } OutStreamer.EmitInstruction(LEA, STI); if (needsPadding) { OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX), STI); OutStreamer.EmitInstruction(MCInstBuilder(X86::DATA16_PREFIX), STI); OutStreamer.EmitInstruction(MCInstBuilder(X86::REX64_PREFIX), STI); } StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr"; MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name); const MCSymbolRefExpr *tlsRef = MCSymbolRefExpr::Create(tlsGetAddr, MCSymbolRefExpr::VK_PLT, context); OutStreamer.EmitInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32 : X86::CALLpcrel32) .addExpr(tlsRef), STI); }
void RISCVMCExpr::visitUsedExpr(MCStreamer &Streamer) const { Streamer.visitUsedExpr(*getSubExpr()); }
/// Remove empty sections from SectionStartEndSyms, to avoid generating /// useless debug info for them. void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { SectionsForRanges.remove_if( [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); }); }
void MCContext::setSymbolValue(MCStreamer &Streamer, StringRef Sym, uint64_t Val) { auto Symbol = getOrCreateSymbol(Sym); Streamer.EmitAssignment(Symbol, MCConstantExpr::create(Val, *this)); }