Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 53ff96a

Browse files
author
Dan Gohman
committed
[WebAssembly] Basic support for Wasm object file encoding.
With the "wasm32-unknown-unknown-wasm" triple, this allows writing out simple wasm object files, and is another step in a larger series toward migrating from ELF to general wasm object support. Note that this code and the binary format itself is still experimental. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296190 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 03791bd commit 53ff96a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2074
-389
lines changed

include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile {
172172
};
173173

174174
class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
175+
mutable unsigned NextUniqueID = 0;
176+
175177
public:
176178
TargetLoweringObjectFileWasm() {}
177179

include/llvm/MC/MCExpr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ class MCSymbolRefExpr : public MCExpr {
270270
VK_Hexagon_IE_GOT,
271271

272272
VK_WebAssembly_FUNCTION, // Function table index, rather than virtual addr
273+
VK_WebAssembly_TYPEINDEX,// Type table index
273274

274275
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
275276
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi

include/llvm/MC/MCSectionWasm.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,15 @@ class MCSectionWasm final : public MCSection {
4040

4141
const MCSymbolWasm *Group;
4242

43+
// The offset of the MC function section in the wasm code section.
44+
uint64_t SectionOffset;
45+
4346
private:
4447
friend class MCContext;
4548
MCSectionWasm(StringRef Section, unsigned type, unsigned flags, SectionKind K,
4649
const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin)
4750
: MCSection(SV_Wasm, K, Begin), SectionName(Section), Type(type),
48-
Flags(flags), UniqueID(UniqueID), Group(group) {
51+
Flags(flags), UniqueID(UniqueID), Group(group), SectionOffset(0) {
4952
}
5053

5154
void setSectionName(StringRef Name) { SectionName = Name; }
@@ -72,6 +75,9 @@ class MCSectionWasm final : public MCSection {
7275
bool isUnique() const { return UniqueID != ~0U; }
7376
unsigned getUniqueID() const { return UniqueID; }
7477

78+
uint64_t getSectionOffset() const { return SectionOffset; }
79+
void setSectionOffset(uint64_t Offset) { SectionOffset = Offset; }
80+
7581
static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; }
7682
};
7783

include/llvm/MC/MCSymbolWasm.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,41 @@
1313

1414
namespace llvm {
1515
class MCSymbolWasm : public MCSymbol {
16+
private:
17+
bool IsFunction = false;
18+
std::string ModuleName;
19+
SmallVector<unsigned, 1> Returns;
20+
SmallVector<unsigned, 4> Params;
21+
22+
/// An expression describing how to calculate the size of a symbol. If a
23+
/// symbol has no size this field will be NULL.
24+
const MCExpr *SymbolSize = nullptr;
25+
1626
public:
27+
// Use a module name of "env" for now, for compatibility with existing tools.
28+
// This is temporary, and may change, as the ABI is not yet stable.
1729
MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
18-
: MCSymbol(SymbolKindWasm, Name, isTemporary) {}
19-
30+
: MCSymbol(SymbolKindWasm, Name, isTemporary),
31+
ModuleName("env") {}
2032
static bool classof(const MCSymbol *S) { return S->isWasm(); }
33+
34+
const MCExpr *getSize() const { return SymbolSize; }
35+
void setSize(const MCExpr *SS) { SymbolSize = SS; }
36+
37+
bool isFunction() const { return IsFunction; }
38+
void setIsFunction(bool isFunc) { IsFunction = isFunc; }
39+
40+
const StringRef getModuleName() const { return ModuleName; }
41+
42+
const SmallVector<unsigned, 1> &getReturns() const { return Returns; }
43+
void setReturns(SmallVectorImpl<unsigned> &&Rets) {
44+
Returns = std::move(Rets);
45+
}
46+
47+
const SmallVector<unsigned, 4> &getParams() const { return Params; }
48+
void setParams(SmallVectorImpl<unsigned> &&Pars) {
49+
Params = std::move(Pars);
50+
}
2151
};
2252
}
2353

include/llvm/MC/MCWasmObjectWriter.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,29 @@ class MCContext;
2222
class MCFixup;
2323
class MCFragment;
2424
class MCObjectWriter;
25+
class MCSectionWasm;
2526
class MCSymbol;
2627
class MCSymbolWasm;
2728
class MCValue;
2829
class raw_pwrite_stream;
2930

31+
// Information about a single relocation.
3032
struct WasmRelocationEntry {
3133
uint64_t Offset; // Where is the relocation.
3234
const MCSymbolWasm *Symbol; // The symbol to relocate with.
35+
uint64_t Addend; // A value to add to the symbol.
3336
unsigned Type; // The type of the relocation.
37+
MCSectionWasm *FixupSection;// The section the relocation is targeting.
3438

3539
WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
36-
unsigned Type)
37-
: Offset(Offset), Symbol(Symbol), Type(Type) {}
40+
uint64_t Addend, unsigned Type,
41+
MCSectionWasm *FixupSection)
42+
: Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type),
43+
FixupSection(FixupSection) {}
3844

