void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { // Check to see if this is a special global used by LLVM, if so, emit it. if (!GV->hasInitializer() || EmitSpecialLLVMGlobal(GV)) return; const DataLayout *TD = TM.getDataLayout(); OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM)); MCSymbol *GVSym = getSymbol(GV); const Constant *C = GV->getInitializer(); unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); // Mark the start of the global getTargetStreamer().emitCCTopData(GVSym->getName()); switch (GV->getLinkage()) { case GlobalValue::AppendingLinkage: report_fatal_error("AppendingLinkage is not supported by this target!"); case GlobalValue::LinkOnceAnyLinkage: case GlobalValue::LinkOnceODRLinkage: case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::ExternalLinkage: emitArrayBound(GVSym, GV); OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); // TODO Use COMDAT groups for LinkOnceLinkage if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); // FALL THROUGH case GlobalValue::InternalLinkage: case GlobalValue::PrivateLinkage: break; default: llvm_unreachable("Unknown linkage type!"); } EmitAlignment(Align > 2 ? Align : 2, GV); if (GV->isThreadLocal()) { report_fatal_error("TLS is not supported by this target!"); } unsigned Size = TD->getTypeAllocSize(C->getType()); if (MAI->hasDotTypeDotSizeDirective()) { OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext)); } OutStreamer.EmitLabel(GVSym); EmitGlobalConstant(C); // The ABI requires that unsigned scalar types smaller than 32 bits // are padded to 32 bits. if (Size < 4) OutStreamer.EmitZeros(4 - Size); // Mark the end of the global getTargetStreamer().emitCCBottomData(GVSym->getName()); }
/// Emit extern decls for functions imported from other modules, and emit /// global declarations for function defined in this module and which are /// available to other modules. /// void PIC16AsmPrinter::EmitFunctionDecls(Module &M) { // Emit declarations for external functions. O <<"\n"<<MAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { if (I->isIntrinsic() || I->getName() == "@abort") continue; if (!I->isDeclaration() && !I->hasExternalLinkage()) continue; MCSymbol *Sym = Mang->getSymbol(I); // Do not emit memcpy, memset, and memmove here. // Calls to these routines can be generated in two ways, // 1. User calling the standard lib function // 2. Codegen generating these calls for llvm intrinsics. // In the first case a prototype is alread availale, while in // second case the call is via and externalsym and the prototype is missing. // So declarations for these are currently always getting printing by // tracking both kind of references in printInstrunction. if (I->isDeclaration() && PAN::isMemIntrinsic(Sym->getName())) continue; const char *directive = I->isDeclaration() ? MAI->getExternDirective() : MAI->getGlobalDirective(); O << directive << Sym->getName() << "\n"; O << directive << PAN::getRetvalLabel(Sym->getName()) << "\n"; O << directive << PAN::getArgsLabel(Sym->getName()) << "\n"; } O << MAI->getCommentString() << "Function Declarations - END." <<"\n"; }
uint64_t MachObjectWriter::getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const { // If this is a variable, then recursively evaluate now. if (S.isVariable()) { if (const MCConstantExpr *C = dyn_cast<const MCConstantExpr>(S.getVariableValue())) return C->getValue(); MCValue Target; if (!S.getVariableValue()->evaluateAsRelocatable(Target, &Layout, nullptr)) report_fatal_error("unable to evaluate offset for variable '" + S.getName() + "'"); // Verify that any used symbols are defined. if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) report_fatal_error("unable to evaluate offset to undefined symbol '" + Target.getSymA()->getSymbol().getName() + "'"); if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) report_fatal_error("unable to evaluate offset to undefined symbol '" + Target.getSymB()->getSymbol().getName() + "'"); uint64_t Address = Target.getConstant(); if (Target.getSymA()) Address += getSymbolAddress(Target.getSymA()->getSymbol(), Layout); if (Target.getSymB()) Address += getSymbolAddress(Target.getSymB()->getSymbol(), Layout); return Address; } return getSectionAddress(S.getFragment()->getParent()) + Layout.getSymbolOffset(S); }
const MCSection *TargetLoweringObjectFileCOFF:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { // If this global is linkonce/weak and the target handles this by emitting it // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); unsigned Characteristics = getCOFFSectionFlags(Kind); Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; MCSymbol *Sym = TM.getSymbol(GV, Mang); return getContext().getCOFFSection(Name, Characteristics, Kind, Sym->getName(), COFF::IMAGE_COMDAT_SELECT_ANY); } if (Kind.isText()) return TextSection; if (Kind.isThreadLocal()) return TLSDataSection; if (Kind.isReadOnly()) return ReadOnlySection; if (Kind.isBSS()) return BSSSection; return DataSection; }
void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); MCSymbol *Label = getContext().GetOrCreateSymbol(NameData); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); StringRef Prefix = ".data."; NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end()); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; const MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS, Flags, SectionKind::getDataRel(), 0, Label->getName()); unsigned Size = TM.getDataLayout()->getPointerSize(0); Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment(0)); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::Create(Size, getContext()); Streamer.EmitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); }
void AArch64AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNum); switch (MO.getType()) { default: llvm_unreachable("<unknown operand type>"); case MachineOperand::MO_Register: { unsigned Reg = MO.getReg(); assert(TargetRegisterInfo::isPhysicalRegister(Reg)); assert(!MO.getSubReg() && "Subregs should be eliminated!"); O << AArch64InstPrinter::getRegisterName(Reg); break; } case MachineOperand::MO_Immediate: { int64_t Imm = MO.getImm(); O << '#' << Imm; break; } case MachineOperand::MO_GlobalAddress: { const GlobalValue *GV = MO.getGlobal(); MCSymbol *Sym = getSymbol(GV); // FIXME: Can we get anything other than a plain symbol here? assert(!MO.getTargetFlags() && "Unknown operand target flag!"); Sym->print(O, MAI); printOffset(MO.getOffset(), O); break; } } }
/// parseDirectiveIndirectSymbol /// ::= .indirect_symbol identifier bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { const MCSectionMachO *Current = static_cast<const MCSectionMachO*>( getStreamer().getCurrentSection().first); MachO::SectionType SectionType = Current->getType(); if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && SectionType != MachO::S_LAZY_SYMBOL_POINTERS && SectionType != MachO::S_SYMBOL_STUBS) return Error(Loc, "indirect symbol not in a symbol pointer or stub " "section"); StringRef Name; if (getParser().parseIdentifier(Name)) return TokError("expected identifier in .indirect_symbol directive"); MCSymbol *Sym = getContext().getOrCreateSymbol(Name); // Assembler local symbols don't make any sense here. Complain loudly. if (Sym->isTemporary()) return TokError("non-local symbol required in directive"); if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) return TokError("unable to emit indirect symbol attribute for: " + Name); if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.indirect_symbol' directive"); Lex(); return false; }
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, int Selection, const char *BeginSymName) { MCSymbol *COMDATSymbol = nullptr; if (!COMDATSymName.empty()) { COMDATSymbol = getOrCreateSymbol(COMDATSymName); COMDATSymName = COMDATSymbol->getName(); } // Do the lookup, if we have a hit, return it. COFFSectionKey T{Section, COMDATSymName, Selection}; auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); auto Iter = IterBool.first; if (!IterBool.second) return Iter->second; MCSymbol *Begin = nullptr; if (BeginSymName) Begin = createTempSymbol(BeginSymName, false); StringRef CachedName = Iter->first.SectionName; MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF( CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin); Iter->second = Result; return Result; }
static bool canUseLocalRelocation(const MCSectionMachO &Section, const MCSymbol &Symbol, unsigned Log2Size) { // Debug info sections can use local relocations. if (Section.hasAttribute(MachO::S_ATTR_DEBUG)) return true; // Otherwise, only pointer sized relocations are supported. if (Log2Size != 3) return false; // But only if they don't point to a few forbidden sections. if (!Symbol.isInSection()) return true; const MCSectionMachO &RefSec = cast<MCSectionMachO>(Symbol.getSection()); if (RefSec.getType() == MachO::S_CSTRING_LITERALS) return false; if (RefSec.getSegmentName() == "__DATA" && RefSec.getSectionName() == "__objc_classrefs") return false; // FIXME: ld64 currently handles internal pointer-sized relocations // incorrectly (applying the addend twice). We should be able to return true // unconditionally by this point when that's fixed. return false; }
MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( const Function &F, const TargetMachine &TM) const { // If the function can be removed, produce a unique section so that // the table doesn't prevent the removal. const Comdat *C = F.getComdat(); bool EmitUniqueSection = TM.getFunctionSections() || C; if (!EmitUniqueSection) return ReadOnlySection; // FIXME: we should produce a symbol for F instead. if (F.hasPrivateLinkage()) return ReadOnlySection; MCSymbol *Sym = TM.getSymbol(&F); StringRef COMDATSymName = Sym->getName(); SectionKind Kind = SectionKind::getReadOnly(); const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); unsigned Characteristics = getCOFFSectionFlags(Kind, TM); Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; unsigned UniqueID = NextUniqueID++; return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); }
const MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { int Selection = 0; unsigned Characteristics = getCOFFSectionFlags(Kind); StringRef Name = GV->getSection(); StringRef COMDATSymName = ""; if ((GV->isWeakForLinker() || GV->hasComdat()) && !Kind.isCommon()) { Selection = getSelectionForCOFF(GV); const GlobalValue *ComdatGV; if (Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) ComdatGV = getComdatGVForCOFF(GV); else ComdatGV = GV; if (!ComdatGV->hasPrivateLinkage()) { MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); COMDATSymName = Sym->getName(); Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; } else { Selection = 0; } } return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, Selection); }
static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val) { if (!S.isVariable()) return getLabelOffset(Layout, S, ReportError, Val); // If SD is a variable, evaluate it. MCValue Target; if (!S.getVariableValue()->evaluateAsValue(Target, Layout)) report_fatal_error("unable to evaluate offset for variable '" + S.getName() + "'"); uint64_t Offset = Target.getConstant(); const MCSymbolRefExpr *A = Target.getSymA(); if (A) { uint64_t ValA; if (!getLabelOffset(Layout, A->getSymbol(), ReportError, ValA)) return false; Offset += ValA; } const MCSymbolRefExpr *B = Target.getSymB(); if (B) { uint64_t ValB; if (!getLabelOffset(Layout, B->getSymbol(), ReportError, ValB)) return false; Offset -= ValB; } Val = Offset; return true; }
const MCSection *TargetLoweringObjectFileCOFF:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { // If this global is linkonce/weak and the target handles this by emitting it // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind); SmallString<128> Name(Prefix, Prefix+strlen(Prefix)); MCSymbol *Sym = Mang->getSymbol(GV); Name.append(Sym->getName().begin() + 1, Sym->getName().end()); unsigned Characteristics = getCOFFSectionFlags(Kind); Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; return getContext().getCOFFSection(Name.str(), Characteristics, COFF::IMAGE_COMDAT_SELECT_ANY, Kind); } if (Kind.isText()) return getTextSection(); if (Kind.isThreadLocal()) return getTLSDataSection(); return getDataSection(); }
void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); // @LOCALMOD-BEGIN // The dwarf section label should not include the version suffix. // Strip it off here. StringRef Name = Sym->getName(); size_t atpos = Name.find("@"); if (atpos != StringRef::npos) Name = Name.substr(0, atpos); // @LOCALMOD-END NameData += Name; // @LOCALMOD MCSymbol *Label = getContext().GetOrCreateSymbol(NameData); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); StringRef Prefix = ".data."; NameData.insert(NameData.begin(), Prefix.begin(), Prefix.end()); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; const MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS, Flags, SectionKind::getDataRel(), 0, Label->getName()); unsigned Size = TM.getDataLayout()->getPointerSize(); Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(TM.getDataLayout()->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 bool canUseLocalRelocation(const MCSectionMachO &Section, const MCSymbol &Symbol, unsigned Log2Size) { // Debug info sections can use local relocations. if (Section.hasAttribute(MachO::S_ATTR_DEBUG)) return true; // Otherwise, only pointer sized relocations are supported. if (Log2Size != 3) return false; // But only if they don't point to a few forbidden sections. if (!Symbol.isInSection()) return true; const MCSectionMachO &RefSec = cast<MCSectionMachO>(Symbol.getSection()); if (RefSec.getType() == MachO::S_CSTRING_LITERALS) return false; if (RefSec.getSegmentName() == "__DATA" && RefSec.getSectionName() == "__cfstring") return false; if (RefSec.getSegmentName() == "__DATA" && RefSec.getSectionName() == "__objc_classrefs") return false; return true; }
void Cse523AsmPrinter::EmitStartOfAsmFile(Module &M) { if (Subtarget->isTargetMacho()) OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); if (Subtarget->isTargetCOFF()) { // Emit an absolute @feat.00 symbol. This appears to be some kind of // compiler features bitfield read by link.exe. if (!Subtarget->is64Bit()) { MCSymbol *S = MMI->getContext().GetOrCreateSymbol(StringRef("@feat.00")); OutStreamer.BeginCOFFSymbolDef(S); OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL); OutStreamer.EndCOFFSymbolDef(); // According to the PE-COFF spec, the LSB of this value marks the object // for "registered SEH". This means that all SEH handler entry points // must be registered in .sxdata. Use of any unregistered handlers will // cause the process to terminate immediately. LLVM does not know how to // register any SEH handlers, so its object files should be safe. S->setAbsolute(); OutStreamer.EmitSymbolAttribute(S, MCSA_Global); OutStreamer.EmitAssignment( S, MCConstantExpr::Create(int64_t(1), MMI->getContext())); } } }
MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { // If we have -ffunction-sections then we should emit the global value to a // uniqued section specifically for it. bool EmitUniquedSection; if (Kind.isText()) EmitUniquedSection = TM.getFunctionSections(); else EmitUniquedSection = TM.getDataSections(); if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) { const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); unsigned Characteristics = getCOFFSectionFlags(Kind); Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; int Selection = getSelectionForCOFF(GV); if (!Selection) Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; const GlobalValue *ComdatGV; if (GV->hasComdat()) ComdatGV = getComdatGVForCOFF(GV); else ComdatGV = GV; unsigned UniqueID = MCContext::GenericSectionID; if (EmitUniquedSection) UniqueID = NextUniqueID++; if (!ComdatGV->hasPrivateLinkage()) { MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); StringRef COMDATSymName = Sym->getName(); return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, Selection, UniqueID); } else { SmallString<256> TmpData; Mang.getNameWithPrefix(TmpData, GV, /*CannotUsePrivateLabel=*/true); return getContext().getCOFFSection(Name, Characteristics, Kind, TmpData, Selection, UniqueID); } } if (Kind.isText()) return TextSection; if (Kind.isThreadLocal()) return TLSDataSection; if (Kind.isReadOnly() || Kind.isReadOnlyWithRel()) return ReadOnlySection; // Note: we claim that common symbols are put in BSSSection, but they are // really emitted with the magic .comm directive, which creates a symbol table // entry but not a section. if (Kind.isBSS() || Kind.isCommon()) return BSSSection; return DataSection; }
/// EmitValue - Emit label value. /// void DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { DwarfDebug *DD = AP->getDwarfDebug(); MCSymbol *Label = DD->getDebugLocEntries()[Index].Label; if (AP->MAI->doesDwarfUseRelocationsAcrossSections() && !DD->useSplitDwarf()) AP->emitSectionOffset(Label); else AP->EmitLabelDifference(Label, Label->getSection().getBeginSymbol(), 4); }
void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) { bool New = !Symbol.isRegistered(); if (Created) *Created = New; if (New) { Symbol.setIsRegistered(true); Symbols.push_back(&Symbol); } }
// printOperand - print operand of insn. void PIC16AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { const MachineOperand &MO = MI->getOperand(opNum); const Function *F = MI->getParent()->getParent()->getFunction(); switch (MO.getType()) { case MachineOperand::MO_Register: { // For indirect load/store insns, the fsr name is printed as INDF. std::string RegName = getRegisterName(MO.getReg()); if ((MI->getOpcode() == PIC16::load_indirect) || (MI->getOpcode() == PIC16::store_indirect)) { RegName.replace (0, 3, "INDF"); } O << RegName; } return; case MachineOperand::MO_Immediate: O << (int)MO.getImm(); return; case MachineOperand::MO_GlobalAddress: { MCSymbol *Sym = Mang->getSymbol(MO.getGlobal()); // FIXME: currently we do not have a memcpy def coming in the module // by any chance, as we do not link in those as .bc lib. So these calls // are always external and it is safe to emit an extern. if (PAN::isMemIntrinsic(Sym->getName())) LibcallDecls.push_back(createESName(Sym->getName())); O << *Sym; break; } case MachineOperand::MO_ExternalSymbol: { const char *Sname = MO.getSymbolName(); std::string Printname = Sname; // Intrinsic stuff needs to be renamed if we are printing IL fn. if (PAN::isIntrinsicStuff(Printname)) { if (PAN::isISR(F->getSection())) { Printname = PAN::Rename(Sname); } // Record these decls, we need to print them in asm as extern. LibcallDecls.push_back(createESName(Printname)); } O << Printname; break; } case MachineOperand::MO_MachineBasicBlock: O << *MO.getMBB()->getSymbol(); return; default: llvm_unreachable(" Operand type not supported."); } }
// Add a symbol for the file name of this module. This is the second // entry in the module's symbol table (the first being the null symbol). void MCELFStreamer::EmitFileDirective(StringRef Filename) { MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); Symbol->setSection(*getCurrentSection()); Symbol->setAbsolute(); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default); }
const MCSection *TargetLoweringObjectFileCOFF:: SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const { // If we have -ffunction-sections then we should emit the global value to a // uniqued section specifically for it. bool EmitUniquedSection; if (Kind.isText()) EmitUniquedSection = TM.getFunctionSections(); else EmitUniquedSection = TM.getDataSections(); // If this global is linkonce/weak and the target handles this by emitting it // into a 'uniqued' section name, create and return the section now. // Section names depend on the name of the symbol which is not feasible if the // symbol has private linkage. if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) && !Kind.isCommon()) { const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); unsigned Characteristics = getCOFFSectionFlags(Kind); Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; int Selection = getSelectionForCOFF(GV); if (!Selection) Selection = COFF::IMAGE_COMDAT_SELECT_NODUPLICATES; const GlobalValue *ComdatGV; if (GV->hasComdat()) ComdatGV = getComdatGVForCOFF(GV); else ComdatGV = GV; if (!ComdatGV->hasPrivateLinkage()) { MCSymbol *Sym = TM.getSymbol(ComdatGV, Mang); StringRef COMDATSymName = Sym->getName(); return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, Selection); } } if (Kind.isText()) return TextSection; if (Kind.isThreadLocal()) return TLSDataSection; if (Kind.isReadOnly()) return ReadOnlySection; // Note: we claim that common symbols are put in BSSSection, but they are // really emitted with the magic .comm directive, which creates a symbol table // entry but not a section. if (Kind.isBSS() || Kind.isCommon()) return BSSSection; return DataSection; }
// Simple getSymbolOffset helper for the non-varibale case. static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, bool ReportError, uint64_t &Val) { if (!S.getFragment()) { if (ReportError) report_fatal_error("unable to evaluate offset to undefined symbol '" + S.getName() + "'"); return false; } Val = Layout.getFragmentOffset(S.getFragment()) + S.getOffset(); return true; }
MCSymbol *MCStreamer::endSection(MCSection *Section) { // TODO: keep track of the last subsection so that this symbol appears in the // correct place. MCSymbol *Sym = Section->getEndSymbol(Context); if (Sym->isInSection()) return Sym; SwitchSection(Section); EmitLabel(Sym); return Sym; }
uint32_t SVMMemoryLayout::getEntryAddress(const MCAssembler &Asm, const MCAsmLayout &Layout) const { MCSymbol *S = Asm.getContext().LookupSymbol("main"); if (!S || !S->isDefined()) report_fatal_error("No entry point exists. Is main() defined?"); SVMSymbolInfo SI = getSymbol(Asm, Layout, S); assert(SI.Kind == SVMSymbolInfo::LOCAL); return SI.Value; }
bool MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const { // FIXME: We don't handle things like // foo = . // creating atoms. if (A.isVariable() || B.isVariable()) return false; return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, A, B, InSet); }
bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const { // Non-temporary labels should always be visible to the linker. if (!Symbol.isTemporary()) return true; // Absolute temporary labels are never visible. if (!Symbol.isInSection()) return false; // Otherwise, check if the section requires symbols even for temporary labels. return getBackend().doesSectionRequireSymbols(Symbol.getSection()); }
/// ParseDirectiveTBSS /// ::= .tbss identifier, size, align bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) { SMLoc IDLoc = getLexer().getLoc(); StringRef Name; if (getParser().ParseIdentifier(Name)) return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); if (getLexer().isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); Lex(); int64_t Size; SMLoc SizeLoc = getLexer().getLoc(); if (getParser().ParseAbsoluteExpression(Size)) return true; int64_t Pow2Alignment = 0; SMLoc Pow2AlignmentLoc; if (getLexer().is(AsmToken::Comma)) { Lex(); Pow2AlignmentLoc = getLexer().getLoc(); if (getParser().ParseAbsoluteExpression(Pow2Alignment)) return true; } if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in '.tbss' directive"); Lex(); if (Size < 0) return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" "zero"); // FIXME: Diagnose overflow. if (Pow2Alignment < 0) return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" "than zero"); if (!Sym->isUndefined()) return Error(IDLoc, "invalid symbol redefinition"); getStreamer().EmitTBSSSymbol(getContext().getMachOSection( "__DATA", "__thread_bss", MCSectionMachO::S_THREAD_LOCAL_ZEROFILL, 0, SectionKind::getThreadBSS()), Sym, Size, 1 << Pow2Alignment); return false; }
void LanaiAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O, const char *Modifier) { const MachineOperand &MO = MI->getOperand(OpNum); unsigned TF = MO.getTargetFlags(); switch (MO.getType()) { case MachineOperand::MO_Register: O << LanaiInstPrinter::getRegisterName(MO.getReg()); break; case MachineOperand::MO_Immediate: O << MO.getImm(); break; case MachineOperand::MO_MachineBasicBlock: O << *MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: if (TF == LanaiII::MO_PLT) O << "plt(" << *getSymbol(MO.getGlobal()) << ")"; else O << *getSymbol(MO.getGlobal()); break; case MachineOperand::MO_BlockAddress: { MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); O << BA->getName(); break; } case MachineOperand::MO_ExternalSymbol: if (TF == LanaiII::MO_PLT) O << "plt(" << *GetExternalSymbolSymbol(MO.getSymbolName()) << ")"; else O << *GetExternalSymbolSymbol(MO.getSymbolName()); break; case MachineOperand::MO_JumpTableIndex: O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); break; case MachineOperand::MO_ConstantPoolIndex: O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' << MO.getIndex(); return; default: llvm_unreachable("<unknown operand type>"); } }
void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) { assert(Section && "Cannot switch to a null section!"); MCSectionSubPair curSection = SectionStack.back().first; SectionStack.back().second = curSection; if (MCSectionSubPair(Section, Subsection) != curSection) { ChangeSection(Section, Subsection); SectionStack.back().first = MCSectionSubPair(Section, Subsection); assert(!Section->hasEnded() && "Section already ended"); MCSymbol *Sym = Section->getBeginSymbol(); if (Sym && !Sym->isInSection()) EmitLabel(Sym); } }