Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions lld/test/wasm/shared-synthetic-symbols.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## Check that synthetic data-layout symbols such as __heap_base and __heap_end
## can be referenced from shared libraries and pie executables without
## generating undefined symbols.

# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
# RUN: wasm-ld --experimental-pic -pie --import-memory -o %t.wasm %t.o
# RUN: obj2yaml %t.wasm | FileCheck %s
# RUN: wasm-ld --experimental-pic -shared -o %t.so %t.o
# RUN: obj2yaml %t.so | FileCheck %s

.globl _start

_start:
.functype _start () -> ()
i32.const __heap_base@GOT
drop
i32.const __heap_end@GOT
drop
i32.const __stack_low@GOT
drop
i32.const __stack_high@GOT
drop
i32.const __global_base@GOT
drop
i32.const __data_end@GOT
drop
end_function

# CHECK: - Type: IMPORT
# CHECK-NEXT: Imports:
# CHECK-NEXT: - Module: env
# CHECK-NEXT: Field: memory
# CHECK-NEXT: Kind: MEMORY
# CHECK-NEXT: Memory:
# CHECK-NEXT: Minimum: 0x0
# CHECK-NEXT: - Module: env
# CHECK-NEXT: Field: __memory_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: false
# CHECK-NEXT: - Module: env
# CHECK-NEXT: Field: __table_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: false
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: __heap_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: __heap_end
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: __stack_low
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: __stack_high
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: __global_base
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: __data_end
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: true
26 changes: 19 additions & 7 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -985,15 +985,27 @@ static void createOptionalSymbols() {

ctx.sym.dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");

if (!ctx.arg.shared)
ctx.sym.dataEnd = symtab->addOptionalDataSymbol("__data_end");
auto addDataLayoutSymbol = [&](StringRef s) -> DefinedData * {
// Data layout symbols are either defined by lld, or (in the case
// of PIC code) defined by the dynamic linker / embedder.
if (ctx.isPic) {
ctx.arg.allowUndefinedSymbols.insert(s);
return nullptr;
} else {
return symtab->addOptionalDataSymbol(s);
}
};

ctx.sym.dataEnd = addDataLayoutSymbol("__data_end");
ctx.sym.stackLow = addDataLayoutSymbol("__stack_low");
ctx.sym.stackHigh = addDataLayoutSymbol("__stack_high");
ctx.sym.globalBase = addDataLayoutSymbol("__global_base");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i suspect __data_end and __global_base don't make much sense for pic. what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, but what should they resolve to? Should they point to the start and end of the data region of the current DSO, or should they point to the start and end of the main module's data (which I guess is what this change would do?

ctx.sym.heapBase = addDataLayoutSymbol("__heap_base");
ctx.sym.heapEnd = addDataLayoutSymbol("__heap_end");

// for pic, __memory_base and __table_base are handled in
// createSyntheticSymbols.
if (!ctx.isPic) {
ctx.sym.stackLow = symtab->addOptionalDataSymbol("__stack_low");
ctx.sym.stackHigh = symtab->addOptionalDataSymbol("__stack_high");
ctx.sym.globalBase = symtab->addOptionalDataSymbol("__global_base");
ctx.sym.heapBase = symtab->addOptionalDataSymbol("__heap_base");
ctx.sym.heapEnd = symtab->addOptionalDataSymbol("__heap_end");
ctx.sym.definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
ctx.sym.definedTableBase = symtab->addOptionalDataSymbol("__table_base");
}
Expand Down