From b210c64b281baad0ac705d62e6c298a1629449eb Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Thu, 10 May 2018 17:38:35 +0000 Subject: [PATCH] [WebAssembly] Create section start symbols automatically for all sections These symbols only get included in the output symbols table if they are used in a relocation. This behaviour matches more closely the ELF object writer. Differential Revision: https://reviews.llvm.org/D46561 llvm-svn: 332005 --- llvm/lib/MC/MCContext.cpp | 13 ++++++++----- llvm/lib/MC/MCObjectFileInfo.cpp | 26 ++++++++++++++------------ llvm/lib/MC/MCWasmStreamer.cpp | 1 + llvm/lib/MC/WasmObjectWriter.cpp | 21 ++++++++++++++++----- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp index 317cec5..da2f0d4 100644 --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -515,15 +515,18 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind, StringRef CachedName = Entry.first.SectionName; - MCSymbol *Begin = nullptr; - if (BeginSymName) { - Begin = createSymbol(BeginSymName, false, false); - cast(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION); - } + MCSymbol *Begin = createSymbol(CachedName, false, false); + cast(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION); MCSectionWasm *Result = new (WasmAllocator.Allocate()) MCSectionWasm(CachedName, Kind, GroupSym, UniqueID, Begin); Entry.second = Result; + + auto *F = new MCDataFragment(); + Result->getFragmentList().insert(Result->begin(), F); + F->setParent(Result); + Begin->setFragment(F); + return Result; } diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index e289017..b075f22 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -861,27 +861,29 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { } void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) { - // TODO: Set the section types and flags. TextSection = Ctx->getWasmSection(".text", SectionKind::getText()); DataSection = Ctx->getWasmSection(".data", SectionKind::getData()); - // TODO: Set the section types and flags. - DwarfLineSection = Ctx->getWasmSection(".debug_line", SectionKind::getMetadata(), ".debug_line"); + DwarfLineSection = + Ctx->getWasmSection(".debug_line", SectionKind::getMetadata()); DwarfLineStrSection = Ctx->getWasmSection(".debug_line_str", SectionKind::getMetadata()); - DwarfStrSection = Ctx->getWasmSection(".debug_str", SectionKind::getMetadata(), ".debug_str"); - DwarfLocSection = Ctx->getWasmSection( - ".debug_loc", SectionKind::getMetadata(), ".debug_loc"); - DwarfAbbrevSection = Ctx->getWasmSection( - ".debug_abbrev", SectionKind::getMetadata(), ".debug_abbrev"); + DwarfStrSection = + Ctx->getWasmSection(".debug_str", SectionKind::getMetadata()); + DwarfLocSection = + Ctx->getWasmSection(".debug_loc", SectionKind::getMetadata()); + DwarfAbbrevSection = + Ctx->getWasmSection(".debug_abbrev", SectionKind::getMetadata()); DwarfARangesSection = Ctx->getWasmSection(".debug_aranges", SectionKind::getMetadata()); - DwarfRangesSection = Ctx->getWasmSection( - ".debug_ranges", SectionKind::getMetadata(), ".debug_ranges"); - DwarfMacinfoSection = Ctx->getWasmSection(".debug_macinfo", SectionKind::getMetadata(), ".debug_macinfo"); + DwarfRangesSection = + Ctx->getWasmSection(".debug_ranges", SectionKind::getMetadata()); + DwarfMacinfoSection = + Ctx->getWasmSection(".debug_macinfo", SectionKind::getMetadata()); DwarfAddrSection = Ctx->getWasmSection(".debug_addr", SectionKind::getMetadata()); DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata()); DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata()); - DwarfInfoSection = Ctx->getWasmSection(".debug_info", SectionKind::getMetadata(), ".debug_info"); + DwarfInfoSection = + Ctx->getWasmSection(".debug_info", SectionKind::getMetadata()); DwarfFrameSection = Ctx->getWasmSection(".debug_frame", SectionKind::getMetadata()); DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", SectionKind::getMetadata()); DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", SectionKind::getMetadata()); diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp index 153ea25..984f491 100644 --- a/llvm/lib/MC/MCWasmStreamer.cpp +++ b/llvm/lib/MC/MCWasmStreamer.cpp @@ -66,6 +66,7 @@ void MCWasmStreamer::ChangeSection(MCSection *Section, Asm.registerSymbol(*Grp); this->MCObjectStreamer::ChangeSection(Section, Subsection); + Asm.registerSymbol(*Section->getBeginSymbol()); } void MCWasmStreamer::EmitWeakReference(MCSymbol *Alias, diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 4cd5fe7..85e1896 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -1204,9 +1204,9 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, MCSymbol* Begin = Sec.getBeginSymbol(); if (Begin) { WasmIndices[cast(Begin)] = CustomSections.size(); - if (Name != Begin->getName()) + if (SectionName != Begin->getName()) report_fatal_error("section name and begin symbol should match: " + - Twine(Name)); + Twine(SectionName)); } CustomSections.emplace_back(Name, &Section); } @@ -1405,16 +1405,27 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, continue; if (WS.getFragmentList().empty()) continue; - if (WS.getFragmentList().size() != 2) + + // init_array is expected to contain a single non-empty data fragment + if (WS.getFragmentList().size() != 3) report_fatal_error("only one .init_array section fragment supported"); - const MCFragment &AlignFrag = *WS.begin(); + + auto IT = WS.begin(); + const MCFragment &EmptyFrag = *IT; + if (EmptyFrag.getKind() != MCFragment::FT_Data) + report_fatal_error(".init_array section should be aligned"); + + IT = std::next(IT); + const MCFragment &AlignFrag = *IT; if (AlignFrag.getKind() != MCFragment::FT_Align) report_fatal_error(".init_array section should be aligned"); if (cast(AlignFrag).getAlignment() != (is64Bit() ? 8 : 4)) report_fatal_error(".init_array section should be aligned for pointers"); - const MCFragment &Frag = *std::next(WS.begin()); + + const MCFragment &Frag = *std::next(IT); if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data) report_fatal_error("only data supported in .init_array section"); + uint16_t Priority = UINT16_MAX; unsigned PrefixLength = strlen(".init_array"); if (WS.getSectionName().size() > PrefixLength) { -- 2.7.4