void MCWinCOFFStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) { // SafeSEH is a feature specific to 32-bit x86. It does not exist (and is // unnecessary) on all platforms which use table-based exception dispatch. if (getContext().getObjectFileInfo()->getTargetTriple().getArch() != Triple::x86) return; const MCSymbolCOFF *CSymbol = cast<MCSymbolCOFF>(Symbol); if (CSymbol->isSafeSEH()) return; MCSection *SXData = getContext().getObjectFileInfo()->getSXDataSection(); getAssembler().registerSection(*SXData); if (SXData->getAlignment() < 4) SXData->setAlignment(4); new MCSafeSEHFragment(Symbol, SXData); getAssembler().registerSymbol(*Symbol); CSymbol->setIsSafeSEH(); // The Microsoft linker requires that the symbol type of a handler be // function. Go ahead and oblige it here. CSymbol->setType(COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT); }
bool MCAssembler::registerSection(MCSection &Section) { if (Section.isRegistered()) return false; Sections.push_back(&Section); Section.setIsRegistered(true); return true; }
void MCObjectStreamer::EmitBytes(StringRef Data) { MCDwarfLineEntry::Make(this, getCurrentSectionOnly()); MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); DF->getContents().append(Data.begin(), Data.end()); // EmitBytes might not cover all possible ways we emit data (or could be used // to emit executable code in some cases), but is the best method we have // right now for checking this. MCSection *Sec = getCurrentSectionOnly(); Sec->setHasData(true); }
void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, unsigned ValueSize, unsigned MaxBytesToEmit) { if (MaxBytesToEmit == 0) MaxBytesToEmit = ByteAlignment; insert(new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit)); // Update the maximum alignment on the current section if necessary. MCSection *CurSec = getCurrentSection().first; if (ByteAlignment > CurSec->getAlignment()) CurSec->setAlignment(ByteAlignment); }
void MCAsmLayout::ensureValid(const MCFragment *F) const { MCSection *Sec = F->getParent(); MCSection::iterator I; if (MCFragment *Cur = LastValidFragment[Sec]) I = ++MCSection::iterator(Cur); else I = Sec->begin(); // Advance the layout position until the fragment is valid. while (!isFragmentValid(F)) { assert(I != Sec->end() && "Layout bookkeeping error"); const_cast<MCAsmLayout *>(this)->layoutFragment(&*I); ++I; } }
void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { if (PendingLabels.empty()) return; if (!F) { F = new MCDataFragment(); MCSection *CurSection = getCurrentSectionOnly(); CurSection->getFragmentList().insert(CurInsertionPoint, F); F->setParent(CurSection); } for (MCSymbol *Sym : PendingLabels) { Sym->setFragment(F); Sym->setOffset(FOffset); } PendingLabels.clear(); }
void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size, unsigned ByteAlignment) { auto *Symbol = cast<MCSymbolCOFF>(S); MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); getAssembler().registerSection(*Section); if (Section->getAlignment() < ByteAlignment) Section->setAlignment(ByteAlignment); getAssembler().registerSymbol(*Symbol); Symbol->setExternal(false); if (ByteAlignment != 1) new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0, ByteAlignment, Section); MCFillFragment *Fragment = new MCFillFragment( /*Value=*/0, Size, Section); Symbol->setFragment(Fragment); }
void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { assert(!Symbol->isInSection() && "Symbol must not already have a section!"); MCSection *Section = getContext().getObjectFileInfo()->getBSSSection(); getAssembler().registerSection(*Section); if (Section->getAlignment() < ByteAlignment) Section->setAlignment(ByteAlignment); getAssembler().registerSymbol(*Symbol); Symbol->setExternal(false); if (ByteAlignment != 1) new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0, ByteAlignment, Section); MCFillFragment *Fragment = new MCFillFragment( /*Value=*/0, Size, Section); Symbol->setFragment(Fragment); }
void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, const MCAsmLayout &Layout) { MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); StringRef SectionName = Section.getSectionName(); auto &MC = Asm.getContext(); const auto &MAI = MC.getAsmInfo(); // Compressing debug_frame requires handling alignment fragments which is // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow // for writing to arbitrary buffers) for little benefit. bool CompressionEnabled = MAI->compressDebugSections() != DebugCompressionType::None; if (!CompressionEnabled || !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { Asm.writeSectionData(&Section, Layout); return; } assert((MAI->compressDebugSections() == DebugCompressionType::Z || MAI->compressDebugSections() == DebugCompressionType::GNU) && "expected zlib or zlib-gnu style compression"); SmallVector<char, 128> UncompressedData; raw_svector_ostream VecOS(UncompressedData); raw_pwrite_stream &OldStream = getStream(); setStream(VecOS); Asm.writeSectionData(&Section, Layout); setStream(OldStream); SmallVector<char, 128> CompressedContents; if (Error E = zlib::compress( StringRef(UncompressedData.data(), UncompressedData.size()), CompressedContents)) { consumeError(std::move(E)); getStream() << UncompressedData; return; } bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z; if (!maybeWriteCompression(UncompressedData.size(), CompressedContents, ZlibStyle, Sec.getAlignment())) { getStream() << UncompressedData; return; } if (ZlibStyle) // Set the compressed flag. That is zlib style. Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED); else // Add "z" prefix to section name. This is zlib-gnu style. MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str()); getStream() << CompressedContents; }
extern "C" void SwitchSection(ObjectWriter *OW, const char *SectionName) { assert(OW && "ObjWriter is null"); auto *AsmPrinter = &OW->getAsmPrinter(); auto &OST = *AsmPrinter->OutStreamer; MCContext &OutContext = OST.getContext(); const MCObjectFileInfo *MOFI = OutContext.getObjectFileInfo(); MCSection *Section = nullptr; if (strcmp(SectionName, "text") == 0) { Section = MOFI->getTextSection(); if (!Section->hasInstructions()) { Section->setHasInstructions(true); OutContext.addGenDwarfSection(Section); } } else if (strcmp(SectionName, "data") == 0) { Section = MOFI->getDataSection(); } else if (strcmp(SectionName, "rdata") == 0) { Section = MOFI->getReadOnlySection(); } else if (strcmp(SectionName, "xdata") == 0) { Section = MOFI->getXDataSection(); } else { std::string SectionNameStr(SectionName); if (OW->CustomSections.find(SectionNameStr) != OW->CustomSections.end()) { Section = OW->CustomSections[SectionNameStr]; } else { // Add more general cases assert(!"Unsupported section"); } } OW->Sections.insert(Section); OST.SwitchSection(Section); if (!Section->getBeginSymbol()) { MCSymbol *SectionStartSym = OutContext.createTempSymbol(); OST.EmitLabel(SectionStartSym); Section->setBeginSymbol(SectionStartSym); } }
/// EmitValue - Emit debug information entry offset. /// void DIEEntry::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { switch (Form) { case dwarf::DW_FORM_ref1: case dwarf::DW_FORM_ref2: case dwarf::DW_FORM_ref4: case dwarf::DW_FORM_ref8: AP->OutStreamer->EmitIntValue(Entry->getOffset(), SizeOf(AP, Form)); return; case dwarf::DW_FORM_ref_udata: AP->EmitULEB128(Entry->getOffset()); return; case dwarf::DW_FORM_ref_addr: { // Get the absolute offset for this DIE within the debug info/types section. unsigned Addr = Entry->getDebugSectionOffset(); if (AP->MAI->doesDwarfUseRelocationsAcrossSections()) { const DwarfDebug *DD = AP->getDwarfDebug(); if (DD) assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations."); const DIEUnit *Unit = Entry->getUnit(); assert(Unit && "CUDie should belong to a CU."); MCSection *Section = Unit->getSection(); if (Section) { const MCSymbol *SectionSym = Section->getBeginSymbol(); AP->EmitLabelPlusOffset(SectionSym, Addr, SizeOf(AP, Form), true); return; } } AP->OutStreamer->EmitIntValue(Addr, SizeOf(AP, Form)); return; } default: llvm_unreachable("Improper form for DIE reference"); } }
void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { MCStreamer::EmitInstruction(Inst, STI); MCSection *Sec = getCurrentSectionOnly(); Sec->setHasInstructions(true); // Now that a machine instruction has been assembled into this section, make // a line entry for any .loc directive that has been seen. MCCVLineEntry::Make(this); MCDwarfLineEntry::Make(this, getCurrentSection().first); // If this instruction doesn't need relaxation, just emit it as data. MCAssembler &Assembler = getAssembler(); if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { EmitInstToData(Inst, STI); return; } // Otherwise, relax and emit it as data if either: // - The RelaxAll flag was passed // - Bundling is enabled and this instruction is inside a bundle-locked // group. We want to emit all such instructions into the same data // fragment. if (Assembler.getRelaxAll() || (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) { MCInst Relaxed; getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed); while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed); EmitInstToData(Relaxed, STI); return; } // Otherwise emit to a separate fragment. EmitInstToFragment(Inst, STI); }
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) : Section(&_Section), Ordinal(~UINT32_C(0)), Alignment(1), BundleLockState(NotBundleLocked), BundleGroupBeforeFirstInst(false), HasInstructions(false) { // @LOCALMOD-BEGIN if (A) { // Necessary for IRT building because the IRT loader expects the end of // the section to be bundle-aligned. Padding happens with 0's though, // so it's not really ideal. TODO(dschuff) figure out how to do it right. A->getSectionList().push_back(this); if (A->isBundlingEnabled() && _Section.UseCodeAlign()) setAlignment(A->getBundleAlignSize()); } // @LOCALMOD-END }
/// Emit the swift_ast section stored in \p Buffers. void DwarfStreamer::emitSwiftAST(StringRef Buffer) { MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection(); SwiftASTSection->setAlignment(1 << 5); MS->SwitchSection(SwiftASTSection); MS->EmitBytes(Buffer); }
extern "C" bool CreateCustomSection(ObjectWriter *OW, const char *SectionName, CustomSectionAttributes attributes, const char *ComdatName) { assert(OW && "ObjWriter is null"); Triple TheTriple(TripleName); auto *AsmPrinter = &OW->getAsmPrinter(); auto &OST = *AsmPrinter->OutStreamer; MCContext &OutContext = OST.getContext(); std::string SectionNameStr(SectionName); assert(OW->CustomSections.find(SectionNameStr) == OW->CustomSections.end() && "Section with duplicate name already exists"); assert(ComdatName == nullptr || OW->MOFI->getObjectFileType() == OW->MOFI->IsCOFF); MCSection *Section = nullptr; SectionKind Kind = (attributes & CustomSectionAttributes_Executable) ? SectionKind::getText() : (attributes & CustomSectionAttributes_Writeable) ? SectionKind::getData() : SectionKind::getReadOnly(); switch (TheTriple.getObjectFormat()) { case Triple::MachO: { unsigned typeAndAttributes = 0; if (attributes & CustomSectionAttributes_MachO_Init_Func_Pointers) { typeAndAttributes |= MachO::SectionType::S_MOD_INIT_FUNC_POINTERS; } Section = OutContext.getMachOSection( (attributes & CustomSectionAttributes_Executable) ? "__TEXT" : "__DATA", SectionName, typeAndAttributes, Kind); break; } case Triple::COFF: { unsigned Characteristics = COFF::IMAGE_SCN_MEM_READ; if (attributes & CustomSectionAttributes_Executable) { Characteristics |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE; } else if (attributes & CustomSectionAttributes_Writeable) { Characteristics |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_WRITE; } else { Characteristics |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; } if (ComdatName != nullptr) { Section = OutContext.getCOFFSection( SectionName, Characteristics | COFF::IMAGE_SCN_LNK_COMDAT, Kind, ComdatName, COFF::COMDATType::IMAGE_COMDAT_SELECT_ANY); } else { Section = OutContext.getCOFFSection(SectionName, Characteristics, Kind); } break; } case Triple::ELF: { unsigned Flags = ELF::SHF_ALLOC; if (attributes & CustomSectionAttributes_Executable) { Flags |= ELF::SHF_EXECINSTR; } else if (attributes & CustomSectionAttributes_Writeable) { Flags |= ELF::SHF_WRITE; } Section = OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, Flags); break; } default: return error("Unknown output format for target " + TripleName); break; } if (attributes & CustomSectionAttributes_Executable) { Section->setHasInstructions(true); OutContext.addGenDwarfSection(Section); } OW->CustomSections[SectionNameStr] = Section; return true; }
bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { return Sec.hasInstructions(); }
bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { StringRef SectionName; if (ParseSectionName(SectionName)) return TokError("expected identifier in directive"); StringRef TypeName; int64_t Size = 0; StringRef GroupName; unsigned Flags = 0; const MCExpr *Subsection = nullptr; bool UseLastGroup = false; MCSymbolELF *Associated = nullptr; int64_t UniqueID = ~0; // Set the defaults first. if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1") Flags |= ELF::SHF_ALLOC; else if (SectionName == ".fini" || SectionName == ".init" || hasPrefix(SectionName, ".text.")) Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; else if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" || hasPrefix(SectionName, ".bss.") || hasPrefix(SectionName, ".init_array.") || hasPrefix(SectionName, ".fini_array.") || hasPrefix(SectionName, ".preinit_array.")) Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; else if (hasPrefix(SectionName, ".tdata.") || hasPrefix(SectionName, ".tbss.")) Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; if (getLexer().is(AsmToken::Comma)) { Lex(); if (IsPush && getLexer().isNot(AsmToken::String)) { if (getParser().parseExpression(Subsection)) return true; if (getLexer().isNot(AsmToken::Comma)) goto EndStmt; Lex(); } unsigned extraFlags; if (getLexer().isNot(AsmToken::String)) { if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() || getLexer().isNot(AsmToken::Hash)) return TokError("expected string in directive"); extraFlags = parseSunStyleSectionFlags(); } else { StringRef FlagsStr = getTok().getStringContents(); Lex(); extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); } if (extraFlags == -1U) return TokError("unknown flag"); Flags |= extraFlags; bool Mergeable = Flags & ELF::SHF_MERGE; bool Group = Flags & ELF::SHF_GROUP; if (Group && UseLastGroup) return TokError("Section cannot specifiy a group name while also acting " "as a member of the last group"); if (maybeParseSectionType(TypeName)) return true; MCAsmLexer &L = getLexer(); if (TypeName.empty()) { if (Mergeable) return TokError("Mergeable section must specify the type"); if (Group) return TokError("Group section must specify the type"); if (L.isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); } if (Mergeable) if (parseMergeSize(Size)) return true; if (Group) if (parseGroup(GroupName)) return true; if (Flags & ELF::SHF_LINK_ORDER) if (parseMetadataSym(Associated)) return true; if (maybeParseUniqueID(UniqueID)) return true; } EndStmt: if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); Lex(); unsigned Type = ELF::SHT_PROGBITS; if (TypeName.empty()) { if (SectionName.startswith(".note")) Type = ELF::SHT_NOTE; else if (hasPrefix(SectionName, ".init_array.")) Type = ELF::SHT_INIT_ARRAY; else if (hasPrefix(SectionName, ".bss.")) Type = ELF::SHT_NOBITS; else if (hasPrefix(SectionName, ".tbss.")) Type = ELF::SHT_NOBITS; else if (hasPrefix(SectionName, ".fini_array.")) Type = ELF::SHT_FINI_ARRAY; else if (hasPrefix(SectionName, ".preinit_array.")) Type = ELF::SHT_PREINIT_ARRAY; } else { if (TypeName == "init_array") Type = ELF::SHT_INIT_ARRAY; else if (TypeName == "fini_array") Type = ELF::SHT_FINI_ARRAY; else if (TypeName == "preinit_array") Type = ELF::SHT_PREINIT_ARRAY; else if (TypeName == "nobits") Type = ELF::SHT_NOBITS; else if (TypeName == "progbits") Type = ELF::SHT_PROGBITS; else if (TypeName == "note") Type = ELF::SHT_NOTE; else if (TypeName == "unwind") Type = ELF::SHT_X86_64_UNWIND; else if (TypeName == "llvm_odrtab") Type = ELF::SHT_LLVM_ODRTAB; else if (TypeName == "llvm_linker_options") Type = ELF::SHT_LLVM_LINKER_OPTIONS; else if (TypeName == "llvm_call_graph_profile") Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE; else if (TypeName.getAsInteger(0, Type)) return TokError("unknown section type"); } if (UseLastGroup) { MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); if (const MCSectionELF *Section = cast_or_null<MCSectionELF>(CurrentSection.first)) if (const MCSymbol *Group = Section->getGroup()) { GroupName = Group->getName(); Flags |= ELF::SHF_GROUP; } } MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, UniqueID, Associated); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { bool InsertResult = getContext().addGenDwarfSection(ELFSection); if (InsertResult) { if (getContext().getDwarfVersion() <= 2) Warning(loc, "DWARF2 only supports one section per compilation unit"); if (!ELFSection->getBeginSymbol()) { MCSymbol *SectionStartSymbol = getContext().createTempSymbol(); getStreamer().EmitLabel(SectionStartSymbol); ELFSection->setBeginSymbol(SectionStartSymbol); } } } return false; }
bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { StringRef SectionName; if (ParseSectionName(SectionName)) return TokError("expected identifier in directive"); StringRef TypeName; int64_t Size = 0; StringRef GroupName; unsigned Flags = 0; const MCExpr *Subsection = nullptr; bool UseLastGroup = false; StringRef UniqueStr; int64_t UniqueID = ~0; // Set the defaults first. if (SectionName == ".fini" || SectionName == ".init" || SectionName == ".rodata") Flags |= ELF::SHF_ALLOC; if (SectionName == ".fini" || SectionName == ".init") Flags |= ELF::SHF_EXECINSTR; if (getLexer().is(AsmToken::Comma)) { Lex(); if (IsPush && getLexer().isNot(AsmToken::String)) { if (getParser().parseExpression(Subsection)) return true; if (getLexer().isNot(AsmToken::Comma)) goto EndStmt; Lex(); } unsigned extraFlags; if (getLexer().isNot(AsmToken::String)) { if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() || getLexer().isNot(AsmToken::Hash)) return TokError("expected string in directive"); extraFlags = parseSunStyleSectionFlags(); } else { StringRef FlagsStr = getTok().getStringContents(); Lex(); extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); } if (extraFlags == -1U) return TokError("unknown flag"); Flags |= extraFlags; bool Mergeable = Flags & ELF::SHF_MERGE; bool Group = Flags & ELF::SHF_GROUP; if (Group && UseLastGroup) return TokError("Section cannot specifiy a group name while also acting " "as a member of the last group"); if (getLexer().isNot(AsmToken::Comma)) { if (Mergeable) return TokError("Mergeable section must specify the type"); if (Group) return TokError("Group section must specify the type"); } else { Lex(); if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) || getLexer().is(AsmToken::String)) { if (!getLexer().is(AsmToken::String)) Lex(); } else return TokError("expected '@<type>', '%<type>' or \"<type>\""); if (getParser().parseIdentifier(TypeName)) return TokError("expected identifier in directive"); if (Mergeable) { if (getLexer().isNot(AsmToken::Comma)) return TokError("expected the entry size"); Lex(); if (getParser().parseAbsoluteExpression(Size)) return true; if (Size <= 0) return TokError("entry size must be positive"); } if (Group) { if (getLexer().isNot(AsmToken::Comma)) return TokError("expected group name"); Lex(); if (getParser().parseIdentifier(GroupName)) return true; if (getLexer().is(AsmToken::Comma)) { Lex(); StringRef Linkage; if (getParser().parseIdentifier(Linkage)) return true; if (Linkage != "comdat") return TokError("Linkage must be 'comdat'"); } } if (getLexer().is(AsmToken::Comma)) { Lex(); if (getParser().parseIdentifier(UniqueStr)) return TokError("expected identifier in directive"); if (UniqueStr != "unique") return TokError("expected 'unique'"); if (getLexer().isNot(AsmToken::Comma)) return TokError("expected commma"); Lex(); if (getParser().parseAbsoluteExpression(UniqueID)) return true; if (UniqueID < 0) return TokError("unique id must be positive"); if (!isUInt<32>(UniqueID) || UniqueID == ~0U) return TokError("unique id is too large"); } } } EndStmt: if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); unsigned Type = ELF::SHT_PROGBITS; if (TypeName.empty()) { if (SectionName.startswith(".note")) Type = ELF::SHT_NOTE; else if (SectionName == ".init_array") Type = ELF::SHT_INIT_ARRAY; else if (SectionName == ".fini_array") Type = ELF::SHT_FINI_ARRAY; else if (SectionName == ".preinit_array") Type = ELF::SHT_PREINIT_ARRAY; } else { if (TypeName == "init_array") Type = ELF::SHT_INIT_ARRAY; else if (TypeName == "fini_array") Type = ELF::SHT_FINI_ARRAY; else if (TypeName == "preinit_array") Type = ELF::SHT_PREINIT_ARRAY; else if (TypeName == "nobits") Type = ELF::SHT_NOBITS; else if (TypeName == "progbits") Type = ELF::SHT_PROGBITS; else if (TypeName == "note") Type = ELF::SHT_NOTE; else if (TypeName == "unwind") Type = ELF::SHT_X86_64_UNWIND; else return TokError("unknown section type"); } if (UseLastGroup) { MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); if (const MCSectionELF *Section = cast_or_null<MCSectionELF>(CurrentSection.first)) if (const MCSymbol *Group = Section->getGroup()) { GroupName = Group->getName(); Flags |= ELF::SHF_GROUP; } } MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, UniqueID); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { bool InsertResult = getContext().addGenDwarfSection(ELFSection); if (InsertResult) { if (getContext().getDwarfVersion() <= 2) Warning(loc, "DWARF2 only supports one section per compilation unit"); MCSymbol *SectionStartSymbol = getContext().createTempSymbol(); getStreamer().EmitLabel(SectionStartSymbol); ELFSection->setBeginSymbol(SectionStartSymbol); } } return false; }