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
31 changes: 19 additions & 12 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,8 @@ static void createSyntheticSymbols() {
} else {
// For non-PIC code
WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true);
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
Copy link
Contributor

Choose a reason for hiding this comment

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

these calls seem too early in the link process.
the symbol table is almost empty here and they are effectively no-op i guess.
createSyntheticSymbols is called even before addFile.

Copy link
Contributor

Choose a reason for hiding this comment

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

@sbc100 are you still interested in working on this? or may i take over?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If you have time to take it over that would be great!

Copy link
Contributor

Choose a reason for hiding this comment

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

ok.
i will try to refresh my memory first. :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

see #153537

WasmSym::stackPointer->markLive();
}

Expand All @@ -986,18 +988,23 @@ static void createOptionalSymbols() {

WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");

if (!ctx.arg.shared)
WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");

if (!ctx.isPic) {
WasmSym::stackLow = symtab->addOptionalDataSymbol("__stack_low");
WasmSym::stackHigh = symtab->addOptionalDataSymbol("__stack_high");
WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end");
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
}
auto addDataLayoutSymbol = [&](StringRef s) -> DefinedData * {
// Data layout symbols are either defined by the lld, or (in the case
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Data layout symbols are either defined by the lld, or (in the case
// 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);
}
};

WasmSym::dataEnd = addDataLayoutSymbol("__data_end");
WasmSym::stackLow = addDataLayoutSymbol("__stack_low");
WasmSym::stackHigh = addDataLayoutSymbol("__stack_high");
WasmSym::globalBase = addDataLayoutSymbol("__global_base");
WasmSym::heapBase = addDataLayoutSymbol("__heap_base");
WasmSym::heapEnd = addDataLayoutSymbol("__heap_end");

// 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
Expand Down
2 changes: 1 addition & 1 deletion lld/wasm/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ struct WasmSym {
// Symbol whose value is the size of the TLS block.
static GlobalSymbol *tlsSize;

// __tls_size
// __tls_align
// Symbol whose value is the alignment of the TLS block.
static GlobalSymbol *tlsAlign;

Expand Down
Loading