summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCWasmStreamer.cpp4
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp292
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp304
-rw-r--r--llvm/lib/ObjectYAML/WasmYAML.cpp29
-rw-r--r--llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp2
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp17
6 files changed, 371 insertions, 277 deletions
diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp
index 611e29c7214..2c77624b685 100644
--- a/llvm/lib/MC/MCWasmStreamer.cpp
+++ b/llvm/lib/MC/MCWasmStreamer.cpp
@@ -113,11 +113,11 @@ bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
break;
case MCSA_ELF_TypeFunction:
- Symbol->setIsFunction(true);
+ Symbol->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
break;
case MCSA_ELF_TypeObject:
- Symbol->setIsFunction(false);
+ Symbol->setType(wasm::WASM_SYMBOL_TYPE_DATA);
break;
default:
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index c47c014467a..1f1132aae49 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -190,13 +190,18 @@ class WasmObjectWriter : public MCObjectWriter {
// Maps function symbols to the table element index space. Used
// for TABLE_INDEX relocation types (i.e. address taken functions).
DenseMap<const MCSymbolWasm *, uint32_t> TableIndices;
- // Maps function/global symbols to the function/global index space.
+ // Maps function/global symbols to the (shared) Symbol index space.
DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
+ // Maps function/global symbols to the function/global Wasm index space.
+ DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
+ // Maps data symbols to the Wasm segment and offset/size with the segment.
+ DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;
DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
FunctionTypeIndices;
SmallVector<WasmFunctionType, 4> FunctionTypes;
SmallVector<WasmGlobal, 4> Globals;
+ SmallVector<WasmDataSegment, 4> DataSegments;
unsigned NumFunctionImports = 0;
unsigned NumGlobalImports = 0;
@@ -224,10 +229,13 @@ private:
DataRelocations.clear();
TypeIndices.clear();
SymbolIndices.clear();
+ WasmIndices.clear();
TableIndices.clear();
+ DataLocations.clear();
FunctionTypeIndices.clear();
FunctionTypes.clear();
Globals.clear();
+ DataSegments.clear();
MCObjectWriter::reset();
NumFunctionImports = 0;
NumGlobalImports = 0;
@@ -262,14 +270,13 @@ private:
void writeElemSection(ArrayRef<uint32_t> TableElems);
void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
ArrayRef<WasmFunction> Functions);
- void writeDataSection(ArrayRef<WasmDataSegment> Segments);
+ void writeDataSection();
void writeCodeRelocSection();
void writeDataRelocSection();
void writeLinkingMetaDataSection(
- ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
- ArrayRef<std::pair<StringRef, uint32_t>> SymbolFlags,
+ uint32_t DataSize, ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
- const std::map<StringRef, std::vector<WasmComdatEntry>>& Comdats);
+ const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats);
uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry);
void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
@@ -494,11 +501,16 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
assert(Sym->isFunction());
return TableIndices[Sym];
}
- case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
- case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
- // Provisional value is function/type/global index itself
+ // Provisional value is same as the index
return getRelocationIndexValue(RelEntry);
+ case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+ case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
+ // Provisional value is function/global Wasm index
+ if (!WasmIndices.count(RelEntry.Symbol))
+ report_fatal_error("symbol not found in wasm index space: " +
+ RelEntry.Symbol->getName());
+ return WasmIndices[RelEntry.Symbol];
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
@@ -507,16 +519,10 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
// For undefined symbols, use zero
if (!Sym->isDefined())
return 0;
-
- if (!SymbolIndices.count(Sym))
- report_fatal_error("symbol not found in function/global index space: " +
- Sym->getName());
- uint32_t GlobalIndex = SymbolIndices[Sym];
- const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports];
- uint64_t Address = Global.InitialValue + RelEntry.Addend;
-
+ const wasm::WasmDataReference &Ref = DataLocations[Sym];
+ const WasmDataSegment &Segment = DataSegments[Ref.Segment];
// Ignore overflow. LLVM allows address arithmetic to silently wrap.
- return Address;
+ return Segment.Offset + Ref.Offset + RelEntry.Addend;
}
default:
llvm_unreachable("invalid relocation type");
@@ -529,7 +535,6 @@ static void addData(SmallVectorImpl<char> &DataBytes,
DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
- size_t LastFragmentSize = 0;
for (const MCFragment &Frag : DataSection) {
if (Frag.hasInstructions())
report_fatal_error("only data supported in data sections");
@@ -554,16 +559,9 @@ static void addData(SmallVectorImpl<char> &DataBytes,
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
- LastFragmentSize = Contents.size();
}
}
- // Don't allow empty segments, or segments that end with zero-sized
- // fragment, otherwise the linker cannot map symbols to a unique
- // data segment. This can be triggered by zero-sized structs
- // See: test/MC/WebAssembly/bss.ll
- if (LastFragmentSize == 0)
- DataBytes.resize(DataBytes.size() + 1);
DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n");
}
@@ -577,7 +575,7 @@ WasmObjectWriter::getRelocationIndexValue(const WasmRelocationEntry &RelEntry) {
}
if (!SymbolIndices.count(RelEntry.Symbol))
- report_fatal_error("symbol not found in function/global index space: " +
+ report_fatal_error("symbol not found in symbol index space: " +
RelEntry.Symbol->getName());
return SymbolIndices[RelEntry.Symbol];
}
@@ -802,16 +800,16 @@ void WasmObjectWriter::writeCodeSection(const MCAssembler &Asm,
endSection(Section);
}
-void WasmObjectWriter::writeDataSection(ArrayRef<WasmDataSegment> Segments) {
- if (Segments.empty())
+void WasmObjectWriter::writeDataSection() {
+ if (DataSegments.empty())
return;
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_DATA);
- encodeULEB128(Segments.size(), getStream()); // count
+ encodeULEB128(DataSegments.size(), getStream()); // count
- for (const WasmDataSegment & Segment : Segments) {
+ for (const WasmDataSegment &Segment : DataSegments) {
encodeULEB128(0, getStream()); // memory index
write8(wasm::WASM_OPCODE_I32_CONST);
encodeSLEB128(Segment.Offset, getStream()); // offset
@@ -864,20 +862,37 @@ void WasmObjectWriter::writeDataRelocSection() {
}
void WasmObjectWriter::writeLinkingMetaDataSection(
- ArrayRef<WasmDataSegment> Segments, uint32_t DataSize,
- ArrayRef<std::pair<StringRef, uint32_t>> SymbolFlags,
+ uint32_t DataSize, ArrayRef<wasm::WasmSymbolInfo> SymbolInfos,
ArrayRef<std::pair<uint16_t, uint32_t>> InitFuncs,
- const std::map<StringRef, std::vector<WasmComdatEntry>>& Comdats) {
+ const std::map<StringRef, std::vector<WasmComdatEntry>> &Comdats) {
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
SectionBookkeeping SubSection;
- if (SymbolFlags.size() != 0) {
- startSection(SubSection, wasm::WASM_SYMBOL_INFO);
- encodeULEB128(SymbolFlags.size(), getStream());
- for (auto Pair: SymbolFlags) {
- writeString(Pair.first);
- encodeULEB128(Pair.second, getStream());
+ if (SymbolInfos.size() != 0) {
+ startSection(SubSection, wasm::WASM_SYMBOL_TABLE);
+ encodeULEB128(SymbolInfos.size(), getStream());
+ for (const wasm::WasmSymbolInfo &Sym : SymbolInfos) {
+ encodeULEB128(Sym.Kind, getStream());
+ encodeULEB128(Sym.Flags, getStream());
+ switch (Sym.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ encodeULEB128(Sym.ElementIndex, getStream());
+ if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ writeString(Sym.Name);
+ break;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ writeString(Sym.Name);
+ if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
+ encodeULEB128(Sym.DataRef.Segment, getStream());
+ encodeULEB128(Sym.DataRef.Offset, getStream());
+ encodeULEB128(Sym.DataRef.Size, getStream());
+ }
+ break;
+ default:
+ llvm_unreachable("unexpected kind");
+ }
}
endSection(SubSection);
}
@@ -888,10 +903,10 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
endSection(SubSection);
}
- if (Segments.size()) {
+ if (DataSegments.size()) {
startSection(SubSection, wasm::WASM_SEGMENT_INFO);
- encodeULEB128(Segments.size(), getStream());
- for (const WasmDataSegment &Segment : Segments) {
+ encodeULEB128(DataSegments.size(), getStream());
+ for (const WasmDataSegment &Segment : DataSegments) {
writeString(Segment.Name);
encodeULEB128(Segment.Alignment, getStream());
encodeULEB128(Segment.Flags, getStream());
@@ -956,19 +971,41 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
MCContext &Ctx = Asm.getContext();
- int32_t PtrType = is64Bit() ? wasm::WASM_TYPE_I64 : wasm::WASM_TYPE_I32;
// Collect information from the available symbols.
SmallVector<WasmFunction, 4> Functions;
SmallVector<uint32_t, 4> TableElems;
SmallVector<wasm::WasmImport, 4> Imports;
SmallVector<wasm::WasmExport, 4> Exports;
- SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags;
+ SmallVector<wasm::WasmSymbolInfo, 4> SymbolInfos;
SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
std::map<StringRef, std::vector<WasmComdatEntry>> Comdats;
- SmallVector<WasmDataSegment, 4> DataSegments;
+ unsigned NumSymbols = 0;
uint32_t DataSize = 0;
+ auto AddSymbol = [&](const MCSymbolWasm &WS) {
+ uint32_t Flags = 0;
+ if (WS.isWeak())
+ Flags |= wasm::WASM_SYMBOL_BINDING_WEAK;
+ if (WS.isHidden())
+ Flags |= wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
+ if (!WS.isExternal() && WS.isDefined())
+ Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
+ if (WS.isUndefined())
+ Flags |= wasm::WASM_SYMBOL_UNDEFINED;
+
+ wasm::WasmSymbolInfo Info;
+ Info.Name = WS.getName();
+ Info.Kind = WS.getType();
+ Info.Flags = Flags;
+ if (!WS.isData())
+ Info.ElementIndex = WasmIndices[&WS];
+ else if (WS.isDefined())
+ Info.DataRef = DataLocations[&WS];
+ SymbolInfos.emplace_back(Info);
+ SymbolIndices[&WS] = NumSymbols++;
+ };
+
// For now, always emit the memory import, since loads and stores are not
// valid without it. In the future, we could perhaps be more clever and omit
// it if there are no loads or stores.
@@ -1005,31 +1042,32 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
continue;
// If the symbol is not defined in this translation unit, import it.
- if ((!WS.isDefined() && !WS.isComdat()) ||
- WS.isVariable()) {
- wasm::WasmImport Import;
- Import.Module = WS.getModuleName();
- Import.Field = WS.getName();
-
+ if (!WS.isDefined() && !WS.isComdat()) {
if (WS.isFunction()) {
+ wasm::WasmImport Import;
+ Import.Module = WS.getModuleName();
+ Import.Field = WS.getName();
Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
Import.SigIndex = getFunctionType(WS);
- SymbolIndices[&WS] = NumFunctionImports;
- ++NumFunctionImports;
- } else {
+ Imports.push_back(Import);
+ WasmIndices[&WS] = NumFunctionImports++;
+ } else if (WS.isGlobal()) {
+ wasm::WasmImport Import;
+ Import.Module = WS.getModuleName();
+ Import.Field = WS.getName();
Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- Import.Global.Type = PtrType;
- // If this global is the stack pointer, make it mutable.
- if (WS.getName() == "__stack_pointer")
- Import.Global.Mutable = true;
- else
- Import.Global.Mutable = false;
-
- SymbolIndices[&WS] = NumGlobalImports;
- ++NumGlobalImports;
+ Import.Global = WS.getGlobalType();
+ Imports.push_back(Import);
+ WasmIndices[&WS] = NumGlobalImports++;
}
- Imports.push_back(Import);
+ // TODO(ncw) We shouldn't be adding the symbol to the symbol table here!
+ // Instead it should be done by removing the "if (WS.isDefined())" block
+ // in the big loop below (line ~1284). However - that would reorder all
+ // the symbols and thus require all the tests to be updated. I think it's
+ // better to make that change therefore in a future commit, to isolate
+ // each test update from the change that caused it.
+ AddSymbol(WS);
}
}
@@ -1053,7 +1091,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
Segment.Alignment = Section.getAlignment();
Segment.Flags = 0;
DataSize += Segment.Data.size();
- Section.setMemoryOffset(Segment.Offset);
+ Section.setSegmentIndex(SegmentIndex);
if (const MCSymbolWasm *C = Section.getGroup()) {
Comdats[C->getName()].emplace_back(
@@ -1078,18 +1116,13 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
<< " isHidden=" << WS.isHidden()
<< " isVariable=" << WS.isVariable() << "\n");
- if (WS.isWeak() || WS.isHidden()) {
- uint32_t Flags = (WS.isWeak() ? wasm::WASM_SYMBOL_BINDING_WEAK : 0) |
- (WS.isHidden() ? wasm::WASM_SYMBOL_VISIBILITY_HIDDEN : 0);
- SymbolFlags.emplace_back(WS.getName(), Flags);
- }
-
if (WS.isVariable())
continue;
-
- unsigned Index;
+ if (WS.isComdat() && !WS.isDefined())
+ continue;
if (WS.isFunction()) {
+ unsigned Index;
if (WS.isDefined()) {
if (WS.getOffset() != 0)
report_fatal_error(
@@ -1099,27 +1132,33 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
report_fatal_error(
"function symbols must have a size set with .size");
- // A definition. Take the next available index.
+ // A definition. Write out the function body.
Index = NumFunctionImports + Functions.size();
-
- // Prepare the function.
WasmFunction Func;
Func.Type = getFunctionType(WS);
Func.Sym = &WS;
- SymbolIndices[&WS] = Index;
+ WasmIndices[&WS] = Index;
Functions.push_back(Func);
+
+ auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
+ if (const MCSymbolWasm *C = Section.getGroup()) {
+ Comdats[C->getName()].emplace_back(
+ WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
+ }
} else {
// An import; the index was assigned above.
- Index = SymbolIndices.find(&WS)->second;
+ Index = WasmIndices.find(&WS)->second;
}
DEBUG(dbgs() << " -> function index: " << Index << "\n");
- } else {
+ } else if (WS.isData()) {
if (WS.isTemporary() && !WS.getSize())
continue;
- if (!WS.isDefined())
+ if (!WS.isDefined()) {
+ DEBUG(dbgs() << " -> segment index: -1");
continue;
+ }
if (!WS.getSize())
report_fatal_error("data symbols must have a size set with .size: " +
@@ -1129,43 +1168,32 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
report_fatal_error(".size expression must be evaluatable");
- // For each global, prepare a corresponding wasm global holding its
- // address. For externals these will also be named exports.
- Index = NumGlobalImports + Globals.size();
auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
assert(DataSection.isWasmData());
- WasmGlobal Global;
- Global.Type.Type = PtrType;
- Global.Type.Mutable = false;
- Global.InitialValue = DataSection.getMemoryOffset() + Layout.getSymbolOffset(WS);
- SymbolIndices[&WS] = Index;
- DEBUG(dbgs() << " -> global index: " << Index << "\n");
- Globals.push_back(Global);
- }
-
- // If the symbol is visible outside this translation unit, export it.
- if (WS.isDefined()) {
- wasm::WasmExport Export;
- Export.Name = WS.getName();
- Export.Index = Index;
- if (WS.isFunction())
- Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
- else
- Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- DEBUG(dbgs() << " -> export " << Exports.size() << "\n");
- Exports.push_back(Export);
-
- if (!WS.isExternal())
- SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
-
- if (WS.isFunction()) {
- auto &Section = static_cast<MCSectionWasm &>(WS.getSection());
- if (const MCSymbolWasm *C = Section.getGroup())
- Comdats[C->getName()].emplace_back(
- WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index});
+ // For each data symbol, export it in the symtab as a reference to the
+ // corresponding Wasm data segment.
+ wasm::WasmDataReference Ref = wasm::WasmDataReference{
+ DataSection.getSegmentIndex(),
+ static_cast<uint32_t>(Layout.getSymbolOffset(WS)),
+ static_cast<uint32_t>(Size)};
+ DataLocations[&WS] = Ref;
+ DEBUG(dbgs() << " -> segment index: " << Ref.Segment);
+ } else {
+ // A "true" Wasm global (currently just __stack_pointer)
+ unsigned WasmIndex;
+ if (WS.isDefined()) {
+ report_fatal_error("don't yet support defined globals");
+ } else {
+ // An import; the index was assigned above
+ WasmIndex = WasmIndices.find(&WS)->second;
}
+
+ DEBUG(dbgs() << " -> global index: " << WasmIndex << "\n");
}
+
+ if (WS.isDefined())
+ AddSymbol(WS);
}
// Handle weak aliases. We need to process these in a separate pass because
@@ -1181,22 +1209,23 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
const auto &WS = static_cast<const MCSymbolWasm &>(S);
const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS);
DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n");
- assert(SymbolIndices.count(ResolvedSym) > 0);
- uint32_t Index = SymbolIndices.find(ResolvedSym)->second;
- DEBUG(dbgs() << " -> index:" << Index << "\n");
- wasm::WasmExport Export;
- Export.Name = WS.getName();
- Export.Index = Index;
- if (WS.isFunction())
- Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
- else
- Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- DEBUG(dbgs() << " -> export " << Exports.size() << "\n");
- Exports.push_back(Export);
-
- if (!WS.isExternal())
- SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
+ if (WS.isFunction()) {
+ assert(WasmIndices.count(ResolvedSym) > 0);
+ uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second;
+ WasmIndices[&WS] = WasmIndex;
+ DEBUG(dbgs() << " -> index:" << WasmIndex << "\n");
+ } else if (WS.isData()) {
+ assert(DataLocations.count(ResolvedSym) > 0);
+ const wasm::WasmDataReference &Ref =
+ DataLocations.find(ResolvedSym)->second;
+ DataLocations[&WS] = Ref;
+ DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n");
+ } else {
+ report_fatal_error("don't yet support global aliases");
+ }
+
+ AddSymbol(WS);
}
{
@@ -1209,12 +1238,12 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
return;
assert(Rel.Symbol->isFunction());
const MCSymbolWasm &WS = *ResolveSymbol(*Rel.Symbol);
- uint32_t SymbolIndex = SymbolIndices.find(&WS)->second;
+ uint32_t FunctionIndex = WasmIndices.find(&WS)->second;
uint32_t TableIndex = TableElems.size() + kInitialTableOffset;
if (TableIndices.try_emplace(&WS, TableIndex).second) {
DEBUG(dbgs() << " -> adding " << WS.getName()
<< " to table: " << TableIndex << "\n");
- TableElems.push_back(SymbolIndex);
+ TableElems.push_back(FunctionIndex);
registerFunctionType(WS);
}
};
@@ -1287,11 +1316,10 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
writeExportSection(Exports);
writeElemSection(TableElems);
writeCodeSection(Asm, Layout, Functions);
- writeDataSection(DataSegments);
+ writeDataSection();
writeCodeRelocSection();
writeDataRelocSection();
- writeLinkingMetaDataSection(DataSegments, DataSize, SymbolFlags,
- InitFuncs, Comdats);
+ writeLinkingMetaDataSection(DataSize, SymbolInfos, InitFuncs, Comdats);
// TODO: Translate the .comment section to the output.
// TODO: Translate debug sections to the output.
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 82adc35076d..4483dae809d 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -317,69 +317,6 @@ Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) {
return Error::success();
}
-void WasmObjectFile::populateSymbolTable() {
- // Add imports to symbol table
- size_t GlobalIndex = 0;
- size_t FunctionIndex = 0;
- for (const wasm::WasmImport& Import : Imports) {
- switch (Import.Kind) {
- case wasm::WASM_EXTERNAL_GLOBAL:
- assert(Import.Global.Type == wasm::WASM_TYPE_I32);
- SymbolMap.try_emplace(Import.Field, Symbols.size());
- Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
- GlobalIndex++);
- DEBUG(dbgs() << "Adding import: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- break;
- case wasm::WASM_EXTERNAL_FUNCTION:
- SymbolMap.try_emplace(Import.Field, Symbols.size());
- Symbols.emplace_back(Import.Field,
- WasmSymbol::SymbolType::FUNCTION_IMPORT,
- FunctionIndex++, Import.SigIndex);
- DEBUG(dbgs() << "Adding import: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- break;
- default:
- break;
- }
- }
-
- // Add exports to symbol table
- for (const wasm::WasmExport& Export : Exports) {
- if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION ||
- Export.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
- WasmSymbol::SymbolType ExportType =
- Export.Kind == wasm::WASM_EXTERNAL_FUNCTION
- ? WasmSymbol::SymbolType::FUNCTION_EXPORT
- : WasmSymbol::SymbolType::GLOBAL_EXPORT;
- auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size());
- if (Pair.second) {
- Symbols.emplace_back(Export.Name, ExportType, Export.Index);
- DEBUG(dbgs() << "Adding export: " << Symbols.back()
- << " sym index:" << Symbols.size() << "\n");
- } else {
- uint32_t SymIndex = Pair.first->second;
- const WasmSymbol &OldSym = Symbols[SymIndex];
- WasmSymbol NewSym(Export.Name, ExportType, Export.Index);
- NewSym.setAltIndex(OldSym.ElementIndex);
- Symbols[SymIndex] = NewSym;
-
- DEBUG(dbgs() << "Replacing existing symbol: " << NewSym
- << " sym index:" << SymIndex << "\n");
- }
- }
- if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION &&
- isDefinedFunctionIndex(Export.Index)) {
- auto &Function = getDefinedFunction(Export.Index);
- if (Function.Name.empty()) {
- // Use the export's name to set a name for the Function, but only if one
- // hasn't already been set.
- Function.Name = Export.Name;
- }
- }
- }
-}
-
Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
const uint8_t *End) {
HasLinkingSection = true;
@@ -388,37 +325,15 @@ Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
"Linking data must come after code section", object_error::parse_failed);
}
- // Only populate the symbol table with imports and exports if the object
- // has a linking section (i.e. its a relocatable object file). Otherwise
- // the global might not represent symbols at all.
- populateSymbolTable();
-
while (Ptr < End) {
uint8_t Type = readVarint7(Ptr);
uint32_t Size = readVaruint32(Ptr);
const uint8_t *SubSectionEnd = Ptr + Size;
switch (Type) {
- case wasm::WASM_SYMBOL_INFO: {
- uint32_t Count = readVaruint32(Ptr);
- while (Count--) {
- StringRef Symbol = readString(Ptr);
- uint32_t Flags = readVaruint32(Ptr);
- auto iter = SymbolMap.find(Symbol);
- if (iter == SymbolMap.end()) {
- return make_error<GenericBinaryError>(
- "Invalid symbol name in linking section: " + Symbol,
- object_error::parse_failed);
- }
- uint32_t SymIndex = iter->second;
- assert(SymIndex < Symbols.size());
- Symbols[SymIndex].Flags = Flags;
- DEBUG(dbgs() << "Set symbol flags index:"
- << SymIndex << " name:"
- << Symbols[SymIndex].Name << " expected:"
- << Symbol << " flags: " << Flags << "\n");
- }
+ case wasm::WASM_SYMBOL_TABLE:
+ if (Error Err = parseLinkingSectionSymtab(Ptr, SubSectionEnd))
+ return Err;
break;
- }
case wasm::WASM_DATA_SIZE:
LinkingData.DataSize = readVaruint32(Ptr);
break;
@@ -440,10 +355,10 @@ Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
for (uint32_t i = 0; i < Count; i++) {
wasm::WasmInitFunc Init;
Init.Priority = readVaruint32(Ptr);
- Init.FunctionIndex = readVaruint32(Ptr);
- if (!isValidFunctionIndex(Init.FunctionIndex))
- return make_error<GenericBinaryError>("Invalid function index: " +
- Twine(Init.FunctionIndex),
+ Init.Symbol = readVaruint32(Ptr);
+ if (!isValidFunctionSymbolIndex(Init.Symbol))
+ return make_error<GenericBinaryError>("Invalid function symbol: " +
+ Twine(Init.Symbol),
object_error::parse_failed);
LinkingData.InitFunctions.emplace_back(Init);
}
@@ -467,6 +382,110 @@ Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
return Error::success();
}
+Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr,
+ const uint8_t *End) {
+ uint32_t Count = readVaruint32(Ptr);
+ LinkingData.SymbolTable.reserve(Count);
+ Symbols.reserve(Count);
+ StringSet<> SymbolNames;
+
+ std::vector<wasm::WasmImport *> ImportedGlobals;
+ std::vector<wasm::WasmImport *> ImportedFunctions;
+ ImportedGlobals.reserve(Imports.size());
+ ImportedFunctions.reserve(Imports.size());
+ for (auto &I : Imports) {
+ if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
+ ImportedFunctions.emplace_back(&I);
+ else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
+ ImportedGlobals.emplace_back(&I);
+ }
+
+ while (Count--) {
+ wasm::WasmSymbolInfo Info;
+ const wasm::WasmSignature *FunctionType = nullptr;
+ const wasm::WasmGlobalType *GlobalType = nullptr;
+
+ Info.Kind = readUint8(Ptr);
+ Info.Flags = readVaruint32(Ptr);
+ bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
+
+ switch (Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ Info.ElementIndex = readVaruint32(Ptr);
+ if (!isValidFunctionIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid function symbol index",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ptr);
+ unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
+ FunctionType = &Signatures[FunctionTypes[FuncIndex]];
+ auto &Function = Functions[FuncIndex];
+ if (Function.Name.empty()) {
+ // Use the symbol's name to set a name for the Function, but only if
+ // one hasn't already been set.
+ Function.Name = Info.Name;
+ }
+ } else {
+ wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
+ FunctionType = &Signatures[Import.SigIndex];
+ Info.Name = Import.Field;
+ }
+ break;
+
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ Info.ElementIndex = readVaruint32(Ptr);
+ if (!isValidGlobalIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid global symbol index",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ptr);
+ unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
+ GlobalType = &Globals[GlobalIndex].Type;
+ } else {
+ wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
+ Info.Name = Import.Field;
+ GlobalType = &Import.Global;
+ }
+ break;
+
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ Info.Name = readString(Ptr);
+ if (IsDefined) {
+ uint32_t Index = readVaruint32(Ptr);
+ if (Index >= DataSegments.size())
+ return make_error<GenericBinaryError>("invalid data symbol index",
+ object_error::parse_failed);
+ uint32_t Offset = readVaruint32(Ptr);
+ uint32_t Size = readVaruint32(Ptr);
+ if (Offset + Size > DataSegments[Index].Data.Content.size())
+ return make_error<GenericBinaryError>("invalid data symbol index",
+ object_error::parse_failed);
+ Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
+ }
+ break;
+
+ default:
+ return make_error<GenericBinaryError>("Invalid symbol type",
+ object_error::parse_failed);
+ }
+
+ if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
+ wasm::WASM_SYMBOL_BINDING_LOCAL &&
+ !SymbolNames.insert(Info.Name).second)
+ return make_error<GenericBinaryError>("Duplicate symbol name " +
+ Twine(Info.Name),
+ object_error::parse_failed);
+ LinkingData.SymbolTable.emplace_back(Info);
+ Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
+ GlobalType);
+ DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
+ }
+
+ return Error::success();
+}
+
Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr,
const uint8_t *End)
{
@@ -706,6 +725,7 @@ Error WasmObjectFile::parseMemorySection(const uint8_t *Ptr, const uint8_t *End)
}
Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) {
+ GlobalSection = Sections.size();
uint32_t Count = readVaruint32(Ptr);
Globals.reserve(Count);
while (Count--) {
@@ -737,12 +757,11 @@ Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End)
return make_error<GenericBinaryError>("Invalid function export",
object_error::parse_failed);
break;
- case wasm::WASM_EXTERNAL_GLOBAL: {
- if (Ex.Index >= Globals.size() + NumImportedGlobals)
+ case wasm::WASM_EXTERNAL_GLOBAL:
+ if (!isValidGlobalIndex(Ex.Index))
return make_error<GenericBinaryError>("Invalid global export",
object_error::parse_failed);
break;
- }
case wasm::WASM_EXTERNAL_MEMORY:
case wasm::WASM_EXTERNAL_TABLE:
break;
@@ -759,18 +778,35 @@ Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End)
}
bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
- return Index < FunctionTypes.size() + NumImportedFunctions;
+ return Index < NumImportedFunctions + FunctionTypes.size();
}
bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
}
-wasm::WasmFunction& WasmObjectFile::getDefinedFunction(uint32_t Index) {
+bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
+ return Index < NumImportedGlobals + Globals.size();
+}
+
+bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
+ return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
+}
+
+bool WasmObjectFile::isValidFunctionSymbolIndex(uint32_t Index) const {
+ return Index < Symbols.size() && Symbols[Index].isTypeFunction();
+}
+
+wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
assert(isDefinedFunctionIndex(Index));
return Functions[Index - NumImportedFunctions];
}
+wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
+ assert(isDefinedGlobalIndex(Index));
+ return Globals[Index - NumImportedGlobals];
+}
+
Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
StartFunction = readVaruint32(Ptr);
if (!isValidFunctionIndex(StartFunction))
@@ -888,21 +924,10 @@ uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
Result |= SymbolRef::SF_Global;
if (Sym.isHidden())
Result |= SymbolRef::SF_Hidden;
-
- switch (Sym.Type) {
- case WasmSymbol::SymbolType::FUNCTION_IMPORT:
- Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
- break;
- case WasmSymbol::SymbolType::FUNCTION_EXPORT:
- Result |= SymbolRef::SF_Executable;
- break;
- case WasmSymbol::SymbolType::GLOBAL_IMPORT:
+ if (!Sym.isDefined())
Result |= SymbolRef::SF_Undefined;
- break;
- case WasmSymbol::SymbolType::GLOBAL_EXPORT:
- break;
- }
-
+ if (Sym.isTypeFunction())
+ Result |= SymbolRef::SF_Executable;
return Result;
}
@@ -927,7 +952,7 @@ const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
}
Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
- return getWasmSymbol(Symb).Name;
+ return getWasmSymbol(Symb).Info.Name;
}
Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
@@ -935,18 +960,17 @@ Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
}
uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
- switch (Sym.Type) {
- case WasmSymbol::SymbolType::FUNCTION_IMPORT:
- case WasmSymbol::SymbolType::GLOBAL_IMPORT:
- case WasmSymbol::SymbolType::FUNCTION_EXPORT:
- return Sym.ElementIndex;
- case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
- uint32_t GlobalIndex = Sym.ElementIndex - NumImportedGlobals;
- assert(GlobalIndex < Globals.size());
- const wasm::WasmGlobal &Global = Globals[GlobalIndex];
- // WasmSymbols correspond only to I32_CONST globals
- assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST);
- return Global.InitExpr.Value.Int32;
+ switch (Sym.Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ return Sym.Info.ElementIndex;
+ case wasm::WASM_SYMBOL_TYPE_DATA: {
+ // The value of a data symbol is the segment offset, plus the symbol
+ // offset within the segment.
+ uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
+ const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
+ assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
+ return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
}
}
llvm_unreachable("invalid symbol type");
@@ -970,12 +994,12 @@ Expected<SymbolRef::Type>
WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
const WasmSymbol &Sym = getWasmSymbol(Symb);
- switch (Sym.Type) {
- case WasmSymbol::SymbolType::FUNCTION_IMPORT:
- case WasmSymbol::SymbolType::FUNCTION_EXPORT:
+ switch (Sym.Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
return SymbolRef::ST_Function;
- case WasmSymbol::SymbolType::GLOBAL_IMPORT:
- case WasmSymbol::SymbolType::GLOBAL_EXPORT:
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ return SymbolRef::ST_Other;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
return SymbolRef::ST_Data;
}
@@ -985,14 +1009,24 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
Expected<section_iterator>
WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
- DataRefImpl Ref;
const WasmSymbol& Sym = getWasmSymbol(Symb);
- if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT)
- Ref.d.a = DataSection;
- else if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT)
- Ref.d.a = CodeSection;
- else
+ if (Sym.isUndefined())
return section_end();
+
+ DataRefImpl Ref;
+ switch (Sym.Info.Kind) {
+ case wasm::WASM_SYMBOL_TYPE_FUNCTION:
+ Ref.d.a = CodeSection;
+ break;
+ case wasm::WASM_SYMBOL_TYPE_GLOBAL:
+ Ref.d.a = GlobalSection;
+ break;
+ case wasm::WASM_SYMBOL_TYPE_DATA:
+ Ref.d.a = DataSection;
+ break;
+ default:
+ llvm_unreachable("Unknown WasmSymbol::SymbolType");
+ }
return section_iterator(SectionRef(Ref, this));
}
diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp
index 4ae6dccccb1..9433cf6a783 100644
--- a/llvm/lib/ObjectYAML/WasmYAML.cpp
+++ b/llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -58,7 +58,7 @@ static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
commonSectionMapping(IO, Section);
IO.mapRequired("Name", Section.Name);
IO.mapRequired("DataSize", Section.DataSize);
- IO.mapOptional("SymbolInfo", Section.SymbolInfos);
+ IO.mapOptional("SymbolTable", Section.SymbolTable);
IO.mapOptional("SegmentInfo", Section.SegmentInfos);
IO.mapOptional("InitFunctions", Section.InitFunctions);
IO.mapOptional("Comdats", Section.Comdats);
@@ -366,7 +366,7 @@ void MappingTraits<WasmYAML::DataSegment>::mapping(
void MappingTraits<WasmYAML::InitFunction>::mapping(
IO &IO, WasmYAML::InitFunction &Init) {
IO.mapRequired("Priority", Init.Priority);
- IO.mapRequired("FunctionIndex", Init.FunctionIndex);
+ IO.mapRequired("Symbol", Init.Symbol);
}
void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration(
@@ -391,8 +391,23 @@ void MappingTraits<WasmYAML::Comdat>::mapping(
void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO,
WasmYAML::SymbolInfo &Info) {
+ IO.mapRequired("Index", Info.Index);
+ IO.mapRequired("Kind", Info.Kind);
IO.mapRequired("Name", Info.Name);
IO.mapRequired("Flags", Info.Flags);
+ if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) {
+ IO.mapRequired("Function", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
+ IO.mapRequired("Global", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
+ IO.mapRequired("Segment", Info.DataRef.Segment);
+ IO.mapOptional("Offset", Info.DataRef.Offset, 0u);
+ IO.mapRequired("Size", Info.DataRef.Size);
+ }
+ } else {
+ llvm_unreachable("unsupported symbol kind");
+ }
}
void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset(
@@ -414,9 +429,19 @@ void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset(
BCaseMask(BINDING_MASK, BINDING_LOCAL);
//BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN);
+ BCaseMask(UNDEFINED, UNDEFINED);
#undef BCaseMask
}
+void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration(
+ IO &IO, WasmYAML::SymbolKind &Kind) {
+#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
+ ECase(FUNCTION);
+ ECase(DATA);
+ ECase(GLOBAL);
+#undef ECase
+}
+
void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration(
IO &IO, WasmYAML::ValueType &Type) {
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
index 739044f6c40..9d4f308ca3c 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
@@ -215,7 +215,7 @@ void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
WasmSym->setParams(std::move(ValParams));
WasmSym->setReturns(std::move(ValResults));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
}
void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index 4a93d4810c7..c8afa39e6e9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -74,7 +74,7 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
WasmSym->setReturns(std::move(Returns));
WasmSym->setParams(std::move(Params));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
}
return WasmSym;
@@ -91,9 +91,16 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
const WebAssemblySubtarget &Subtarget = Printer.getSubtarget();
// __stack_pointer is a global variable; all other external symbols used by
- // CodeGen are functions.
- if (strcmp(Name, "__stack_pointer") == 0)
+ // CodeGen are functions. It's OK to hardcode knowledge of specific symbols
+ // here; this method is precisely there for fetching the signatures of known
+ // Clang-provided symbols.
+ if (strcmp(Name, "__stack_pointer") == 0) {
+ wasm::ValType iPTR =
+ Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ WasmSym->setGlobalType(wasm::WasmGlobalType{int32_t(iPTR), true});
return WasmSym;
+ }
SmallVector<wasm::ValType, 4> Returns;
SmallVector<wasm::ValType, 4> Params;
@@ -101,7 +108,7 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
WasmSym->setReturns(std::move(Returns));
WasmSym->setParams(std::move(Params));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
return WasmSym;
}
@@ -189,7 +196,7 @@ void WebAssemblyMCInstLower::Lower(const MachineInstr *MI,
MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Sym);
WasmSym->setReturns(std::move(Returns));
WasmSym->setParams(std::move(Params));
- WasmSym->setIsFunction(true);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
const MCExpr *Expr =
MCSymbolRefExpr::create(WasmSym,
OpenPOWER on IntegriCloud