1 //===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements Wasm object file writer information. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/ADT/SmallPtrSet.h" 16 #include "llvm/ADT/SmallString.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/MC/MCAsmBackend.h" 19 #include "llvm/MC/MCAsmInfo.h" 20 #include "llvm/MC/MCAsmLayout.h" 21 #include "llvm/MC/MCAssembler.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCExpr.h" 24 #include "llvm/MC/MCFixupKindInfo.h" 25 #include "llvm/MC/MCObjectFileInfo.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCSectionWasm.h" 28 #include "llvm/MC/MCSymbolWasm.h" 29 #include "llvm/MC/MCValue.h" 30 #include "llvm/MC/MCWasmObjectWriter.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/Endian.h" 33 #include "llvm/Support/ErrorHandling.h" 34 #include "llvm/Support/StringSaver.h" 35 #include "llvm/Support/Wasm.h" 36 #include <vector> 37 38 using namespace llvm; 39 40 #undef DEBUG_TYPE 41 #define DEBUG_TYPE "reloc-info" 42 43 namespace { 44 typedef DenseMap<const MCSectionWasm *, uint32_t> SectionIndexMapTy; 45 46 class WasmObjectWriter : public MCObjectWriter { 47 /// Helper struct for containing some precomputed information on symbols. 48 struct WasmSymbolData { 49 const MCSymbolWasm *Symbol; 50 StringRef Name; 51 52 // Support lexicographic sorting. 53 bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; } 54 }; 55 56 /// The target specific Wasm writer instance. 57 std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter; 58 59 // TargetObjectWriter wrappers. 60 bool is64Bit() const { return TargetObjectWriter->is64Bit(); } 61 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 62 const MCFixup &Fixup, bool IsPCRel) const { 63 return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel); 64 } 65 66 public: 67 WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS) 68 : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {} 69 70 void reset() override { 71 MCObjectWriter::reset(); 72 } 73 74 ~WasmObjectWriter() override; 75 76 void writeHeader(const MCAssembler &Asm); 77 78 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, 79 const MCFragment *Fragment, const MCFixup &Fixup, 80 MCValue Target, bool &IsPCRel, 81 uint64_t &FixedValue) override; 82 83 void executePostLayoutBinding(MCAssembler &Asm, 84 const MCAsmLayout &Layout) override; 85 86 void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; 87 }; 88 } // end anonymous namespace 89 90 WasmObjectWriter::~WasmObjectWriter() {} 91 92 // Emit the Wasm header. 93 void WasmObjectWriter::writeHeader(const MCAssembler &Asm) { 94 writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic))); 95 writeLE32(wasm::WasmVersion); 96 } 97 98 void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm, 99 const MCAsmLayout &Layout) { 100 } 101 102 void WasmObjectWriter::recordRelocation(MCAssembler &Asm, 103 const MCAsmLayout &Layout, 104 const MCFragment *Fragment, 105 const MCFixup &Fixup, MCValue Target, 106 bool &IsPCRel, uint64_t &FixedValue) { 107 // TODO: Implement 108 } 109 110 void WasmObjectWriter::writeObject(MCAssembler &Asm, 111 const MCAsmLayout &Layout) { 112 // Write out the Wasm header. 113 writeHeader(Asm); 114 115 // TODO: Write the contents. 116 } 117 118 MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW, 119 raw_pwrite_stream &OS) { 120 return new WasmObjectWriter(MOTW, OS); 121 } 122