3945
void print(raw_ostream &Out) const {
40-
Out << "Off=" << Offset << ", Sym=" << Symbol << ", Type=" << Type;
46+
Out << "Off=" << Offset << ", Sym=" << Symbol << ", Addend=" << Addend
47+
<< ", Type=" << Type << ", FixupSection=" << FixupSection;
4148
}
4249
void dump() const { print(errs()); }
4350
};

include/llvm/MC/MCWasmStreamer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class MCWasmStreamer : public MCObjectStreamer {
5454
void EmitCOFFSymbolType(int Type) override;
5555
void EndCOFFSymbolDef() override;
5656

57+
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
58+
5759
void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
5860
unsigned ByteAlignment) override;
5961

lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,18 +1162,73 @@ void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
11621162
// Wasm
11631163
//===----------------------------------------------------------------------===//
11641164

1165+
static const Comdat *getWasmComdat(const GlobalValue *GV) {
1166+
const Comdat *C = GV->getComdat();
1167+
if (!C)
1168+
return nullptr;
1169+
1170+
if (C->getSelectionKind() != Comdat::Any)
1171+
report_fatal_error("Wasm COMDATs only support SelectionKind::Any, '" +
1172+
C->getName() + "' cannot be lowered.");
1173+
1174+
return C;
1175+
}
1176+
11651177
MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
11661178
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
11671179
llvm_unreachable("getExplicitSectionGlobal not yet implemented");
11681180
return nullptr;
11691181
}
11701182

1183+
static MCSectionWasm *
1184+
selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO,
1185+
SectionKind Kind, Mangler &Mang,
1186+
const TargetMachine &TM, bool EmitUniqueSection,
1187+
unsigned Flags, unsigned *NextUniqueID) {
1188+
StringRef Group = "";
1189+
if (getWasmComdat(GO))
1190+
llvm_unreachable("comdat not yet supported for wasm");
1191+
1192+
bool UniqueSectionNames = TM.getUniqueSectionNames();
1193+
SmallString<128> Name = getSectionPrefixForGlobal(Kind);
1194+
1195+
if (const auto *F = dyn_cast<Function>(GO)) {
1196+
const auto &OptionalPrefix = F->getSectionPrefix();
1197+
if (OptionalPrefix)
1198+
Name += *OptionalPrefix;
1199+
}
1200+
1201+
if (EmitUniqueSection && UniqueSectionNames) {
1202+
Name.push_back('.');
1203+
TM.getNameWithPrefix(Name, GO, Mang, true);
1204+
}
1205+
unsigned UniqueID = MCContext::GenericSectionID;
1206+
if (EmitUniqueSection && !UniqueSectionNames) {
1207+
UniqueID = *NextUniqueID;
1208+
(*NextUniqueID)++;
1209+
}
1210+
return Ctx.getWasmSection(Name, /*Type=*/0, Flags,
1211+
Group, UniqueID);
1212+
}
1213+
11711214
MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(
11721215
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
1216+
1217+
if (Kind.isCommon())
1218+
report_fatal_error("mergable sections not supported yet on wasm");
1219+
1220+
// If we have -ffunction-section or -fdata-section then we should emit the
1221+
// global value to a uniqued section specifically for it.
1222+
bool EmitUniqueSection = false;
11731223
if (Kind.isText())
1174-
return TextSection;
1175-
assert(!Kind.isMetadata() && "metadata sections not yet implemented");
1176-
return DataSection;
1224+
EmitUniqueSection = TM.getFunctionSections();
1225+
else
1226+
EmitUniqueSection = TM.getDataSections();
1227+
EmitUniqueSection |= GO->hasComdat();
1228+
1229+
return selectWasmSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
1230+
EmitUniqueSection, /*Flags=*/0,
1231+
&NextUniqueID);
11771232
}
11781233

