Skip to content

Commit

Permalink
[lld][WebAssembly] Fix func reloc for internal GOT with extended-const
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D155542
  • Loading branch information
yamt authored and sbc100 committed Jul 27, 2023
1 parent 2e00eba commit 47ba908
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 13 deletions.
11 changes: 11 additions & 0 deletions lld/test/wasm/Inputs/internal_func.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.globl internal_func1
internal_func1:
.functype internal_func1 () -> (i32)
i32.const 0
end_function

.globl internal_func2
internal_func2:
.functype internal_func2 () -> (i32)
i32.const 0
end_function
51 changes: 46 additions & 5 deletions lld/test/wasm/pie.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
; RUN: llc -relocation-model=pic -mattr=+mutable-globals -filetype=obj %s -o %t.o
; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -o %t.wasm %t.o
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -filetype=obj %S/Inputs/internal_func.s -o %t.internal_func.o
; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -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

Expand Down Expand Up @@ -27,19 +28,31 @@ entry:
ret ptr @data_addr_external
}

define default ptr @get_internal_func1_address() {
entry:
ret ptr @internal_func1
}

define default ptr @get_internal_func2_address() {
entry:
ret ptr @internal_func2
}

define void @_start() {
call void @external_func()
ret void
}

declare void @external_func()
declare ptr @internal_func1()
declare ptr @internal_func2()

; CHECK: Sections:
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: dylink.0
; CHECK-NEXT: MemorySize: 16
; CHECK-NEXT: MemoryAlignment: 2
; CHECK-NEXT: TableSize: 1
; CHECK-NEXT: TableSize: 3
; CHECK-NEXT: TableAlignment: 0
; CHECK-NEXT: Needed: []

Expand All @@ -52,7 +65,7 @@ declare void @external_func()
; CHECK-NEXT: Index: 0
; CHECK-NEXT: ElemType: FUNCREF
; CHECK-NEXT: Limits:
; CHECK-NEXT: Minimum: 0x1
; CHECK-NEXT: Minimum: 0x3
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: __stack_pointer
; CHECK-NEXT: Kind: GLOBAL
Expand Down Expand Up @@ -88,7 +101,15 @@ declare void @external_func()
; CHECK-NEXT: - Index: 5
; CHECK-NEXT: Name: get_data_address
; CHECK-NEXT: - Index: 6
; CHECK-NEXT: Name: get_internal_func1_address
; CHECK-NEXT: - Index: 7
; CHECK-NEXT: Name: get_internal_func2_address
; CHECK-NEXT: - Index: 8
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 9
; CHECK-NEXT: Name: internal_func1
; CHECK-NEXT: - Index: 10
; CHECK-NEXT: Name: internal_func2
; CHECK-NEXT: GlobalNames:

; DISASSEM-LABEL: <__wasm_call_ctors>:
Expand All @@ -104,7 +125,8 @@ declare void @external_func()
; to be mutable.

; RUN: llc -relocation-model=pic -mattr=+extended-const,+mutable-globals,+atomics,+bulk-memory -filetype=obj %s -o %t.extended.o
; RUN: wasm-ld --no-gc-sections --allow-undefined --experimental-pic -pie -o %t.extended.wasm %t.extended.o
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -filetype=obj %S/Inputs/internal_func.s -o %t.internal_func.extended.o
; RUN: wasm-ld --no-gc-sections --experimental-pic -pie -o %t.extended.wasm %t.extended.o %t.internal_func.extended.o
; RUN: obj2yaml %t.extended.wasm | FileCheck %s --check-prefix=EXTENDED-CONST

; EXTENDED-CONST-NOT: __wasm_apply_global_relocs
Expand All @@ -131,6 +153,20 @@ declare void @external_func()
; 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: 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: Type: I32
; EXTENDED-CONST-NEXT: Mutable: false
; EXTENDED-CONST-NEXT: InitExpr:
; EXTENDED-CONST-NEXT: Extended: true
; This instruction sequence decodes to:
; (global.get[0x23] 0x2 i32.const[0x41] 0x1 i32.add[0x6A] end[0x0b])
; EXTENDED-CONST-NEXT: Body: 230241016A0B

; EXTENDED-CONST-NOT: - Type: START

Expand All @@ -148,7 +184,8 @@ declare void @external_func()
; function.

; RUN: llc -relocation-model=pic -mattr=+mutable-globals,+atomics,+bulk-memory -filetype=obj %s -o %t.shmem.o
; RUN: wasm-ld --no-gc-sections --shared-memory --allow-undefined --experimental-pic -pie -o %t.shmem.wasm %t.shmem.o
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-emscripten -filetype=obj %S/Inputs/internal_func.s -o %t.internal_func.shmem.o
; RUN: wasm-ld --no-gc-sections --shared-memory --experimental-pic -pie -o %t.shmem.wasm %t.shmem.o %t.internal_func.shmem.o
; RUN: obj2yaml %t.shmem.wasm | FileCheck %s --check-prefix=SHMEM
; RUN: llvm-objdump --disassemble-symbols=__wasm_start --no-show-raw-insn --no-leading-addr %t.shmem.wasm | FileCheck %s --check-prefix DISASSEM-SHMEM

Expand Down Expand Up @@ -181,4 +218,8 @@ declare void @external_func()
; SHMEM-NEXT: - Index: 8
; SHMEM-NEXT: Name: get_data_address
; SHMEM-NEXT: - Index: 9
; SHMEM-NEXT: Name: get_internal_func1_address
; SHMEM-NEXT: - Index: 10
; SHMEM-NEXT: Name: get_internal_func2_address
; SHMEM-NEXT: - Index: 11
; SHMEM-NEXT: Name: _start
31 changes: 23 additions & 8 deletions lld/wasm/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,31 @@ void GlobalSection::writeBody() {
WasmGlobalType type{itype, mutable_};
writeGlobalType(os, type);

if (config->extendedConst && config->isPic && !sym->isTLS() &&
isa<DefinedData>(sym)) {
bool useExtendedConst = false;
uint32_t globalIdx;
int64_t offset;
if (config->extendedConst && config->isPic) {
if (auto *d = dyn_cast<DefinedData>(sym)) {
if (!sym->isTLS()) {
globalIdx = WasmSym::memoryBase->getGlobalIndex();
offset = d->getVA();
useExtendedConst = true;
}
} else if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
if (!sym->isStub) {
globalIdx = WasmSym::tableBase->getGlobalIndex();
offset = f->getTableIndex();
useExtendedConst = true;
}
}
}
if (useExtendedConst) {
// We can use an extended init expression to add a constant
// offset of __memory_base.
auto *d = cast<DefinedData>(sym);
// offset of __memory_base/__table_base.
writeU8(os, WASM_OPCODE_GLOBAL_GET, "global get");
writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(),
"literal (global index)");
if (d->getVA()) {
writePtrConst(os, d->getVA(), is64, "offset");
writeUleb128(os, globalIdx, "literal (global index)");
if (offset) {
writePtrConst(os, offset, is64, "offset");
writeU8(os, is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD, "add");
}
writeU8(os, WASM_OPCODE_END, "opcode:end");
Expand Down

0 comments on commit 47ba908

Please sign in to comment.