118eafb6cSDan Gohman //===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===//
218eafb6cSDan Gohman //
318eafb6cSDan Gohman //                     The LLVM Compiler Infrastructure
418eafb6cSDan Gohman //
518eafb6cSDan Gohman // This file is distributed under the University of Illinois Open Source
618eafb6cSDan Gohman // License. See LICENSE.TXT for details.
718eafb6cSDan Gohman //
818eafb6cSDan Gohman //===----------------------------------------------------------------------===//
918eafb6cSDan Gohman //
1018eafb6cSDan Gohman // This file implements Wasm object file writer information.
1118eafb6cSDan Gohman //
1218eafb6cSDan Gohman //===----------------------------------------------------------------------===//
1318eafb6cSDan Gohman 
1418eafb6cSDan Gohman #include "llvm/ADT/STLExtras.h"
1518eafb6cSDan Gohman #include "llvm/ADT/SmallPtrSet.h"
1618eafb6cSDan Gohman #include "llvm/ADT/SmallString.h"
1718eafb6cSDan Gohman #include "llvm/ADT/StringMap.h"
1818eafb6cSDan Gohman #include "llvm/MC/MCAsmBackend.h"
1918eafb6cSDan Gohman #include "llvm/MC/MCAsmInfo.h"
2018eafb6cSDan Gohman #include "llvm/MC/MCAsmLayout.h"
2118eafb6cSDan Gohman #include "llvm/MC/MCAssembler.h"
2218eafb6cSDan Gohman #include "llvm/MC/MCContext.h"
2318eafb6cSDan Gohman #include "llvm/MC/MCExpr.h"
2418eafb6cSDan Gohman #include "llvm/MC/MCFixupKindInfo.h"
2518eafb6cSDan Gohman #include "llvm/MC/MCObjectFileInfo.h"
2618eafb6cSDan Gohman #include "llvm/MC/MCObjectWriter.h"
2718eafb6cSDan Gohman #include "llvm/MC/MCSectionWasm.h"
2818eafb6cSDan Gohman #include "llvm/MC/MCSymbolWasm.h"
2918eafb6cSDan Gohman #include "llvm/MC/MCValue.h"
3018eafb6cSDan Gohman #include "llvm/MC/MCWasmObjectWriter.h"
3118eafb6cSDan Gohman #include "llvm/Support/Debug.h"
3218eafb6cSDan Gohman #include "llvm/Support/Endian.h"
3318eafb6cSDan Gohman #include "llvm/Support/ErrorHandling.h"
3418eafb6cSDan Gohman #include "llvm/Support/StringSaver.h"
35*7ea5adffSDan Gohman #include "llvm/Support/Wasm.h"
3618eafb6cSDan Gohman #include <vector>
3718eafb6cSDan Gohman 
3818eafb6cSDan Gohman using namespace llvm;
3918eafb6cSDan Gohman 
4018eafb6cSDan Gohman #undef DEBUG_TYPE
4118eafb6cSDan Gohman #define DEBUG_TYPE "reloc-info"
4218eafb6cSDan Gohman 
4318eafb6cSDan Gohman namespace {
4418eafb6cSDan Gohman typedef DenseMap<const MCSectionWasm *, uint32_t> SectionIndexMapTy;
4518eafb6cSDan Gohman 
4618eafb6cSDan Gohman class WasmObjectWriter : public MCObjectWriter {
4718eafb6cSDan Gohman   /// Helper struct for containing some precomputed information on symbols.
4818eafb6cSDan Gohman   struct WasmSymbolData {
4918eafb6cSDan Gohman     const MCSymbolWasm *Symbol;
5018eafb6cSDan Gohman     StringRef Name;
5118eafb6cSDan Gohman 
5218eafb6cSDan Gohman     // Support lexicographic sorting.
5318eafb6cSDan Gohman     bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; }
5418eafb6cSDan Gohman   };
5518eafb6cSDan Gohman 
5618eafb6cSDan Gohman   /// The target specific Wasm writer instance.
5718eafb6cSDan Gohman   std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
5818eafb6cSDan Gohman 
5918eafb6cSDan Gohman   // TargetObjectWriter wrappers.
6018eafb6cSDan Gohman   bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
6118eafb6cSDan Gohman   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
6218eafb6cSDan Gohman                         const MCFixup &Fixup, bool IsPCRel) const {
6318eafb6cSDan Gohman     return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
6418eafb6cSDan Gohman   }
6518eafb6cSDan Gohman 
6618eafb6cSDan Gohman public:
6718eafb6cSDan Gohman   WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
6818eafb6cSDan Gohman       : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {}
6918eafb6cSDan Gohman 
7018eafb6cSDan Gohman   void reset() override {
7118eafb6cSDan Gohman     MCObjectWriter::reset();
7218eafb6cSDan Gohman   }
7318eafb6cSDan Gohman 
7418eafb6cSDan Gohman   ~WasmObjectWriter() override;
7518eafb6cSDan Gohman 
7618eafb6cSDan Gohman   void writeHeader(const MCAssembler &Asm);
7718eafb6cSDan Gohman 
7818eafb6cSDan Gohman   void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
7918eafb6cSDan Gohman                         const MCFragment *Fragment, const MCFixup &Fixup,
8018eafb6cSDan Gohman                         MCValue Target, bool &IsPCRel,
8118eafb6cSDan Gohman                         uint64_t &FixedValue) override;
8218eafb6cSDan Gohman 
8318eafb6cSDan Gohman   void executePostLayoutBinding(MCAssembler &Asm,
8418eafb6cSDan Gohman                                 const MCAsmLayout &Layout) override;
8518eafb6cSDan Gohman 
8618eafb6cSDan Gohman   void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
8718eafb6cSDan Gohman };
8818eafb6cSDan Gohman } // end anonymous namespace
8918eafb6cSDan Gohman 
9018eafb6cSDan Gohman WasmObjectWriter::~WasmObjectWriter() {}
9118eafb6cSDan Gohman 
9218eafb6cSDan Gohman // Emit the Wasm header.
9318eafb6cSDan Gohman void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
94*7ea5adffSDan Gohman   writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic)));
95*7ea5adffSDan Gohman   writeLE32(wasm::WasmVersion);
9618eafb6cSDan Gohman }
9718eafb6cSDan Gohman 
9818eafb6cSDan Gohman void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
9918eafb6cSDan Gohman                                                 const MCAsmLayout &Layout) {
10018eafb6cSDan Gohman }
10118eafb6cSDan Gohman 
10218eafb6cSDan Gohman void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
10318eafb6cSDan Gohman                                         const MCAsmLayout &Layout,
10418eafb6cSDan Gohman                                         const MCFragment *Fragment,
10518eafb6cSDan Gohman                                         const MCFixup &Fixup, MCValue Target,
10618eafb6cSDan Gohman                                         bool &IsPCRel, uint64_t &FixedValue) {
10718eafb6cSDan Gohman   // TODO: Implement
10818eafb6cSDan Gohman }
10918eafb6cSDan Gohman 
11018eafb6cSDan Gohman void WasmObjectWriter::writeObject(MCAssembler &Asm,
11118eafb6cSDan Gohman                                    const MCAsmLayout &Layout) {
11218eafb6cSDan Gohman   // Write out the Wasm header.
11318eafb6cSDan Gohman   writeHeader(Asm);
11418eafb6cSDan Gohman 
11518eafb6cSDan Gohman   // TODO: Write the contents.
11618eafb6cSDan Gohman }
11718eafb6cSDan Gohman 
11818eafb6cSDan Gohman MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
11918eafb6cSDan Gohman                                              raw_pwrite_stream &OS) {
12018eafb6cSDan Gohman   return new WasmObjectWriter(MOTW, OS);
12118eafb6cSDan Gohman }
122