Index: test/wasm/relocatable.ll =================================================================== --- test/wasm/relocatable.ll +++ test/wasm/relocatable.ll @@ -159,7 +159,7 @@ ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 16 -; CHECK-NEXT: Content: FFFFFFFF +; CHECK-NEXT: Content: '00000000' ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 20 Index: test/wasm/weak-undefined.ll =================================================================== --- test/wasm/weak-undefined.ll +++ test/wasm/weak-undefined.ll @@ -40,8 +40,8 @@ ; CHECK-NEXT: - ElemType: ANYFUNC ; CHECK-NEXT: Limits: ; CHECK-NEXT: Flags: [ HAS_MAX ] -; CHECK-NEXT: Initial: 0x00000002 -; CHECK-NEXT: Maximum: 0x00000002 +; CHECK-NEXT: Initial: 0x00000001 +; CHECK-NEXT: Maximum: 0x00000001 ; CHECK-NEXT: - Type: MEMORY ; CHECK-NEXT: Memories: ; CHECK-NEXT: - Initial: 0x00000002 @@ -66,20 +66,14 @@ ; CHECK-NEXT: - Name: get_address_of_global_var ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 -; CHECK-NEXT: - Type: ELEM -; CHECK-NEXT: Segments: -; CHECK-NEXT: - Offset: -; CHECK-NEXT: Opcode: I32_CONST -; CHECK-NEXT: Value: 1 -; CHECK-NEXT: Functions: [ 0 ] ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Locals: -; CHECK-NEXT: Body: 4181808080000B +; CHECK-NEXT: Body: 4180808080000B ; CHECK-NEXT: - Locals: -; CHECK-NEXT: Body: 41FFFFFFFF7F0B +; CHECK-NEXT: Body: 4180808080000B ; CHECK-NEXT: - Locals: -; CHECK-NEXT: Body: 41002802FFFFFFFF0F0B +; CHECK-NEXT: Body: 4100280280808080000B ; CHECK-NEXT: - Type: CUSTOM ; CHECK-NEXT: Name: linking ; CHECK-NEXT: DataSize: 0 Index: wasm/InputFiles.h =================================================================== --- wasm/InputFiles.h +++ wasm/InputFiles.h @@ -93,7 +93,7 @@ uint32_t relocateFunctionIndex(uint32_t Original) const; uint32_t relocateGlobalIndex(uint32_t Original) const; uint32_t relocateTableIndex(uint32_t Original) const; - uint32_t getRelocatedAddress(uint32_t Index) const; + uint32_t getRelocatedAddress(uint32_t Index, uint32_t Addend) const; // Returns true if the given function index is an imported function, // as opposed to the locally defined function. Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -65,8 +65,8 @@ return GlobalSymbols[Index]; } -uint32_t ObjFile::getRelocatedAddress(uint32_t Index) const { - return getGlobalSymbol(Index)->getVirtualAddress(); +uint32_t ObjFile::getRelocatedAddress(uint32_t Index, uint32_t Addend) const { + return getGlobalSymbol(Index)->getVirtualAddress(Addend); } uint32_t ObjFile::relocateFunctionIndex(uint32_t Original) const { @@ -83,7 +83,7 @@ uint32_t ObjFile::relocateTableIndex(uint32_t Original) const { Symbol *Sym = getTableSymbol(Original); - uint32_t Index = Sym->getTableIndex(); + uint32_t Index = Sym->hasTableIndex() ? Sym->getTableIndex() : 0; DEBUG(dbgs() << "relocateTableIndex: " << toString(*Sym) << ": " << Original << " -> " << Index << "\n"); return Index; @@ -91,7 +91,7 @@ uint32_t ObjFile::relocateGlobalIndex(uint32_t Original) const { Symbol *Sym = getGlobalSymbol(Original); - uint32_t Index = Sym->getOutputIndex(); + uint32_t Index = Sym->hasOutputIndex() ? Sym->getOutputIndex() : 0; DEBUG(dbgs() << "relocateGlobalIndex: " << toString(*Sym) << ": " << Original << " -> " << Index << "\n"); return Index; Index: wasm/OutputSections.cpp =================================================================== --- wasm/OutputSections.cpp +++ wasm/OutputSections.cpp @@ -157,16 +157,12 @@ if (Config->EmitRelocs) NewReloc.NewIndex = calcNewIndex(File, Reloc); - else - NewReloc.NewIndex = UINT32_MAX; switch (Reloc.Type) { case R_WEBASSEMBLY_MEMORY_ADDR_SLEB: case R_WEBASSEMBLY_MEMORY_ADDR_I32: case R_WEBASSEMBLY_MEMORY_ADDR_LEB: - NewReloc.Value = File.getRelocatedAddress(Reloc.Index); - if (NewReloc.Value != UINT32_MAX) - NewReloc.Value += Reloc.Addend; + NewReloc.Value = File.getRelocatedAddress(Reloc.Index, Reloc.Addend); break; default: NewReloc.Value = calcNewIndex(File, Reloc); Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -71,23 +71,28 @@ bool hasFunctionType() const { return FunctionType != nullptr; } const WasmSignature &getFunctionType() const; - uint32_t getOutputIndex() const; - uint32_t getTableIndex() const { return TableIndex.getValue(); } - // Returns the virtual address of a defined global. - // Only works for globals, not functions. - uint32_t getVirtualAddress() const; + uint32_t getOutputIndex() const { return OutputIndex.getValue(); } + + // Returns true if an output index has been set for this symbol + bool hasOutputIndex() const { return OutputIndex.hasValue(); } // Set the output index of the symbol (in the function or global index // space of the output object. void setOutputIndex(uint32_t Index); + uint32_t getTableIndex() const { return TableIndex.getValue(); } + // Returns true if a table index has been set for this symbol bool hasTableIndex() const { return TableIndex.hasValue(); } // Set the table index of the symbol void setTableIndex(uint32_t Index); + // Returns the virtual address of a defined global. + // Only works for globals, not functions. + uint32_t getVirtualAddress(uint32_t Addend = 0) const; + void setVirtualAddress(uint32_t VA); void update(Kind K, InputFile *F = nullptr, const WasmSymbol *Sym = nullptr, Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -36,13 +36,13 @@ return *FunctionType; } -uint32_t Symbol::getVirtualAddress() const { +uint32_t Symbol::getVirtualAddress(uint32_t Addend) const { assert(isGlobal()); DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); if (isUndefined()) - return UINT32_MAX; + return 0; if (VirtualAddress.hasValue()) - return VirtualAddress.getValue(); + return VirtualAddress.getValue() + Addend; assert(Sym != nullptr); ObjFile *Obj = cast(File); @@ -50,13 +50,7 @@ Obj->getWasmObj()->globals()[getGlobalIndex() - Obj->NumGlobalImports()]; assert(Global.Type == llvm::wasm::WASM_TYPE_I32); assert(Segment); - return Segment->translateVA(Global.InitExpr.Value.Int32); -} - -uint32_t Symbol::getOutputIndex() const { - if (isUndefined() && isWeak()) - return 0; - return OutputIndex.getValue(); + return Segment->translateVA(Global.InitExpr.Value.Int32 + Addend); } void Symbol::setVirtualAddress(uint32_t Value) { Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -629,12 +629,14 @@ Sym->setOutputIndex(GlobalIndex++); } } + } + for (ObjFile *File : Symtab->ObjectFiles) { for (Symbol *Sym : File->getTableSymbols()) { - if (!Sym->hasTableIndex()) { - Sym->setTableIndex(TableIndex++); - IndirectFunctions.emplace_back(Sym); - } + if (Sym->hasTableIndex() || !Sym->hasOutputIndex()) + continue; + Sym->setTableIndex(TableIndex++); + IndirectFunctions.emplace_back(Sym); } } }