11791234
bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection(

lib/MC/MCExpr.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
286286
case VK_Hexagon_IE: return "IE";
287287
case VK_Hexagon_IE_GOT: return "IEGOT";
288288
case VK_WebAssembly_FUNCTION: return "FUNCTION";
289+
case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX";
289290
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
290291
case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
291292
case VK_AMDGPU_REL32_LO: return "rel32@lo";

lib/MC/MCObjectFileInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,8 +801,8 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
801801

802802
void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
803803
// TODO: Set the section types and flags.
804-
TextSection = Ctx->getWasmSection("", 0, 0);
805-
DataSection = Ctx->getWasmSection("", 0, 0);
804+
TextSection = Ctx->getWasmSection(".text", 0, 0);
805+
DataSection = Ctx->getWasmSection(".data", 0, 0);
806806

807807
// TODO: Set the section types and flags.
808808
DwarfLineSection = Ctx->getWasmSection(".debug_line", 0, 0);

lib/MC/MCWasmStreamer.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,29 @@ bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
8989
// the symbol with the assembler.
9090
getAssembler().registerSymbol(*Symbol);
9191

92-
// TODO: Set the symbol binding, type, etc.
92+
switch (Attribute) {
93+
case MCSA_LazyReference:
94+
case MCSA_Reference:
95+
case MCSA_SymbolResolver:
96+
case MCSA_PrivateExtern:
97+
case MCSA_WeakDefinition:
98+
case MCSA_WeakDefAutoPrivate:
99+
case MCSA_Invalid:
100+
case MCSA_IndirectSymbol:
101+
return false;
102+
case MCSA_Global:
103+
Symbol->setExternal(true);
104+
break;
105+
case MCSA_ELF_TypeFunction:
106+
Symbol->setIsFunction(true);
107+
break;
108+
case MCSA_ELF_TypeObject:
109+
Symbol->setIsFunction(false);
110+
break;
111+
default:
112+
// unrecognized directive
113+
return false;
114+
}
93115

94116
return true;
95117
}
@@ -99,6 +121,10 @@ void MCWasmStreamer::EmitCommonSymbol(MCSymbol *S, uint64_t Size,
99121
llvm_unreachable("Common symbols are not yet implemented for Wasm");
100122
}
101123

124+
void MCWasmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
125+
cast<MCSymbolWasm>(Symbol)->setSize(Value);
126+
}
127+
102128
void MCWasmStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
103129
unsigned ByteAlignment) {
104130
llvm_unreachable("Local common symbols are not yet implemented for Wasm");
@@ -124,7 +150,17 @@ void MCWasmStreamer::EmitFileDirective(StringRef Filename) {
124150
}
125151

126152
void MCWasmStreamer::EmitIdent(StringRef IdentString) {
127-
llvm_unreachable("Ident sections not yet implemented for wasm");
153+
MCSection *Comment = getAssembler().getContext().getWasmSection(
154+
".comment", 0, 0);
155+
PushSection();
156+
SwitchSection(Comment);
157+
if (!SeenIdent) {
158+
EmitIntValue(0, 1);
159+
SeenIdent = true;
160+
}
161+
EmitBytes(IdentString);
162+
EmitIntValue(0, 1);
163+
PopSection();
128164
}
129165

130166
void MCWasmStreamer::EmitInstToFragment(const MCInst &Inst,

0 commit comments

Comments
 (0)