summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/CMakeLists.txt5
-rw-r--r--llvm/lib/MC/MCAsmInfoWasm.cpp27
-rw-r--r--llvm/lib/MC/MCContext.cpp80
-rw-r--r--llvm/lib/MC/MCObjectFileInfo.cpp28
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp3
-rw-r--r--llvm/lib/MC/MCSectionWasm.cpp97
-rw-r--r--llvm/lib/MC/MCWasmObjectTargetWriter.cpp27
-rw-r--r--llvm/lib/MC/MCWasmStreamer.cpp203
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp119
9 files changed, 587 insertions, 2 deletions
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index 2f1b39e58e3..a86fd383003 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_library(LLVMMC
MCAsmInfoCOFF.cpp
MCAsmInfoDarwin.cpp
MCAsmInfoELF.cpp
+ MCAsmInfoWasm.cpp
MCAsmStreamer.cpp
MCAssembler.cpp
MCCodeEmitter.cpp
@@ -34,17 +35,21 @@ add_llvm_library(LLVMMC
MCSectionCOFF.cpp
MCSectionELF.cpp
MCSectionMachO.cpp
+ MCSectionWasm.cpp
MCStreamer.cpp
MCSubtargetInfo.cpp
MCSymbol.cpp
MCSymbolELF.cpp
MCTargetOptions.cpp
MCValue.cpp
+ MCWasmObjectTargetWriter.cpp
+ MCWasmStreamer.cpp
MCWin64EH.cpp
MCWinEH.cpp
MachObjectWriter.cpp
StringTableBuilder.cpp
SubtargetFeature.cpp
+ WasmObjectWriter.cpp
WinCOFFObjectWriter.cpp
WinCOFFStreamer.cpp
diff --git a/llvm/lib/MC/MCAsmInfoWasm.cpp b/llvm/lib/MC/MCAsmInfoWasm.cpp
new file mode 100644
index 00000000000..aa26616dda3
--- /dev/null
+++ b/llvm/lib/MC/MCAsmInfoWasm.cpp
@@ -0,0 +1,27 @@
+//===-- MCAsmInfoWasm.cpp - Wasm asm properties -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target asm properties related what form asm statements
+// should take in general on Wasm-based targets
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCAsmInfoWasm.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSectionWasm.h"
+using namespace llvm;
+
+void MCAsmInfoWasm::anchor() { }
+
+MCAsmInfoWasm::MCAsmInfoWasm() {
+ HasIdentDirective = true;
+ WeakRefDirective = "\t.weak\t";
+ PrivateGlobalPrefix = ".L";
+ PrivateLabelPrefix = ".L";
+}
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index e6fda3dbeb1..3dfc0af1c03 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -23,11 +23,13 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCSymbolMachO.h"
+#include "llvm/MC/MCSymbolWasm.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/COFF.h"
@@ -154,6 +156,8 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
return new (Name, *this) MCSymbolELF(Name, IsTemporary);
case MCObjectFileInfo::IsMachO:
return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
+ case MCObjectFileInfo::IsWasm:
+ return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
}
}
return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
@@ -345,7 +349,7 @@ MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
StringMap<bool>::iterator I;
bool Inserted;
std::tie(I, Inserted) =
- ELFRelSecNames.insert(std::make_pair(Name.str(), true));
+ RelSecNames.insert(std::make_pair(Name.str(), true));
return createELFSectionImpl(I->getKey(), Type, Flags,
SectionKind::getReadOnly(), EntrySize, Group,
@@ -477,6 +481,80 @@ MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
"", 0, UniqueID);
}
+void MCContext::renameWasmSection(MCSectionWasm *Section, StringRef Name) {
+ StringRef GroupName;
+ assert(!Section->getGroup() && "not yet implemented");
+
+ unsigned UniqueID = Section->getUniqueID();
+ WasmUniquingMap.erase(
+ WasmSectionKey{Section->getSectionName(), GroupName, UniqueID});
+ auto I = WasmUniquingMap.insert(std::make_pair(
+ WasmSectionKey{Name, GroupName, UniqueID},
+ Section))
+ .first;
+ StringRef CachedName = I->first.SectionName;
+ const_cast<MCSectionWasm *>(Section)->setSectionName(CachedName);
+}
+
+MCSectionWasm *MCContext::createWasmRelSection(const Twine &Name, unsigned Type,
+ unsigned Flags,
+ const MCSymbolWasm *Group) {
+ StringMap<bool>::iterator I;
+ bool Inserted;
+ std::tie(I, Inserted) =
+ RelSecNames.insert(std::make_pair(Name.str(), true));
+
+ return new (WasmAllocator.Allocate())
+ MCSectionWasm(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
+ Group, ~0, nullptr);
+}
+
+MCSectionWasm *MCContext::getWasmNamedSection(const Twine &Prefix,
+ const Twine &Suffix, unsigned Type,
+ unsigned Flags) {
+ return getWasmSection(Prefix + "." + Suffix, Type, Flags, Suffix);
+}
+
+MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags,
+ const Twine &Group, unsigned UniqueID,
+ const char *BeginSymName) {
+ MCSymbolWasm *GroupSym = nullptr;
+ if (!Group.isTriviallyEmpty() && !Group.str().empty())
+ GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
+
+ return getWasmSection(Section, Type, Flags, GroupSym, UniqueID, BeginSymName);
+}
+
+MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type,
+ unsigned Flags,
+ const MCSymbolWasm *GroupSym,
+ unsigned UniqueID,
+ const char *BeginSymName) {
+ StringRef Group = "";
+ if (GroupSym)
+ Group = GroupSym->getName();
+ // Do the lookup, if we have a hit, return it.
+ auto IterBool = WasmUniquingMap.insert(
+ std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
+ auto &Entry = *IterBool.first;
+ if (!IterBool.second)
+ return Entry.second;
+
+ StringRef CachedName = Entry.first.SectionName;
+
+ SectionKind Kind = SectionKind::getText();
+
+ MCSymbol *Begin = nullptr;
+ if (BeginSymName)
+ Begin = createTempSymbol(BeginSymName, false);
+
+ MCSectionWasm *Result = new (WasmAllocator.Allocate())
+ MCSectionWasm(CachedName, Type, Flags, Kind, GroupSym, UniqueID, Begin);
+ Entry.second = Result;
+ return Result;
+}
+
MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
}
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 78feb5a0eae..a6650134f77 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/MC/MCSectionWasm.h"
#include "llvm/Support/COFF.h"
#include "llvm/Support/ELF.h"
@@ -798,6 +799,30 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
SectionKind::getReadOnly());
}
+void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
+ // TODO: Set the section types and flags.
+ TextSection = Ctx->getWasmSection("", 0, 0);
+ DataSection = Ctx->getWasmSection("", 0, 0);
+
+ // TODO: Set the section types and flags.
+ DwarfLineSection = Ctx->getWasmSection(".debug_line", 0, 0);
+ DwarfStrSection = Ctx->getWasmSection(".debug_str", 0, 0);
+ DwarfLocSection = Ctx->getWasmSection(".debug_loc", 0, 0);
+ DwarfAbbrevSection = Ctx->getWasmSection(".debug_abbrev", 0, 0, "section_abbrev");
+ DwarfARangesSection = Ctx->getWasmSection(".debug_aranges", 0, 0);
+ DwarfRangesSection = Ctx->getWasmSection(".debug_ranges", 0, 0, "debug_range");
+ DwarfMacinfoSection = Ctx->getWasmSection(".debug_macinfo", 0, 0, "debug_macinfo");
+ DwarfAddrSection = Ctx->getWasmSection(".debug_addr", 0, 0);
+ DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", 0, 0);
+ DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", 0, 0);
+ DwarfInfoSection = Ctx->getWasmSection(".debug_info", 0, 0, "section_info");
+ DwarfFrameSection = Ctx->getWasmSection(".debug_frame", 0, 0);
+ DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", 0, 0);
+ DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", 0, 0);
+
+ // TODO: Define more sections.
+}
+
void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
CodeModel::Model cm,
MCContext &ctx) {
@@ -843,7 +868,8 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
initELFMCObjectFileInfo(TT);
break;
case Triple::Wasm:
- report_fatal_error("Cannot initialize MC for wasm object file format yet.");
+ Env = IsWasm;
+ initWasmMCObjectFileInfo(TT);
break;
case Triple::UnknownObjectFormat:
report_fatal_error("Cannot initialize MC for unknown object file format.");
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 33843d7cbed..7f8359148da 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -596,6 +596,9 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
case MCObjectFileInfo::IsELF:
PlatformParser.reset(createELFAsmParser());
break;
+ case MCObjectFileInfo::IsWasm:
+ llvm_unreachable("Wasm parsing not supported yet");
+ break;
}
PlatformParser->Initialize(*this);
diff --git a/llvm/lib/MC/MCSectionWasm.cpp b/llvm/lib/MC/MCSectionWasm.cpp
new file mode 100644
index 00000000000..c61f28e129f
--- /dev/null
+++ b/llvm/lib/MC/MCSectionWasm.cpp
@@ -0,0 +1,97 @@
+//===- lib/MC/MCSectionWasm.cpp - Wasm Code Section Representation --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSectionWasm.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+MCSectionWasm::~MCSectionWasm() {} // anchor.
+
+// Decides whether a '.section' directive
+// should be printed before the section name.
+bool MCSectionWasm::ShouldOmitSectionDirective(StringRef Name,
+ const MCAsmInfo &MAI) const {
+ return MAI.shouldOmitSectionDirective(Name);
+}
+
+static void printName(raw_ostream &OS, StringRef Name) {
+ if (Name.find_first_not_of("0123456789_."
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
+ OS << Name;
+ return;
+ }
+ OS << '"';
+ for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
+ if (*B == '"') // Unquoted "
+ OS << "\\\"";
+ else if (*B != '\\') // Neither " or backslash
+ OS << *B;
+ else if (B + 1 == E) // Trailing backslash
+ OS << "\\\\";
+ else {
+ OS << B[0] << B[1]; // Quoted character
+ ++B;
+ }
+ }
+ OS << '"';
+}
+
+void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
+ raw_ostream &OS,
+ const MCExpr *Subsection) const {
+
+ if (ShouldOmitSectionDirective(SectionName, MAI)) {
+ OS << '\t' << getSectionName();
+ if (Subsection) {
+ OS << '\t';
+ Subsection->print(OS, &MAI);
+ }
+ OS << '\n';
+ return;
+ }
+
+ OS << "\t.section\t";
+ printName(OS, getSectionName());
+ OS << ",\"";
+
+ // TODO: Print section flags.
+
+ OS << '"';
+
+ OS << ',';
+
+ // If comment string is '@', e.g. as on ARM - use '%' instead
+ if (MAI.getCommentString()[0] == '@')
+ OS << '%';
+ else
+ OS << '@';
+
+ // TODO: Print section type.
+
+ if (isUnique())
+ OS << ",unique," << UniqueID;
+
+ OS << '\n';
+
+ if (Subsection) {
+ OS << "\t.subsection\t";
+ Subsection->print(OS, &MAI);
+ OS << '\n';
+ }
+}
+
+bool MCSectionWasm::UseCodeAlign() const { return false; }
+
+bool MCSectionWasm::isVirtualSection() const { return false; }
diff --git a/llvm/lib/MC/MCWasmObjectTargetWriter.cpp b/llvm/lib/MC/MCWasmObjectTargetWriter.cpp
new file mode 100644
index 00000000000..a09a17d7a12
--- /dev/null
+++ b/llvm/lib/MC/MCWasmObjectTargetWriter.cpp
@@ -0,0 +1,27 @@
+//===-- MCWasmObjectTargetWriter.cpp - Wasm Target Writer Subclass --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCWasmObjectWriter.h"
+
+using namespace llvm;
+
+MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit_)
+ : Is64Bit(Is64Bit_) {}
+
+bool MCWasmObjectTargetWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
+ unsigned Type) const {
+ return false;
+}
+
+void MCWasmObjectTargetWriter::sortRelocs(
+ const MCAssembler &Asm, std::vector<WasmRelocationEntry> &Relocs) {
+}
diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp
new file mode 100644
index 00000000000..f0a2f460a75
--- /dev/null
+++ b/llvm/lib/MC/MCWasmStreamer.cpp
@@ -0,0 +1,203 @@
+//===- lib/MC/MCWasmStreamer.cpp - Wasm Object Output ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file assembles .s files and emits Wasm .o object files.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCWasmStreamer.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionWasm.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+MCWasmStreamer::~MCWasmStreamer() {}
+
+void MCWasmStreamer::mergeFragment(MCDataFragment *DF, MCDataFragment *EF) {
+ flushPendingLabels(DF, DF->getContents().size());
+
+ for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) {
+ EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() +
+ DF->getContents().size());
+ DF->getFixups().push_back(EF->getFixups()[i]);
+ }
+ DF->setHasInstructions(true);
+ DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
+}
+
+void MCWasmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
+ // Let the target do whatever target specific stuff it needs to do.
+ getAssembler().getBackend().handleAssemblerFlag(Flag);
+
+ // Do any generic stuff we need to do.
+ llvm_unreachable("invalid assembler flag!");
+}
+
+void MCWasmStreamer::ChangeSection(MCSection *Section,
+ const MCExpr *Subsection) {
+ MCAssembler &Asm = getAssembler();
+ auto *SectionWasm = static_cast<const MCSectionWasm *>(Section);
+ const MCSymbol *Grp = SectionWasm->getGroup();
+ if (Grp)
+ Asm.registerSymbol(*Grp);
+
+ this->MCObjectStreamer::ChangeSection(Section, Subsection);
+}
+
+void MCWasmStreamer::EmitWeakReference(MCSymbol *Alias,
+ const MCSymbol *Symbol) {
+ getAssembler().registerSymbol(*Symbol);
+ const MCExpr *Value = MCSymbolRefExpr::create(
+ Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
+ Alias->setVariableValue(Value);
+}
+
+bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
+ assert(Attribute != MCSA_IndirectSymbol && "indirect symbols not supported");
+
+ auto *Symbol = cast<MCSymbolWasm>(S);
+
+ // Adding a symbol attribute always introduces the symbol, note that an
+ // important side effect of calling registerSymbol here is to register
+ // the symbol with the assembler.
+ getAssembler().registerSymbol(*Symbol);
+
+ // TODO: Set the symbol binding, type, etc.
+
+ return true;
+}
+
+void MCWasmStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
+ unsigned ByteAlignment) {
+ llvm_unreachable("Common symbols are not yet implemented for Wasm");
+}
+
+void MCWasmStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
+ unsigned ByteAlignment) {
+ llvm_unreachable("Local common symbols are not yet implemented for Wasm");
+}
+
+void MCWasmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
+ SMLoc Loc) {
+ MCObjectStreamer::EmitValueImpl(Value, Size, Loc);
+}
+
+void MCWasmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
+ unsigned ValueSize,
+ unsigned MaxBytesToEmit) {
+ MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value, ValueSize,
+ MaxBytesToEmit);
+}
+
+// Add a symbol for the file name of this module. They start after the
+// null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol
+// with the same name may appear.
+void MCWasmStreamer::EmitFileDirective(StringRef Filename) {
+ getAssembler().addFileName(Filename);
+}
+
+void MCWasmStreamer::EmitIdent(StringRef IdentString) {
+ llvm_unreachable("Ident sections not yet implemented for wasm");
+}
+
+void MCWasmStreamer::EmitInstToFragment(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ this->MCObjectStreamer::EmitInstToFragment(Inst, STI);
+}
+
+void MCWasmStreamer::EmitInstToData(const MCInst &Inst,
+ const MCSubtargetInfo &STI) {
+ MCAssembler &Assembler = getAssembler();
+ SmallVector<MCFixup, 4> Fixups;
+ SmallString<256> Code;
+ raw_svector_ostream VecOS(Code);
+ Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
+
+ // Append the encoded instruction to the current data fragment (or create a
+ // new such fragment if the current fragment is not a data fragment).
+ MCDataFragment *DF = getOrCreateDataFragment();
+
+ // Add the fixups and data.
+ for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+ Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
+ DF->getFixups().push_back(Fixups[i]);
+ }
+ DF->setHasInstructions(true);
+ DF->getContents().append(Code.begin(), Code.end());
+}
+
+void MCWasmStreamer::FinishImpl() {
+ EmitFrames(nullptr);
+
+ this->MCObjectStreamer::FinishImpl();
+}
+
+MCStreamer *llvm::createWasmStreamer(MCContext &Context, MCAsmBackend &MAB,
+ raw_pwrite_stream &OS, MCCodeEmitter *CE,
+ bool RelaxAll) {
+ MCWasmStreamer *S = new MCWasmStreamer(Context, MAB, OS, CE);
+ if (RelaxAll)
+ S->getAssembler().setRelaxAll(true);
+ return S;
+}
+
+void MCWasmStreamer::EmitThumbFunc(MCSymbol *Func) {
+ llvm_unreachable("Generic Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitCOFFSymbolType(int Type) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EndCOFFSymbolDef() {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
+
+void MCWasmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment) {
+ llvm_unreachable("Wasm doesn't support this directive");
+}
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
new file mode 100644
index 00000000000..cb11bab01eb
--- /dev/null
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -0,0 +1,119 @@
+//===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Wasm object file writer information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixupKindInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCSectionWasm.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/MC/MCWasmObjectWriter.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/StringSaver.h"
+#include <vector>
+
+using namespace llvm;
+
+#undef DEBUG_TYPE
+#define DEBUG_TYPE "reloc-info"
+
+namespace {
+typedef DenseMap<const MCSectionWasm *, uint32_t> SectionIndexMapTy;
+
+class WasmObjectWriter : public MCObjectWriter {
+ /// Helper struct for containing some precomputed information on symbols.
+ struct WasmSymbolData {
+ const MCSymbolWasm *Symbol;
+ StringRef Name;
+
+ // Support lexicographic sorting.
+ bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; }
+ };
+
+ /// The target specific Wasm writer instance.
+ std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
+
+ // TargetObjectWriter wrappers.
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
+ const MCFixup &Fixup, bool IsPCRel) const {
+ return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
+ }
+
+public:
+ WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
+ : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {}
+
+ void reset() override {
+ MCObjectWriter::reset();
+ }
+
+ ~WasmObjectWriter() override;
+
+ void writeHeader(const MCAssembler &Asm);
+
+ void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, bool &IsPCRel,
+ uint64_t &FixedValue) override;
+
+ void executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) override;
+
+ void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
+};
+} // end anonymous namespace
+
+WasmObjectWriter::~WasmObjectWriter() {}
+
+// Emit the Wasm header.
+void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
+ // TODO: write the magic cookie and the version.
+}
+
+void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+}
+
+void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ bool &IsPCRel, uint64_t &FixedValue) {
+ // TODO: Implement
+}
+
+void WasmObjectWriter::writeObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ // Write out the Wasm header.
+ writeHeader(Asm);
+
+ // TODO: Write the contents.
+}
+
+MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
+ raw_pwrite_stream &OS) {
+ return new WasmObjectWriter(MOTW, OS);
+}
OpenPOWER on IntegriCloud