Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -119,6 +119,14 @@ std::vector Functions; }; +// Represents the location of a Wasm data symbol within a WasmDataSegment, as +// the index of the segment, and the offset and size within the segment. +struct WasmDataReference { + uint32_t Segment; + uint32_t Offset; + uint32_t Size; +}; + struct WasmRelocation { uint32_t Type; // The type of the relocation. uint32_t Index; // Index into function or global index space. @@ -131,6 +139,16 @@ uint32_t Symbol; }; +struct WasmSymbolInfo { + StringRef Name; + uint32_t Kind; + uint32_t Flags; + // For a function or global symbol, the index into the the Wasm index space. + uint32_t ElementIndex; + // For a data symbol, the segment (or empty if the data symbol is undefined). + Optional Segment; +}; + struct WasmFunctionName { uint32_t Index; StringRef Name; @@ -139,6 +157,7 @@ struct WasmLinkingData { uint32_t DataSize; std::vector InitFunctions; + std::vector SymbolTable; }; enum : unsigned { @@ -205,11 +224,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 @@ -218,6 +237,13 @@ WASM_COMDAT_FUNCTION = 0x1, }; +// Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE +enum WasmSymbolType : unsigned { + WASM_SYMBOL_TYPE_FUNCTION = 0x0, + WASM_SYMBOL_TYPE_DATA = 0x1, + WASM_SYMBOL_TYPE_GLOBAL = 0x2, +}; + const unsigned WASM_SYMBOL_BINDING_MASK = 0x3; const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0x4; @@ -227,6 +253,10 @@ const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0; const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; +// Flags used internally in WasmObject but not written to the binary +const unsigned WASM_SYMBOL_OBJECT_MASK = 0x100; +const unsigned WASM_SYMBOL_OBJECT_DEFINED = 0x100; + #define WASM_RELOC(name, value) name = value, enum : unsigned { @@ -235,19 +265,6 @@ #undef WASM_RELOC -struct Global { - ValType Type; - bool Mutable; - - // The initial value for this global is either the value of an imported - // global, in which case InitialModule and InitialName specify the global - // import, or a value, in which case InitialModule is empty and InitialValue - // holds the value. - StringRef InitialModule; - StringRef InitialName; - uint64_t InitialValue; -}; - } // end namespace wasm } // end namespace llvm 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,16 +15,25 @@ 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; std::string ModuleName; SmallVector Returns; SmallVector Params; + wasm::WasmGlobalType GlobalType; bool ParamsSet = false; bool ReturnsSet = false; + bool GlobalTypeSet = false; /// An expression describing how to calculate the size of a symbol. If a /// symbol has no size this field will be NULL. @@ -41,8 +50,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; } @@ -74,6 +85,16 @@ ParamsSet = true; Params = std::move(Pars); } + + const wasm::WasmGlobalType &getGlobalType() const { + assert(GlobalTypeSet); + return GlobalType; + } + + void setGlobalType(wasm::WasmGlobalType GT) { + GlobalTypeSet = true; + GlobalType = GT; + } }; } // end namespace llvm 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" @@ -34,44 +35,39 @@ class WasmSymbol { public: - enum class SymbolType { - FUNCTION_IMPORT, - FUNCTION_EXPORT, - GLOBAL_IMPORT, - GLOBAL_EXPORT, - }; + WasmSymbol(uint32_t Section, const wasm::WasmSignature *FunctionType, + const wasm::WasmGlobalType *GlobalType, + const wasm::WasmSymbolInfo &Info) + : Section(Section), FunctionType(FunctionType), GlobalType(GlobalType), + Info(Info) {} - WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, - uint32_t SymbolIndex, uint32_t ElementIndex, - uint32_t FunctionType = 0) - : Name(Name), Type(Type), Section(Section), SymbolIndex(SymbolIndex), - ElementIndex(ElementIndex), FunctionType(FunctionType) {} - - StringRef Name; - SymbolType Type; uint32_t Section; - uint32_t Flags = 0; - // Index into the Symbol index space, which consists of all Symbols - // together, in order of declaration. - uint32_t SymbolIndex; - // For a function or global symbol, the index into the the Wasm index space. - // This is the index space used by the Wasm format for referring to a function - // or global, and consists of the imports then definitions. - uint32_t ElementIndex; + const wasm::WasmSignature *FunctionType; + const wasm::WasmGlobalType *GlobalType; - // For a function symbol, the type index. - uint32_t FunctionType; + const wasm::WasmSymbolInfo &Info; bool isTypeFunction() const { - return Type == WasmSymbol::SymbolType::FUNCTION_IMPORT || - Type == WasmSymbol::SymbolType::FUNCTION_EXPORT; + return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION; + } + + bool isTypeData() const { + return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; } bool isTypeGlobal() const { - return Type == SymbolType::GLOBAL_IMPORT || - Type == SymbolType::GLOBAL_EXPORT; + return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL; + } + + + bool isDefined() const { + return (Info.Flags & wasm::WASM_SYMBOL_OBJECT_DEFINED) != 0; + } + + bool isUndefined() const { + return !isDefined(); } @@ -88,7 +84,7 @@ } unsigned getBinding() const { - return Flags & wasm::WASM_SYMBOL_BINDING_MASK; + return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK; } bool isHidden() const { @@ -96,12 +92,16 @@ } unsigned getVisibility() const { - return Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK; + return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK; } void print(raw_ostream &Out) const { - Out << "Name=" << Name << ", Type=" << static_cast(Type) - << ", Flags=" << Flags << " ElemIndex=" << ElementIndex; + Out << "Name=" << Info.Name << ", Kind=" << static_cast(Info.Kind) + << ", Flags=" << Info.Flags; + if (!isTypeData()) + Out << ", ElemIndex=" << Info.ElementIndex; + else if (Info.Segment.hasValue()) + Out << ", SegmentIndex=" << Info.Segment.getValue().Segment; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -213,7 +213,8 @@ bool isValidGlobalIndex(uint32_t Index) const; bool isDefinedGlobalIndex(uint32_t Index) const; bool isValidFunctionSymbolIndex(uint32_t Index) const; - wasm::WasmFunction& getDefinedFunction(uint32_t Index); + wasm::WasmFunction &getDefinedFunction(uint32_t Index); + wasm::WasmGlobal &getDefinedGlobal(uint32_t Index); const WasmSection &getWasmSection(DataRefImpl Ref) const; const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const; @@ -242,12 +243,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; @@ -269,11 +269,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 Segment; + uint32_t Offset; + uint32_t Size; +}; + struct SymbolInfo { + uint32_t Index; StringRef Name; + SymbolKind Kind; SymbolFlags Flags; + union { + uint32_t FunctionIndex; + uint32_t GlobalIndex; + SymbolInfoSegment Segment; + }; }; struct InitFunction { @@ -189,7 +203,7 @@ } uint32_t DataSize; - std::vector SymbolInfos; + std::vector SymbolTable; std::vector SegmentInfos; std::vector InitFunctions; std::vector Comdats; @@ -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 @@ -147,6 +147,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. @@ -210,11 +219,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; @@ -244,9 +257,11 @@ SymbolIndices.clear(); WasmIndices.clear(); TableIndices.clear(); + SegmentIndices.clear(); FunctionTypeIndices.clear(); FunctionTypes.clear(); Globals.clear(); + DataSegments.clear(); MCObjectWriter::reset(); NumFunctionImports = 0; NumGlobalImports = 0; @@ -281,12 +296,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); @@ -519,13 +533,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().Segment]; // 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"); @@ -538,7 +549,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"); @@ -563,16 +573,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"); } @@ -812,16 +815,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 @@ -874,20 +877,42 @@ } 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_SYMBOL_TYPE_FUNCTION: + encodeULEB128(Sym.WasmIndex, getStream()); + if (Sym.WasmIndex >= NumFunctionImports) + writeString(Sym.Name); + break; + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + encodeULEB128(Sym.WasmIndex, getStream()); + if (Sym.WasmIndex >= NumGlobalImports) + writeString(Sym.Name); + break; + case wasm::WASM_SYMBOL_TYPE_DATA: + writeString(Sym.Name); + getStream() << static_cast(Sym.Segment.hasValue()); + if (Sym.Segment.hasValue()) { + encodeULEB128(Sym.Segment.getValue().Segment, getStream()); + encodeULEB128(Sym.Segment.getValue().Offset, getStream()); + encodeULEB128(Sym.Segment.getValue().Size, getStream()); + } + break; + default: + llvm_unreachable("unexpected kind"); + } } endSection(SubSection); } @@ -898,10 +923,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()); @@ -973,19 +998,24 @@ 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_SYMBOL_TYPE_DATA, Flags, 0, + SegmentIndices[&WS]}); + } else { + SymbolInfos.emplace_back( + WasmSymbolEntry{WS.getName(), static_cast(WS.getType()), + Flags, WasmIndices[&WS], None}); } }; @@ -1026,25 +1056,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 = 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); } @@ -1070,7 +1112,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( @@ -1100,9 +1142,8 @@ if (WS.isComdat() && !WS.isDefined()) continue; - unsigned WasmIndex; - if (WS.isFunction()) { + unsigned WasmIndex; if (WS.isDefined()) { if (WS.getOffset() != 0) report_fatal_error( @@ -1112,7 +1153,7 @@ report_fatal_error( "function symbols must have a size set with .size"); - // A definition. Export the function body. + // A definition. Write out the function body. WasmIndex = NumFunctionImports + Functions.size(); WasmFunction Func; Func.Type = getFunctionType(WS); @@ -1131,10 +1172,11 @@ } DEBUG(dbgs() << " -> function index: " << WasmIndex << "\n"); - } else { + } else if (WS.isData()) { if (WS.isTemporary() && !WS.getSize()) continue; + Optional SegInfo; if (WS.isDefined()) { if (!WS.getSize()) report_fatal_error("data symbols must have a size set with .size: " + @@ -1147,35 +1189,34 @@ 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.Type = PtrType; - Global.Type.Mutable = false; - Global.InitialValue = - DataSection.getMemoryOffset() + Layout.getSymbolOffset(WS); - 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. + SegInfo = wasm::WasmDataReference{ + DataSection.getSegmentIndex(), + static_cast(Layout.getSymbolOffset(WS)), + static_cast(Size)}; + SegmentIndices[&WS] = SegInfo; } else { // An import; the index was assigned above. + SegInfo = SegmentIndices.find(&WS)->second; + } + DEBUG(dbgs() << " -> segment index: " + << (SegInfo.hasValue() ? (int)SegInfo.getValue().Segment : -1) + << "\n"); + } 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 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); } @@ -1195,20 +1236,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().Segment << "\n"); + } else { + report_fatal_error("don't yet support global aliases"); + } SymbolIndices[&WS] = NumSymbols++; AddSymbol(WS); @@ -1302,11 +1342,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,119 @@ return Error::success(); } +Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr, + const uint8_t *End) { + uint32_t LinkingSection = Sections.size(); + uint32_t Count = readVaruint32(Ptr); + LinkingData.SymbolTable.reserve(Count); + 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--) { + wasm::WasmSymbolInfo Info; + uint32_t Section; + const wasm::WasmSignature *FunctionType = nullptr; + const wasm::WasmGlobalType *GlobalType = nullptr; + + Info.Kind = readVaruint32(Ptr); + Info.Flags = readVaruint32(Ptr); + + switch (Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + Info.ElementIndex = readVaruint32(Ptr); + if (!isValidFunctionIndex(Info.ElementIndex)) + return make_error("invalid function symbol index", + object_error::parse_failed); + if (isDefinedFunctionIndex(Info.ElementIndex)) { + Section = CodeSection; + Info.Name = readString(Ptr); + unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions; + FunctionType = &Signatures[FunctionTypes[FuncIndex]]; + Info.Flags |= wasm::WASM_SYMBOL_OBJECT_DEFINED; + 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 { + Section = ImportSection; + 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)) + return make_error("invalid global symbol index", + object_error::parse_failed); + if (isDefinedGlobalIndex(Info.ElementIndex)) { + Section = GlobalSection; + Info.Name = readString(Ptr); + unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals; + GlobalType = &Globals[GlobalIndex].Type; + Info.Flags |= wasm::WASM_SYMBOL_OBJECT_DEFINED; + } else { + Section = ImportSection; + 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 (*Ptr++) { + Section = DataSection; + uint32_t Index = readVaruint32(Ptr); + if (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); + Info.Segment = wasm::WasmDataReference{Index, Offset, Size}; + Info.Flags |= wasm::WASM_SYMBOL_OBJECT_DEFINED; + } else { + Section = LinkingSection; + } + break; + + default: + return make_error("Invalid symbol kind", + 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("Duplicate symbol name " + + Twine(Info.Name), + object_error::parse_failed); + LinkingData.SymbolTable.emplace_back(Info); + Symbols.emplace_back(Section, FunctionType, GlobalType, + LinkingData.SymbolTable.back()); + DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n"); + } + + return Error::success(); +} + Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End) { @@ -721,6 +735,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 +754,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++) { @@ -793,11 +807,16 @@ return Index < Symbols.size() && Symbols[Index].isTypeFunction(); } -wasm::WasmFunction& WasmObjectFile::getDefinedFunction(uint32_t Index) { +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)) @@ -807,6 +826,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 +890,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); @@ -913,21 +934,10 @@ 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.isUndefined()) Result |= SymbolRef::SF_Undefined; - break; - case WasmSymbol::SymbolType::GLOBAL_EXPORT: - break; - } - + if (Sym.isTypeFunction()) + Result |= SymbolRef::SF_Executable; return Result; } @@ -952,7 +962,7 @@ } Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const { - return getWasmSymbol(Symb).Name; + return getWasmSymbol(Symb).Info.Name; } Expected WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const { @@ -960,21 +970,20 @@ } 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: { + auto &SegmentSym = Sym.Info.Segment.getValue(); + auto &Segment = DataSegments[SegmentSym.Segment].Data; + assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST); + return Segment.Offset.Value.Int32 + SegmentSym.Offset; } + default: + llvm_unreachable("invalid symbol kind"); + break; } - llvm_unreachable("invalid symbol type"); } uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const { @@ -995,17 +1004,17 @@ 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; + default: + llvm_unreachable("Unknown WasmSymbol::SymbolType"); + return SymbolRef::ST_Other; } - - llvm_unreachable("Unknown WasmSymbol::SymbolType"); - return SymbolRef::ST_Other; } Expected Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ lib/ObjectYAML/WasmYAML.cpp @@ -58,7 +58,7 @@ 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); @@ -391,8 +391,23 @@ void MappingTraits::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("FunctionIndex", Info.FunctionIndex); + } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) { + IO.mapRequired("GlobalIndex", Info.GlobalIndex); + } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) { + IO.mapOptional("SegmentIndex", Info.Segment.Segment, -1); + if (Info.Segment.Segment >= 0) { + IO.mapOptional("Offset", Info.Segment.Offset, 0u); + IO.mapRequired("Size", Info.Segment.Size); + } + } else { + llvm_unreachable("unsupported symbol kind"); + } } void ScalarBitSetTraits::bitset( @@ -414,9 +429,19 @@ BCaseMask(BINDING_MASK, BINDING_LOCAL); //BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT); BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN); + //BCaseMask(OBJECT_MASK, OBJECT_DEFINED) #undef BCaseMask } +void ScalarEnumerationTraits::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::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 @@ -205,7 +205,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; @@ -91,9 +91,16 @@ 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(MCSymbolWasm::SymbolType::GLOBAL); + WasmSym->setGlobalType(wasm::WasmGlobalType{int32_t(iPTR), true}); return WasmSym; + } SmallVector Returns; SmallVector Params; @@ -101,7 +108,7 @@ WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(MCSymbolWasm::SymbolType::FUNCTION); return WasmSym; } @@ -189,7 +196,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,13 @@ ; CHECK: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 2 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: gBd +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: gBd ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 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,60 @@ @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: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: g0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: g1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: bar +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 3 +; CHECK-NEXT: Size: 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 @@ -98,24 +76,44 @@ ; CHECK-NEXT: - Type: CUSTOM ; 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: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: funcImport +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: callImport +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: basicInlineFn +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: sharedFn +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: constantData +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 3 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .rodata.constantData ; CHECK-NEXT: Alignment: 1 ; CHECK-NEXT: Flags: [ ] ; CHECK-NEXT: Comdats: -; CHECK-NEXT: - Name: basicInlineFn +; CHECK-NEXT: Name: basicInlineFn ; CHECK-NEXT: Entries: ; CHECK-NEXT: - Kind: FUNCTION ; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: sharedComdat +; CHECK-NEXT: Name: sharedComdat ; CHECK-NEXT: Entries: ; CHECK-NEXT: - Kind: FUNCTION ; CHECK-NEXT: Index: 3 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,35 @@ ; 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: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Offset: 8 +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: Size: 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: @@ -141,17 +111,62 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 4 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: __dso_handle +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func3 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: __dso_handle ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: .Lcall_dtors.42 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: __cxa_atexit +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func0 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: - Index: 6 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: .Lcall_dtors.42 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] -; CHECK-NEXT: - Name: .Lregister_call_dtors.42 +; CHECK-NEXT: FunctionIndex: 5 +; CHECK-NEXT: - Index: 7 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: .Lregister_call_dtors.42 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] -; CHECK-NEXT: - Name: .Lcall_dtors +; CHECK-NEXT: FunctionIndex: 6 +; CHECK-NEXT: - Index: 8 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: .Lcall_dtors ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] -; CHECK-NEXT: - Name: .Lregister_call_dtors +; CHECK-NEXT: FunctionIndex: 7 +; CHECK-NEXT: - Index: 9 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: .Lregister_call_dtors ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: FunctionIndex: 8 +; CHECK-NEXT: - Index: 10 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 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 @@ -85,11 +45,31 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 28 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: .L.str1 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: .L.str1 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] -; CHECK-NEXT: - Name: .L.str2 +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 6 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: .L.str2 ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Size: 6 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: a +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: b +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 3 +; CHECK-NEXT: Size: 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 @@ -17,7 +17,15 @@ ; CHECK: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 0 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: hiddenVis +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: defaultVis +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: hiddenVis ; 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: @@ -191,21 +139,61 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 20 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: foo +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: foo ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: call_direct +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: call_direct ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: call_alias +; CHECK-NEXT: FunctionIndex: 1 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: call_alias ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: call_direct_ptr +; CHECK-NEXT: FunctionIndex: 2 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: call_direct_ptr ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: call_alias_ptr +; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: direct_address +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 1 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: call_alias_ptr ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: foo_alias +; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: - Index: 6 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: alias_address +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 2 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 7 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: bar +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 8 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: foo_alias ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: bar_alias +; CHECK-NEXT: FunctionIndex: 0 +; CHECK-NEXT: - Index: 9 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: bar_alias ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: SegmentIndex: 0 +; CHECK-NEXT: Size: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.bar @@ -222,13 +210,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,19 +18,19 @@ ; 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 ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 0 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: weak_external_data +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: weak_external_data ; CHECK-NEXT: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: weak_function +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: weak_function ; 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,39 @@ 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: SymbolTable: +WASM-NEXT: - Index: 0 +WASM-NEXT: Kind: FUNCTION +WASM-NEXT: Name: puts +WASM-NEXT: Flags: [ ] +WASM-NEXT: FunctionIndex: 0 +WASM-NEXT: - Index: 1 +WASM: Name: SomeOtherFunction +WASM: - Index: 2 +WASM: Name: main +WASM: - Index: 3 +WASM-NEXT: Kind: DATA +WASM-NEXT: Name: .L.str +WASM-NEXT: Flags: [ BINDING_LOCAL ] +WASM-NEXT: SegmentIndex: 0 +WASM-NEXT: Size: 13 +WASM-NEXT: - Index: 4 +WASM: 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 @@ -30,9 +30,12 @@ - Type: CUSTOM Name: linking DataSize: 999 - SymbolInfo: - - Name: bar + SymbolTable: + - Index: 0 + Kind: FUNCTION + Name: bar Flags: [ BINDING_WEAK ] + FunctionIndex: 0 SegmentInfo: - Index: 0 Alignment: 4 @@ -49,9 +52,12 @@ # CHECK: - Type: CUSTOM # CHECK-NEXT: Name: linking # CHECK-NEXT: DataSize: 999 -# CHECK-NEXT: SymbolInfo: -# CHECK-NEXT: - Name: bar +# CHECK-NEXT: SymbolTable: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: bar # 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 @@ -37,11 +37,17 @@ - Type: CUSTOM Name: linking DataSize: 10 - SymbolInfo: - - Name: function_export + SymbolTable: + - Index: 0 + Kind: FUNCTION + Name: function_export Flags: [ BINDING_WEAK ] - - Name: global_export + FunctionIndex: 0 + - Index: 1 + Kind: GLOBAL + Name: global_export Flags: [ BINDING_WEAK ] + GlobalIndex: 0 ... # CHECK: --- !WASM # CHECK: FileHeader: @@ -58,8 +64,14 @@ # CHECK: - Type: CUSTOM # 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: SymbolTable: +# CHECK: - Index: 0 +# CHECK: Kind: FUNCTION +# CHECK: Name: function_export +# CHECK: Flags: [ BINDING_WEAK ] +# CHECK: FunctionIndex: 0 +# CHECK: - Index: 1 +# CHECK: Kind: GLOBAL +# CHECK: Name: global_export +# 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,55 @@ 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 + SymbolTable: + - Index: 0 + Kind: FUNCTION + Name: fexport + Flags: [ ] + FunctionIndex: 0 + - Index: 1 + Kind: GLOBAL + Name: gexport + Flags: [ ] + GlobalIndex: 0 + - Index: 2 + Kind: DATA + Name: dexport + Flags: [ ] + SegmentIndex: 0 + Size: 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 + SymbolTable: + - Index: 0 + Kind: FUNCTION + Name: fimport + Flags: [ ] + FunctionIndex: 0 + - Index: 1 + Kind: GLOBAL + Name: gimport + Flags: [ ] + GlobalIndex: 0 + - Index: 2 + Kind: DATA + Name: dimport + 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,63 @@ 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 - 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 ] + DataSize: 3 + SymbolTable: + - Index: 0 + Kind: DATA + Name: weak_defined_data + Flags: [ BINDING_WEAK ] + SegmentIndex: 0 + Size: 3 + - Index: 1 + Kind: FUNCTION + Name: weak_defined_func + Flags: [ BINDING_WEAK ] + FunctionIndex: 1 + - Index: 2 + Kind: GLOBAL + Name: weak_defined_global + Flags: [ BINDING_WEAK ] + GlobalIndex: 1 + - Index: 3 + Kind: DATA + Name: weak_import_data + Flags: [ BINDING_WEAK ] + - Index: 4 + Kind: FUNCTION + Name: weak_import_func + Flags: [ BINDING_WEAK ] + FunctionIndex: 0 + - Index: 5 + Kind: GLOBAL + Name: weak_import_global + 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 0000005e 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: 73 +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: Flags: 0x0 +WASM-NEXT: Type: FUNCTION (0x0) +WASM-NEXT: Flags: 0x100 +WASM-NEXT: } +WASM-NEXT: Symbol { +WASM-NEXT: Name: .L.str +WASM-NEXT: Type: DATA (0x1) +WASM-NEXT: Flags: 0x102 WASM-NEXT: } WASM-NEXT: ] Index: tools/llvm-readobj/WasmDumper.cpp =================================================================== --- tools/llvm-readobj/WasmDumper.cpp +++ tools/llvm-readobj/WasmDumper.cpp @@ -23,11 +23,10 @@ namespace { 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), +#define ENUM_ENTRY(X) { #X, wasm::WASM_SYMBOL_TYPE_##X } + ENUM_ENTRY(FUNCTION), + ENUM_ENTRY(DATA), + ENUM_ENTRY(GLOBAL), #undef ENUM_ENTRY }; @@ -203,9 +202,9 @@ void WasmDumper::printSymbol(const SymbolRef &Sym) { DictScope D(W, "Symbol"); WasmSymbol Symbol = Obj->getWasmSymbol(Sym.getRawDataRefImpl()); - W.printString("Name", Symbol.Name); - W.printEnum("Type", static_cast(Symbol.Type), makeArrayRef(WasmSymbolTypes)); - W.printHex("Flags", Symbol.Flags); + W.printString("Name", Symbol.Info.Name); + W.printEnum("Type", Symbol.Info.Kind, makeArrayRef(WasmSymbolTypes)); + W.printHex("Flags", Symbol.Info.Flags); } } Index: tools/obj2yaml/wasm2yaml.cpp =================================================================== --- tools/obj2yaml/wasm2yaml.cpp +++ tools/obj2yaml/wasm2yaml.cpp @@ -91,12 +91,34 @@ } SegmentIndex++; } - 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); + uint32_t SymbolIndex = 0; + for (const wasm::WasmSymbolInfo &Symbol: Obj.linkingData().SymbolTable) { + WasmYAML::SymbolInfo Info; + Info.Index = SymbolIndex++; + Info.Kind = static_cast(Symbol.Kind); + Info.Name = Symbol.Name; + Info.Flags = Symbol.Flags; + switch (Symbol.Kind) { + case wasm::WASM_SYMBOL_TYPE_DATA: + if (Symbol.Segment.hasValue()) { + Info.Segment.Segment = + static_cast(Symbol.Segment.getValue().Segment); + Info.Segment.Offset = Symbol.Segment.getValue().Offset; + Info.Segment.Size = Symbol.Segment.getValue().Size; + } else { + Info.Segment.Segment = -1; + Info.Segment.Offset = 0; + Info.Segment.Size = 0; + } + break; + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + Info.FunctionIndex = Symbol.ElementIndex; + break; + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + Info.GlobalIndex = Symbol.ElementIndex; + break; } + LinkingSec->SymbolTable.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,43 @@ encodeULEB128(Section.DataSize, SubSection.GetStream()); SubSection.Done(); - // SYMBOL_INFO subsection - if (Section.SymbolInfos.size()) { - encodeULEB128(wasm::WASM_SYMBOL_INFO, OS); + // SYMBOL_TABLE subsection + if (Section.SymbolTable.size()) { + encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS); - encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream()); - for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) { - writeStringRef(Info.Name, SubSection.GetStream()); - encodeULEB128(Info.Flags, SubSection.GetStream()); + encodeULEB128(Section.SymbolTable.size(), SubSection.GetStream()); + uint32_t SymbolIndex = 0; + (void)SymbolIndex; + for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) { + assert(Info.Index == SymbolIndex++); + encodeULEB128(Info.Kind, SubSection.GetStream()); + encodeULEB128(Info.Flags & ~wasm::WASM_SYMBOL_OBJECT_MASK, + SubSection.GetStream()); + switch (Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + encodeULEB128(Info.FunctionIndex, SubSection.GetStream()); + if (Info.FunctionIndex >= NumImportedFunctions) + writeStringRef(Info.Name, SubSection.GetStream()); + break; + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + encodeULEB128(Info.GlobalIndex, SubSection.GetStream()); + if (Info.GlobalIndex >= NumImportedGlobals) + writeStringRef(Info.Name, SubSection.GetStream()); + break; + case wasm::WASM_SYMBOL_TYPE_DATA: + writeStringRef(Info.Name, SubSection.GetStream()); + SubSection.GetStream() << + static_cast(Info.Segment.Segment >= 0); + if (Info.Segment.Segment >= 0) { + encodeULEB128(static_cast(Info.Segment.Segment), + SubSection.GetStream()); + encodeULEB128(Info.Segment.Offset, SubSection.GetStream()); + encodeULEB128(Info.Segment.Size, SubSection.GetStream()); + } + break; + default: + llvm_unreachable("unexpected kind"); + } } SubSection.Done();