diff --git a/lld/test/wasm/pie.s b/lld/test/wasm/pie.s index 21eac79207318..78d6c85097b10 100644 --- a/lld/test/wasm/pie.s +++ b/lld/test/wasm/pie.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten %S/Inputs/internal_func.s -o %t.internal_func.o # RUN: wasm-ld --no-gc-sections --experimental-pic -pie --unresolved-symbols=import-dynamic -o %t.wasm %t.o %t.internal_func.o # RUN: obj2yaml %t.wasm | FileCheck %s -# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM +# RUN: llvm-objdump --disassemble-symbols=__wasm_call_ctors,__wasm_apply_data_relocs,__wasm_apply_global_relocs --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DISASSEM .functype external_func () -> () .functype internal_func1 () -> (i32) @@ -41,6 +41,9 @@ foo: drop global.get __stack_pointer + drop + + global.get __wasm_first_page_end@GOT end_function get_data_address: @@ -145,6 +148,18 @@ _start: # DISASSEM-LABEL: <__wasm_apply_data_relocs>: # DISASSEM: end +# global 6 is __wasm_first_page_end, which is noReloc and +# thus should not be relocated. +# +# DISASSEM-LABEL: <__wasm_apply_global_relocs>: +# DISASSEM: global.set 4 +# DISASSEM: global.set 5 +# DISASSEM-NOT: global.set 6 +# DISASSEM: global.set 7 +# DISASSEM: global.set 8 +# DISASSEM: global.set 9 +# DISASSEM: end + # Run the same test with extended-const support. When this is available # we don't need __wasm_apply_global_relocs and instead rely on the add # instruction in the InitExpr. We also, therefore, do not need these globals @@ -173,17 +188,23 @@ _start: # EXTENDED-CONST-NEXT: Type: I32 # EXTENDED-CONST-NEXT: Mutable: false # EXTENDED-CONST-NEXT: InitExpr: +# EXTENDED-CONST-NEXT: Opcode: I32_CONST +# EXTENDED-CONST-NEXT: Value: 65536 +# EXTENDED-CONST-NEXT: - Index: 7 +# EXTENDED-CONST-NEXT: Type: I32 +# EXTENDED-CONST-NEXT: Mutable: false +# EXTENDED-CONST-NEXT: InitExpr: # EXTENDED-CONST-NEXT: Extended: true # This instruction sequence decodes to: # (global.get[0x23] 0x1 i32.const[0x41] 0x0C i32.add[0x6A] end[0x0b]) # EXTENDED-CONST-NEXT: Body: 2301410C6A0B -# EXTENDED-CONST-NEXT: - Index: 7 +# EXTENDED-CONST-NEXT: - Index: 8 # EXTENDED-CONST-NEXT: Type: I32 # EXTENDED-CONST-NEXT: Mutable: false # EXTENDED-CONST-NEXT: InitExpr: # EXTENDED-CONST-NEXT: Opcode: GLOBAL_GET # EXTENDED-CONST-NEXT: Index: 2 -# EXTENDED-CONST-NEXT: - Index: 8 +# EXTENDED-CONST-NEXT: - Index: 9 # EXTENDED-CONST-NEXT: Type: I32 # EXTENDED-CONST-NEXT: Mutable: false # EXTENDED-CONST-NEXT: InitExpr: diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 1c5d21c06f5af..5ad8c1bde289d 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -999,8 +999,10 @@ static void createOptionalSymbols() { } ctx.sym.firstPageEnd = symtab->addOptionalDataSymbol("__wasm_first_page_end"); - if (ctx.sym.firstPageEnd) + if (ctx.sym.firstPageEnd) { ctx.sym.firstPageEnd->setVA(ctx.arg.pageSize); + ctx.sym.firstPageEnd->noReloc = true; + } // For non-shared memory programs we still need to define __tls_base since we // allow object files built with TLS to be linked into single threaded diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index 55ee21939ce07..caee04865545d 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -142,7 +142,7 @@ class Symbol { : name(name), file(f), symbolKind(k), referenced(!ctx.arg.gcSections), requiresGOT(false), isUsedInRegularObj(false), forceExport(false), forceImport(false), canInline(false), traced(false), isStub(false), - flags(flags) {} + noReloc(false), flags(flags) {} StringRef name; InputFile *file; @@ -185,6 +185,9 @@ class Symbol { // the null function pointer). bool isStub : 1; + // True if this symbol is not relative to __memory_base. + bool noReloc : 1; + uint32_t flags; std::optional importName; diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp index e1192706ea913..4d0c5abf799db 100644 --- a/lld/wasm/SyntheticSections.cpp +++ b/lld/wasm/SyntheticSections.cpp @@ -440,6 +440,8 @@ void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const { : WASM_OPCODE_I32_ADD; for (const Symbol *sym : internalGotSymbols) { + if (sym->noReloc) + continue; if (TLS != sym->isTLS()) continue; @@ -503,7 +505,7 @@ void GlobalSection::writeBody() { bool useExtendedConst = false; uint32_t globalIdx; int64_t offset; - if (ctx.arg.extendedConst && ctx.isPic) { + if (ctx.arg.extendedConst && ctx.isPic && !sym->noReloc) { if (auto *d = dyn_cast(sym)) { if (!sym->isTLS()) { globalIdx = ctx.sym.memoryBase->getGlobalIndex();