diff options
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/CMakeLists.txt | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmInfoWasm.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/MC/MCContext.cpp | 80 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCSectionWasm.cpp | 97 | ||||
-rw-r--r-- | llvm/lib/MC/MCWasmObjectTargetWriter.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/MC/MCWasmStreamer.cpp | 203 | ||||
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 119 |
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); +} |