Index: llvm/trunk/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/trunk/lib/MC/WasmObjectWriter.cpp +++ llvm/trunk/lib/MC/WasmObjectWriter.cpp @@ -477,13 +477,22 @@ Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset); } +static const MCSymbolWasm* ResolveSymbol(const MCSymbolWasm& Symbol) { + if (Symbol.isVariable()) { + const MCExpr *Expr = Symbol.getVariableValue(); + auto *Inner = cast(Expr); + return cast(&Inner->getSymbol()); + } + return &Symbol; +} + // Compute a value to write into the code at the location covered // by RelEntry. This value isn't used by the static linker, since // we have addends; it just serves to make the code more readable // and to make standalone wasm modules directly usable. uint32_t WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { - const MCSymbolWasm *Sym = RelEntry.Symbol; + const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol); // For undefined symbols, use a hopefully invalid value. if (!Sym->isDefined(/*SetUsed=*/false)) @@ -934,16 +943,9 @@ assert(Symbol.isFunction()); WasmFunctionType F; - if (Symbol.isVariable()) { - const MCExpr *Expr = Symbol.getVariableValue(); - auto *Inner = cast(Expr); - const auto *ResolvedSym = cast(&Inner->getSymbol()); - F.Returns = ResolvedSym->getReturns(); - F.Params = ResolvedSym->getParams(); - } else { - F.Returns = Symbol.getReturns(); - F.Params = Symbol.getParams(); - } + const MCSymbolWasm* ResolvedSym = ResolveSymbol(Symbol); + F.Returns = ResolvedSym->getReturns(); + F.Params = ResolvedSym->getParams(); auto Pair = FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size())); @@ -1255,11 +1257,9 @@ continue; assert(S.isDefined(/*SetUsed=*/false)); - const auto &WS = static_cast(S); // Find the target symbol of this weak alias and export that index - const MCExpr *Expr = WS.getVariableValue(); - auto *Inner = cast(Expr); - const auto *ResolvedSym = cast(&Inner->getSymbol()); + 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; 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 @@ -1,8 +1,13 @@ ; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s -; foo_alias() function is weak alias of function foo() +; 'foo_alias()' is weak alias of function 'foo()' +; 'bar_alias' is weak alias of global variable 'bar' ; Generates two exports of the same function, one of them weak +@bar = global i32 7, align 8 +@bar_alias = weak hidden alias i32, i32* @bar +@bar_alias_address = global i32* @bar_alias, align 8 + @foo_alias = weak hidden alias i32 (), i32 ()* @foo define hidden i32 @call_alias() #0 { @@ -29,6 +34,11 @@ ; 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: - Type: FUNCTION ; CHECK-NEXT: FunctionTypes: [ 0, 0 ] @@ -41,9 +51,37 @@ ; CHECK-NEXT: - Name: foo ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: bar +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: bar_alias_address +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: foo_alias ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: bar_alias +; CHECK-NEXT: Kind: GLOBAL +; CHECK-NEXT: Index: 1 + +; CHECK: - Type: DATA +; CHECK-NEXT: Relocations: +; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: Offset: 0x0000000F +; CHECK-NEXT: Segments: +; CHECK-NEXT: - SectionOffset: 6 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 0 +; CHECK-NEXT: Content: '07000000' +; CHECK-NEXT: - SectionOffset: 15 +; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: Offset: +; CHECK-NEXT: Opcode: I32_CONST +; CHECK-NEXT: Value: 8 +; CHECK-NEXT: Content: '00000000' ; CHECK: - Type: CUSTOM ; CHECK-NEXT: Name: name @@ -56,9 +94,11 @@ ; CHECK-NEXT: Name: foo ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking -; CHECK-NEXT: DataSize: 0 -; CHECK-NEXT: DataAlignment: 0 +; CHECK-NEXT: DataSize: 12 +; CHECK-NEXT: DataAlignment: 8 ; CHECK-NEXT: SymbolInfo: ; CHECK-NEXT: - Name: foo_alias ; CHECK-NEXT: Flags: 1 +; CHECK-NEXT: - Name: bar_alias +; CHECK-NEXT: Flags: 1 ; CHECK-NEXT: ...