Index: llvm/trunk/include/llvm/Object/Wasm.h =================================================================== --- llvm/trunk/include/llvm/Object/Wasm.h +++ llvm/trunk/include/llvm/Object/Wasm.h @@ -43,9 +43,9 @@ }; WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, - uint32_t ElementIndex, uint32_t ImportIndex = 0) + uint32_t ElementIndex, uint32_t FunctionType = 0) : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex), - ImportIndex(ImportIndex) {} + FunctionType(FunctionType) {} StringRef Name; SymbolType Type; @@ -55,8 +55,18 @@ // Index into either the function or global index space. uint32_t ElementIndex; - // For imports, the index into the import table - uint32_t ImportIndex; + // 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; + } bool isFunction() const { return Type == WasmSymbol::SymbolType::FUNCTION_IMPORT || @@ -91,8 +101,7 @@ void print(raw_ostream &Out) const { Out << "Name=" << Name << ", Type=" << static_cast(Type) - << ", Flags=" << Flags << " ElemIndex=" << ElementIndex - << ", ImportIndex=" << ImportIndex; + << ", Flags=" << Flags << " ElemIndex=" << ElementIndex; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) Index: llvm/trunk/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WasmObjectWriter.cpp +++ llvm/trunk/lib/MC/WasmObjectWriter.cpp @@ -1116,7 +1116,7 @@ continue; // If the symbol is not defined in this translation unit, import it. - if (!WS.isDefined(/*SetUsed=*/false)) { + if (!WS.isDefined(/*SetUsed=*/false) || WS.isVariable()) { WasmImport Import; Import.ModuleName = WS.getModuleName(); Import.FieldName = WS.getName(); @@ -1288,7 +1288,7 @@ uint32_t Index = SymbolIndices.find(ResolvedSym)->second; DEBUG(dbgs() << " -> index:" << Index << "\n"); - SymbolIndices[&WS] = Index; + //SymbolIndices[&WS] = Index; WasmExport Export; Export.FieldName = WS.getName(); Export.Index = Index; Index: llvm/trunk/lib/Object/WasmObjectFile.cpp =================================================================== --- llvm/trunk/lib/Object/WasmObjectFile.cpp +++ llvm/trunk/lib/Object/WasmObjectFile.cpp @@ -303,7 +303,6 @@ void WasmObjectFile::populateSymbolTable() { // Add imports to symbol table - size_t ImportIndex = 0; size_t GlobalIndex = 0; size_t FunctionIndex = 0; for (const wasm::WasmImport& Import : Imports) { @@ -312,7 +311,7 @@ assert(Import.Global.Type == wasm::WASM_TYPE_I32); SymbolMap.try_emplace(Import.Field, Symbols.size()); Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT, - ImportSection, GlobalIndex++, ImportIndex); + ImportSection, GlobalIndex++); DEBUG(dbgs() << "Adding import: " << Symbols.back() << " sym index:" << Symbols.size() << "\n"); break; @@ -320,14 +319,13 @@ SymbolMap.try_emplace(Import.Field, Symbols.size()); Symbols.emplace_back(Import.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT, - ImportSection, FunctionIndex++, ImportIndex); + ImportSection, FunctionIndex++, Import.SigIndex); DEBUG(dbgs() << "Adding import: " << Symbols.back() << " sym index:" << Symbols.size() << "\n"); break; default: break; } - ImportIndex++; } // Add exports to symbol table @@ -338,11 +336,22 @@ Export.Kind == wasm::WASM_EXTERNAL_FUNCTION ? WasmSymbol::SymbolType::FUNCTION_EXPORT : WasmSymbol::SymbolType::GLOBAL_EXPORT; - SymbolMap.try_emplace(Export.Name, Symbols.size()); - Symbols.emplace_back(Export.Name, ExportType, - ExportSection, Export.Index); - DEBUG(dbgs() << "Adding export: " << Symbols.back() - << " sym index:" << Symbols.size() << "\n"); + auto Pair = SymbolMap.try_emplace(Export.Name, Symbols.size()); + if (Pair.second) { + Symbols.emplace_back(Export.Name, ExportType, + ExportSection, 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, ExportSection, Export.Index); + NewSym.setAltIndex(OldSym.ElementIndex); + Symbols[SymIndex] = NewSym; + + DEBUG(dbgs() << "Replacing existing symbol: " << NewSym + << " sym index:" << SymIndex << "\n"); + } } } } 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 @@ -43,6 +43,15 @@ ; CHECK-NEXT: ElemType: ANYFUNC ; CHECK-NEXT: Limits: ; CHECK-NEXT: Initial: 0x00000000 +; 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 ] ; CHECK-NEXT: - Type: GLOBAL @@ -61,24 +70,33 @@ ; CHECK-NEXT: Exports: ; CHECK-NEXT: - Name: call_alias ; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Name: foo ; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: bar ; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Name: bar_alias_address ; CHECK-NEXT: Kind: GLOBAL -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: foo_alias ; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: bar_alias ; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: CODE +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB ; CHECK-NEXT: Index: 0 - -; CHECK: - Type: DATA +; CHECK-NEXT: Offset: 0x00000004 +; CHECK-NEXT: Functions: +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 1080808080000B +; CHECK-NEXT: - Locals: +; CHECK-NEXT: Body: 41000B +; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Relocations: ; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 ; CHECK-NEXT: Index: 0 @@ -101,21 +119,23 @@ ; CHECK-NEXT: Name: name ; CHECK-NEXT: FunctionNames: ; CHECK-NEXT: - Index: 0 -; CHECK-NEXT: Name: call_alias +; CHECK-NEXT: Name: foo_alias ; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: Name: call_alias +; CHECK-NEXT: - Index: 2 ; CHECK-NEXT: Name: foo ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 12 ; CHECK-NEXT: SymbolInfo: -; CHECK-NEXT: - Name: call_alias -; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] -; CHECK-NEXT: - Name: foo -; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] ; 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: call_alias +; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] +; CHECK-NEXT: - Name: foo +; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ] ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.bar @@ -128,11 +148,12 @@ ; CHECK-NEXT: ... ; CHECK-SYMS: SYMBOL TABLE: -; CHECK-SYMS-NEXT: 00000000 g F name call_alias -; CHECK-SYMS-NEXT: 00000001 g F name foo -; CHECK-SYMS-NEXT: 00000000 g F EXPORT .hidden call_alias -; CHECK-SYMS-NEXT: 00000001 g F EXPORT .hidden foo +; CHECK-SYMS-NEXT: 00000000 g F name foo_alias +; CHECK-SYMS-NEXT: 00000001 g F name call_alias +; CHECK-SYMS-NEXT: 00000002 g F name foo +; CHECK-SYMS-NEXT: 00000002 gw F EXPORT .hidden foo_alias +; CHECK-SYMS-NEXT: 00000000 gw EXPORT .hidden bar_alias +; CHECK-SYMS-NEXT: 00000001 g F EXPORT .hidden call_alias +; CHECK-SYMS-NEXT: 00000002 g F EXPORT .hidden foo ; CHECK-SYMS-NEXT: 00000000 g EXPORT bar ; CHECK-SYMS-NEXT: 00000008 g EXPORT bar_alias_address -; CHECK-SYMS-NEXT: 00000001 gw F EXPORT .hidden foo_alias -; CHECK-SYMS-NEXT: 00000000 gw EXPORT .hidden bar_alias