Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -132,6 +132,15 @@ StringRef Name; }; +// Represents the location of a Wasm symbol within a WasmDataSegment, as the +// index of the segment (or empty index if the symbol is undefined), and the +// offset and size within the segment. +struct WasmSegmentSymbol { + uint32_t Index; + uint32_t Offset; + uint32_t Size; +}; + struct WasmLinkingData { uint32_t DataSize; std::vector InitFunctions; @@ -201,11 +210,11 @@ // Kind codes used in the custom "linking" section enum : unsigned { - WASM_SYMBOL_INFO = 0x2, WASM_DATA_SIZE = 0x3, WASM_SEGMENT_INFO = 0x5, WASM_INIT_FUNCS = 0x6, WASM_COMDAT_INFO = 0x7, + WASM_SYMBOL_TABLE = 0x8, }; // Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO @@ -214,6 +223,13 @@ WASM_COMDAT_FUNCTION = 0x1, }; +// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE +enum : unsigned { + WASM_SYMTAB_FUNCTION = 0x0, + WASM_SYMTAB_DATA = 0x1, + WASM_SYMTAB_GLOBAL = 0x2, +}; + const unsigned WASM_SYMBOL_BINDING_MASK = 0x3; const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0x4; Index: include/llvm/MC/MCSectionWasm.h =================================================================== --- include/llvm/MC/MCSectionWasm.h +++ include/llvm/MC/MCSectionWasm.h @@ -43,13 +43,13 @@ // For data sections, this is the offset of the corresponding wasm data // segment - uint64_t MemoryOffset; + uint32_t SegmentIndex; friend class MCContext; MCSectionWasm(StringRef Section, SectionKind K, const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin) : MCSection(SV_Wasm, K, Begin), SectionName(Section), UniqueID(UniqueID), - Group(group), SectionOffset(0) {} + Group(group), SectionOffset(0), SegmentIndex((uint32_t)-1) {} void setSectionName(StringRef Name) { SectionName = Name; } @@ -79,8 +79,8 @@ uint64_t getSectionOffset() const { return SectionOffset; } void setSectionOffset(uint64_t Offset) { SectionOffset = Offset; } - uint32_t getMemoryOffset() const { return MemoryOffset; } - void setMemoryOffset(uint32_t Offset) { MemoryOffset = Offset; } + uint32_t getSegmentIndex() const { return SegmentIndex; } + void setSegmentIndex(uint32_t Index) { SegmentIndex = Index; } static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; } }; Index: include/llvm/MC/MCSymbolWasm.h =================================================================== --- include/llvm/MC/MCSymbolWasm.h +++ include/llvm/MC/MCSymbolWasm.h @@ -15,8 +15,15 @@ namespace llvm { class MCSymbolWasm : public MCSymbol { +public: + enum class SymbolType { + FUNCTION, + DATA, + GLOBAL + }; + private: - bool IsFunction = false; + SymbolType Type = SymbolType::DATA; bool IsWeak = false; bool IsHidden = false; bool IsComdat = false; @@ -41,8 +48,10 @@ const MCExpr *getSize() const { return SymbolSize; } void setSize(const MCExpr *SS) { SymbolSize = SS; } - bool isFunction() const { return IsFunction; } - void setIsFunction(bool isFunc) { IsFunction = isFunc; } + bool isFunction() const { return Type == SymbolType::FUNCTION; } + bool isData() const { return Type == SymbolType::DATA; } + SymbolType getType() const { return Type; } + void setType(SymbolType type) { Type = type; } bool isWeak() const { return IsWeak; } void setWeak(bool isWeak) { IsWeak = isWeak; } Index: include/llvm/Object/Wasm.h =================================================================== --- include/llvm/Object/Wasm.h +++ include/llvm/Object/Wasm.h @@ -18,6 +18,7 @@ #define LLVM_OBJECT_WASM_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/BinaryFormat/Wasm.h" @@ -35,22 +36,23 @@ class WasmSymbol { public: enum class SymbolType { - FUNCTION_IMPORT, - FUNCTION_EXPORT, - GLOBAL_IMPORT, - GLOBAL_EXPORT, + FUNCTION = wasm::WASM_SYMTAB_FUNCTION, + DATA = wasm::WASM_SYMTAB_DATA, + GLOBAL = wasm::WASM_SYMTAB_GLOBAL, }; - WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, - uint32_t SymbolIndex, uint32_t WasmIndex, - uint32_t FunctionType = 0) - : Name(Name), Type(Type), Section(Section), SymbolIndex(SymbolIndex), - WasmIndex(WasmIndex), FunctionType(FunctionType) {} + WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, uint32_t Flags, + uint32_t SymbolIndex, uint32_t WasmIndex = (uint32_t)-1, + uint32_t FunctionType = (uint32_t)-1, + Optional Segment = None) + : Name(Name), Type(Type), Section(Section), Flags(Flags), + SymbolIndex(SymbolIndex), WasmIndex(WasmIndex), + FunctionType(FunctionType), Segment(Segment) {} StringRef Name; SymbolType Type; uint32_t Section; - uint32_t Flags = 0; + uint32_t Flags; // Index into either the Symbol index space, which consists of all Symbols // together, in order of declaration. @@ -63,21 +65,23 @@ // For a function symbol, the type index. uint32_t FunctionType; + // For a data symbol, the segment (or empty if the data symbol is undefined). + Optional Segment; + bool isFunction() const { - return Type == WasmSymbol::SymbolType::FUNCTION_IMPORT || - Type == WasmSymbol::SymbolType::FUNCTION_EXPORT; + return Type == WasmSymbol::SymbolType::FUNCTION; } - bool isWeak() const { + bool isBindingWeak() const { return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK; } - bool isGlobal() const { + bool isBindingGlobal() const { return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL; } - bool isLocal() const { + bool isBindingLocal() const { return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL; } @@ -237,12 +241,11 @@ // Custom section types Error parseNameSection(const uint8_t *Ptr, const uint8_t *End); Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End); + Error parseLinkingSectionSymtab(const uint8_t *&Ptr, const uint8_t *End); Error parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End); Error parseRelocSection(StringRef Name, const uint8_t *Ptr, const uint8_t *End); - Error populateSymbolTable(); - wasm::WasmObjectHeader Header; std::vector Sections; std::vector Signatures; @@ -264,11 +267,9 @@ uint32_t NumImportedGlobals = 0; uint32_t NumImportedFunctions = 0; uint32_t ImportSection = 0; - uint32_t ExportSection = 0; - - // TODO: will get rid of this map in next commit, once we get replace the - // WASM_SYMBOL_INFO section with WASM_SYMBOL_TABLE - StringMap SymbolMap; + uint32_t GlobalSection = 0; + uint32_t CodeSection = 0; + uint32_t DataSection = 0; }; } // end namespace object Index: include/llvm/ObjectYAML/WasmYAML.h =================================================================== --- include/llvm/ObjectYAML/WasmYAML.h +++ include/llvm/ObjectYAML/WasmYAML.h @@ -35,6 +35,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode) LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType) LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind) LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags) LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags) LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind) @@ -129,9 +130,22 @@ ValueType ReturnType; }; +struct SymbolInfoSegment { + int32_t Index; + uint32_t Offset; + uint32_t Size; +}; + struct SymbolInfo { StringRef Name; + SymbolKind Kind; + uint32_t SymbolIndex; SymbolFlags Flags; + union { + uint32_t FunctionIndex; + uint32_t GlobalIndex; + SymbolInfoSegment Segment; + }; }; struct InitFunction { @@ -368,6 +382,10 @@ static void bitset(IO &IO, WasmYAML::SymbolFlags &Value); }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, WasmYAML::SymbolKind &Kind); +}; + template <> struct ScalarBitSetTraits { static void bitset(IO &IO, WasmYAML::SegmentFlags &Value); }; Index: lib/MC/MCWasmStreamer.cpp =================================================================== --- lib/MC/MCWasmStreamer.cpp +++ lib/MC/MCWasmStreamer.cpp @@ -113,11 +113,11 @@ break; case MCSA_ELF_TypeFunction: - Symbol->setIsFunction(true); + Symbol->setType(MCSymbolWasm::SymbolType::FUNCTION); break; case MCSA_ELF_TypeObject: - Symbol->setIsFunction(false); + Symbol->setType(MCSymbolWasm::SymbolType::DATA); break; default: Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -150,6 +150,15 @@ uint32_t Index; }; +// Information about a single entry to be written to the symbol table +struct WasmSymbolEntry { + StringRef Name; + unsigned Kind; + uint32_t Flags; + uint32_t WasmIndex; + Optional Segment; +}; + // Information about a single relocation. struct WasmRelocationEntry { uint64_t Offset; // Where is the relocation. @@ -213,11 +222,15 @@ DenseMap SymbolIndices; // Maps function/global symbols to the function/global Wasm index space. DenseMap WasmIndices; + // Maps data symbols to the Wasm segment and offset/size with the segment. + DenseMap> + SegmentIndices; DenseMap FunctionTypeIndices; SmallVector FunctionTypes; SmallVector Globals; + SmallVector DataSegments; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; @@ -247,9 +260,11 @@ SymbolIndices.clear(); WasmIndices.clear(); TableIndices.clear(); + SegmentIndices.clear(); FunctionTypeIndices.clear(); FunctionTypes.clear(); Globals.clear(); + DataSegments.clear(); MCObjectWriter::reset(); NumFunctionImports = 0; NumGlobalImports = 0; @@ -284,12 +299,11 @@ void writeElemSection(ArrayRef TableElems); void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout, ArrayRef Functions); - void writeDataSection(ArrayRef Segments); + void writeDataSection(); void writeCodeRelocSection(); void writeDataRelocSection(); void writeLinkingMetaDataSection( - ArrayRef Segments, uint32_t DataSize, - ArrayRef> SymbolFlags, + uint32_t DataSize, ArrayRef SymbolInfos, ArrayRef> InitFuncs, const std::map>& Comdats); @@ -522,13 +536,10 @@ // For undefined symbols, use zero if (!Sym->isDefined()) return 0; - - uint32_t GlobalIndex = WasmIndices[Sym]; - const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports]; - uint64_t Address = Global.InitialValue + RelEntry.Addend; - + auto &SI = SegmentIndices[Sym]; + const WasmDataSegment &Segment = DataSegments[SI.getValue().Index]; // Ignore overflow. LLVM allows address arithmetic to silently wrap. - return Address; + return Segment.Offset + SI.getValue().Offset + RelEntry.Addend; } default: llvm_unreachable("invalid relocation type"); @@ -541,7 +552,6 @@ 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"); @@ -566,16 +576,9 @@ const SmallVectorImpl &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"); } @@ -822,16 +825,16 @@ endSection(Section); } -void WasmObjectWriter::writeDataSection(ArrayRef 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 @@ -884,20 +887,44 @@ } void WasmObjectWriter::writeLinkingMetaDataSection( - ArrayRef Segments, uint32_t DataSize, - ArrayRef> SymbolFlags, + uint32_t DataSize, ArrayRef SymbolInfos, ArrayRef> InitFuncs, const std::map>& 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 (auto &Sym : SymbolInfos) { + encodeULEB128(Sym.Kind, getStream()); + encodeULEB128(Sym.Flags, getStream()); + switch (Sym.Kind) { + case wasm::WASM_SYMTAB_FUNCTION: + encodeULEB128(Sym.WasmIndex, getStream()); + if (Sym.WasmIndex >= NumFunctionImports) + writeString(Sym.Name); + break; + case wasm::WASM_SYMTAB_GLOBAL: + encodeULEB128(Sym.WasmIndex, getStream()); + if (Sym.WasmIndex >= NumGlobalImports) + writeString(Sym.Name); + break; + case wasm::WASM_SYMTAB_DATA: + writeString(Sym.Name); + if (Sym.Segment.hasValue()) { + encodeSLEB128(static_cast(Sym.Segment.getValue().Index), + getStream()); + encodeULEB128(Sym.Segment.getValue().Offset, getStream()); + encodeULEB128(Sym.Segment.getValue().Size, getStream()); + } else { + encodeSLEB128(-1, getStream()); + } + break; + default: + llvm_unreachable("unexpected kind"); + } } endSection(SubSection); } @@ -908,10 +935,10 @@ 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()); @@ -983,25 +1010,32 @@ SmallVector TableElems; SmallVector Imports; SmallVector Exports; - SmallVector, 4> SymbolFlags; + SmallVector SymbolInfos; SmallVector, 2> InitFuncs; std::map> Comdats; unsigned NumSymbols = 0; - SmallVector DataSegments; uint32_t DataSize = 0; auto AddSymbol = [&](const MCSymbolWasm &WS) { uint32_t Flags = (WS.isWeak() ? wasm::WASM_SYMBOL_BINDING_WEAK : 0) | (WS.isHidden() ? wasm::WASM_SYMBOL_VISIBILITY_HIDDEN : 0) | (!WS.isExternal() && WS.isDefined() ? wasm::WASM_SYMBOL_BINDING_LOCAL : 0); - if (Flags != 0) { - SymbolFlags.emplace_back(WS.getName(), Flags); + if (WS.isData()) { + SymbolInfos.emplace_back( + WasmSymbolEntry{WS.getName(), wasm::WASM_SYMTAB_DATA, Flags, 0, + SegmentIndices[&WS]}); + } else { + SymbolInfos.emplace_back( + WasmSymbolEntry{WS.getName(), static_cast(WS.getType()), + Flags, WasmIndices[&WS], None}); } }; // In the special .global_variables section, we've encoded global // variables used by the function. Translate them into the Globals // list. + /* TODO This is constructed in emitGlobal(), but that code doesn't ever seem + * to be used. Is this entire block now dead code? */ MCSectionWasm *GlobalVars = Ctx.getWasmSection(".global_variables", SectionKind::getMetadata()); if (!GlobalVars->getFragmentList().empty()) { @@ -1094,25 +1128,37 @@ // If the symbol is not defined in this translation unit, import it. if (!WS.isDefined() && !WS.isComdat()) { - WasmImport Import; - Import.ModuleName = WS.getModuleName(); - Import.FieldName = WS.getName(); if (WS.isFunction()) { + WasmImport Import; + Import.ModuleName = WS.getModuleName(); + Import.FieldName = WS.getName(); Import.Kind = wasm::WASM_EXTERNAL_FUNCTION; Import.Type = getFunctionType(WS); + Imports.push_back(Import); WasmIndices[&WS] = NumFunctionImports++; + } else if (WS.isData()) { + SegmentIndices[&WS] = None; } else { + WasmImport Import; + Import.ModuleName = WS.getModuleName(); + Import.FieldName = WS.getName(); Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; Import.Type = int32_t(PtrType); Import.IsMutable = false; - WasmIndices[&WS] = NumGlobalImports++; // If this global is the stack pointer, make it mutable. if (WS.getName() == "__stack_pointer") Import.IsMutable = true; + 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. SymbolIndices[&WS] = NumSymbols++; AddSymbol(WS); } @@ -1138,7 +1184,7 @@ 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( @@ -1168,9 +1214,8 @@ if (WS.isComdat() && !WS.isDefined()) continue; - unsigned WasmIndex; - if (WS.isFunction()) { + unsigned WasmIndex; if (WS.isDefined()) { if (WS.getOffset() != 0) report_fatal_error( @@ -1199,10 +1244,11 @@ } DEBUG(dbgs() << " -> function index: " << WasmIndex << "\n"); - } else { + } else if (WS.isData()) { if (WS.isTemporary() && !WS.getSize()) continue; + Optional SegmentInfo; if (WS.isDefined()) { if (!WS.getSize()) report_fatal_error("data symbols must have a size set with .size: " + @@ -1215,37 +1261,29 @@ auto& DataSection = static_cast(WS.getSection()); assert(DataSection.isWasmData()); - // For each global, prepare a corresponding wasm global holding its - // address. For externals these will also be named exports. - WasmIndex = NumGlobalImports + Globals.size(); - WasmGlobal Global; - Global.Type = PtrType; - Global.IsMutable = false; - Global.HasImport = false; - Global.InitialValue = - DataSection.getMemoryOffset() + Layout.getSymbolOffset(WS); - Global.ImportIndex = 0; - WasmIndices[&WS] = WasmIndex; - Globals.push_back(Global); + // For each data symbol, export it in the symtab as a reference to the + // corresponding Wasm data segment. + SegmentInfo = wasm::WasmSegmentSymbol{ + DataSection.getSegmentIndex(), + static_cast(Layout.getSymbolOffset(WS)), + static_cast(Size)}; + SegmentIndices[&WS] = SegmentInfo; } else { // An import; the index was assigned above. - WasmIndex = WasmIndices.find(&WS)->second; + SegmentInfo = SegmentIndices.find(&WS)->second; } + DEBUG(dbgs() << " -> segment index: " << + (SegmentInfo.hasValue() ? (int)SegmentInfo.getValue().Index : -1) << + "\n"); + } else { + // A "true" Wasm global (currently just __stack_pointer) + if (WS.isDefined()) + report_fatal_error("don't support defined globals"); + unsigned WasmIndex = WasmIndices.find(&WS)->second; DEBUG(dbgs() << " -> global index: " << WasmIndex << "\n"); } - // If the symbol is visible outside this translation unit, export it. if (WS.isDefined()) { - WasmExport Export; - Export.FieldName = WS.getName(); - Export.Index = WasmIndex; - 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); - SymbolIndices[&WS] = NumSymbols++; AddSymbol(WS); } @@ -1265,20 +1303,19 @@ const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS); DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n"); - assert(WasmIndices.count(ResolvedSym) > 0); - uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second; - WasmIndices[&WS] = WasmIndex; - DEBUG(dbgs() << " -> index:" << WasmIndex << "\n"); - - WasmExport Export; - Export.FieldName = WS.getName(); - Export.Index = WasmIndex; - 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.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(SegmentIndices.count(ResolvedSym) > 0); + auto &SI = SegmentIndices.find(ResolvedSym)->second; + SegmentIndices[&WS] = SI; + DEBUG(dbgs() << " -> index:" << SI.getValue().Index << "\n"); + } else { + report_fatal_error("don't support global aliases"); + } SymbolIndices[&WS] = NumSymbols++; AddSymbol(WS); @@ -1371,11 +1408,10 @@ 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. Index: lib/Object/WasmObjectFile.cpp =================================================================== --- lib/Object/WasmObjectFile.cpp +++ lib/Object/WasmObjectFile.cpp @@ -317,82 +317,6 @@ return Error::success(); } -Error WasmObjectFile::populateSymbolTable() { - Symbols.reserve(NumImportedFunctions + NumImportedGlobals + Exports.size()); - - // Add imports to symbol table - for (const wasm::WasmImport& Import : Imports) { - WasmSymbol::SymbolType ImportType; - unsigned FunctionType = 0; - switch (Import.Kind) { - case wasm::WASM_EXTERNAL_GLOBAL: - assert(Import.Global.Type == wasm::WASM_TYPE_I32); - ImportType = WasmSymbol::SymbolType::GLOBAL_IMPORT; - break; - case wasm::WASM_EXTERNAL_FUNCTION: - ImportType = WasmSymbol::SymbolType::FUNCTION_IMPORT; - FunctionType = Import.SigIndex; - break; - default: - continue; - } - unsigned SymbolIndex = Symbols.size(); - if (!SymbolMap.try_emplace(Import.Field, SymbolIndex).second) - return make_error( - "Duplicate symbol name " + Import.Field, - object_error::parse_failed); - unsigned WasmIndex = SymbolIndex; - Symbols.emplace_back(Import.Field, ImportType, ImportSection, SymbolIndex, - WasmIndex, FunctionType); - DEBUG(dbgs() << "Adding import: " << Symbols.back() - << " sym index:" << SymbolIndex << "\n"); - } - - // Add exports to symbol table - for (const wasm::WasmExport& Export : Exports) { - WasmSymbol::SymbolType ExportType; - unsigned FunctionType = 0; - switch (Export.Kind) { - case wasm::WASM_EXTERNAL_GLOBAL: - assert(isValidGlobalIndex(Export.Index)); - if (!isDefinedGlobalIndex(Export.Index)) - return make_error("symbol cannot export an import", - object_error::parse_failed); - ExportType = WasmSymbol::SymbolType::GLOBAL_EXPORT; - break; - case wasm::WASM_EXTERNAL_FUNCTION: { - assert(isValidFunctionIndex(Export.Index)); - if (!isDefinedFunctionIndex(Export.Index)) - return make_error("symbol cannot export an import", - object_error::parse_failed); - ExportType = WasmSymbol::SymbolType::FUNCTION_EXPORT; - FunctionType = FunctionTypes[Export.Index - NumImportedFunctions]; - 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; - } - break; - } - default: - continue; - } - unsigned SymbolIndex = Symbols.size(); - if (!SymbolMap.try_emplace(Export.Name, SymbolIndex).second) - return make_error( - "Duplicate symbol name " + Export.Name, - object_error::parse_failed); - unsigned WasmIndex = Export.Index; - Symbols.emplace_back(Export.Name, ExportType, ExportSection, SymbolIndex, - WasmIndex, FunctionType); - DEBUG(dbgs() << "Adding export: " << Symbols.back() - << " sym index:" << SymbolIndex << "\n"); - } - - return Error::success(); -} - Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr, const uint8_t *End) { HasLinkingSection = true; @@ -401,38 +325,15 @@ "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. - if (Error Err = populateSymbolTable()) - return Err; - 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( - "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; @@ -481,6 +382,112 @@ return Error::success(); } +Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr, + const uint8_t *End) { + uint32_t LinkingSection = Sections.size(); + uint32_t Count = readVaruint32(Ptr); + Symbols.reserve(Count); + StringSet<> SymbolNames; + + std::vector ImportedGlobals; + std::vector 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--) { + uint32_t Kind = readVaruint32(Ptr); + uint32_t Flags = readVaruint32(Ptr); + + StringRef Name; + uint32_t Section; + uint32_t WasmIndex = (uint32_t)-1; + uint32_t FunctionType = (uint32_t)-1; + Optional Segment; + + switch (Kind) { + case wasm::WASM_SYMTAB_FUNCTION: + WasmIndex = readVaruint32(Ptr); + if (!isValidFunctionIndex(WasmIndex)) + return make_error("invalid function symbol index", + object_error::parse_failed); + if (isDefinedFunctionIndex(WasmIndex)) { + Section = CodeSection; + Name = readString(Ptr); + FunctionType = FunctionTypes[WasmIndex - ImportedFunctions.size()]; + auto &Function = getDefinedFunction(WasmIndex); + 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 = Name; + } + } else { + Section = ImportSection; + wasm::WasmImport &Import = *ImportedFunctions[WasmIndex]; + FunctionType = Import.SigIndex; + Name = Import.Field; + } + break; + + case wasm::WASM_SYMTAB_GLOBAL: + WasmIndex = readVaruint32(Ptr); + if (!isValidGlobalIndex(WasmIndex)) + return make_error("invalid global symbol index", + object_error::parse_failed); + if (isDefinedGlobalIndex(WasmIndex)) { + Section = GlobalSection; + Name = readString(Ptr); + } else { + Section = ImportSection; + wasm::WasmImport &Import = *ImportedGlobals[WasmIndex]; + Name = Import.Field; + } + break; + + case wasm::WASM_SYMTAB_DATA: { + Name = readString(Ptr); + int32_t Index = readVarint32(Ptr); + if (Index >= 0) { + Section = DataSection; + if (static_cast(Index) >= DataSegments.size()) + return make_error("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("invalid data symbol index", + object_error::parse_failed); + Segment = wasm::WasmSegmentSymbol{static_cast(Index), + Offset, Size}; + } else { + Section = LinkingSection; + } + break; + } + + default: + return make_error("Invalid symbol kind", + object_error::parse_failed); + } + + unsigned SymbolIndex = Symbols.size(); + if (!SymbolNames.insert(Name).second) + return make_error("Duplicate symbol name " + Name, + object_error::parse_failed); + Symbols.emplace_back(Name, static_cast(Kind), + Section, Flags, SymbolIndex, WasmIndex, FunctionType, + Segment); + DEBUG(dbgs() << "Adding symbol: " << Symbols.back()); + } + + return Error::success(); +} + Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End) { @@ -721,6 +728,7 @@ } Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) { + GlobalSection = Sections.size(); uint32_t Count = readVaruint32(Ptr); Globals.reserve(Count); while (Count--) { @@ -739,7 +747,6 @@ } Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) { - ExportSection = Sections.size(); uint32_t Count = readVaruint32(Ptr); Exports.reserve(Count); for (uint32_t i = 0; i < Count; i++) { @@ -807,6 +814,7 @@ } Error WasmObjectFile::parseCodeSection(const uint8_t *Ptr, const uint8_t *End) { + CodeSection = Sections.size(); const uint8_t *CodeSectionStart = Ptr; uint32_t FunctionCount = readVaruint32(Ptr); if (FunctionCount != FunctionTypes.size()) { @@ -870,6 +878,7 @@ } Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) { + DataSection = Sections.size(); const uint8_t *Start = Ptr; uint32_t Count = readVaruint32(Ptr); DataSegments.reserve(Count); @@ -907,24 +916,26 @@ const WasmSymbol &Sym = getWasmSymbol(Symb); DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n"); - if (Sym.isWeak()) + if (Sym.isBindingWeak()) Result |= SymbolRef::SF_Weak; - if (!Sym.isLocal()) + if (!Sym.isBindingLocal()) 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: + case WasmSymbol::SymbolType::FUNCTION: Result |= SymbolRef::SF_Executable; + if (!isDefinedFunctionIndex(Sym.WasmIndex)) + Result |= SymbolRef::SF_Undefined; break; - case WasmSymbol::SymbolType::GLOBAL_IMPORT: - Result |= SymbolRef::SF_Undefined; + case WasmSymbol::SymbolType::GLOBAL: + if (!isDefinedGlobalIndex(Sym.WasmIndex)) + Result |= SymbolRef::SF_Undefined; break; - case WasmSymbol::SymbolType::GLOBAL_EXPORT: + case WasmSymbol::SymbolType::DATA: + if (!Sym.Segment.hasValue()) + Result |= SymbolRef::SF_Undefined; break; } @@ -961,17 +972,14 @@ 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: + case WasmSymbol::SymbolType::FUNCTION: + case WasmSymbol::SymbolType::GLOBAL: return Sym.WasmIndex; - case WasmSymbol::SymbolType::GLOBAL_EXPORT: { - uint32_t GlobalIndex = Sym.WasmIndex - 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; + case WasmSymbol::SymbolType::DATA: { + auto &SegmentSym = Sym.Segment.getValue(); + auto &Segment = DataSegments[SegmentSym.Index].Data; + assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST); + return Segment.Offset.Value.Int32 + SegmentSym.Offset; } } llvm_unreachable("invalid symbol type"); @@ -996,11 +1004,11 @@ const WasmSymbol &Sym = getWasmSymbol(Symb); switch (Sym.Type) { - case WasmSymbol::SymbolType::FUNCTION_IMPORT: - case WasmSymbol::SymbolType::FUNCTION_EXPORT: + case WasmSymbol::SymbolType::FUNCTION: return SymbolRef::ST_Function; - case WasmSymbol::SymbolType::GLOBAL_IMPORT: - case WasmSymbol::SymbolType::GLOBAL_EXPORT: + case WasmSymbol::SymbolType::GLOBAL: + return SymbolRef::ST_Other; + case WasmSymbol::SymbolType::DATA: return SymbolRef::ST_Data; } Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ lib/ObjectYAML/WasmYAML.cpp @@ -392,7 +392,22 @@ void MappingTraits::mapping(IO &IO, WasmYAML::SymbolInfo &Info) { IO.mapRequired("Name", Info.Name); + IO.mapRequired("Kind", Info.Kind); + IO.mapRequired("SymbolIndex", Info.SymbolIndex); IO.mapRequired("Flags", Info.Flags); + if (Info.Kind == wasm::WASM_SYMTAB_FUNCTION) { + IO.mapRequired("FunctionIndex", Info.FunctionIndex); + } else if (Info.Kind == wasm::WASM_SYMTAB_GLOBAL) { + IO.mapRequired("GlobalIndex", Info.GlobalIndex); + } else if (Info.Kind == wasm::WASM_SYMTAB_DATA) { + IO.mapOptional("SegmentIndex", Info.Segment.Index, -1); + if (Info.Segment.Index >= 0) { + IO.mapRequired("DataOffset", Info.Segment.Offset); + IO.mapRequired("DataSize", Info.Segment.Size); + } + } else { + llvm_unreachable("unsupported symbol kind"); + } } void ScalarBitSetTraits::bitset( @@ -417,6 +432,15 @@ #undef BCaseMask } +void ScalarEnumerationTraits::enumeration( + IO &IO, WasmYAML::SymbolKind &Kind) { +#define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMTAB_##X); + ECase(FUNCTION); + ECase(DATA); + ECase(GLOBAL); +#undef ECase +} + void ScalarEnumerationTraits::enumeration( IO &IO, WasmYAML::ValueType &Type) { #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X); Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -256,7 +256,7 @@ WasmSym->setParams(std::move(ValParams)); WasmSym->setReturns(std::move(ValResults)); - WasmSym->setIsFunction(true); + WasmSym->setType(MCSymbolWasm::SymbolType::FUNCTION); } void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) { Index: lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -74,7 +74,7 @@ WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(MCSymbolWasm::SymbolType::FUNCTION); } return WasmSym; @@ -92,8 +92,10 @@ // __stack_pointer is a global variable; all other external symbols used by // CodeGen are functions. - if (strcmp(Name, "__stack_pointer") == 0) + if (strcmp(Name, "__stack_pointer") == 0) { + WasmSym->setType(MCSymbolWasm::SymbolType::GLOBAL); return WasmSym; + } SmallVector Returns; SmallVector Params; @@ -101,7 +103,7 @@ WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(MCSymbolWasm::SymbolType::FUNCTION); return WasmSym; } @@ -189,7 +191,7 @@ MCSymbolWasm *WasmSym = cast(Sym); WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(MCSymbolWasm::SymbolType::FUNCTION); const MCExpr *Expr = MCSymbolRefExpr::create(WasmSym, Index: test/MC/WebAssembly/array-fill.ll =================================================================== --- test/MC/WebAssembly/array-fill.ll +++ test/MC/WebAssembly/array-fill.ll @@ -15,9 +15,14 @@ ; CHECK: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 2 -; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: SymbolInfo: ; CHECK-NEXT: - Name: gBd +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 0 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 2 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data Index: test/MC/WebAssembly/bss.ll =================================================================== --- test/MC/WebAssembly/bss.ll +++ test/MC/WebAssembly/bss.ll @@ -9,75 +9,64 @@ @foo = global %union.u1 zeroinitializer, align 1 @bar = global %union.u1 zeroinitializer, align 1 -; CHECK: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 4 -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 8 -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 9 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: g0 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: g1 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: foo -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: bar -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Type: DATA -; CHECK-NEXT: Segments: +; CHECK: - Type: DATA +; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 ; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: '00000000' ; CHECK-NEXT: - SectionOffset: 15 ; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 4 ; CHECK-NEXT: Content: '00000000' ; CHECK-NEXT: - SectionOffset: 24 ; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 -; CHECK-NEXT: Content: '00' -; CHECK-NEXT: - SectionOffset: 30 +; CHECK-NEXT: Content: '' +; CHECK-NEXT: - SectionOffset: 29 ; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 9 -; CHECK-NEXT: Content: '00' +; CHECK-NEXT: Value: 8 +; CHECK-NEXT: Content: '' ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking -; CHECK-NEXT: DataSize: 10 +; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: - Name: g0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: g1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: - Name: bar +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 3 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 0 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .bss.g0 Index: test/MC/WebAssembly/comdat.ll =================================================================== --- test/MC/WebAssembly/comdat.ll +++ test/MC/WebAssembly/comdat.ll @@ -50,28 +50,6 @@ ; CHECK-NEXT: SigIndex: 0 ; CHECK-NEXT: - Type: FUNCTION ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ] -; CHECK-NEXT: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: callImport -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: basicInlineFn -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: sharedFn -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: constantData -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 0 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB @@ -99,12 +77,33 @@ ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 3 ; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: basicInlineFn -; CHECK-NEXT: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: sharedFn -; CHECK-NEXT: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: constantData -; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: - Name: funcImport +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Name: callImport +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Name: basicInlineFn +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Name: sharedFn +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Name: constantData +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 4 +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 3 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .rodata.constantData Index: test/MC/WebAssembly/explicit-sections.ll =================================================================== --- test/MC/WebAssembly/explicit-sections.ll +++ test/MC/WebAssembly/explicit-sections.ll @@ -9,47 +9,8 @@ @global2 = global i64 7, align 8, section ".sec1" @global3 = global i32 8, align 8, section ".sec2" -; CHECK: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 8 -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 16 -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 24 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: global0 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: global1 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: global2 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: global3 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Type: DATA + +; CHECK: - Type: DATA ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 ; CHECK-NEXT: MemoryIndex: 0 @@ -69,10 +30,38 @@ ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 24 ; CHECK-NEXT: Content: '08000000' - -; CHECK: - Type: CUSTOM +; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 28 +; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: - Name: global0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: global1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: - Name: global2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 8 +; CHECK-NEXT: DataSize: 8 +; CHECK-NEXT: - Name: global3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.global0 Index: test/MC/WebAssembly/func-address.ll =================================================================== --- test/MC/WebAssembly/func-address.ll +++ test/MC/WebAssembly/func-address.ll @@ -30,7 +30,7 @@ ; CHECK: } ; CHECK: Relocations [ -; CHECK: Section (6) CODE { +; CHECK: Section (5) CODE { ; CHECK: Relocation { ; CHECK: Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0) ; CHECK: Offset: 0x4 Index: test/MC/WebAssembly/global-ctor-dtor.ll =================================================================== --- test/MC/WebAssembly/global-ctor-dtor.ll +++ test/MC/WebAssembly/global-ctor-dtor.ll @@ -38,11 +38,6 @@ ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: SigIndex: 1 ; CHECK-NEXT: - Module: env -; CHECK-NEXT: Field: __dso_handle -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: GlobalType: I32 -; CHECK-NEXT: GlobalMutable: false -; CHECK-NEXT: - Module: env ; CHECK-NEXT: Field: __cxa_atexit ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: SigIndex: 2 @@ -60,31 +55,6 @@ ; CHECK-NEXT: SigIndex: 1 ; CHECK-NEXT: - Type: FUNCTION ; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1 ] -; CHECK-NEXT: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: .Lcall_dtors.42 -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 5 -; CHECK-NEXT: - Name: .Lregister_call_dtors.42 -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 6 -; CHECK-NEXT: - Name: .Lcall_dtors -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 7 -; CHECK-NEXT: - Name: .Lregister_call_dtors -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 8 -; CHECK-NEXT: - Name: global1 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: @@ -142,16 +112,62 @@ ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: - Name: func3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: - Name: __dso_handle +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 1 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: - Name: __cxa_atexit +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Name: func2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Name: func1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Name: func0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 5 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 4 ; CHECK-NEXT: - Name: .Lcall_dtors.42 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 6 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: FunctionIndex: 5 ; CHECK-NEXT: - Name: .Lregister_call_dtors.42 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 7 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: FunctionIndex: 6 ; CHECK-NEXT: - Name: .Lcall_dtors +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 8 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: FunctionIndex: 7 ; CHECK-NEXT: - Name: .Lregister_call_dtors +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 9 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: FunctionIndex: 8 +; CHECK-NEXT: - Name: global1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 10 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.global1 Index: test/MC/WebAssembly/reloc-code.ll =================================================================== --- test/MC/WebAssembly/reloc-code.ll +++ test/MC/WebAssembly/reloc-code.ll @@ -24,7 +24,7 @@ ; CHECK: Format: WASM ; CHECK: Relocations [ -; CHECK-NEXT: Section (6) CODE { +; CHECK-NEXT: Section (4) CODE { ; CHECK-NEXT: Relocation { ; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3) ; CHECK-NEXT: Offset: 0x9 Index: test/MC/WebAssembly/reloc-data.ll =================================================================== --- test/MC/WebAssembly/reloc-data.ll +++ test/MC/WebAssembly/reloc-data.ll @@ -13,7 +13,7 @@ ; CHECK: Format: WASM ; CHECK: Relocations [ -; CHECK-NEXT: Section (4) DATA { +; CHECK-NEXT: Section (2) DATA { ; CHECK-NEXT: Relocation { ; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 (5) ; CHECK-NEXT: Offset: 0x13 Index: test/MC/WebAssembly/sections.ll =================================================================== --- test/MC/WebAssembly/sections.ll +++ test/MC/WebAssembly/sections.ll @@ -29,12 +29,6 @@ ; CHECK: Type: FUNCTION (0x3) ; CHECK: } ; CHECK: Section { -; CHECK: Type: GLOBAL (0x6) -; CHECK: } -; CHECK: Section { -; CHECK: Type: EXPORT (0x7) -; CHECK: } -; CHECK: Section { ; CHECK: Type: CODE (0xA) ; CHECK: } ; CHECK: Section { Index: test/MC/WebAssembly/unnamed-data.ll =================================================================== --- test/MC/WebAssembly/unnamed-data.ll +++ test/MC/WebAssembly/unnamed-data.ll @@ -9,47 +9,7 @@ @b = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i32 0, i32 0), align 8 -; CHECK: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 6 -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 16 -; CHECK-NEXT: - Index: 3 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 24 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: .L.str1 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: .L.str2 -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: a -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: b -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Type: DATA +; CHECK: - Type: DATA ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 ; CHECK-NEXT: Index: 0 @@ -87,9 +47,33 @@ ; CHECK-NEXT: DataSize: 28 ; CHECK-NEXT: SymbolInfo: ; CHECK-NEXT: - Name: .L.str1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 0 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 6 ; CHECK-NEXT: - Name: .L.str2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 1 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 6 +; CHECK-NEXT: - Name: a +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: b +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 3 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .rodata..L.str1 Index: test/MC/WebAssembly/visibility.ll =================================================================== --- test/MC/WebAssembly/visibility.ll +++ test/MC/WebAssembly/visibility.ll @@ -18,6 +18,14 @@ ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 0 ; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: - Name: defaultVis +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: - Name: hiddenVis +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 1 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 1 ; CHECK-NEXT: ... Index: test/MC/WebAssembly/weak-alias.ll =================================================================== --- test/MC/WebAssembly/weak-alias.ll +++ test/MC/WebAssembly/weak-alias.ll @@ -67,58 +67,6 @@ ; CHECK-NEXT: Initial: 0x00000001 ; CHECK-NEXT: - Type: FUNCTION ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ] -; CHECK-NEXT: - Type: GLOBAL -; CHECK-NEXT: Globals: -; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 8 -; CHECK-NEXT: - Index: 1 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 16 -; CHECK-NEXT: - Index: 2 -; CHECK-NEXT: Type: I32 -; CHECK-NEXT: Mutable: false -; CHECK-NEXT: InitExpr: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 0 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: foo -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: call_direct -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: call_alias -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: call_direct_ptr -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: direct_address -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: call_alias_ptr -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: alias_address -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: bar -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: foo_alias -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: bar_alias -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: @@ -193,19 +141,63 @@ ; CHECK-NEXT: DataSize: 20 ; CHECK-NEXT: SymbolInfo: ; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 0 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: - Name: call_direct +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 1 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 1 ; CHECK-NEXT: - Name: call_alias +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 2 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 2 ; CHECK-NEXT: - Name: call_direct_ptr +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 3 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Name: direct_address +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 4 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: - Name: call_alias_ptr +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 5 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: - Name: alias_address +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 6 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 +; CHECK-NEXT: - Name: bar +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 7 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: - Name: foo_alias +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 8 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: - Name: bar_alias +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 9 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: DataOffset: 0 +; CHECK-NEXT: DataSize: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.bar @@ -222,13 +214,13 @@ ; CHECK-NEXT: ... ; CHECK-SYMS: SYMBOL TABLE: -; CHECK-SYMS-NEXT: 00000000 g F EXPORT .hidden foo -; CHECK-SYMS-NEXT: 00000001 g F EXPORT .hidden call_direct -; CHECK-SYMS-NEXT: 00000002 g F EXPORT .hidden call_alias -; CHECK-SYMS-NEXT: 00000003 g F EXPORT .hidden call_direct_ptr -; CHECK-SYMS-NEXT: 00000008 g EXPORT direct_address -; CHECK-SYMS-NEXT: 00000004 g F EXPORT .hidden call_alias_ptr -; CHECK-SYMS-NEXT: 00000010 g EXPORT alias_address -; CHECK-SYMS-NEXT: 00000000 g EXPORT bar -; CHECK-SYMS-NEXT: 00000000 gw F EXPORT .hidden foo_alias -; CHECK-SYMS-NEXT: 00000000 gw EXPORT .hidden bar_alias +; CHECK-SYMS-NEXT: 00000000 g F CODE .hidden foo +; CHECK-SYMS-NEXT: 00000001 g F CODE .hidden call_direct +; CHECK-SYMS-NEXT: 00000002 g F CODE .hidden call_alias +; CHECK-SYMS-NEXT: 00000003 g F CODE .hidden call_direct_ptr +; CHECK-SYMS-NEXT: 00000008 g DATA direct_address +; CHECK-SYMS-NEXT: 00000004 g F CODE .hidden call_alias_ptr +; CHECK-SYMS-NEXT: 00000010 g DATA alias_address +; CHECK-SYMS-NEXT: 00000000 g DATA bar +; CHECK-SYMS-NEXT: 00000000 gw F CODE .hidden foo_alias +; CHECK-SYMS-NEXT: 00000000 gw DATA .hidden bar_alias Index: test/MC/WebAssembly/weak.ll =================================================================== --- test/MC/WebAssembly/weak.ll +++ test/MC/WebAssembly/weak.ll @@ -18,11 +18,6 @@ ; CHECK-NEXT: Field: __linear_memory ; CHECK: - Module: env ; CHECK-NEXT: Field: __indirect_function_table -; CHECK: - Module: env -; CHECK-NEXT: Field: weak_external_data -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: GlobalType: I32 -; CHECK-NEXT: GlobalMutable: false ; CHECK: - Type: CUSTOM @@ -30,7 +25,12 @@ ; CHECK-NEXT: DataSize: 0 ; CHECK-NEXT: SymbolInfo: ; CHECK-NEXT: - Name: weak_external_data +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: SymbolIndex: 0 ; CHECK-NEXT: Flags: [ BINDING_WEAK ] ; CHECK-NEXT: - Name: weak_function +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: SymbolIndex: 1 ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: FunctionIndex: 0 ; CHECK-NEXT: ... Index: test/Object/nm-trivial-object.test =================================================================== --- test/Object/nm-trivial-object.test +++ test/Object/nm-trivial-object.test @@ -59,11 +59,14 @@ COFF32-NEXT: 00000000 T _main COFF32-NEXT: U _puts -WASM: U SomeOtherFunction + +WASM: 00000000 d .L.str +WASM-NEXT: U SomeOtherFunction WASM-NEXT: 00000002 T main WASM-NEXT: U puts WASM-NEXT: 00000010 D var + COFF64: 00000000 d .data COFF64-NEXT: 00000000 t .text COFF64-NEXT: 00000000 r ??__Ex@@YAXXZ Index: test/Object/obj2yaml.test =================================================================== --- test/Object/obj2yaml.test +++ test/Object/obj2yaml.test @@ -645,17 +645,37 @@ ELF-AVR-NEXT: Section: .data ELF-AVR-NEXT: Value: 0x0000000000800060 + WASM: --- !WASM WASM-NEXT: FileHeader: WASM-NEXT: Version: 0x00000001 -WASM: - Type: EXPORT -WASM-NEXT: Exports: -WASM-NEXT: - Name: main -WASM-NEXT: Kind: FUNCTION -WASM-NEXT: Index: 2 -WASM-NEXT: - Name: var -WASM-NEXT: Kind: GLOBAL -WASM-NEXT: Index: 1 +WASM: - Type: CUSTOM +WASM-NEXT: Name: linking +WASM-NEXT: DataSize: 20 +WASM-NEXT: SymbolInfo: +WASM-NEXT: - Name: puts +WASM-NEXT: Kind: FUNCTION +WASM-NEXT: SymbolIndex: 0 +WASM-NEXT: Flags: [ ] +WASM-NEXT: FunctionIndex: 0 +WASM-NEXT: - Name: SomeOtherFunction +WASM: - Name: main +WASM: - Name: .L.str +WASM-NEXT: Kind: DATA +WASM-NEXT: SymbolIndex: 3 +WASM-NEXT: Flags: [ BINDING_LOCAL ] +WASM-NEXT: SegmentIndex: 0 +WASM-NEXT: DataOffset: 0 +WASM-NEXT: DataSize: 13 +WASM-NEXT: - Name: var +WASM: SegmentInfo: +WASM-NEXT: - Index: 0 +WASM-NEXT: Name: .rodata..L.str +WASM-NEXT: Alignment: 1 +WASM-NEXT: Flags: [ ] +WASM-NEXT: - Index: 1 +WASM: ... + ELF-X86-64-UNWIND: - Name: .eh_frame ELF-X86-64-UNWIND-NEXT: Type: SHT_X86_64_UNWIND Index: test/Object/objdump-relocations.test =================================================================== --- test/Object/objdump-relocations.test +++ test/Object/objdump-relocations.test @@ -60,7 +60,7 @@ ELF-MIPSEL: R_MIPS_CALL16 SomeOtherFunction WASM: CODE -WASM-NEXT: R_WEBASSEMBLY_MEMORY_ADDR_SLEB 0+0 +WASM-NEXT: R_WEBASSEMBLY_MEMORY_ADDR_SLEB 3+0 WASM-NEXT: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 0+0 WASM-NEXT: R_WEBASSEMBLY_FUNCTION_INDEX_LEB 1+0 Index: test/ObjectYAML/wasm/linking_section.yaml =================================================================== --- test/ObjectYAML/wasm/linking_section.yaml +++ test/ObjectYAML/wasm/linking_section.yaml @@ -32,7 +32,10 @@ DataSize: 999 SymbolInfo: - Name: bar + Kind: FUNCTION + SymbolIndex: 0 Flags: [ BINDING_WEAK ] + FunctionIndex: 0 SegmentInfo: - Index: 0 Alignment: 4 @@ -51,7 +54,10 @@ # CHECK-NEXT: DataSize: 999 # CHECK-NEXT: SymbolInfo: # CHECK-NEXT: - Name: bar +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: SymbolIndex: 0 # CHECK-NEXT: Flags: [ BINDING_WEAK ] +# CHECK-NEXT: FunctionIndex: 0 # CHECK-NEXT: SegmentInfo: # CHECK-NEXT: - Index: 0 # CHECK-NEXT: Name: mydata Index: test/ObjectYAML/wasm/weak_symbols.yaml =================================================================== --- test/ObjectYAML/wasm/weak_symbols.yaml +++ test/ObjectYAML/wasm/weak_symbols.yaml @@ -39,9 +39,15 @@ DataSize: 10 SymbolInfo: - Name: function_export + Kind: FUNCTION + SymbolIndex: 0 Flags: [ BINDING_WEAK ] + FunctionIndex: 0 - Name: global_export + Kind: GLOBAL + SymbolIndex: 1 Flags: [ BINDING_WEAK ] + GlobalIndex: 0 ... # CHECK: --- !WASM # CHECK: FileHeader: @@ -59,7 +65,13 @@ # CHECK: Name: linking # CHECK: DataSize: 10 # CHECK: SymbolInfo: -# CHECK: - Name: function_export -# CHECK: Flags: [ BINDING_WEAK ] -# CHECK: - Name: global_export -# CHECK: Flags: [ BINDING_WEAK ] +# CHECK: - Name: function_export +# CHECK: Kind: FUNCTION +# CHECK: SymbolIndex: 0 +# CHECK: Flags: [ BINDING_WEAK ] +# CHECK: FunctionIndex: 0 +# CHECK: - Name: global_export +# CHECK: Kind: GLOBAL +# CHECK: SymbolIndex: 1 +# CHECK: Flags: [ BINDING_WEAK ] +# CHECK: GlobalIndex: 0 Index: test/tools/llvm-nm/wasm/exports.yaml =================================================================== --- test/tools/llvm-nm/wasm/exports.yaml +++ test/tools/llvm-nm/wasm/exports.yaml @@ -1,7 +1,6 @@ # RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s -# That wasm exports of functions and globals are displayed as global data and -# code symbols. +# Check that wasm exports of functions/globals/data are displayed correctly --- !WASM FileHeader: @@ -13,69 +12,56 @@ ReturnType: I32 ParamTypes: - I32 - - Type: IMPORT - Imports: - - Module: env - Field: fimport - Kind: FUNCTION - SigIndex: 0 - - Module: env - Field: gimport - Kind: GLOBAL - GlobalType: I32 - GlobalMutable: false - Type: FUNCTION - FunctionTypes: [ 0, 0, 0, 0, 0 ] + FunctionTypes: [ 0 ] - Type: GLOBAL Globals: - - Index: 1 + - Index: 0 Type: I32 Mutable: false InitExpr: Opcode: I64_CONST Value: 32 - - Index: 2 - Type: I32 - Mutable: false - InitExpr: - Opcode: I32_CONST - Value: 64 - - Index: 3 - Type: I32 - Mutable: false - InitExpr: - Opcode: I32_CONST - Value: 1024 - - Type: EXPORT - Exports: - - Name: foo - Kind: FUNCTION - Index: 0x00000004 - - Name: bar - Kind: GLOBAL - Index: 0x00000003 - Type: CODE Functions: - - Index: 1 - Locals: - Body: 00 - - Index: 2 - Locals: - Body: 00 - - Index: 3 - Locals: - Body: 00 - - Index: 4 - Locals: - Body: 00 - - Index: 5 + - Index: 0 Locals: Body: 00 + - Type: DATA + Segments: + - SectionOffset: 6 + MemoryIndex: 0 + Offset: + Opcode: I32_CONST + Value: 0 + Content: '616263' - Type: CUSTOM - Name: "linking" - DataSize: 0 + Name: linking + DataSize: 3 + SymbolInfo: + - Name: fexport + Kind: FUNCTION + SymbolIndex: 0 + Flags: [ ] + FunctionIndex: 0 + - Name: gexport + Kind: GLOBAL + SymbolIndex: 1 + Flags: [ ] + GlobalIndex: 0 + - Name: dexport + Kind: DATA + SymbolIndex: 2 + Flags: [ ] + SegmentIndex: 0 + DataOffset: 0 + DataSize: 3 + SegmentInfo: + - Index: 0 + Name: .rodata.constantData + Alignment: 1 + Flags: [ ] -# CHECK: 00000400 D bar -# CHECK-NEXT: U fimport -# CHECK-NEXT: 00000004 T foo -# CHECK-NEXT: U gimport +# CHECK: 00000000 D dexport +# CHECK-NEXT: 00000000 T fexport +# CHECK-NEXT: 00000000 D gexport Index: test/tools/llvm-nm/wasm/imports.yaml =================================================================== --- test/tools/llvm-nm/wasm/imports.yaml +++ test/tools/llvm-nm/wasm/imports.yaml @@ -1,5 +1,7 @@ # RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s +# Check that wasm import of functions/globals/data are displayed correctly + --- !WASM FileHeader: Version: 0x00000001 @@ -13,17 +15,33 @@ - Type: IMPORT Imports: - Module: env - Field: foo + Field: fimport Kind: FUNCTION SigIndex: 0 - Module: env - Field: bar + Field: gimport Kind: GLOBAL GlobalType: I32 GlobalMutable: false - Type: CUSTOM - Name: "linking" - DataSize: 0 + Name: linking + DataSize: 3 + SymbolInfo: + - Name: fimport + Kind: FUNCTION + SymbolIndex: 0 + Flags: [ ] + FunctionIndex: 0 + - Name: gimport + Kind: GLOBAL + SymbolIndex: 1 + Flags: [ ] + GlobalIndex: 0 + - Name: dimport + Kind: DATA + SymbolIndex: 2 + Flags: [ ] -# CHECK: U bar -# CHECK: U foo +# CHECK: U dimport +# CHECK-NEXT: U fimport +# CHECK-NEXT: U gimport Index: test/tools/llvm-nm/wasm/weak-symbols.yaml =================================================================== --- test/tools/llvm-nm/wasm/weak-symbols.yaml +++ test/tools/llvm-nm/wasm/weak-symbols.yaml @@ -1,7 +1,6 @@ # RUN: yaml2obj < %s | llvm-nm - | FileCheck -strict-whitespace %s -# That wasm exports of functions and globals are displayed as global data and -# code symbols. +# Check that wasm weak function/global/data symbols are displayed correctly --- !WASM FileHeader: @@ -20,12 +19,12 @@ Kind: FUNCTION SigIndex: 0 - Module: env - Field: weak_import_data + Field: weak_import_global Kind: GLOBAL GlobalType: I32 GlobalMutable: false - Type: FUNCTION - FunctionTypes: [ 0, 0, 0, 0 ] + FunctionTypes: [ 0 ] - Type: GLOBAL Globals: - Index: 1 @@ -34,54 +33,64 @@ InitExpr: Opcode: I64_CONST Value: 32 - - Index: 2 - Type: I32 - Mutable: false - InitExpr: - Opcode: I32_CONST - Value: 64 - - Index: 3 - Type: I32 - Mutable: false - InitExpr: - Opcode: I32_CONST - Value: 1024 - - Type: EXPORT - Exports: - - Name: weak_global_func - Kind: FUNCTION - Index: 0x00000004 - - Name: weak_global_data - Kind: GLOBAL - Index: 0x00000003 - Type: CODE Functions: - Index: 1 Locals: Body: 00 - - Index: 2 - Locals: - Body: 00 - - Index: 3 - Locals: - Body: 00 - - Index: 4 - Locals: - Body: 00 + - Type: DATA + Segments: + - SectionOffset: 6 + MemoryIndex: 0 + Offset: + Opcode: I32_CONST + Value: 0 + Content: '616263' - Type: CUSTOM Name: linking - DataSize: 0 + DataSize: 3 SymbolInfo: - - Name: weak_global_func - Flags: [ BINDING_WEAK ] - - Name: weak_global_data - Flags: [ BINDING_WEAK ] - - Name: weak_import_func - Flags: [ BINDING_WEAK ] - - Name: weak_import_data - Flags: [ BINDING_WEAK ] + - Name: weak_defined_data + Kind: DATA + SymbolIndex: 0 + Flags: [ BINDING_WEAK ] + SegmentIndex: 0 + DataOffset: 0 + DataSize: 3 + - Name: weak_defined_func + Kind: FUNCTION + SymbolIndex: 1 + Flags: [ BINDING_WEAK ] + FunctionIndex: 1 + - Name: weak_defined_global + Kind: GLOBAL + SymbolIndex: 2 + Flags: [ BINDING_WEAK ] + GlobalIndex: 1 + - Name: weak_import_data + Kind: DATA + SymbolIndex: 3 + Flags: [ BINDING_WEAK ] + - Name: weak_import_func + Kind: FUNCTION + SymbolIndex: 4 + Flags: [ BINDING_WEAK ] + FunctionIndex: 0 + - Name: weak_import_global + Kind: GLOBAL + SymbolIndex: 5 + Flags: [ BINDING_WEAK ] + GlobalIndex: 0 + SegmentInfo: + - Index: 0 + Name: .rodata.constantData + Alignment: 1 + Flags: [ ] -# CHECK: 00000400 W weak_global_data -# CHECK: 00000004 W weak_global_func -# CHECK: w weak_import_data -# CHECK: w weak_import_func + +# CHECK: 00000000 W weak_defined_data +# CHECK-NEXT: 00000001 W weak_defined_func +# CHECK-NEXT: 00000001 W weak_defined_global +# CHECK-NEXT: w weak_import_data +# CHECK-NEXT: w weak_import_func +# CHECK-NEXT: w weak_import_global Index: test/tools/llvm-objdump/WebAssembly/symbol-table.test =================================================================== --- test/tools/llvm-objdump/WebAssembly/symbol-table.test +++ test/tools/llvm-objdump/WebAssembly/symbol-table.test @@ -3,6 +3,6 @@ CHECK: SYMBOL TABLE: CHECK-NEXT: 00000000 g F IMPORT puts CHECK-NEXT: 00000000 g F IMPORT SomeOtherFunction -CHECK-NEXT: 00000002 g F EXPORT main -CHECK-NEXT: 00000010 g EXPORT var - +CHECK-NEXT: 00000002 g F CODE main +CHECK-NEXT: 00000000 l DATA .L.str +CHECK-NEXT: 00000010 g DATA var Index: test/tools/llvm-objdump/wasm.txt =================================================================== --- test/tools/llvm-objdump/wasm.txt +++ test/tools/llvm-objdump/wasm.txt @@ -2,18 +2,13 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size Address Type -# CHECK-NEXT: 0 TYPE 0000000e 0000000000000000 -# CHECK-NEXT: 1 IMPORT 00000024 0000000000000000 -# CHECK-NEXT: 2 FUNCTION 00000002 0000000000000000 -# CHECK-NEXT: 3 TABLE 00000004 0000000000000000 -# CHECK-NEXT: 4 MEMORY 00000003 0000000000000000 -# CHECK-NEXT: 5 GLOBAL 0000000b 0000000000000000 -# CHECK-NEXT: 6 EXPORT 0000000e 0000000000000000 -# CHECK-NEXT: 7 CODE 00000019 0000000000000000 TEXT -# CHECK-NEXT: 8 DATA 0000001a 0000000000000000 DATA -# CHECK-NEXT: 9 name 0000002b 0000000000000000 -# CHECK-NEXT: 10 reloc.CODE 00000017 0000000000000000 -# CHECK-NEXT: 11 linking 00000016 0000000000000000 +# CHECK-NEXT: 0 TYPE 0000000e 0000000000000000 +# CHECK-NEXT: 1 IMPORT 0000005d 0000000000000000 +# CHECK-NEXT: 2 FUNCTION 00000002 0000000000000000 +# CHECK-NEXT: 3 CODE 00000019 0000000000000000 TEXT +# CHECK-NEXT: 4 DATA 0000001c 0000000000000000 DATA +# CHECK-NEXT: 5 reloc.CODE 00000017 0000000000000000 +# CHECK-NEXT: 6 linking 0000005c 0000000000000000 # RUN: llvm-objdump -p %p/Inputs/trivial.obj.wasm | FileCheck %s -check-prefix CHECK-HEADER Index: test/tools/llvm-readobj/relocations.test =================================================================== --- test/tools/llvm-readobj/relocations.test +++ test/tools/llvm-readobj/relocations.test @@ -287,11 +287,11 @@ MACHO-ARM-NEXT: ] WASM: Relocations [ -WASM-NEXT: Section (8) CODE { +WASM-NEXT: Section (4) CODE { WASM-NEXT: Relocation { WASM-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB (4) WASM-NEXT: Offset: 0x4 -WASM-NEXT: Index: 0x0 +WASM-NEXT: Index: 0x3 WASM-NEXT: Addend: 0 WASM-NEXT: } WASM-NEXT: Relocation { Index: test/tools/llvm-readobj/sections.test =================================================================== --- test/tools/llvm-readobj/sections.test +++ test/tools/llvm-readobj/sections.test @@ -501,50 +501,26 @@ WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: IMPORT (0x2) -WASM-NEXT: Size: 36 +WASM-NEXT: Size: 93 WASM-NEXT: Offset: 28 WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: FUNCTION (0x3) WASM-NEXT: Size: 2 -WASM-NEXT: Offset: 70 -WASM-NEXT: } -WASM-NEXT: Section { -WASM-NEXT: Type: TABLE (0x4) -WASM-NEXT: Size: 4 -WASM-NEXT: Offset: 78 -WASM-NEXT: } -WASM-NEXT: Section { -WASM-NEXT: Type: MEMORY (0x5) -WASM-NEXT: Size: 3 -WASM-NEXT: Offset: 88 -WASM-NEXT: Memories [ -WASM-NEXT: Memory { -WASM-NEXT: InitialPages: 1 -WASM-NEXT: } -WASM-NEXT: ] -WASM-NEXT: } -WASM-NEXT: Section { -WASM-NEXT: Type: GLOBAL (0x6) -WASM-NEXT: Size: 6 -WASM-NEXT: Offset: 97 -WASM-NEXT: } -WASM-NEXT: Section { -WASM-NEXT: Type: EXPORT (0x7) -WASM-NEXT: Size: 8 -WASM-NEXT: Offset: 109 +WASM-NEXT: Offset: 127 WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: CODE (0xA) WASM-NEXT: Size: 25 -WASM-NEXT: Offset: 123 +WASM-NEXT: Offset: 135 WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: DATA (0xB) WASM-NEXT: Size: 19 -WASM-NEXT: Offset: 154 +WASM-NEXT: Offset: 166 WASM-NEXT: Segments [ WASM-NEXT: Segment { +WASM-NEXT: Name: .rodata..L.str WASM-NEXT: Size: 13 WASM-NEXT: Offset: 0 WASM-NEXT: } @@ -552,20 +528,14 @@ WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: CUSTOM (0x0) -WASM-NEXT: Size: 43 -WASM-NEXT: Offset: 179 -WASM-NEXT: Name: name -WASM-NEXT: } -WASM-NEXT: Section { -WASM-NEXT: Type: CUSTOM (0x0) WASM-NEXT: Size: 23 -WASM-NEXT: Offset: 228 +WASM-NEXT: Offset: 191 WASM-NEXT: Name: reloc.CODE WASM-NEXT: } WASM-NEXT: Section { WASM-NEXT: Type: CUSTOM (0x0) -WASM-NEXT: Size: 22 -WASM-NEXT: Offset: 257 +WASM-NEXT: Size: 72 +WASM-NEXT: Offset: 220 WASM-NEXT: Name: linking WASM-NEXT: DataSize: 13 WASM-NEXT: } Index: test/tools/llvm-readobj/symbols.test =================================================================== --- test/tools/llvm-readobj/symbols.test +++ test/tools/llvm-readobj/symbols.test @@ -74,17 +74,22 @@ WASM: Symbols [ WASM-NEXT: Symbol { WASM-NEXT: Name: puts -WASM-NEXT: Type: FUNCTION_IMPORT (0x0) +WASM-NEXT: Type: FUNCTION (0x0) WASM-NEXT: Flags: 0x0 WASM-NEXT: } WASM-NEXT: Symbol { WASM-NEXT: Name: SomeOtherFunction -WASM-NEXT: Type: FUNCTION_IMPORT (0x0) +WASM-NEXT: Type: FUNCTION (0x0) WASM-NEXT: Flags: 0x0 WASM-NEXT: } WASM-NEXT: Symbol { WASM-NEXT: Name: main -WASM-NEXT: Type: FUNCTION_EXPORT (0x1) +WASM-NEXT: Type: FUNCTION (0x0) WASM-NEXT: Flags: 0x0 WASM-NEXT: } +WASM-NEXT: Symbol { +WASM-NEXT: Name: .L.str +WASM-NEXT: Type: DATA (0x1) +WASM-NEXT: Flags: 0x2 +WASM-NEXT: } WASM-NEXT: ] Index: tools/llvm-readobj/WasmDumper.cpp =================================================================== --- tools/llvm-readobj/WasmDumper.cpp +++ tools/llvm-readobj/WasmDumper.cpp @@ -24,10 +24,9 @@ static const EnumEntry WasmSymbolTypes[] = { #define ENUM_ENTRY(X) { #X, static_cast(WasmSymbol::SymbolType::X) } - ENUM_ENTRY(FUNCTION_IMPORT), - ENUM_ENTRY(FUNCTION_EXPORT), - ENUM_ENTRY(GLOBAL_IMPORT), - ENUM_ENTRY(GLOBAL_EXPORT), + ENUM_ENTRY(FUNCTION), + ENUM_ENTRY(DATA), + ENUM_ENTRY(GLOBAL), #undef ENUM_ENTRY }; Index: tools/obj2yaml/wasm2yaml.cpp =================================================================== --- tools/obj2yaml/wasm2yaml.cpp +++ tools/obj2yaml/wasm2yaml.cpp @@ -93,10 +93,32 @@ } for (const object::SymbolRef& Sym: Obj.symbols()) { const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym); - if (Symbol.Flags != 0) { - WasmYAML::SymbolInfo Info{Symbol.Name, Symbol.Flags}; - LinkingSec->SymbolInfos.emplace_back(Info); + WasmYAML::SymbolInfo Info; + Info.Name = Symbol.Name; + Info.Kind = static_cast(Symbol.Type); + Info.SymbolIndex = Symbol.SymbolIndex; + Info.Flags = Symbol.Flags; + switch (Symbol.Type) { + case object::WasmSymbol::SymbolType::DATA: + if (Symbol.Segment.hasValue()) { + Info.Segment.Index = + static_cast(Symbol.Segment.getValue().Index); + Info.Segment.Offset = Symbol.Segment.getValue().Offset; + Info.Segment.Size = Symbol.Segment.getValue().Size; + } else { + Info.Segment.Index = -1; + Info.Segment.Offset = 0; + Info.Segment.Size = 0; + } + break; + case object::WasmSymbol::SymbolType::FUNCTION: + Info.FunctionIndex = Symbol.WasmIndex; + break; + case object::WasmSymbol::SymbolType::GLOBAL: + Info.GlobalIndex = Symbol.WasmIndex; + break; } + LinkingSec->SymbolInfos.emplace_back(Info); } LinkingSec->DataSize = Obj.linkingData().DataSize; for (const wasm::WasmInitFunc &Func : Obj.linkingData().InitFunctions) { Index: tools/yaml2obj/yaml2wasm.cpp =================================================================== --- tools/yaml2obj/yaml2wasm.cpp +++ tools/yaml2obj/yaml2wasm.cpp @@ -12,6 +12,7 @@ /// //===----------------------------------------------------------------------===// // + #include "llvm/ObjectYAML/ObjectYAML.h" #include "llvm/Support/Endian.h" #include "llvm/Support/LEB128.h" @@ -140,14 +141,39 @@ encodeULEB128(Section.DataSize, SubSection.GetStream()); SubSection.Done(); - // SYMBOL_INFO subsection + // SYMBOL_TABLE subsection if (Section.SymbolInfos.size()) { - encodeULEB128(wasm::WASM_SYMBOL_INFO, OS); + encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS); encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream()); + uint32_t SymbolIndex = 0; + (void)SymbolIndex; for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) { - writeStringRef(Info.Name, SubSection.GetStream()); + assert(Info.SymbolIndex == SymbolIndex++); + encodeULEB128(Info.Kind, SubSection.GetStream()); encodeULEB128(Info.Flags, SubSection.GetStream()); + switch (Info.Kind) { + case wasm::WASM_SYMTAB_FUNCTION: + encodeULEB128(Info.FunctionIndex, SubSection.GetStream()); + if (Info.FunctionIndex >= NumImportedFunctions) + writeStringRef(Info.Name, SubSection.GetStream()); + break; + case wasm::WASM_SYMTAB_GLOBAL: + encodeULEB128(Info.GlobalIndex, SubSection.GetStream()); + if (Info.GlobalIndex >= NumImportedGlobals) + writeStringRef(Info.Name, SubSection.GetStream()); + break; + case wasm::WASM_SYMTAB_DATA: + writeStringRef(Info.Name, SubSection.GetStream()); + encodeSLEB128(Info.Segment.Index, SubSection.GetStream()); + if (Info.Segment.Index >= 0) { + encodeULEB128(Info.Segment.Offset, SubSection.GetStream()); + encodeULEB128(Info.Segment.Size, SubSection.GetStream()); + } + break; + default: + llvm_unreachable("unexpected kind"); + } } SubSection.Done();