diff --git a/lld/test/wasm/shared64.s b/lld/test/wasm/shared64.s --- a/lld/test/wasm/shared64.s +++ b/lld/test/wasm/shared64.s @@ -17,13 +17,13 @@ .section .data.indirect_func_external,"",@ indirect_func_external: - .int32 func_external -.size indirect_func_external, 4 + .int64 func_external +.size indirect_func_external, 8 .section .data.indirect_func,"",@ indirect_func: - .int32 foo - .size indirect_func, 4 + .int64 foo + .size indirect_func, 8 # Test data relocations @@ -68,7 +68,8 @@ i32.load 0 local.set 1 global.get indirect_func@GOT - i32.load 0 + i64.load 0 + i32.wrap_i64 call_indirect () -> (i32) drop local.get 0 @@ -128,7 +129,7 @@ # CHECK: Sections: # CHECK-NEXT: - Type: CUSTOM # CHECK-NEXT: Name: dylink -# CHECK-NEXT: MemorySize: 28 +# CHECK-NEXT: MemorySize: 36 # CHECK-NEXT: MemoryAlignment: 2 # CHECK-NEXT: TableSize: 2 # CHECK-NEXT: TableAlignment: 0 @@ -180,22 +181,22 @@ # CHECK-NEXT: - Module: GOT.mem # CHECK-NEXT: Field: indirect_func # CHECK-NEXT: Kind: GLOBAL -# CHECK-NEXT: GlobalType: I32 +# CHECK-NEXT: GlobalType: I64 # CHECK-NEXT: GlobalMutable: true # CHECK-NEXT: - Module: GOT.func # CHECK-NEXT: Field: func_external # CHECK-NEXT: Kind: GLOBAL -# CHECK-NEXT: GlobalType: I32 +# CHECK-NEXT: GlobalType: I64 # CHECK-NEXT: GlobalMutable: true # CHECK-NEXT: - Module: GOT.mem # CHECK-NEXT: Field: data_external # CHECK-NEXT: Kind: GLOBAL -# CHECK-NEXT: GlobalType: I32 +# CHECK-NEXT: GlobalType: I64 # CHECK-NEXT: GlobalMutable: true # CHECK-NEXT: - Module: GOT.mem # CHECK-NEXT: Field: extern_struct # CHECK-NEXT: Kind: GLOBAL -# CHECK-NEXT: GlobalType: I32 +# CHECK-NEXT: GlobalType: I64 # CHECK-NEXT: GlobalMutable: true # CHECK-NEXT: - Type: FUNCTION @@ -224,7 +225,7 @@ # CHECK-NEXT: Body: 10020B # CHECK-NEXT: - Index: 2 # CHECK-NEXT: Locals: [] -# CHECK-NEXT: Body: 230142047C2305360200230142087C230241016A3602002301420C7C230141006A360200230142107C2306370200230142187C230741046A3602000B +# CHECK-NEXT: Body: 230142047C23053702002301420C7C230242017C370200230142147C230141006A360200230142187C2306370200230142207C230741046A3602000B # check the data segment initialized with __memory_base global as offset @@ -235,4 +236,4 @@ # CHECK-NEXT: Offset: # CHECK-NEXT: Opcode: GLOBAL_GET # CHECK-NEXT: Index: 1 -# CHECK-NEXT: Content: '02000000000000000100000000000000000000000000000000000000' +# CHECK-NEXT: Content: '020000000000000000000000010000000000000000000000000000000000000000000000' diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -621,6 +621,8 @@ "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, make(nullSignature, "__wasm_call_ctors")); + bool is64 = config->is64.getValueOr(false); + if (config->isPic) { WasmSym::stackPointer = createUndefinedGlobal("__stack_pointer", config->is64.getValueOr(false) @@ -631,7 +633,6 @@ // which to load our static data and function table. // See: // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md - bool is64 = config->is64.getValueOr(false); auto *globalType = is64 ? &globalTypeI64 : &globalTypeI32; WasmSym::memoryBase = createUndefinedGlobal("__memory_base", globalType); WasmSym::tableBase = createUndefinedGlobal("__table_base", globalType); @@ -657,7 +658,7 @@ WasmSym::initTLS = symtab->addSyntheticFunction( "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN, make( - config->is64.getValueOr(false) ? i64ArgSignature : i32ArgSignature, + is64 ? i64ArgSignature : i32ArgSignature, "__wasm_init_tls")); } } diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -39,6 +39,10 @@ case R_WASM_MEMORY_ADDR_SLEB64: case R_WASM_MEMORY_ADDR_REL_SLEB64: case R_WASM_MEMORY_ADDR_I64: + case R_WASM_TABLE_INDEX_SLEB64: + case R_WASM_TABLE_INDEX_I64: + case R_WASM_FUNCTION_OFFSET_I64: + case R_WASM_TABLE_INDEX_REL_SLEB64: return true; default: return false; @@ -355,12 +359,11 @@ LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName() << " count=" << relocations.size() << "\n"); - unsigned opcode_ptr_const = config->is64.getValueOr(false) - ? WASM_OPCODE_I64_CONST - : WASM_OPCODE_I32_CONST; - unsigned opcode_ptr_add = config->is64.getValueOr(false) - ? WASM_OPCODE_I64_ADD - : WASM_OPCODE_I32_ADD; + bool is64 = config->is64.getValueOr(false); + unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST + : WASM_OPCODE_I32_CONST; + unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD + : WASM_OPCODE_I32_ADD; uint64_t tombstone = getTombstone(); // TODO(sbc): Encode the relocations in the data section and write a loop diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -125,6 +125,8 @@ writeUleb128(os, getNumImports(), "import count"); + bool is64 = config->is64.getValueOr(false); + if (config->importMemory) { WasmImport import; import.Module = defaultModule; @@ -138,7 +140,7 @@ } if (config->sharedMemory) import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; - if (config->is64.getValueOr(false)) + if (is64) import.Memory.Flags |= WASM_LIMITS_FLAG_IS_64; writeImport(os, import); } @@ -180,7 +182,8 @@ for (const Symbol *sym : gotSymbols) { WasmImport import; import.Kind = WASM_EXTERNAL_GLOBAL; - import.Global = {WASM_TYPE_I32, true}; + auto ptrType = is64 ? WASM_TYPE_I64 : WASM_TYPE_I32; + import.Global = {static_cast(ptrType), true}; if (isa(sym)) import.Module = "GOT.mem"; else @@ -317,12 +320,11 @@ } void GlobalSection::generateRelocationCode(raw_ostream &os) const { - unsigned opcode_ptr_const = config->is64.getValueOr(false) - ? WASM_OPCODE_I64_CONST - : WASM_OPCODE_I32_CONST; - unsigned opcode_ptr_add = config->is64.getValueOr(false) - ? WASM_OPCODE_I64_ADD - : WASM_OPCODE_I32_ADD; + bool is64 = config->is64.getValueOr(false); + unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST + : WASM_OPCODE_I32_CONST; + unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD + : WASM_OPCODE_I32_ADD; for (const Symbol *sym : internalGotSymbols) { if (auto *d = dyn_cast(sym)) {