llvm.org GIT mirror llvm / d660a5d
[WebAssembly] Add skeleton MC support for the Wasm container format This just adds the basic skeleton for supporting a new object file format. All of the actual encoding will be implemented in followup patches. Differential Revision: https://reviews.llvm.org/D26722 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295803 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 3 years ago
35 changed file(s) with 1308 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
170170 const GlobalValue *GV) const override;
171171 };
172172
173 class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
174 public:
175 TargetLoweringObjectFileWasm() {}
176
177 ~TargetLoweringObjectFileWasm() override {}
178
179 MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
180 const TargetMachine &TM) const override;
181
182 MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
183 const TargetMachine &TM) const override;
184
185 bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
186 const Function &F) const override;
187
188 void InitializeWasm();
189
190 const MCExpr *lowerRelativeReference(const GlobalValue *LHS,
191 const GlobalValue *RHS,
192 const TargetMachine &TM) const override;
193 };
194
173195 void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
174196 const Triple &TT, Mangler &Mangler);
175197
0 //===-- llvm/MC/MCAsmInfoWasm.h - Wasm Asm info -----------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_MC_MCASMINFOWASM_H
10 #define LLVM_MC_MCASMINFOWASM_H
11
12 #include "llvm/MC/MCAsmInfo.h"
13
14 namespace llvm {
15 class MCAsmInfoWasm : public MCAsmInfo {
16 virtual void anchor();
17
18 protected:
19 MCAsmInfoWasm();
20 };
21 }
22
23 #endif
4444 class MCSectionCOFF;
4545 class MCSectionELF;
4646 class MCSectionMachO;
47 class MCSectionWasm;
4748 class MCSymbol;
4849 class MCSymbolELF;
50 class MCSymbolWasm;
4951 class SMLoc;
5052
5153 /// Context object for machine code objects. This class owns all of the
8284 SpecificBumpPtrAllocator COFFAllocator;
8385 SpecificBumpPtrAllocator ELFAllocator;
8486 SpecificBumpPtrAllocator MachOAllocator;
87 SpecificBumpPtrAllocator WasmAllocator;
8588
8689 /// Bindings of names to symbols.
8790 SymbolTable Symbols;
215218 }
216219 };
217220
221 struct WasmSectionKey {
222 std::string SectionName;
223 StringRef GroupName;
224 unsigned UniqueID;
225 WasmSectionKey(StringRef SectionName, StringRef GroupName,
226 unsigned UniqueID)
227 : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
228 }
229 bool operator<(const WasmSectionKey &Other) const {
230 if (SectionName != Other.SectionName)
231 return SectionName < Other.SectionName;
232 if (GroupName != Other.GroupName)
233 return GroupName < Other.GroupName;
234 return UniqueID < Other.UniqueID;
235 }
236 };
237
218238 StringMap MachOUniquingMap;
219239 std::map ELFUniquingMap;
220240 std::map COFFUniquingMap;
221 StringMap ELFRelSecNames;
241 std::map WasmUniquingMap;
242 StringMap RelSecNames;
222243
223244 SpecificBumpPtrAllocator MCSubtargetAllocator;
224245
414435 MCSectionCOFF *
415436 getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym,
416437 unsigned UniqueID = GenericSectionID);
438
439 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
440 unsigned Flags) {
441 return getWasmSection(Section, Type, Flags, nullptr);
442 }
443
444 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
445 unsigned Flags, const char *BeginSymName) {
446 return getWasmSection(Section, Type, Flags, "", BeginSymName);
447 }
448
449 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
450 unsigned Flags, const Twine &Group) {
451 return getWasmSection(Section, Type, Flags, Group, nullptr);
452 }
453
454 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
455 unsigned Flags, const Twine &Group,
456 const char *BeginSymName) {
457 return getWasmSection(Section, Type, Flags, Group, ~0, BeginSymName);
458 }
459
460 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
461 unsigned Flags, const Twine &Group,
462 unsigned UniqueID) {
463 return getWasmSection(Section, Type, Flags, Group, UniqueID, nullptr);
464 }
465
466 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
467 unsigned Flags, const Twine &Group,
468 unsigned UniqueID, const char *BeginSymName);
469
470 MCSectionWasm *getWasmSection(const Twine &Section, unsigned Type,
471 unsigned Flags, const MCSymbolWasm *Group,
472 unsigned UniqueID, const char *BeginSymName);
473
474 /// Get a section with the provided group identifier. This section is
475 /// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type
476 /// describes the type of the section and \p Flags are used to further
477 /// configure this named section.
478 MCSectionWasm *getWasmNamedSection(const Twine &Prefix, const Twine &Suffix,
479 unsigned Type, unsigned Flags);
480
481 MCSectionWasm *createWasmRelSection(const Twine &Name, unsigned Type,
482 unsigned Flags,
483 const MCSymbolWasm *Group);
484
485 void renameWasmSection(MCSectionWasm *Section, StringRef Name);
417486
418487 // Create and save a copy of STI and return a reference to the copy.
419488 MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
128128 /// it'll go here.
129129 MCSection *TLSExtraDataSection;
130130
131 /// Section directive for Thread Local data. ELF, MachO and COFF.
131 /// Section directive for Thread Local data. ELF, MachO, COFF, and Wasm.
132132 MCSection *TLSDataSection; // Defaults to ".tdata".
133133
134134 /// Section directive for Thread Local uninitialized data.
337337 return EHFrameSection;
338338 }
339339
340 enum Environment { IsMachO, IsELF, IsCOFF };
340 enum Environment { IsMachO, IsELF, IsCOFF, IsWasm };
341341 Environment getObjectFileType() const { return Env; }
342342
343343 bool isPositionIndependent() const { return PositionIndependent; }
352352 void initMachOMCObjectFileInfo(const Triple &T);
353353 void initELFMCObjectFileInfo(const Triple &T);
354354 void initCOFFMCObjectFileInfo(const Triple &T);
355 void initWasmMCObjectFileInfo(const Triple &T);
355356
356357 public:
357358 const Triple &getTargetTriple() const { return TT; }
3737 /// current translation unit. The MCContext class uniques and creates these.
3838 class MCSection {
3939 public:
40 enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO };
40 enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm };
4141
4242 /// \brief Express the state of bundle locked groups while emitting code.
4343 enum BundleLockStateType {
0 //===- MCSectionWasm.h - Wasm Machine Code Sections -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the MCSectionWasm class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_MC_MCSECTIONWASM_H
14 #define LLVM_MC_MCSECTIONWASM_H
15
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/MC/MCSection.h"
18 #include "llvm/MC/MCSymbolWasm.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/raw_ostream.h"
21
22 namespace llvm {
23
24 class MCSymbol;
25
26 /// This represents a section on wasm.
27 class MCSectionWasm final : public MCSection {
28 /// This is the name of the section. The referenced memory is owned by
29 /// TargetLoweringObjectFileWasm's WasmUniqueMap.
30 StringRef SectionName;
31
32 /// This is the sh_type field of a section, drawn from the enums below.
33 unsigned Type;
34
35 /// This is the sh_flags field of a section, drawn from the enums below.
36 unsigned Flags;
37
38 unsigned UniqueID;
39
40 const MCSymbolWasm *Group;
41
42 private:
43 friend class MCContext;
44 MCSectionWasm(StringRef Section, unsigned type, unsigned flags, SectionKind K,
45 const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin)
46 : MCSection(SV_Wasm, K, Begin), SectionName(Section), Type(type),
47 Flags(flags), UniqueID(UniqueID), Group(group) {
48 }
49
50 void setSectionName(StringRef Name) { SectionName = Name; }
51
52 public:
53 ~MCSectionWasm();
54
55 /// Decides whether a '.section' directive should be printed before the
56 /// section name
57 bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
58
59 StringRef getSectionName() const { return SectionName; }
60 unsigned getType() const { return Type; }
61 unsigned getFlags() const { return Flags; }
62 void setFlags(unsigned F) { Flags = F; }
63 const MCSymbolWasm *getGroup() const { return Group; }
64
65 void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
66 raw_ostream &OS,
67 const MCExpr *Subsection) const override;
68 bool UseCodeAlign() const override;
69 bool isVirtualSection() const override;
70
71 bool isUnique() const { return UniqueID != ~0U; }
72 unsigned getUniqueID() const { return UniqueID; }
73
74 static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; }
75 };
76
77 } // end namespace llvm
78
79 #endif
4343 class MCSection;
4444 class MCStreamer;
4545 class MCSymbolRefExpr;
46 class MCSymbolWasm;
4647 class MCSubtargetInfo;
4748 class raw_ostream;
4849 class Twine;
4747 SymbolKindCOFF,
4848 SymbolKindELF,
4949 SymbolKindMachO,
50 SymbolKindWasm,
5051 };
5152
5253 /// A symbol can contain an Offset, or Value, or be Common, but never more
99100
100101 /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
101102 /// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
102 unsigned Kind : 2;
103 unsigned Kind : 3;
103104
104105 /// True if we have created a relocation that uses this symbol.
105106 mutable unsigned IsUsedInReloc : 1;
283284
284285 bool isMachO() const { return Kind == SymbolKindMachO; }
285286
287 bool isWasm() const { return Kind == SymbolKindWasm; }
288
286289 /// @}
287290 /// \name Variable Symbols
288291 /// @{
0 //===- MCSymbolWasm.h - ----------------------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LLVM_MC_MCSYMBOLWASM_H
9 #define LLVM_MC_MCSYMBOLWASM_H
10
11 #include "llvm/MC/MCSymbol.h"
12
13 namespace llvm {
14 class MCSymbolWasm : public MCSymbol {
15 public:
16 MCSymbolWasm(const StringMapEntry *Name, bool isTemporary)
17 : MCSymbol(SymbolKindWasm, Name, isTemporary) {}
18
19 static bool classof(const MCSymbol *S) { return S->isWasm(); }
20 };
21 }
22
23 #endif
0 //===-- llvm/MC/MCWasmObjectWriter.h - Wasm Object Writer -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_MC_MCWASMOBJECTWRITER_H
10 #define LLVM_MC_MCWASMOBJECTWRITER_H
11
12 #include "llvm/ADT/Triple.h"
13 #include "llvm/MC/MCValue.h"
14 #include "llvm/Support/DataTypes.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include
17
18 namespace llvm {
19 class MCAssembler;
20 class MCContext;
21 class MCFixup;
22 class MCFragment;
23 class MCObjectWriter;
24 class MCSymbol;
25 class MCSymbolWasm;
26 class MCValue;
27 class raw_pwrite_stream;
28
29 struct WasmRelocationEntry {
30 uint64_t Offset; // Where is the relocation.
31 const MCSymbolWasm *Symbol; // The symbol to relocate with.
32 unsigned Type; // The type of the relocation.
33
34 WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
35 unsigned Type)
36 : Offset(Offset), Symbol(Symbol), Type(Type) {}
37
38 void print(raw_ostream &Out) const {
39 Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type;
40 }
41 void dump() const { print(errs()); }
42 };
43
44 class MCWasmObjectTargetWriter {
45 const unsigned Is64Bit : 1;
46
47 protected:
48 explicit MCWasmObjectTargetWriter(bool Is64Bit_);
49
50 public:
51 virtual ~MCWasmObjectTargetWriter() {}
52
53 virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
54 const MCFixup &Fixup, bool IsPCRel) const = 0;
55
56 virtual bool needsRelocateWithSymbol(const MCSymbol &Sym,
57 unsigned Type) const;
58
59 virtual void sortRelocs(const MCAssembler &Asm,
60 std::vector &Relocs);
61
62 /// \name Accessors
63 /// @{
64 bool is64Bit() const { return Is64Bit; }
65 /// @}
66 };
67
68 /// \brief Construct a new Wasm writer instance.
69 ///
70 /// \param MOTW - The target specific Wasm writer subclass.
71 /// \param OS - The stream to write to.
72 /// \returns The constructed object writer.
73 MCObjectWriter *createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
74 raw_pwrite_stream &OS);
75 } // End llvm namespace
76
77 #endif
0 //===- MCWasmStreamer.h - MCStreamer Wasm Object File Interface -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_MC_MCWASMSTREAMER_H
10 #define LLVM_MC_MCWASMSTREAMER_H
11
12 #include "llvm/ADT/SmallPtrSet.h"
13 #include "llvm/MC/MCDirectives.h"
14 #include "llvm/MC/MCObjectStreamer.h"
15 #include "llvm/MC/SectionKind.h"
16 #include "llvm/Support/DataTypes.h"
17
18 namespace llvm {
19 class MCAsmBackend;
20 class MCAssembler;
21 class MCCodeEmitter;
22 class MCExpr;
23 class MCInst;
24 class raw_ostream;
25
26 class MCWasmStreamer : public MCObjectStreamer {
27 public:
28 MCWasmStreamer(MCContext &Context, MCAsmBackend &TAB, raw_pwrite_stream &OS,
29 MCCodeEmitter *Emitter)
30 : MCObjectStreamer(Context, TAB, OS, Emitter), SeenIdent(false) {}
31
32 ~MCWasmStreamer() override;
33
34 /// state management
35 void reset() override {
36 SeenIdent = false;
37 MCObjectStreamer::reset();
38 }
39
40 /// \name MCStreamer Interface
41 /// @{
42
43 void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
44 void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
45 void EmitThumbFunc(MCSymbol *Func) override;
46 void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
47 bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
48 void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
49 void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
50 unsigned ByteAlignment) override;
51 void BeginCOFFSymbolDef(const MCSymbol *Symbol) override;
52 void EmitCOFFSymbolStorageClass(int StorageClass) override;
53 void EmitCOFFSymbolType(int Type) override;
54 void EndCOFFSymbolDef() override;
55
56 void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
57 unsigned ByteAlignment) override;
58
59 void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
60 uint64_t Size = 0, unsigned ByteAlignment = 0) override;
61 void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
62 unsigned ByteAlignment = 0) override;
63 void EmitValueImpl(const MCExpr *Value, unsigned Size,
64 SMLoc Loc = SMLoc()) override;
65
66 void EmitFileDirective(StringRef Filename) override;
67
68 void EmitIdent(StringRef IdentString) override;
69
70 void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
71
72 void FinishImpl() override;
73
74 private:
75 void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
76 void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
77
78 /// \brief Merge the content of the fragment \p EF into the fragment \p DF.
79 void mergeFragment(MCDataFragment *, MCDataFragment *);
80
81 bool SeenIdent;
82 };
83
84 } // end namespace llvm
85
86 #endif
6767 raw_pwrite_stream &OS, MCCodeEmitter *CE,
6868 bool RelaxAll, bool DWARFMustBeAtTheEnd,
6969 bool LabelSections = false);
70 MCStreamer *createWasmStreamer(MCContext &Ctx, MCAsmBackend &TAB,
71 raw_pwrite_stream &OS, MCCodeEmitter *CE,
72 bool RelaxAll);
7073
7174 MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx);
7275
142145 MCCodeEmitter *Emitter,
143146 bool RelaxAll,
144147 bool IncrementalLinkerCompatible);
148 typedef MCStreamer *(*WasmStreamerCtorTy)(const Triple &T, MCContext &Ctx,
149 MCAsmBackend &TAB,
150 raw_pwrite_stream &OS,
151 MCCodeEmitter *Emitter,
152 bool RelaxAll);
145153 typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
146154 typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)(
147155 MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
226234 COFFStreamerCtorTy COFFStreamerCtorFn;
227235 MachOStreamerCtorTy MachOStreamerCtorFn;
228236 ELFStreamerCtorTy ELFStreamerCtorFn;
237 WasmStreamerCtorTy WasmStreamerCtorFn;
229238
230239 /// Construction function for this target's null TargetStreamer, if
231240 /// registered (default = nullptr).
250259 public:
251260 Target()
252261 : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr),
253 ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr),
262 ELFStreamerCtorFn(nullptr), WasmStreamerCtorFn(nullptr),
263 NullTargetStreamerCtorFn(nullptr),
254264 AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr),
255265 MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
256266
460470 else
461471 S = createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
462472 break;
473 case Triple::Wasm:
474 if (WasmStreamerCtorFn)
475 S = WasmStreamerCtorFn(T, Ctx, TAB, OS, Emitter, RelaxAll);
476 else
477 S = createWasmStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
478 break;
463479 }
464480 if (ObjectTargetStreamerCtorFn)
465481 ObjectTargetStreamerCtorFn(*S, STI);
799815 T.ELFStreamerCtorFn = Fn;
800816 }
801817
818 static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) {
819 T.WasmStreamerCtorFn = Fn;
820 }
821
802822 static void RegisterNullTargetStreamer(Target &T,
803823 Target::NullTargetStreamerCtorTy Fn) {
804824 T.NullTargetStreamerCtorFn = Fn;
2929 #include "llvm/MC/MCSectionCOFF.h"
3030 #include "llvm/MC/MCSectionELF.h"
3131 #include "llvm/MC/MCSectionMachO.h"
32 #include "llvm/MC/MCSectionWasm.h"
3233 #include "llvm/MC/MCStreamer.h"
3334 #include "llvm/MC/MCSymbolELF.h"
35 #include "llvm/MC/MCSymbolWasm.h"
3436 #include "llvm/MC/MCValue.h"
3537 #include "llvm/ProfileData/InstrProf.h"
3638 #include "llvm/Support/COFF.h"
11541156 raw_ostream &OS, const GlobalValue *GV) const {
11551157 emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
11561158 }
1159
1160 //===----------------------------------------------------------------------===//
1161 // Wasm
1162 //===----------------------------------------------------------------------===//
1163
1164 MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
1165 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1166 llvm_unreachable("getExplicitSectionGlobal not yet implemented");
1167 return nullptr;
1168 }
1169
1170 MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(
1171 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1172 if (Kind.isText())
1173 return TextSection;
1174 assert(!Kind.isMetadata() && "metadata sections not yet implemented");
1175 return DataSection;
1176 }
1177
1178 bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection(
1179 bool UsesLabelDifference, const Function &F) const {
1180 // We can always create relative relocations, so use another section
1181 // that can be marked non-executable.
1182 return false;
1183 }
1184
1185 const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference(
1186 const GlobalValue *LHS, const GlobalValue *RHS,
1187 const TargetMachine &TM) const {
1188 // We may only use a PLT-relative relocation to refer to unnamed_addr
1189 // functions.
1190 if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
1191 return nullptr;
1192
1193 // Basic sanity checks.
1194 if (LHS->getType()->getPointerAddressSpace() != 0 ||
1195 RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() ||
1196 RHS->isThreadLocal())
1197 return nullptr;
1198
1199 return MCBinaryExpr::createSub(
1200 MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None,
1201 getContext()),
1202 MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext());
1203 }
1204
1205 void
1206 TargetLoweringObjectFileWasm::InitializeWasm() {
1207 // TODO: Initialize StaticCtorSection and StaticDtorSection.
1208 }
55 MCAsmInfoCOFF.cpp
66 MCAsmInfoDarwin.cpp
77 MCAsmInfoELF.cpp
8 MCAsmInfoWasm.cpp
89 MCAsmStreamer.cpp
910 MCAssembler.cpp
1011 MCCodeEmitter.cpp
3334 MCSectionCOFF.cpp
3435 MCSectionELF.cpp
3536 MCSectionMachO.cpp
37 MCSectionWasm.cpp
3638 MCStreamer.cpp
3739 MCSubtargetInfo.cpp
3840 MCSymbol.cpp
3941 MCSymbolELF.cpp
4042 MCTargetOptions.cpp
4143 MCValue.cpp
44 MCWasmObjectTargetWriter.cpp
45 MCWasmStreamer.cpp
4246 MCWin64EH.cpp
4347 MCWinEH.cpp
4448 MachObjectWriter.cpp
4549 StringTableBuilder.cpp
4650 SubtargetFeature.cpp
51 WasmObjectWriter.cpp
4752 WinCOFFObjectWriter.cpp
4853 WinCOFFStreamer.cpp
4954
0 //===-- MCAsmInfoWasm.cpp - Wasm asm properties -----------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines target asm properties related what form asm statements
10 // should take in general on Wasm-based targets
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/MC/MCAsmInfoWasm.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCSectionWasm.h"
17 using namespace llvm;
18
19 void MCAsmInfoWasm::anchor() { }
20
21 MCAsmInfoWasm::MCAsmInfoWasm() {
22 HasIdentDirective = true;
23 WeakRefDirective = "\t.weak\t";
24 PrivateGlobalPrefix = ".L";
25 PrivateLabelPrefix = ".L";
26 }
2222 #include "llvm/MC/MCSectionCOFF.h"
2323 #include "llvm/MC/MCSectionELF.h"
2424 #include "llvm/MC/MCSectionMachO.h"
25 #include "llvm/MC/MCSectionWasm.h"
2526 #include "llvm/MC/MCStreamer.h"
2627 #include "llvm/MC/MCSymbol.h"
2728 #include "llvm/MC/MCSymbolCOFF.h"
2829 #include "llvm/MC/MCSymbolELF.h"
2930 #include "llvm/MC/MCSymbolMachO.h"
31 #include "llvm/MC/MCSymbolWasm.h"
3032 #include "llvm/MC/SectionKind.h"
3133 #include "llvm/Support/Casting.h"
3234 #include "llvm/Support/COFF.h"
153155 return new (Name, *this) MCSymbolELF(Name, IsTemporary);
154156 case MCObjectFileInfo::IsMachO:
155157 return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
158 case MCObjectFileInfo::IsWasm:
159 return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
156160 }
157161 }
158162 return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
344348 StringMap::iterator I;
345349 bool Inserted;
346350 std::tie(I, Inserted) =
347 ELFRelSecNames.insert(std::make_pair(Name.str(), true));
351 RelSecNames.insert(std::make_pair(Name.str(), true));
348352
349353 return createELFSectionImpl(I->getKey(), Type, Flags,
350354 SectionKind::getReadOnly(), EntrySize, Group,
476480 "", 0, UniqueID);
477481 }
478482
483 void MCContext::renameWasmSection(MCSectionWasm *Section, StringRef Name) {
484 StringRef GroupName;
485 assert(!Section->getGroup() && "not yet implemented");
486
487 unsigned UniqueID = Section->getUniqueID();
488 WasmUniquingMap.erase(
489 WasmSectionKey{Section->getSectionName(), GroupName, UniqueID});
490 auto I = WasmUniquingMap.insert(std::make_pair(
491 WasmSectionKey{Name, GroupName, UniqueID},
492 Section))
493 .first;
494 StringRef CachedName = I->first.SectionName;
495 const_cast(Section)->setSectionName(CachedName);
496 }
497
498 MCSectionWasm *MCContext::createWasmRelSection(const Twine &Name, unsigned Type,
499 unsigned Flags,
500 const MCSymbolWasm *Group) {
501 StringMap::iterator I;
502 bool Inserted;
503 std::tie(I, Inserted) =
504 RelSecNames.insert(std::make_pair(Name.str(), true));
505
506 return new (WasmAllocator.Allocate())
507 MCSectionWasm(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
508 Group, ~0, nullptr);
509 }
510
511 MCSectionWasm *MCContext::getWasmNamedSection(const Twine &Prefix,
512 const Twine &Suffix, unsigned Type,
513 unsigned Flags) {
514 return getWasmSection(Prefix + "." + Suffix, Type, Flags, Suffix);
515 }
516
517 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type,
518 unsigned Flags,
519 const Twine &Group, unsigned UniqueID,
520 const char *BeginSymName) {
521 MCSymbolWasm *GroupSym = nullptr;
522 if (!Group.isTriviallyEmpty() && !Group.str().empty())
523 GroupSym = cast(getOrCreateSymbol(Group));
524
525 return getWasmSection(Section, Type, Flags, GroupSym, UniqueID, BeginSymName);
526 }
527
528 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type,
529 unsigned Flags,
530 const MCSymbolWasm *GroupSym,
531 unsigned UniqueID,
532 const char *BeginSymName) {
533 StringRef Group = "";
534 if (GroupSym)
535 Group = GroupSym->getName();
536 // Do the lookup, if we have a hit, return it.
537 auto IterBool = WasmUniquingMap.insert(
538 std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
539 auto &Entry = *IterBool.first;
540 if (!IterBool.second)
541 return Entry.second;
542
543 StringRef CachedName = Entry.first.SectionName;
544
545 SectionKind Kind = SectionKind::getText();
546
547 MCSymbol *Begin = nullptr;
548 if (BeginSymName)
549 Begin = createTempSymbol(BeginSymName, false);
550
551 MCSectionWasm *Result = new (WasmAllocator.Allocate())
552 MCSectionWasm(CachedName, Type, Flags, Kind, GroupSym, UniqueID, Begin);
553 Entry.second = Result;
554 return Result;
555 }
556
479557 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
480558 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
481559 }
1515 #include "llvm/MC/MCSectionCOFF.h"
1616 #include "llvm/MC/MCSectionELF.h"
1717 #include "llvm/MC/MCSectionMachO.h"
18 #include "llvm/MC/MCSectionWasm.h"
1819 #include "llvm/Support/COFF.h"
1920 #include "llvm/Support/ELF.h"
2021
797798 SectionKind::getReadOnly());
798799 }
799800
801 void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
802 // TODO: Set the section types and flags.
803 TextSection = Ctx->getWasmSection("", 0, 0);
804 DataSection = Ctx->getWasmSection("", 0, 0);
805
806 // TODO: Set the section types and flags.
807 DwarfLineSection = Ctx->getWasmSection(".debug_line", 0, 0);
808 DwarfStrSection = Ctx->getWasmSection(".debug_str", 0, 0);
809 DwarfLocSection = Ctx->getWasmSection(".debug_loc", 0, 0);
810 DwarfAbbrevSection = Ctx->getWasmSection(".debug_abbrev", 0, 0, "section_abbrev");
811 DwarfARangesSection = Ctx->getWasmSection(".debug_aranges", 0, 0);
812 DwarfRangesSection = Ctx->getWasmSection(".debug_ranges", 0, 0, "debug_range");
813 DwarfMacinfoSection = Ctx->getWasmSection(".debug_macinfo", 0, 0, "debug_macinfo");
814 DwarfAddrSection = Ctx->getWasmSection(".debug_addr", 0, 0);
815 DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", 0, 0);
816 DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", 0, 0);
817 DwarfInfoSection = Ctx->getWasmSection(".debug_info", 0, 0, "section_info");
818 DwarfFrameSection = Ctx->getWasmSection(".debug_frame", 0, 0);
819 DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", 0, 0);
820 DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", 0, 0);
821
822 // TODO: Define more sections.
823 }
824
800825 void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
801826 CodeModel::Model cm,
802827 MCContext &ctx) {
842867 initELFMCObjectFileInfo(TT);
843868 break;
844869 case Triple::Wasm:
845 report_fatal_error("Cannot initialize MC for wasm object file format yet.");
870 Env = IsWasm;
871 initWasmMCObjectFileInfo(TT);
846872 break;
847873 case Triple::UnknownObjectFormat:
848874 report_fatal_error("Cannot initialize MC for unknown object file format.");
594594 break;
595595 case MCObjectFileInfo::IsELF:
596596 PlatformParser.reset(createELFAsmParser());
597 break;
598 case MCObjectFileInfo::IsWasm:
599 llvm_unreachable("Wasm parsing not supported yet");
597600 break;
598601 }
599602
0 //===- lib/MC/MCSectionWasm.cpp - Wasm Code Section Representation --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/MC/MCSectionWasm.h"
10 #include "llvm/MC/MCAsmInfo.h"
11 #include "llvm/MC/MCContext.h"
12 #include "llvm/MC/MCExpr.h"
13 #include "llvm/MC/MCSymbol.h"
14 #include "llvm/Support/raw_ostream.h"
15
16 using namespace llvm;
17
18 MCSectionWasm::~MCSectionWasm() {} // anchor.
19
20 // Decides whether a '.section' directive
21 // should be printed before the section name.
22 bool MCSectionWasm::ShouldOmitSectionDirective(StringRef Name,
23 const MCAsmInfo &MAI) const {
24 return MAI.shouldOmitSectionDirective(Name);
25 }
26
27 static void printName(raw_ostream &OS, StringRef Name) {
28 if (Name.find_first_not_of("0123456789_."
29 "abcdefghijklmnopqrstuvwxyz"
30 "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
31 OS << Name;
32 return;
33 }
34 OS << '"';
35 for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
36 if (*B == '"') // Unquoted "
37 OS << "\\\"";
38 else if (*B != '\\') // Neither " or backslash
39 OS << *B;
40 else if (B + 1 == E) // Trailing backslash
41 OS << "\\\\";
42 else {
43 OS << B[0] << B[1]; // Quoted character
44 ++B;
45 }
46 }
47 OS << '"';
48 }
49
50 void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
51 raw_ostream &OS,
52 const MCExpr *Subsection) const {
53
54 if (ShouldOmitSectionDirective(SectionName, MAI)) {
55 OS << '\t' << getSectionName();
56 if (Subsection) {
57 OS << '\t';
58 Subsection->print(OS, &MAI);
59 }
60 OS << '\n';
61 return;
62 }
63
64 OS << "\t.section\t";
65 printName(OS, getSectionName());
66 OS << ",\"";
67
68 // TODO: Print section flags.
69
70 OS << '"';
71
72 OS << ',';
73
74 // If comment string is '@', e.g. as on ARM - use '%' instead
75 if (MAI.getCommentString()[0] == '@')
76 OS << '%';
77 else
78 OS << '@';
79
80 // TODO: Print section type.
81
82 if (isUnique())
83 OS << ",unique," << UniqueID;
84
85 OS << '\n';
86
87 if (Subsection) {
88 OS << "\t.subsection\t";
89 Subsection->print(OS, &MAI);
90 OS << '\n';
91 }
92 }
93
94 bool MCSectionWasm::UseCodeAlign() const { return false; }
95
96 bool MCSectionWasm::isVirtualSection() const { return false; }
0 //===-- MCWasmObjectTargetWriter.cpp - Wasm Target Writer Subclass --------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ADT/STLExtras.h"
10 #include "llvm/MC/MCExpr.h"
11 #include "llvm/MC/MCValue.h"
12 #include "llvm/MC/MCWasmObjectWriter.h"
13
14 using namespace llvm;
15
16 MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit_)
17 : Is64Bit(Is64Bit_) {}
18
19 bool MCWasmObjectTargetWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
20 unsigned Type) const {
21 return false;
22 }
23
24 void MCWasmObjectTargetWriter::sortRelocs(
25 const MCAssembler &Asm, std::vector &Relocs) {
26 }
0 //===- lib/MC/MCWasmStreamer.cpp - Wasm Object Output ---------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file assembles .s files and emits Wasm .o object files.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/MC/MCWasmStreamer.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/MC/MCAsmBackend.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCAsmLayout.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCObjectStreamer.h"
26 #include "llvm/MC/MCObjectWriter.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionWasm.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/MCSymbolWasm.h"
31 #include "llvm/MC/MCValue.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/raw_ostream.h"
37
38 using namespace llvm;
39
40 MCWasmStreamer::~MCWasmStreamer() {}
41
42 void MCWasmStreamer::mergeFragment(MCDataFragment *DF, MCDataFragment *EF) {
43 flushPendingLabels(DF, DF->getContents().size());
44
45 for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) {
46 EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() +
47 DF->getContents().size());
48 DF->getFixups().push_back(EF->getFixups()[i]);
49 }
50 DF->setHasInstructions(true);
51 DF->getContents().append(EF->getContents().begin(), EF->getContents().end());
52 }
53
54 void MCWasmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
55 // Let the target do whatever target specific stuff it needs to do.
56 getAssembler().getBackend().handleAssemblerFlag(Flag);
57
58 // Do any generic stuff we need to do.
59 llvm_unreachable("invalid assembler flag!");
60 }
61
62 void MCWasmStreamer::ChangeSection(MCSection *Section,
63 const MCExpr *Subsection) {
64 MCAssembler &Asm = getAssembler();
65 auto *SectionWasm = static_cast(Section);
66 const MCSymbol *Grp = SectionWasm->getGroup();
67 if (Grp)
68 Asm.registerSymbol(*Grp);
69
70 this->MCObjectStreamer::ChangeSection(Section, Subsection);
71 }
72
73 void MCWasmStreamer::EmitWeakReference(MCSymbol *Alias,
74 const MCSymbol *Symbol) {
75 getAssembler().registerSymbol(*Symbol);
76 const MCExpr *Value = MCSymbolRefExpr::create(
77 Symbol, MCSymbolRefExpr::VK_WEAKREF, getContext());
78 Alias->setVariableValue(Value);
79 }
80
81 bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
82 assert(Attribute != MCSA_IndirectSymbol && "indirect symbols not supported");
83
84 auto *Symbol = cast(S);
85
86 // Adding a symbol attribute always introduces the symbol, note that an
87 // important side effect of calling registerSymbol here is to register
88 // the symbol with the assembler.
89 getAssembler().registerSymbol(*Symbol);
90
91 // TODO: Set the symbol binding, type, etc.
92
93 return true;
94 }
95
96 void MCWasmStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
97 unsigned ByteAlignment) {
98 llvm_unreachable("Common symbols are not yet implemented for Wasm");
99 }
100
101 void MCWasmStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
102 unsigned ByteAlignment) {
103 llvm_unreachable("Local common symbols are not yet implemented for Wasm");
104 }
105
106 void MCWasmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
107 SMLoc Loc) {
108 MCObjectStreamer::EmitValueImpl(Value, Size, Loc);
109 }
110
111 void MCWasmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
112 unsigned ValueSize,
113 unsigned MaxBytesToEmit) {
114 MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value, ValueSize,
115 MaxBytesToEmit);
116 }
117
118 // Add a symbol for the file name of this module. They start after the
119 // null symbol and don't count as normal symbol, i.e. a non-STT_FILE symbol
120 // with the same name may appear.
121 void MCWasmStreamer::EmitFileDirective(StringRef Filename) {
122 getAssembler().addFileName(Filename);
123 }
124
125 void MCWasmStreamer::EmitIdent(StringRef IdentString) {
126 llvm_unreachable("Ident sections not yet implemented for wasm");
127 }
128
129 void MCWasmStreamer::EmitInstToFragment(const MCInst &Inst,
130 const MCSubtargetInfo &STI) {
131 this->MCObjectStreamer::EmitInstToFragment(Inst, STI);
132 }
133
134 void MCWasmStreamer::EmitInstToData(const MCInst &Inst,
135 const MCSubtargetInfo &STI) {
136 MCAssembler &Assembler = getAssembler();
137 SmallVector Fixups;
138 SmallString<256> Code;
139 raw_svector_ostream VecOS(Code);
140 Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
141
142 // Append the encoded instruction to the current data fragment (or create a
143 // new such fragment if the current fragment is not a data fragment).
144 MCDataFragment *DF = getOrCreateDataFragment();
145
146 // Add the fixups and data.
147 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
148 Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
149 DF->getFixups().push_back(Fixups[i]);
150 }
151 DF->setHasInstructions(true);
152 DF->getContents().append(Code.begin(), Code.end());
153 }
154
155 void MCWasmStreamer::FinishImpl() {
156 EmitFrames(nullptr);
157
158 this->MCObjectStreamer::FinishImpl();
159 }
160
161 MCStreamer *llvm::createWasmStreamer(MCContext &Context, MCAsmBackend &MAB,
162 raw_pwrite_stream &OS, MCCodeEmitter *CE,
163 bool RelaxAll) {
164 MCWasmStreamer *S = new MCWasmStreamer(Context, MAB, OS, CE);
165 if (RelaxAll)
166 S->getAssembler().setRelaxAll(true);
167 return S;
168 }
169
170 void MCWasmStreamer::EmitThumbFunc(MCSymbol *Func) {
171 llvm_unreachable("Generic Wasm doesn't support this directive");
172 }
173
174 void MCWasmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
175 llvm_unreachable("Wasm doesn't support this directive");
176 }
177
178 void MCWasmStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
179 llvm_unreachable("Wasm doesn't support this directive");
180 }
181
182 void MCWasmStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
183 llvm_unreachable("Wasm doesn't support this directive");
184 }
185
186 void MCWasmStreamer::EmitCOFFSymbolType(int Type) {
187 llvm_unreachable("Wasm doesn't support this directive");
188 }
189
190 void MCWasmStreamer::EndCOFFSymbolDef() {
191 llvm_unreachable("Wasm doesn't support this directive");
192 }
193
194 void MCWasmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
195 uint64_t Size, unsigned ByteAlignment) {
196 llvm_unreachable("Wasm doesn't support this directive");
197 }
198
199 void MCWasmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
200 uint64_t Size, unsigned ByteAlignment) {
201 llvm_unreachable("Wasm doesn't support this directive");
202 }
0 //===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements Wasm object file writer information.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/MC/MCAsmBackend.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCAsmLayout.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFixupKindInfo.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/MC/MCSectionWasm.h"
27 #include "llvm/MC/MCSymbolWasm.h"
28 #include "llvm/MC/MCValue.h"
29 #include "llvm/MC/MCWasmObjectWriter.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/Endian.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/StringSaver.h"
34 #include
35
36 using namespace llvm;
37
38 #undef DEBUG_TYPE
39 #define DEBUG_TYPE "reloc-info"
40
41 namespace {
42 typedef DenseMap SectionIndexMapTy;
43
44 class WasmObjectWriter : public MCObjectWriter {
45 /// Helper struct for containing some precomputed information on symbols.
46 struct WasmSymbolData {
47 const MCSymbolWasm *Symbol;
48 StringRef Name;
49
50 // Support lexicographic sorting.
51 bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; }
52 };
53
54 /// The target specific Wasm writer instance.
55 std::unique_ptr TargetObjectWriter;
56
57 // TargetObjectWriter wrappers.
58 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
59 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
60 const MCFixup &Fixup, bool IsPCRel) const {
61 return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
62 }
63
64 public:
65 WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
66 : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {}
67
68 void reset() override {
69 MCObjectWriter::reset();
70 }
71
72 ~WasmObjectWriter() override;
73
74 void writeHeader(const MCAssembler &Asm);
75
76 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
77 const MCFragment *Fragment, const MCFixup &Fixup,
78 MCValue Target, bool &IsPCRel,
79 uint64_t &FixedValue) override;
80
81 void executePostLayoutBinding(MCAssembler &Asm,
82 const MCAsmLayout &Layout) override;
83
84 void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
85 };
86 } // end anonymous namespace
87
88 WasmObjectWriter::~WasmObjectWriter() {}
89
90 // Emit the Wasm header.
91 void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
92 // TODO: write the magic cookie and the version.
93 }
94
95 void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
96 const MCAsmLayout &Layout) {
97 }
98
99 void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
100 const MCAsmLayout &Layout,
101 const MCFragment *Fragment,
102 const MCFixup &Fixup, MCValue Target,
103 bool &IsPCRel, uint64_t &FixedValue) {
104 // TODO: Implement
105 }
106
107 void WasmObjectWriter::writeObject(MCAssembler &Asm,
108 const MCAsmLayout &Layout) {
109 // Write out the Wasm header.
110 writeHeader(Asm);
111
112 // TODO: Write the contents.
113 }
114
115 MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
116 raw_pwrite_stream &OS) {
117 return new WasmObjectWriter(MOTW, OS);
118 }
54835483 enum {
54845484 COFF = (1 << MCObjectFileInfo::IsCOFF),
54855485 ELF = (1 << MCObjectFileInfo::IsELF),
5486 MACHO = (1 << MCObjectFileInfo::IsMachO)
5486 MACHO = (1 << MCObjectFileInfo::IsMachO),
5487 WASM = (1 << MCObjectFileInfo::IsWasm),
54875488 };
54885489 static const struct PrefixEntry {
54895490 const char *Spelling;
55165517 break;
55175518 case MCObjectFileInfo::IsCOFF:
55185519 CurrentFormat = COFF;
5520 break;
5521 case MCObjectFileInfo::IsWasm:
5522 CurrentFormat = WASM;
55195523 break;
55205524 }
55215525
44 WebAssemblyMCCodeEmitter.cpp
55 WebAssemblyMCTargetDesc.cpp
66 WebAssemblyTargetStreamer.cpp
7 WebAssemblyWasmObjectWriter.cpp
78 )
1616 #include "llvm/MC/MCAssembler.h"
1717 #include "llvm/MC/MCDirectives.h"
1818 #include "llvm/MC/MCELFObjectWriter.h"
19 #include "llvm/MC/MCWasmObjectWriter.h"
1920 #include "llvm/MC/MCExpr.h"
2021 #include "llvm/MC/MCFixupKindInfo.h"
2122 #include "llvm/MC/MCObjectWriter.h"
2627 using namespace llvm;
2728
2829 namespace {
30 class WebAssemblyAsmBackendELF final : public MCAsmBackend {
31 bool Is64Bit;
32
33 public:
34 explicit WebAssemblyAsmBackendELF(bool Is64Bit)
35 : MCAsmBackend(), Is64Bit(Is64Bit) {}
36 ~WebAssemblyAsmBackendELF() override {}
37
38 void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
39 uint64_t Value, bool IsPCRel) const override;
40
41 MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
42
43 // No instruction requires relaxation
44 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
45 const MCRelaxableFragment *DF,
46 const MCAsmLayout &Layout) const override {
47 return false;
48 }
49
50 unsigned getNumFixupKinds() const override {
51 // We currently just use the generic fixups in MCFixup.h and don't have any
52 // target-specific fixups.
53 return 0;
54 }
55
56 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
57
58 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
59 MCInst &Res) const override {}
60
61 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
62 };
63
2964 class WebAssemblyAsmBackend final : public MCAsmBackend {
3065 bool Is64Bit;
3166
6095 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
6196 };
6297
98 bool WebAssemblyAsmBackendELF::writeNopData(uint64_t Count,
99 MCObjectWriter *OW) const {
100 for (uint64_t i = 0; i < Count; ++i)
101 OW->write8(WebAssembly::Nop);
102
103 return true;
104 }
105
106 void WebAssemblyAsmBackendELF::applyFixup(const MCFixup &Fixup, char *Data,
107 unsigned DataSize, uint64_t Value,
108 bool IsPCRel) const {
109 const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind());
110 assert(Info.Flags == 0 && "WebAssembly does not use MCFixupKindInfo flags");
111
112 unsigned NumBytes = alignTo(Info.TargetSize, 8) / 8;
113 if (Value == 0)
114 return; // Doesn't change encoding.
115
116 // Shift the value into position.
117 Value <<= Info.TargetOffset;
118
119 unsigned Offset = Fixup.getOffset();
120 assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
121
122 // For each byte of the fragment that the fixup touches, mask in the
123 // bits from the fixup value.
124 for (unsigned i = 0; i != NumBytes; ++i)
125 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
126 }
127
128 MCObjectWriter *
129 WebAssemblyAsmBackendELF::createObjectWriter(raw_pwrite_stream &OS) const {
130 return createWebAssemblyELFObjectWriter(OS, Is64Bit, 0);
131 }
132
63133 bool WebAssemblyAsmBackend::writeNopData(uint64_t Count,
64134 MCObjectWriter *OW) const {
65135 if (Count == 0)
77147 const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind());
78148 assert(Info.Flags == 0 && "WebAssembly does not use MCFixupKindInfo flags");
79149
80 unsigned NumBytes = (Info.TargetSize + 7) / 8;
150 unsigned NumBytes = alignTo(Info.TargetSize, 8) / 8;
81151 if (Value == 0)
82152 return; // Doesn't change encoding.
83153
95165
96166 MCObjectWriter *
97167 WebAssemblyAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
98 return createWebAssemblyELFObjectWriter(OS, Is64Bit, 0);
168 return createWebAssemblyWasmObjectWriter(OS, Is64Bit);
99169 }
100170 } // end anonymous namespace
101171
102172 MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) {
173 if (TT.isOSBinFormatELF())
174 return new WebAssemblyAsmBackendELF(TT.isArch64Bit());
103175 return new WebAssemblyAsmBackend(TT.isArch64Bit());
104176 }
1717 using namespace llvm;
1818
1919 #define DEBUG_TYPE "wasm-mc-asm-info"
20
21 WebAssemblyMCAsmInfoELF::~WebAssemblyMCAsmInfoELF() {}
22
23 WebAssemblyMCAsmInfoELF::WebAssemblyMCAsmInfoELF(const Triple &T) {
24 PointerSize = CalleeSaveStackSlotSize = T.isArch64Bit() ? 8 : 4;
25
26 // TODO: What should MaxInstLength be?
27
28 UseDataRegionDirectives = true;
29
30 // Use .skip instead of .zero because .zero is confusing when used with two
31 // arguments (it doesn't actually zero things out).
32 ZeroDirective = "\t.skip\t";
33
34 Data8bitsDirective = "\t.int8\t";
35 Data16bitsDirective = "\t.int16\t";
36 Data32bitsDirective = "\t.int32\t";
37 Data64bitsDirective = "\t.int64\t";
38
39 AlignmentIsInBytes = false;
40 COMMDirectiveAlignmentIsInBytes = false;
41 LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
42
43 SupportsDebugInformation = true;
44
45 // For now, WebAssembly does not support exceptions.
46 ExceptionsType = ExceptionHandling::None;
47
48 // TODO: UseIntegratedAssembler?
49
50 // WebAssembly's stack is never executable.
51 UsesNonexecutableStackSection = false;
52 }
2053
2154 WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() {}
2255
4679 ExceptionsType = ExceptionHandling::None;
4780
4881 // TODO: UseIntegratedAssembler?
49
50 // WebAssembly's stack is never executable.
51 UsesNonexecutableStackSection = false;
5282 }
1515 #define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H
1616
1717 #include "llvm/MC/MCAsmInfoELF.h"
18 #include "llvm/MC/MCAsmInfoWasm.h"
1819
1920 namespace llvm {
2021
2122 class Triple;
2223
23 class WebAssemblyMCAsmInfo final : public MCAsmInfoELF {
24 class WebAssemblyMCAsmInfoELF final : public MCAsmInfoELF {
25 public:
26 explicit WebAssemblyMCAsmInfoELF(const Triple &T);
27 ~WebAssemblyMCAsmInfoELF() override;
28 };
29
30 class WebAssemblyMCAsmInfo final : public MCAsmInfoWasm {
2431 public:
2532 explicit WebAssemblyMCAsmInfo(const Triple &T);
2633 ~WebAssemblyMCAsmInfo() override;
3535
3636 static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
3737 const Triple &TT) {
38 if (TT.isOSBinFormatELF())
39 return new WebAssemblyMCAsmInfoELF(TT);
3840 return new WebAssemblyMCAsmInfo(TT);
3941 }
4042
8789 }
8890
8991 static MCTargetStreamer *
90 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo & /*STI*/) {
91 return new WebAssemblyTargetELFStreamer(S);
92 createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
93 const Triple &TT = STI.getTargetTriple();
94 if (TT.isOSBinFormatELF())
95 return new WebAssemblyTargetELFStreamer(S);
96
97 return new WebAssemblyTargetWasmStreamer(S);
9298 }
9399
94100 static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
4040
4141 MCObjectWriter *createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
4242 bool Is64Bit, uint8_t OSABI);
43
44 MCObjectWriter *createWebAssemblyWasmObjectWriter(raw_pwrite_stream &OS,
45 bool Is64Bit);
4346
4447 namespace WebAssembly {
4548 enum OperandType {
1717 #include "WebAssemblyMCTargetDesc.h"
1818 #include "llvm/MC/MCContext.h"
1919 #include "llvm/MC/MCSectionELF.h"
20 #include "llvm/MC/MCSectionWasm.h"
2021 #include "llvm/MC/MCSubtargetInfo.h"
2122 #include "llvm/MC/MCSymbolELF.h"
22 #include "llvm/Support/ELF.h"
23 #include "llvm/MC/MCSymbolWasm.h"
2324 #include "llvm/Support/ErrorHandling.h"
2425 #include "llvm/Support/FormattedStream.h"
2526 using namespace llvm;
3233 : WebAssemblyTargetStreamer(S), OS(OS) {}
3334
3435 WebAssemblyTargetELFStreamer::WebAssemblyTargetELFStreamer(MCStreamer &S)
36 : WebAssemblyTargetStreamer(S) {}
37
38 WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
3539 : WebAssemblyTargetStreamer(S) {}
3640
3741 static void PrintTypes(formatted_raw_ostream &OS, ArrayRef Types) {
116120 }
117121
118122 void WebAssemblyTargetELFStreamer::emitGlobalImport(StringRef name) {
119 }
123 }
124
125 void WebAssemblyTargetWasmStreamer::emitParam(ArrayRef Types) {
126 // Nothing to emit; params are declared as part of the function signature.
127 }
128
129 void WebAssemblyTargetWasmStreamer::emitResult(ArrayRef Types) {
130 // Nothing to emit; results are declared as part of the function signature.
131 }
132
133 void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef Types) {
134 Streamer.EmitULEB128IntValue(Types.size());
135 for (MVT Type : Types)
136 Streamer.EmitIntValue(int64_t(WebAssembly::toValType(Type)), 1);
137 }
138
139 void WebAssemblyTargetWasmStreamer::emitEndFunc() {
140 Streamer.EmitIntValue(WebAssembly::End, 1);
141 }
142
143 void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
144 llvm_unreachable(".indidx encoding not yet implemented");
145 }
146
147 void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
148 StringRef name, SmallVectorImpl &Params, SmallVectorImpl &Results) {
149 // Nothing to emit here. TODO: Re-design how linking works and re-evaluate
150 // whether it's necessary for .o files to declare indirect function types.
151 }
152
153 void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
154 }
2121 namespace llvm {
2222
2323 class MCELFStreamer;
24 class MCWasmStreamer;
2425
2526 /// WebAssembly-specific streamer interface, to implement support
2627 /// WebAssembly-specific assembly directives.
8283 void emitGlobalImport(StringRef name) override;
8384 };
8485
86 /// This part is for Wasm object output
87 class WebAssemblyTargetWasmStreamer final : public WebAssemblyTargetStreamer {
88 public:
89 explicit WebAssemblyTargetWasmStreamer(MCStreamer &S);
90
91 void emitParam(ArrayRef Types) override;
92 void emitResult(ArrayRef Types) override;
93 void emitLocal(ArrayRef Types) override;
94 void emitEndFunc() override;
95 void emitIndirectFunctionType(StringRef name,
96 SmallVectorImpl &Params,
97 SmallVectorImpl &Results) override;
98 void emitIndIdx(const MCExpr *Value) override;
99 void emitGlobalImport(StringRef name) override;
100 };
101
85102 } // end namespace llvm
86103
87104 #endif
0 //===-- WebAssemblyWasmObjectWriter.cpp - WebAssembly Wasm Writer ---------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief This file handles Wasm-specific object emission, converting LLVM's
11 /// internal fixups into the appropriate relocations.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16 #include "llvm/MC/MCFixup.h"
17 #include "llvm/MC/MCWasmObjectWriter.h"
18 #include "llvm/Support/ErrorHandling.h"
19 using namespace llvm;
20
21 namespace {
22 class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter {
23 public:
24 explicit WebAssemblyWasmObjectWriter(bool Is64Bit);
25
26 private:
27 unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
28 const MCFixup &Fixup, bool IsPCRel) const override;
29 };
30 } // end anonymous namespace
31
32 WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit)
33 : MCWasmObjectTargetWriter(Is64Bit) {}
34
35 unsigned WebAssemblyWasmObjectWriter::getRelocType(MCContext &Ctx,
36 const MCValue &Target,
37 const MCFixup &Fixup,
38 bool IsPCRel) const {
39 llvm_unreachable("Relocations not yet implemented");
40 return 0;
41 }
42
43 MCObjectWriter *llvm::createWebAssemblyWasmObjectWriter(raw_pwrite_stream &OS,
44 bool Is64Bit) {
45 MCWasmObjectTargetWriter *MOTW = new WebAssemblyWasmObjectWriter(Is64Bit);
46 return createWasmObjectWriter(MOTW, OS);
47 }
7373 : "e-m:e-p:32:32-i64:64-n32:64-S128",
7474 TT, CPU, FS, Options, getEffectiveRelocModel(RM),
7575 CM, OL),
76 TLOF(make_unique()) {
76 TLOF(TT.isOSBinFormatELF() ?
77 static_cast(
78 new WebAssemblyTargetObjectFileELF()) :
79 static_cast(
80 new WebAssemblyTargetObjectFile())) {
7781 // WebAssembly type-checks instructions, but a noreturn function with a return
7882 // type that doesn't match the context will cause a check failure. So we lower
7983 // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
1616 #include "WebAssemblyTargetMachine.h"
1717 using namespace llvm;
1818
19 void WebAssemblyTargetObjectFile::Initialize(MCContext &Ctx,
20 const TargetMachine &TM) {
19 void WebAssemblyTargetObjectFileELF::Initialize(MCContext &Ctx,
20 const TargetMachine &TM) {
2121 TargetLoweringObjectFileELF::Initialize(Ctx, TM);
2222 InitializeELF(TM.Options.UseInitArray);
2323 }
24
25 void WebAssemblyTargetObjectFile::Initialize(MCContext &Ctx,
26 const TargetMachine &TM) {
27 TargetLoweringObjectFileWasm::Initialize(Ctx, TM);
28 InitializeWasm();
29 }
1919
2020 namespace llvm {
2121
22 class WebAssemblyTargetObjectFile final : public TargetLoweringObjectFileELF {
22 class WebAssemblyTargetObjectFileELF final
23 : public TargetLoweringObjectFileELF {
24 public:
25 void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
26 };
27
28 class WebAssemblyTargetObjectFile final : public TargetLoweringObjectFileWasm {
2329 public:
2430 void Initialize(MCContext &Ctx, const TargetMachine &TM) override;
2531 };