Index: llvm/trunk/include/llvm/BinaryFormat/Wasm.h =================================================================== --- llvm/trunk/include/llvm/BinaryFormat/Wasm.h +++ llvm/trunk/include/llvm/BinaryFormat/Wasm.h @@ -119,16 +119,37 @@ 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. + uint32_t Index; // Index into either symbol or type index space. uint64_t Offset; // Offset from the start of the section. int64_t Addend; // A value to add to the symbol. }; struct WasmInitFunc { uint32_t Priority; - uint32_t FunctionIndex; + uint32_t Symbol; +}; + +struct WasmSymbolInfo { + StringRef Name; + uint32_t Kind; + uint32_t Flags; + union { + // For function or global symbols, the index in function of global index + // space. + uint32_t ElementIndex; + // For a data symbols, the address of the data relative to segment. + WasmDataReference DataRef; + }; }; struct WasmFunctionName { @@ -139,6 +160,7 @@ struct WasmLinkingData { uint32_t DataSize; std::vector InitFunctions; + std::vector SymbolTable; }; enum : unsigned { @@ -205,11 +227,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,14 +240,22 @@ 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; +const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc; const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0; const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1; const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2; const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0; const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; +const unsigned WASM_SYMBOL_UNDEFINED = 0x10; #define WASM_RELOC(name, value) name = value, @@ -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: llvm/trunk/include/llvm/MC/MCSectionWasm.h =================================================================== --- llvm/trunk/include/llvm/MC/MCSectionWasm.h +++ llvm/trunk/include/llvm/MC/MCSectionWasm.h @@ -37,17 +37,17 @@ // The offset of the MC function/data section in the wasm code/data section. // For data relocations the offset is relative to start of the data payload // itself and does not include the size of the section header. - uint64_t SectionOffset; + uint64_t SectionOffset = 0; - // For data sections, this is the offset of the corresponding wasm data + // For data sections, this is the index of of the corresponding wasm data // segment - uint64_t MemoryOffset; + uint32_t SegmentIndex = 0; 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) {} void setSectionName(StringRef Name) { SectionName = Name; } @@ -77,8 +77,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: llvm/trunk/include/llvm/MC/MCSymbolWasm.h =================================================================== --- llvm/trunk/include/llvm/MC/MCSymbolWasm.h +++ llvm/trunk/include/llvm/MC/MCSymbolWasm.h @@ -15,15 +15,17 @@ namespace llvm { class MCSymbolWasm : public MCSymbol { - bool IsFunction = false; + wasm::WasmSymbolType Type = wasm::WASM_SYMBOL_TYPE_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. @@ -40,8 +42,11 @@ 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 == wasm::WASM_SYMBOL_TYPE_FUNCTION; } + bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; } + bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; } + wasm::WasmSymbolType getType() const { return Type; } + void setType(wasm::WasmSymbolType type) { Type = type; } bool isWeak() const { return IsWeak; } void setWeak(bool isWeak) { IsWeak = isWeak; } @@ -74,6 +79,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: llvm/trunk/include/llvm/Object/Wasm.h =================================================================== --- llvm/trunk/include/llvm/Object/Wasm.h +++ llvm/trunk/include/llvm/Object/Wasm.h @@ -34,48 +34,30 @@ class WasmSymbol { public: - enum class SymbolType { - FUNCTION_IMPORT, - FUNCTION_EXPORT, - GLOBAL_IMPORT, - GLOBAL_EXPORT, - }; - - WasmSymbol(StringRef Name, SymbolType Type, uint32_t ElementIndex, - uint32_t FunctionType = 0) - : Name(Name), Type(Type), ElementIndex(ElementIndex), - FunctionType(FunctionType) {} - - StringRef Name; - SymbolType Type; - uint32_t Flags = 0; - - // Index into either the function or global index space. - uint32_t ElementIndex; - - // For function, the type index - uint32_t FunctionType; - - // Symbols can be both exported and imported (in the case of the weakly - // defined symbol). In this the import index is stored as AltIndex. - uint32_t AltIndex = 0; - bool HasAltIndex = false; - - void setAltIndex(uint32_t Index) { - HasAltIndex = true; - AltIndex = Index; - } + WasmSymbol(const wasm::WasmSymbolInfo &Info, + const wasm::WasmSignature *FunctionType, + const wasm::WasmGlobalType *GlobalType) + : Info(Info), FunctionType(FunctionType), GlobalType(GlobalType) {} + + const wasm::WasmSymbolInfo &Info; + const wasm::WasmSignature *FunctionType; + const wasm::WasmGlobalType *GlobalType; bool isTypeFunction() const { - return Type == SymbolType::FUNCTION_IMPORT || - Type == 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 !isUndefined(); } + + bool isUndefined() const { + return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0; + } bool isBindingWeak() const { return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK; @@ -90,7 +72,7 @@ } unsigned getBinding() const { - return Flags & wasm::WASM_SYMBOL_BINDING_MASK; + return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK; } bool isHidden() const { @@ -98,12 +80,19 @@ } 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=" << Info.Kind + << ", Flags=" << Info.Flags; + if (!isTypeData()) { + Out << ", ElemIndex=" << Info.ElementIndex; + } else if (isDefined()) { + Out << ", Segment=" << Info.DataRef.Segment; + Out << ", Offset=" << Info.DataRef.Offset; + Out << ", Size=" << Info.DataRef.Size; + } } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -154,6 +143,8 @@ ArrayRef comdats() const { return Comdats; } ArrayRef debugNames() const { return DebugNames; } uint32_t startFunction() const { return StartFunction; } + uint32_t getNumImportedGlobals() const { return NumImportedGlobals; } + uint32_t getNumImportedFunctions() const { return NumImportedFunctions; } void moveSymbolNext(DataRefImpl &Symb) const override; @@ -210,7 +201,11 @@ private: bool isValidFunctionIndex(uint32_t Index) const; bool isDefinedFunctionIndex(uint32_t Index) const; - wasm::WasmFunction& getDefinedFunction(uint32_t Index); + 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::WasmGlobal &getDefinedGlobal(uint32_t Index); const WasmSection &getWasmSection(DataRefImpl Ref) const; const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const; @@ -239,12 +234,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); - void populateSymbolTable(); - wasm::WasmObjectHeader Header; std::vector Sections; std::vector Signatures; @@ -267,8 +261,7 @@ uint32_t NumImportedFunctions = 0; uint32_t CodeSection = 0; uint32_t DataSection = 0; - - StringMap SymbolMap; + uint32_t GlobalSection = 0; }; } // end namespace object Index: llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h =================================================================== --- llvm/trunk/include/llvm/ObjectYAML/WasmYAML.h +++ llvm/trunk/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) @@ -130,13 +131,19 @@ }; struct SymbolInfo { + uint32_t Index; StringRef Name; + SymbolKind Kind; SymbolFlags Flags; + union { + uint32_t ElementIndex; + wasm::WasmDataReference DataRef; + }; }; struct InitFunction { uint32_t Priority; - uint32_t FunctionIndex; + uint32_t Symbol; }; struct ComdatEntry { @@ -189,7 +196,7 @@ } uint32_t DataSize; - std::vector SymbolInfos; + std::vector SymbolTable; std::vector SegmentInfos; std::vector InitFunctions; std::vector Comdats; @@ -368,6 +375,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: llvm/trunk/lib/MC/MCWasmStreamer.cpp =================================================================== --- llvm/trunk/lib/MC/MCWasmStreamer.cpp +++ llvm/trunk/lib/MC/MCWasmStreamer.cpp @@ -113,11 +113,11 @@ break; case MCSA_ELF_TypeFunction: - Symbol->setIsFunction(true); + Symbol->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); break; case MCSA_ELF_TypeObject: - Symbol->setIsFunction(false); + Symbol->setType(wasm::WASM_SYMBOL_TYPE_DATA); break; default: Index: llvm/trunk/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WasmObjectWriter.cpp +++ llvm/trunk/lib/MC/WasmObjectWriter.cpp @@ -190,13 +190,18 @@ // Maps function symbols to the table element index space. Used // for TABLE_INDEX relocation types (i.e. address taken functions). DenseMap TableIndices; - // Maps function/global symbols to the function/global index space. + // Maps function/global symbols to the (shared) Symbol index space. 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 DataLocations; DenseMap FunctionTypeIndices; SmallVector FunctionTypes; SmallVector Globals; + SmallVector DataSegments; unsigned NumFunctionImports = 0; unsigned NumGlobalImports = 0; @@ -224,10 +229,13 @@ DataRelocations.clear(); TypeIndices.clear(); SymbolIndices.clear(); + WasmIndices.clear(); TableIndices.clear(); + DataLocations.clear(); FunctionTypeIndices.clear(); FunctionTypes.clear(); Globals.clear(); + DataSegments.clear(); MCObjectWriter::reset(); NumFunctionImports = 0; NumGlobalImports = 0; @@ -262,14 +270,13 @@ 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); + const std::map> &Comdats); uint32_t getProvisionalValue(const WasmRelocationEntry &RelEntry); void applyRelocations(ArrayRef Relocations, @@ -494,11 +501,16 @@ assert(Sym->isFunction()); return TableIndices[Sym]; } - case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: - case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: - // Provisional value is function/type/global index itself + // Provisional value is same as the index return getRelocationIndexValue(RelEntry); + case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: + case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: + // Provisional value is function/global Wasm index + if (!WasmIndices.count(RelEntry.Symbol)) + report_fatal_error("symbol not found in wasm index space: " + + RelEntry.Symbol->getName()); + return WasmIndices[RelEntry.Symbol]; case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: { @@ -507,16 +519,10 @@ // For undefined symbols, use zero if (!Sym->isDefined()) return 0; - - if (!SymbolIndices.count(Sym)) - report_fatal_error("symbol not found in function/global index space: " + - Sym->getName()); - uint32_t GlobalIndex = SymbolIndices[Sym]; - const WasmGlobal& Global = Globals[GlobalIndex - NumGlobalImports]; - uint64_t Address = Global.InitialValue + RelEntry.Addend; - + const wasm::WasmDataReference &Ref = DataLocations[Sym]; + const WasmDataSegment &Segment = DataSegments[Ref.Segment]; // Ignore overflow. LLVM allows address arithmetic to silently wrap. - return Address; + return Segment.Offset + Ref.Offset + RelEntry.Addend; } default: llvm_unreachable("invalid relocation type"); @@ -529,7 +535,6 @@ DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment())); - size_t LastFragmentSize = 0; for (const MCFragment &Frag : DataSection) { if (Frag.hasInstructions()) report_fatal_error("only data supported in data sections"); @@ -554,16 +559,9 @@ 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"); } @@ -577,7 +575,7 @@ } if (!SymbolIndices.count(RelEntry.Symbol)) - report_fatal_error("symbol not found in function/global index space: " + + report_fatal_error("symbol not found in symbol index space: " + RelEntry.Symbol->getName()); return SymbolIndices[RelEntry.Symbol]; } @@ -802,16 +800,16 @@ 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 @@ -864,20 +862,37 @@ } void WasmObjectWriter::writeLinkingMetaDataSection( - ArrayRef Segments, uint32_t DataSize, - ArrayRef> SymbolFlags, + uint32_t DataSize, ArrayRef SymbolInfos, ArrayRef> InitFuncs, - const std::map>& Comdats) { + 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 (const wasm::WasmSymbolInfo &Sym : SymbolInfos) { + encodeULEB128(Sym.Kind, getStream()); + encodeULEB128(Sym.Flags, getStream()); + switch (Sym.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + encodeULEB128(Sym.ElementIndex, getStream()); + if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) + writeString(Sym.Name); + break; + case wasm::WASM_SYMBOL_TYPE_DATA: + writeString(Sym.Name); + if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { + encodeULEB128(Sym.DataRef.Segment, getStream()); + encodeULEB128(Sym.DataRef.Offset, getStream()); + encodeULEB128(Sym.DataRef.Size, getStream()); + } + break; + default: + llvm_unreachable("unexpected kind"); + } } endSection(SubSection); } @@ -888,10 +903,10 @@ endSection(SubSection); } - if (Segments.size()) { + if (DataSegments.size()) { startSection(SubSection, wasm::WASM_SEGMENT_INFO); - encodeULEB128(Segments.size(), getStream()); - for (const WasmDataSegment &Segment : Segments) { + encodeULEB128(DataSegments.size(), getStream()); + for (const WasmDataSegment &Segment : DataSegments) { writeString(Segment.Name); encodeULEB128(Segment.Alignment, getStream()); encodeULEB128(Segment.Flags, getStream()); @@ -956,19 +971,41 @@ const MCAsmLayout &Layout) { DEBUG(dbgs() << "WasmObjectWriter::writeObject\n"); MCContext &Ctx = Asm.getContext(); - int32_t PtrType = is64Bit() ? wasm::WASM_TYPE_I64 : wasm::WASM_TYPE_I32; // Collect information from the available symbols. SmallVector Functions; SmallVector TableElems; SmallVector Imports; SmallVector Exports; - SmallVector, 4> SymbolFlags; + SmallVector SymbolInfos; SmallVector, 2> InitFuncs; std::map> Comdats; - SmallVector DataSegments; + unsigned NumSymbols = 0; uint32_t DataSize = 0; + auto AddSymbol = [&](const MCSymbolWasm &WS) { + uint32_t Flags = 0; + if (WS.isWeak()) + Flags |= wasm::WASM_SYMBOL_BINDING_WEAK; + if (WS.isHidden()) + Flags |= wasm::WASM_SYMBOL_VISIBILITY_HIDDEN; + if (!WS.isExternal() && WS.isDefined()) + Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL; + if (WS.isUndefined()) + Flags |= wasm::WASM_SYMBOL_UNDEFINED; + + wasm::WasmSymbolInfo Info; + Info.Name = WS.getName(); + Info.Kind = WS.getType(); + Info.Flags = Flags; + if (!WS.isData()) + Info.ElementIndex = WasmIndices[&WS]; + else if (WS.isDefined()) + Info.DataRef = DataLocations[&WS]; + SymbolInfos.emplace_back(Info); + SymbolIndices[&WS] = NumSymbols++; + }; + // For now, always emit the memory import, since loads and stores are not // valid without it. In the future, we could perhaps be more clever and omit // it if there are no loads or stores. @@ -1005,31 +1042,32 @@ continue; // If the symbol is not defined in this translation unit, import it. - if ((!WS.isDefined() && !WS.isComdat()) || - WS.isVariable()) { - wasm::WasmImport Import; - Import.Module = WS.getModuleName(); - Import.Field = WS.getName(); - + if (!WS.isDefined() && !WS.isComdat()) { if (WS.isFunction()) { + wasm::WasmImport Import; + Import.Module = WS.getModuleName(); + Import.Field = WS.getName(); Import.Kind = wasm::WASM_EXTERNAL_FUNCTION; Import.SigIndex = getFunctionType(WS); - SymbolIndices[&WS] = NumFunctionImports; - ++NumFunctionImports; - } else { + Imports.push_back(Import); + WasmIndices[&WS] = NumFunctionImports++; + } else if (WS.isGlobal()) { + wasm::WasmImport Import; + Import.Module = WS.getModuleName(); + Import.Field = WS.getName(); Import.Kind = wasm::WASM_EXTERNAL_GLOBAL; - Import.Global.Type = PtrType; - // If this global is the stack pointer, make it mutable. - if (WS.getName() == "__stack_pointer") - Import.Global.Mutable = true; - else - Import.Global.Mutable = false; - - SymbolIndices[&WS] = NumGlobalImports; - ++NumGlobalImports; + Import.Global = WS.getGlobalType(); + Imports.push_back(Import); + WasmIndices[&WS] = NumGlobalImports++; } - Imports.push_back(Import); + // TODO(ncw) We shouldn't be adding the symbol to the symbol table here! + // Instead it should be done by removing the "if (WS.isDefined())" block + // in the big loop below (line ~1284). However - that would reorder all + // the symbols and thus require all the tests to be updated. I think it's + // better to make that change therefore in a future commit, to isolate + // each test update from the change that caused it. + AddSymbol(WS); } } @@ -1053,7 +1091,7 @@ Segment.Alignment = Section.getAlignment(); Segment.Flags = 0; DataSize += Segment.Data.size(); - Section.setMemoryOffset(Segment.Offset); + Section.setSegmentIndex(SegmentIndex); if (const MCSymbolWasm *C = Section.getGroup()) { Comdats[C->getName()].emplace_back( @@ -1078,18 +1116,13 @@ << " isHidden=" << WS.isHidden() << " isVariable=" << WS.isVariable() << "\n"); - if (WS.isWeak() || WS.isHidden()) { - uint32_t Flags = (WS.isWeak() ? wasm::WASM_SYMBOL_BINDING_WEAK : 0) | - (WS.isHidden() ? wasm::WASM_SYMBOL_VISIBILITY_HIDDEN : 0); - SymbolFlags.emplace_back(WS.getName(), Flags); - } - if (WS.isVariable()) continue; - - unsigned Index; + if (WS.isComdat() && !WS.isDefined()) + continue; if (WS.isFunction()) { + unsigned Index; if (WS.isDefined()) { if (WS.getOffset() != 0) report_fatal_error( @@ -1099,27 +1132,33 @@ report_fatal_error( "function symbols must have a size set with .size"); - // A definition. Take the next available index. + // A definition. Write out the function body. Index = NumFunctionImports + Functions.size(); - - // Prepare the function. WasmFunction Func; Func.Type = getFunctionType(WS); Func.Sym = &WS; - SymbolIndices[&WS] = Index; + WasmIndices[&WS] = Index; Functions.push_back(Func); + + auto &Section = static_cast(WS.getSection()); + if (const MCSymbolWasm *C = Section.getGroup()) { + Comdats[C->getName()].emplace_back( + WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index}); + } } else { // An import; the index was assigned above. - Index = SymbolIndices.find(&WS)->second; + Index = WasmIndices.find(&WS)->second; } DEBUG(dbgs() << " -> function index: " << Index << "\n"); - } else { + } else if (WS.isData()) { if (WS.isTemporary() && !WS.getSize()) continue; - if (!WS.isDefined()) + if (!WS.isDefined()) { + DEBUG(dbgs() << " -> segment index: -1"); continue; + } if (!WS.getSize()) report_fatal_error("data symbols must have a size set with .size: " + @@ -1129,43 +1168,32 @@ if (!WS.getSize()->evaluateAsAbsolute(Size, Layout)) report_fatal_error(".size expression must be evaluatable"); - // For each global, prepare a corresponding wasm global holding its - // address. For externals these will also be named exports. - Index = NumGlobalImports + Globals.size(); auto &DataSection = static_cast(WS.getSection()); assert(DataSection.isWasmData()); - WasmGlobal Global; - Global.Type.Type = PtrType; - Global.Type.Mutable = false; - Global.InitialValue = DataSection.getMemoryOffset() + Layout.getSymbolOffset(WS); - SymbolIndices[&WS] = Index; - DEBUG(dbgs() << " -> global index: " << Index << "\n"); - Globals.push_back(Global); - } - - // If the symbol is visible outside this translation unit, export it. - if (WS.isDefined()) { - wasm::WasmExport Export; - Export.Name = WS.getName(); - Export.Index = Index; - if (WS.isFunction()) - Export.Kind = wasm::WASM_EXTERNAL_FUNCTION; - else - Export.Kind = wasm::WASM_EXTERNAL_GLOBAL; - DEBUG(dbgs() << " -> export " << Exports.size() << "\n"); - Exports.push_back(Export); - - if (!WS.isExternal()) - SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL); - - if (WS.isFunction()) { - auto &Section = static_cast(WS.getSection()); - if (const MCSymbolWasm *C = Section.getGroup()) - Comdats[C->getName()].emplace_back( - WasmComdatEntry{wasm::WASM_COMDAT_FUNCTION, Index}); + // For each data symbol, export it in the symtab as a reference to the + // corresponding Wasm data segment. + wasm::WasmDataReference Ref = wasm::WasmDataReference{ + DataSection.getSegmentIndex(), + static_cast(Layout.getSymbolOffset(WS)), + static_cast(Size)}; + DataLocations[&WS] = Ref; + DEBUG(dbgs() << " -> segment index: " << Ref.Segment); + } else { + // A "true" Wasm global (currently just __stack_pointer) + unsigned WasmIndex; + if (WS.isDefined()) { + report_fatal_error("don't yet support defined globals"); + } else { + // An import; the index was assigned above + WasmIndex = WasmIndices.find(&WS)->second; } + + DEBUG(dbgs() << " -> global index: " << WasmIndex << "\n"); } + + if (WS.isDefined()) + AddSymbol(WS); } // Handle weak aliases. We need to process these in a separate pass because @@ -1181,22 +1209,23 @@ const auto &WS = static_cast(S); const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS); DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n"); - assert(SymbolIndices.count(ResolvedSym) > 0); - uint32_t Index = SymbolIndices.find(ResolvedSym)->second; - DEBUG(dbgs() << " -> index:" << Index << "\n"); - - wasm::WasmExport Export; - Export.Name = WS.getName(); - Export.Index = Index; - if (WS.isFunction()) - Export.Kind = wasm::WASM_EXTERNAL_FUNCTION; - else - Export.Kind = wasm::WASM_EXTERNAL_GLOBAL; - DEBUG(dbgs() << " -> export " << Exports.size() << "\n"); - Exports.push_back(Export); - if (!WS.isExternal()) - SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL); + if (WS.isFunction()) { + assert(WasmIndices.count(ResolvedSym) > 0); + uint32_t WasmIndex = WasmIndices.find(ResolvedSym)->second; + WasmIndices[&WS] = WasmIndex; + DEBUG(dbgs() << " -> index:" << WasmIndex << "\n"); + } else if (WS.isData()) { + assert(DataLocations.count(ResolvedSym) > 0); + const wasm::WasmDataReference &Ref = + DataLocations.find(ResolvedSym)->second; + DataLocations[&WS] = Ref; + DEBUG(dbgs() << " -> index:" << Ref.Segment << "\n"); + } else { + report_fatal_error("don't yet support global aliases"); + } + + AddSymbol(WS); } { @@ -1209,12 +1238,12 @@ return; assert(Rel.Symbol->isFunction()); const MCSymbolWasm &WS = *ResolveSymbol(*Rel.Symbol); - uint32_t SymbolIndex = SymbolIndices.find(&WS)->second; + uint32_t FunctionIndex = WasmIndices.find(&WS)->second; uint32_t TableIndex = TableElems.size() + kInitialTableOffset; if (TableIndices.try_emplace(&WS, TableIndex).second) { DEBUG(dbgs() << " -> adding " << WS.getName() << " to table: " << TableIndex << "\n"); - TableElems.push_back(SymbolIndex); + TableElems.push_back(FunctionIndex); registerFunctionType(WS); } }; @@ -1287,11 +1316,10 @@ 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: llvm/trunk/lib/Object/WasmObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/WasmObjectFile.cpp +++ llvm/trunk/lib/Object/WasmObjectFile.cpp @@ -317,69 +317,6 @@ return Error::success(); } -void WasmObjectFile::populateSymbolTable() { - // Add imports to symbol table - size_t GlobalIndex = 0; - size_t FunctionIndex = 0; - for (const wasm::WasmImport& Import : Imports) { - switch (Import.Kind) { - case wasm::WASM_EXTERNAL_GLOBAL: - assert(Import.Global.Type == wasm::WASM_TYPE_I32); - SymbolMap.try_emplace(Import.Field, Symbols.size()); - Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT, - GlobalIndex++); - DEBUG(dbgs() << "Adding import: " << Symbols.back() - << " sym index:" << Symbols.size() << "\n"); - break; - case wasm::WASM_EXTERNAL_FUNCTION: - SymbolMap.try_emplace(Import.Field, Symbols.size()); - Symbols.emplace_back(Import.Field, - WasmSymbol::SymbolType::FUNCTION_IMPORT, - FunctionIndex++, Import.SigIndex); - DEBUG(dbgs() << "Adding import: " << Symbols.back() - << " sym index:" << Symbols.size() << "\n"); - break; - default: - break; - } - } - - // Add exports to symbol table - for (const wasm::WasmExport& Export : Exports) { - if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION || - Export.Kind == wasm::WASM_EXTERNAL_GLOBAL) { - WasmSymbol::SymbolType ExportType = - Export.Kind == wasm::WASM_EXTERNAL_FUNCTION - ? WasmSymbol::SymbolType::FUNCTION_EXPORT - : WasmSymbol::SymbolType::GLOBAL_EXPORT; - auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size()); - if (Pair.second) { - Symbols.emplace_back(Export.Name, ExportType, Export.Index); - DEBUG(dbgs() << "Adding export: " << Symbols.back() - << " sym index:" << Symbols.size() << "\n"); - } else { - uint32_t SymIndex = Pair.first->second; - const WasmSymbol &OldSym = Symbols[SymIndex]; - WasmSymbol NewSym(Export.Name, ExportType, Export.Index); - NewSym.setAltIndex(OldSym.ElementIndex); - Symbols[SymIndex] = NewSym; - - DEBUG(dbgs() << "Replacing existing symbol: " << NewSym - << " sym index:" << SymIndex << "\n"); - } - } - if (Export.Kind == wasm::WASM_EXTERNAL_FUNCTION && - isDefinedFunctionIndex(Export.Index)) { - auto &Function = getDefinedFunction(Export.Index); - if (Function.Name.empty()) { - // Use the export's name to set a name for the Function, but only if one - // hasn't already been set. - Function.Name = Export.Name; - } - } - } -} - Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr, const uint8_t *End) { HasLinkingSection = true; @@ -388,37 +325,15 @@ "Linking data must come after code section", object_error::parse_failed); } - // Only populate the symbol table with imports and exports if the object - // has a linking section (i.e. its a relocatable object file). Otherwise - // the global might not represent symbols at all. - populateSymbolTable(); - while (Ptr < End) { uint8_t Type = readVarint7(Ptr); uint32_t Size = readVaruint32(Ptr); const uint8_t *SubSectionEnd = Ptr + Size; switch (Type) { - case wasm::WASM_SYMBOL_INFO: { - uint32_t Count = readVaruint32(Ptr); - while (Count--) { - StringRef Symbol = readString(Ptr); - uint32_t Flags = readVaruint32(Ptr); - auto iter = SymbolMap.find(Symbol); - if (iter == SymbolMap.end()) { - return make_error( - "Invalid symbol name in linking section: " + Symbol, - object_error::parse_failed); - } - uint32_t SymIndex = iter->second; - assert(SymIndex < Symbols.size()); - Symbols[SymIndex].Flags = Flags; - DEBUG(dbgs() << "Set symbol flags index:" - << SymIndex << " name:" - << Symbols[SymIndex].Name << " expected:" - << Symbol << " flags: " << Flags << "\n"); - } + case wasm::WASM_SYMBOL_TABLE: + if (Error Err = parseLinkingSectionSymtab(Ptr, SubSectionEnd)) + return Err; break; - } case wasm::WASM_DATA_SIZE: LinkingData.DataSize = readVaruint32(Ptr); break; @@ -440,10 +355,10 @@ for (uint32_t i = 0; i < Count; i++) { wasm::WasmInitFunc Init; Init.Priority = readVaruint32(Ptr); - Init.FunctionIndex = readVaruint32(Ptr); - if (!isValidFunctionIndex(Init.FunctionIndex)) - return make_error("Invalid function index: " + - Twine(Init.FunctionIndex), + Init.Symbol = readVaruint32(Ptr); + if (!isValidFunctionSymbolIndex(Init.Symbol)) + return make_error("Invalid function symbol: " + + Twine(Init.Symbol), object_error::parse_failed); LinkingData.InitFunctions.emplace_back(Init); } @@ -467,6 +382,110 @@ return Error::success(); } +Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr, + const uint8_t *End) { + uint32_t Count = readVaruint32(Ptr); + LinkingData.SymbolTable.reserve(Count); + Symbols.reserve(Count); + StringSet<> SymbolNames; + + std::vector 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; + const wasm::WasmSignature *FunctionType = nullptr; + const wasm::WasmGlobalType *GlobalType = nullptr; + + Info.Kind = readUint8(Ptr); + Info.Flags = readVaruint32(Ptr); + bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0; + + switch (Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + Info.ElementIndex = readVaruint32(Ptr); + if (!isValidFunctionIndex(Info.ElementIndex) || + IsDefined != isDefinedFunctionIndex(Info.ElementIndex)) + return make_error("invalid function symbol index", + object_error::parse_failed); + if (IsDefined) { + Info.Name = readString(Ptr); + unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions; + FunctionType = &Signatures[FunctionTypes[FuncIndex]]; + auto &Function = Functions[FuncIndex]; + if (Function.Name.empty()) { + // Use the symbol's name to set a name for the Function, but only if + // one hasn't already been set. + Function.Name = Info.Name; + } + } else { + wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex]; + FunctionType = &Signatures[Import.SigIndex]; + Info.Name = Import.Field; + } + break; + + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + Info.ElementIndex = readVaruint32(Ptr); + if (!isValidGlobalIndex(Info.ElementIndex) || + IsDefined != isDefinedGlobalIndex(Info.ElementIndex)) + return make_error("invalid global symbol index", + object_error::parse_failed); + if (IsDefined) { + Info.Name = readString(Ptr); + unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals; + GlobalType = &Globals[GlobalIndex].Type; + } else { + wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex]; + Info.Name = Import.Field; + GlobalType = &Import.Global; + } + break; + + case wasm::WASM_SYMBOL_TYPE_DATA: + Info.Name = readString(Ptr); + if (IsDefined) { + uint32_t Index = readVaruint32(Ptr); + if (Index >= DataSegments.size()) + return make_error("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.DataRef = wasm::WasmDataReference{Index, Offset, Size}; + } + break; + + default: + return make_error("Invalid symbol type", + object_error::parse_failed); + } + + if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) != + wasm::WASM_SYMBOL_BINDING_LOCAL && + !SymbolNames.insert(Info.Name).second) + return make_error("Duplicate symbol name " + + Twine(Info.Name), + object_error::parse_failed); + LinkingData.SymbolTable.emplace_back(Info); + Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType, + GlobalType); + DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n"); + } + + return Error::success(); +} + Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr, const uint8_t *End) { @@ -706,6 +725,7 @@ } Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) { + GlobalSection = Sections.size(); uint32_t Count = readVaruint32(Ptr); Globals.reserve(Count); while (Count--) { @@ -737,12 +757,11 @@ return make_error("Invalid function export", object_error::parse_failed); break; - case wasm::WASM_EXTERNAL_GLOBAL: { - if (Ex.Index >= Globals.size() + NumImportedGlobals) + case wasm::WASM_EXTERNAL_GLOBAL: + if (!isValidGlobalIndex(Ex.Index)) return make_error("Invalid global export", object_error::parse_failed); break; - } case wasm::WASM_EXTERNAL_MEMORY: case wasm::WASM_EXTERNAL_TABLE: break; @@ -759,18 +778,35 @@ } bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const { - return Index < FunctionTypes.size() + NumImportedFunctions; + return Index < NumImportedFunctions + FunctionTypes.size(); } bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const { return Index >= NumImportedFunctions && isValidFunctionIndex(Index); } -wasm::WasmFunction& WasmObjectFile::getDefinedFunction(uint32_t Index) { +bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const { + return Index < NumImportedGlobals + Globals.size(); +} + +bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const { + return Index >= NumImportedGlobals && isValidGlobalIndex(Index); +} + +bool WasmObjectFile::isValidFunctionSymbolIndex(uint32_t Index) const { + return Index < Symbols.size() && Symbols[Index].isTypeFunction(); +} + +wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) { assert(isDefinedFunctionIndex(Index)); return Functions[Index - NumImportedFunctions]; } +wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) { + assert(isDefinedGlobalIndex(Index)); + return Globals[Index - NumImportedGlobals]; +} + Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) { StartFunction = readVaruint32(Ptr); if (!isValidFunctionIndex(StartFunction)) @@ -888,21 +924,10 @@ Result |= SymbolRef::SF_Global; if (Sym.isHidden()) Result |= SymbolRef::SF_Hidden; - - switch (Sym.Type) { - case WasmSymbol::SymbolType::FUNCTION_IMPORT: - Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable; - break; - case WasmSymbol::SymbolType::FUNCTION_EXPORT: - Result |= SymbolRef::SF_Executable; - break; - case WasmSymbol::SymbolType::GLOBAL_IMPORT: + if (!Sym.isDefined()) Result |= SymbolRef::SF_Undefined; - break; - case WasmSymbol::SymbolType::GLOBAL_EXPORT: - break; - } - + if (Sym.isTypeFunction()) + Result |= SymbolRef::SF_Executable; return Result; } @@ -927,7 +952,7 @@ } Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const { - return getWasmSymbol(Symb).Name; + return getWasmSymbol(Symb).Info.Name; } Expected WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const { @@ -935,18 +960,17 @@ } uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const { - switch (Sym.Type) { - case WasmSymbol::SymbolType::FUNCTION_IMPORT: - case WasmSymbol::SymbolType::GLOBAL_IMPORT: - case WasmSymbol::SymbolType::FUNCTION_EXPORT: - return Sym.ElementIndex; - case WasmSymbol::SymbolType::GLOBAL_EXPORT: { - uint32_t GlobalIndex = Sym.ElementIndex - NumImportedGlobals; - assert(GlobalIndex < Globals.size()); - const wasm::WasmGlobal &Global = Globals[GlobalIndex]; - // WasmSymbols correspond only to I32_CONST globals - assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST); - return Global.InitExpr.Value.Int32; + switch (Sym.Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + return Sym.Info.ElementIndex; + case wasm::WASM_SYMBOL_TYPE_DATA: { + // The value of a data symbol is the segment offset, plus the symbol + // offset within the segment. + uint32_t SegmentIndex = Sym.Info.DataRef.Segment; + const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data; + assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST); + return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; } } llvm_unreachable("invalid symbol type"); @@ -970,12 +994,12 @@ WasmObjectFile::getSymbolType(DataRefImpl Symb) const { const WasmSymbol &Sym = getWasmSymbol(Symb); - switch (Sym.Type) { - case WasmSymbol::SymbolType::FUNCTION_IMPORT: - case WasmSymbol::SymbolType::FUNCTION_EXPORT: + switch (Sym.Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: return SymbolRef::ST_Function; - case WasmSymbol::SymbolType::GLOBAL_IMPORT: - case WasmSymbol::SymbolType::GLOBAL_EXPORT: + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + return SymbolRef::ST_Other; + case wasm::WASM_SYMBOL_TYPE_DATA: return SymbolRef::ST_Data; } @@ -985,14 +1009,24 @@ Expected WasmObjectFile::getSymbolSection(DataRefImpl Symb) const { - DataRefImpl Ref; const WasmSymbol& Sym = getWasmSymbol(Symb); - if (Sym.Type == WasmSymbol::SymbolType::GLOBAL_EXPORT) - Ref.d.a = DataSection; - else if (Sym.Type == WasmSymbol::SymbolType::FUNCTION_EXPORT) - Ref.d.a = CodeSection; - else + if (Sym.isUndefined()) return section_end(); + + DataRefImpl Ref; + switch (Sym.Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + Ref.d.a = CodeSection; + break; + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + Ref.d.a = GlobalSection; + break; + case wasm::WASM_SYMBOL_TYPE_DATA: + Ref.d.a = DataSection; + break; + default: + llvm_unreachable("Unknown WasmSymbol::SymbolType"); + } return section_iterator(SectionRef(Ref, this)); } Index: llvm/trunk/lib/ObjectYAML/WasmYAML.cpp =================================================================== --- llvm/trunk/lib/ObjectYAML/WasmYAML.cpp +++ llvm/trunk/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); @@ -366,7 +366,7 @@ void MappingTraits::mapping( IO &IO, WasmYAML::InitFunction &Init) { IO.mapRequired("Priority", Init.Priority); - IO.mapRequired("FunctionIndex", Init.FunctionIndex); + IO.mapRequired("Symbol", Init.Symbol); } void ScalarEnumerationTraits::enumeration( @@ -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("Function", Info.ElementIndex); + } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) { + IO.mapRequired("Global", Info.ElementIndex); + } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) { + if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { + IO.mapRequired("Segment", Info.DataRef.Segment); + IO.mapOptional("Offset", Info.DataRef.Offset, 0u); + IO.mapRequired("Size", Info.DataRef.Size); + } + } else { + llvm_unreachable("unsupported symbol kind"); + } } void ScalarBitSetTraits::bitset( @@ -414,9 +429,19 @@ BCaseMask(BINDING_MASK, BINDING_LOCAL); //BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT); BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN); + BCaseMask(UNDEFINED, UNDEFINED); #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: llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp =================================================================== --- llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp +++ llvm/trunk/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp @@ -215,7 +215,7 @@ WasmSym->setParams(std::move(ValParams)); WasmSym->setReturns(std::move(ValResults)); - WasmSym->setIsFunction(true); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); } void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) { Index: llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp =================================================================== --- llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -74,7 +74,7 @@ WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); } return WasmSym; @@ -91,9 +91,16 @@ const WebAssemblySubtarget &Subtarget = Printer.getSubtarget(); // __stack_pointer is a global variable; all other external symbols used by - // CodeGen are functions. - if (strcmp(Name, "__stack_pointer") == 0) + // CodeGen are functions. It's OK to hardcode knowledge of specific symbols + // here; this method is precisely there for fetching the signatures of known + // Clang-provided symbols. + if (strcmp(Name, "__stack_pointer") == 0) { + wasm::ValType iPTR = + Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32; + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL); + WasmSym->setGlobalType(wasm::WasmGlobalType{int32_t(iPTR), true}); return WasmSym; + } SmallVector Returns; SmallVector Params; @@ -101,7 +108,7 @@ WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); return WasmSym; } @@ -189,7 +196,7 @@ MCSymbolWasm *WasmSym = cast(Sym); WasmSym->setReturns(std::move(Returns)); WasmSym->setParams(std::move(Params)); - WasmSym->setIsFunction(true); + WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION); const MCExpr *Expr = MCSymbolRefExpr::create(WasmSym, Index: llvm/trunk/test/MC/WebAssembly/array-fill.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/array-fill.ll +++ llvm/trunk/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: Segment: 0 +; CHECK-NEXT: Size: 2 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data Index: llvm/trunk/test/MC/WebAssembly/bss.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/bss.ll +++ llvm/trunk/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: Segment: 0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: g1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 1 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 2 +; CHECK-NEXT: Size: 0 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: bar +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 3 +; CHECK-NEXT: Size: 0 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .bss.g0 Index: llvm/trunk/test/MC/WebAssembly/comdat.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/comdat.ll +++ llvm/trunk/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: [ UNDEFINED ] +; CHECK-NEXT: Function: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: callImport +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Function: 1 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: basicInlineFn +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: Function: 2 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: sharedFn +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: Function: 3 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: constantData +; CHECK-NEXT: Flags: [ BINDING_WEAK ] +; CHECK-NEXT: Segment: 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: llvm/trunk/test/MC/WebAssembly/explicit-sections.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/explicit-sections.ll +++ llvm/trunk/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: Segment: 0 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 1 +; CHECK-NEXT: Size: 8 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global2 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 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: Segment: 2 +; CHECK-NEXT: Size: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.global0 Index: llvm/trunk/test/MC/WebAssembly/func-address.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/func-address.ll +++ llvm/trunk/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 @@ -44,6 +44,6 @@ ; CHECK: Relocation { ; CHECK: Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB (1) ; CHECK: Offset: 0x1E -; CHECK: Index: 0x2 +; CHECK: Index: 0x3 ; CHECK: } ; CHECK: } Index: llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/global-ctor-dtor.ll +++ llvm/trunk/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: @@ -97,25 +67,25 @@ ; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000004 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; CHECK-NEXT: Index: 5 +; CHECK-NEXT: Index: 6 ; CHECK-NEXT: Offset: 0x0000000F ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x00000017 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: Offset: 0x0000001D ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 2 +; CHECK-NEXT: Index: 3 ; CHECK-NEXT: Offset: 0x0000002C ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB -; CHECK-NEXT: Index: 7 +; CHECK-NEXT: Index: 8 ; CHECK-NEXT: Offset: 0x00000037 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_SLEB -; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: Offset: 0x0000003F ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: Offset: 0x00000045 ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Index: 5 @@ -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: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: .Lcall_dtors.42 +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func3 +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: __dso_handle +; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, UNDEFINED ] +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: __cxa_atexit +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 1 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func2 +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 2 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func1 +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 3 +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: func0 +; CHECK-NEXT: Flags: [ UNDEFINED ] +; CHECK-NEXT: Function: 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: Function: 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: Function: 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: Function: 7 +; CHECK-NEXT: - Index: 9 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: .Lregister_call_dtors ; CHECK-NEXT: Flags: [ BINDING_LOCAL ] +; CHECK-NEXT: Function: 8 +; CHECK-NEXT: - Index: 10 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: global1 +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 0 +; CHECK-NEXT: Size: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.global1 @@ -159,11 +174,11 @@ ; CHECK-NEXT: Flags: [ ] ; CHECK-NEXT: InitFunctions: ; CHECK-NEXT: - Priority: 42 -; CHECK-NEXT: FunctionIndex: 3 +; CHECK-NEXT: Symbol: 4 ; CHECK-NEXT: - Priority: 42 -; CHECK-NEXT: FunctionIndex: 6 +; CHECK-NEXT: Symbol: 7 ; CHECK-NEXT: - Priority: 65535 -; CHECK-NEXT: FunctionIndex: 4 +; CHECK-NEXT: Symbol: 5 ; CHECK-NEXT: - Priority: 65535 -; CHECK-NEXT: FunctionIndex: 8 +; CHECK-NEXT: Symbol: 9 ; CHECK-NEXT: ... Index: llvm/trunk/test/MC/WebAssembly/reloc-code.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/reloc-code.ll +++ llvm/trunk/test/MC/WebAssembly/reloc-code.ll @@ -24,17 +24,17 @@ ; 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 -; CHECK-NEXT: Index: 0x0 +; CHECK-NEXT: Index: 0x3 ; CHECK-NEXT: Addend: 0 ; CHECK-NEXT: } ; CHECK-NEXT: Relocation { ; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3) ; CHECK-NEXT: Offset: 0x14 -; CHECK-NEXT: Index: 0x1 +; CHECK-NEXT: Index: 0x4 ; CHECK-NEXT: Addend: 0 ; CHECK-NEXT: } ; CHECK-NEXT: Relocation { Index: llvm/trunk/test/MC/WebAssembly/reloc-data.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/reloc-data.ll +++ llvm/trunk/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: llvm/trunk/test/MC/WebAssembly/sections.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/sections.ll +++ llvm/trunk/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: llvm/trunk/test/MC/WebAssembly/unnamed-data.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/unnamed-data.ll +++ llvm/trunk/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: Segment: 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: Segment: 1 +; CHECK-NEXT: Size: 6 +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: a +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 2 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: b +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 3 +; CHECK-NEXT: Size: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .rodata..L.str1 Index: llvm/trunk/test/MC/WebAssembly/visibility.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/visibility.ll +++ llvm/trunk/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: Function: 0 +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: hiddenVis ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: Function: 1 ; CHECK-NEXT: ... Index: llvm/trunk/test/MC/WebAssembly/weak-alias.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/weak-alias.ll +++ llvm/trunk/test/MC/WebAssembly/weak-alias.ll @@ -65,118 +65,57 @@ ; CHECK-NEXT: ElemType: ANYFUNC ; CHECK-NEXT: Limits: ; CHECK-NEXT: Initial: 0x00000001 -; CHECK-NEXT: - Module: env -; CHECK-NEXT: Field: foo_alias -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: SigIndex: 0 -; CHECK-NEXT: - Module: env -; CHECK-NEXT: Field: bar_alias -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: GlobalType: I32 -; CHECK-NEXT: GlobalMutable: false ; CHECK-NEXT: - Type: FUNCTION ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ] -; 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: 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: 0 -; CHECK-NEXT: - Type: EXPORT -; CHECK-NEXT: Exports: -; CHECK-NEXT: - Name: foo -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: call_direct -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: call_alias -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: call_direct_ptr -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 4 -; CHECK-NEXT: - Name: direct_address -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: call_alias_ptr -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 5 -; CHECK-NEXT: - Name: alias_address -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 2 -; CHECK-NEXT: - Name: bar -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 3 -; CHECK-NEXT: - Name: foo_alias -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Name: bar_alias -; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 3 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 1 -; CHECK-NEXT: Functions: [ 1 ] +; CHECK-NEXT: Functions: [ 0 ] ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000009 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB -; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Index: 8 ; CHECK-NEXT: Offset: 0x00000012 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 4 ; CHECK-NEXT: Offset: 0x0000001E ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB ; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000024 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB -; CHECK-NEXT: Index: 2 +; CHECK-NEXT: Index: 6 ; CHECK-NEXT: Offset: 0x00000031 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB ; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x00000037 ; CHECK-NEXT: Functions: -; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Locals: ; CHECK-NEXT: Body: 41000B -; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: - Index: 1 ; CHECK-NEXT: Locals: -; CHECK-NEXT: Body: 1081808080000B -; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: Body: 1080808080000B +; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Locals: ; CHECK-NEXT: Body: 1080808080000B -; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: - Index: 3 ; CHECK-NEXT: Locals: ; CHECK-NEXT: Body: 410028028880808000118080808000000B -; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: - Index: 4 ; CHECK-NEXT: Locals: ; CHECK-NEXT: Body: 410028029080808000118080808000000B ; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 0 ; CHECK-NEXT: Offset: 0x0000000F ; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32 -; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Index: 8 ; CHECK-NEXT: Offset: 0x00000018 ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 @@ -200,21 +139,61 @@ ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 20 -; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: foo_alias -; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: bar_alias -; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] -; 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: Function: 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: Function: 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: Function: 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: Function: 3 +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: direct_address +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 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: Function: 4 +; CHECK-NEXT: - Index: 6 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: alias_address +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 2 +; CHECK-NEXT: Size: 4 +; CHECK-NEXT: - Index: 7 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: bar +; CHECK-NEXT: Flags: [ ] +; CHECK-NEXT: Segment: 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: Function: 0 +; CHECK-NEXT: - Index: 9 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: bar_alias +; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: Segment: 0 +; CHECK-NEXT: Size: 4 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.bar @@ -231,13 +210,13 @@ ; CHECK-NEXT: ... ; CHECK-SYMS: SYMBOL TABLE: -; CHECK-SYMS-NEXT: 00000001 gw F CODE .hidden foo_alias -; CHECK-SYMS-NEXT: 00000000 gw DATA .hidden bar_alias -; CHECK-SYMS-NEXT: 00000001 g F CODE .hidden foo -; CHECK-SYMS-NEXT: 00000002 g F CODE .hidden call_direct -; CHECK-SYMS-NEXT: 00000003 g F CODE .hidden call_alias -; CHECK-SYMS-NEXT: 00000004 g F CODE .hidden call_direct_ptr +; 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: 00000005 g F CODE .hidden call_alias_ptr +; 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: llvm/trunk/test/MC/WebAssembly/weak.ll =================================================================== --- llvm/trunk/test/MC/WebAssembly/weak.ll +++ llvm/trunk/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: Flags: [ BINDING_WEAK ] -; CHECK-NEXT: - Name: weak_function +; CHECK-NEXT: SymbolTable: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: Kind: DATA +; CHECK-NEXT: Name: weak_external_data +; CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ] +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Name: weak_function ; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ] +; CHECK-NEXT: Function: 0 ; CHECK-NEXT: ... Index: llvm/trunk/test/Object/nm-trivial-object.test =================================================================== --- llvm/trunk/test/Object/nm-trivial-object.test +++ llvm/trunk/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: llvm/trunk/test/Object/obj2yaml.test =================================================================== --- llvm/trunk/test/Object/obj2yaml.test +++ llvm/trunk/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: [ UNDEFINED ] +WASM-NEXT: Function: 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: Segment: 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: llvm/trunk/test/Object/objdump-relocations.test =================================================================== --- llvm/trunk/test/Object/objdump-relocations.test +++ llvm/trunk/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: llvm/trunk/test/ObjectYAML/wasm/linking_section.yaml =================================================================== --- llvm/trunk/test/ObjectYAML/wasm/linking_section.yaml +++ llvm/trunk/test/ObjectYAML/wasm/linking_section.yaml @@ -30,9 +30,12 @@ - Type: CUSTOM Name: linking DataSize: 999 - SymbolInfo: - - Name: bar - Flags: [ BINDING_WEAK ] + SymbolTable: + - Index: 0 + Kind: FUNCTION + Name: bar + Flags: [ BINDING_WEAK, UNDEFINED ] + Function: 0 SegmentInfo: - Index: 0 Alignment: 4 @@ -44,14 +47,17 @@ Name: moredata InitFunctions: - Priority: 1 - FunctionIndex: 0 + Symbol: 0 ... # CHECK: - Type: CUSTOM # CHECK-NEXT: Name: linking # CHECK-NEXT: DataSize: 999 -# CHECK-NEXT: SymbolInfo: -# CHECK-NEXT: - Name: bar -# CHECK-NEXT: Flags: [ BINDING_WEAK ] +# CHECK-NEXT: SymbolTable: +# CHECK-NEXT: - Index: 0 +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Name: bar +# CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ] +# CHECK-NEXT: Function: 0 # CHECK-NEXT: SegmentInfo: # CHECK-NEXT: - Index: 0 # CHECK-NEXT: Name: mydata @@ -63,5 +69,5 @@ # CHECK-NEXT: Flags: [ ] # CHECK-NEXT: InitFunctions: # CHECK-NEXT: - Priority: 1 -# CHECK-NEXT: FunctionIndex: 0 +# CHECK-NEXT: Symbol: 0 # CHECK-NEXT: ... Index: llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml =================================================================== --- llvm/trunk/test/ObjectYAML/wasm/weak_symbols.yaml +++ llvm/trunk/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 + Function: 0 + - Index: 1 + Kind: GLOBAL + Name: global_export Flags: [ BINDING_WEAK ] + Global: 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: Function: 0 +# CHECK: - Index: 1 +# CHECK: Kind: GLOBAL +# CHECK: Name: global_export +# CHECK: Flags: [ BINDING_WEAK ] +# CHECK: Global: 0 Index: llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml =================================================================== --- llvm/trunk/test/tools/llvm-nm/wasm/exports.yaml +++ llvm/trunk/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: [ ] + Function: 0 + - Index: 1 + Kind: GLOBAL + Name: gexport + Flags: [ ] + Global: 0 + - Index: 2 + Kind: DATA + Name: dexport + Flags: [ ] + Segment: 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: llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml =================================================================== --- llvm/trunk/test/tools/llvm-nm/wasm/imports.yaml +++ llvm/trunk/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: [ UNDEFINED ] + Function: 0 + - Index: 1 + Kind: GLOBAL + Name: gimport + Flags: [ UNDEFINED ] + Global: 0 + - Index: 2 + Kind: DATA + Name: dimport + Flags: [ UNDEFINED ] -# CHECK: U bar -# CHECK: U foo +# CHECK: U dimport +# CHECK-NEXT: U fimport +# CHECK-NEXT: U gimport Index: llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml =================================================================== --- llvm/trunk/test/tools/llvm-nm/wasm/weak-symbols.yaml +++ llvm/trunk/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 ] + Segment: 0 + Size: 3 + - Index: 1 + Kind: FUNCTION + Name: weak_defined_func + Flags: [ BINDING_WEAK ] + Function: 1 + - Index: 2 + Kind: GLOBAL + Name: weak_defined_global + Flags: [ BINDING_WEAK ] + Global: 1 + - Index: 3 + Kind: DATA + Name: weak_import_data + Flags: [ BINDING_WEAK, UNDEFINED ] + - Index: 4 + Kind: FUNCTION + Name: weak_import_func + Flags: [ BINDING_WEAK, UNDEFINED ] + Function: 0 + - Index: 5 + Kind: GLOBAL + Name: weak_import_global + Flags: [ BINDING_WEAK, UNDEFINED ] + Global: 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: llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test =================================================================== --- llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test +++ llvm/trunk/test/tools/llvm-objdump/WebAssembly/symbol-table.test @@ -4,5 +4,5 @@ CHECK-NEXT: 00000000 g F *UND* puts CHECK-NEXT: 00000000 g F *UND* SomeOtherFunction CHECK-NEXT: 00000002 g F CODE main +CHECK-NEXT: 00000000 l DATA .L.str CHECK-NEXT: 00000010 g DATA var - Index: llvm/trunk/test/tools/llvm-objdump/wasm.txt =================================================================== --- llvm/trunk/test/tools/llvm-objdump/wasm.txt +++ llvm/trunk/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: llvm/trunk/test/tools/llvm-readobj/relocations.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/relocations.test +++ llvm/trunk/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: llvm/trunk/test/tools/llvm-readobj/sections.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/sections.test +++ llvm/trunk/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: llvm/trunk/test/tools/llvm-readobj/symbols.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/symbols.test +++ llvm/trunk/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: Flags: 0x0 +WASM-NEXT: Type: FUNCTION (0x0) +WASM-NEXT: Flags: 0x10 WASM-NEXT: } WASM-NEXT: Symbol { WASM-NEXT: Name: SomeOtherFunction -WASM-NEXT: Type: FUNCTION_IMPORT (0x0) -WASM-NEXT: Flags: 0x0 +WASM-NEXT: Type: FUNCTION (0x0) +WASM-NEXT: Flags: 0x10 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: llvm/trunk/tools/llvm-readobj/WasmDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/WasmDumper.cpp +++ llvm/trunk/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 }; @@ -158,8 +157,7 @@ if (!LinkingData.InitFunctions.empty()) { ListScope Group(W, "InitFunctions"); for (const wasm::WasmInitFunc &F: LinkingData.InitFunctions) - W.startLine() << F.FunctionIndex << " (priority=" << F.Priority - << ")\n"; + W.startLine() << F.Symbol << " (priority=" << F.Priority << ")\n"; } } break; @@ -203,9 +201,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: llvm/trunk/tools/obj2yaml/wasm2yaml.cpp =================================================================== --- llvm/trunk/tools/obj2yaml/wasm2yaml.cpp +++ llvm/trunk/tools/obj2yaml/wasm2yaml.cpp @@ -91,16 +91,27 @@ } 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: + Info.DataRef = Symbol.DataRef; + break; + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + Info.ElementIndex = Symbol.ElementIndex; + break; } + LinkingSec->SymbolTable.emplace_back(Info); } LinkingSec->DataSize = Obj.linkingData().DataSize; for (const wasm::WasmInitFunc &Func : Obj.linkingData().InitFunctions) { - WasmYAML::InitFunction F{Func.Priority, Func.FunctionIndex}; + WasmYAML::InitFunction F{Func.Priority, Func.Symbol}; LinkingSec->InitFunctions.emplace_back(F); } CustomSec = std::move(LinkingSec); Index: llvm/trunk/tools/yaml2obj/yaml2wasm.cpp =================================================================== --- llvm/trunk/tools/yaml2obj/yaml2wasm.cpp +++ llvm/trunk/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,36 @@ encodeULEB128(Section.DataSize, SubSection.GetStream()); SubSection.Done(); - // SYMBOL_INFO subsection - if (Section.SymbolInfos.size()) { - encodeULEB128(wasm::WASM_SYMBOL_INFO, OS); - - encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream()); - for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) { - writeStringRef(Info.Name, SubSection.GetStream()); + // SYMBOL_TABLE subsection + if (Section.SymbolTable.size()) { + encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS); + + encodeULEB128(Section.SymbolTable.size(), SubSection.GetStream()); +#ifndef _NDEBUG + uint32_t SymbolIndex = 0; +#endif + for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) { + assert(Info.Index == SymbolIndex++); + encodeULEB128(Info.Kind, SubSection.GetStream()); encodeULEB128(Info.Flags, SubSection.GetStream()); + switch (Info.Kind) { + case wasm::WASM_SYMBOL_TYPE_FUNCTION: + case wasm::WASM_SYMBOL_TYPE_GLOBAL: + encodeULEB128(Info.ElementIndex, SubSection.GetStream()); + if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) + writeStringRef(Info.Name, SubSection.GetStream()); + break; + case wasm::WASM_SYMBOL_TYPE_DATA: + writeStringRef(Info.Name, SubSection.GetStream()); + if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { + encodeULEB128(Info.DataRef.Segment, SubSection.GetStream()); + encodeULEB128(Info.DataRef.Offset, SubSection.GetStream()); + encodeULEB128(Info.DataRef.Size, SubSection.GetStream()); + } + break; + default: + llvm_unreachable("unexpected kind"); + } } SubSection.Done(); @@ -171,7 +194,7 @@ encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream()); for (const WasmYAML::InitFunction &Func : Section.InitFunctions) { encodeULEB128(Func.Priority, SubSection.GetStream()); - encodeULEB128(Func.FunctionIndex, SubSection.GetStream()); + encodeULEB128(Func.Symbol, SubSection.GetStream()); } SubSection.Done(); }