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