Skip to content

Commit

Permalink
[lld][WebAssembly] Add --table-base setting
Browse files Browse the repository at this point in the history
This is similar to `--global-base` but determines where to place the
table segments rather than that data segments.

See emscripten-core/emscripten#20097

Differential Revision: https://reviews.llvm.org/D158892
  • Loading branch information
sbc100 committed Aug 25, 2023
1 parent f66e4bd commit 93adcb7
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 11 deletions.
72 changes: 72 additions & 0 deletions lld/test/wasm/table-base.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o

# RUN: wasm-ld --export=__table_base -o %t.wasm %t.o
# RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-DEFAULT

# RUN: wasm-ld --table-base=100 --export=__table_base -o %t.wasm %t.o
# RUN: obj2yaml %t.wasm | FileCheck %s -check-prefix=CHECK-100

.globl _start
_start:
.functype _start () -> ()
i32.const _start
drop
end_function

# CHECK-DEFAULT: - Type: TABLE
# CHECK-DEFAULT-NEXT: Tables:
# CHECK-DEFAULT-NEXT: - Index: 0
# CHECK-DEFAULT-NEXT: ElemType: FUNCREF
# CHECK-DEFAULT-NEXT: Limits:
# CHECK-DEFAULT-NEXT: Flags: [ HAS_MAX ]
# CHECK-DEFAULT-NEXT: Minimum: 0x2
# CHECK-DEFAULT-NEXT: Maximum: 0x2

# CHECK-DEFAULT: - Type: GLOBAL
# CHECK-DEFAULT-NEXT: Globals:
# CHECK-DEFAULT-NEXT: - Index: 0
# CHECK-DEFAULT-NEXT: Type: I32
# CHECK-DEFAULT-NEXT: Mutable: true
# CHECK-DEFAULT-NEXT: InitExpr:
# CHECK-DEFAULT-NEXT: Opcode: I32_CONST
# CHECK-DEFAULT-NEXT: Value: 66560
# CHECK-DEFAULT-NEXT: - Index: 1
# CHECK-DEFAULT-NEXT: Type: I32
# CHECK-DEFAULT-NEXT: Mutable: false
# CHECK-DEFAULT-NEXT: InitExpr:
# CHECK-DEFAULT-NEXT: Opcode: I32_CONST
# CHECK-DEFAULT-NEXT: Value: 1

# CHECK-DEFAULT: - Type: EXPORT
# CHECK-DEFAULT: - Name: __table_base
# CHECK-DEFAULT-NEXT: Kind: GLOBAL
# CHECK-DEFAULT-NEXT: Index: 1

# CHECK-100: - Type: TABLE
# CHECK-100-NEXT: Tables:
# CHECK-100-NEXT: - Index: 0
# CHECK-100-NEXT: ElemType: FUNCREF
# CHECK-100-NEXT: Limits:
# CHECK-100-NEXT: Flags: [ HAS_MAX ]
# CHECK-100-NEXT: Minimum: 0x65
# CHECK-100-NEXT: Maximum: 0x65

# CHECK-100: - Type: GLOBAL
# CHECK-100-NEXT: Globals:
# CHECK-100-NEXT: - Index: 0
# CHECK-100-NEXT: Type: I32
# CHECK-100-NEXT: Mutable: true
# CHECK-100-NEXT: InitExpr:
# CHECK-100-NEXT: Opcode: I32_CONST
# CHECK-100-NEXT: Value: 66560
# CHECK-100-NEXT: - Index: 1
# CHECK-100-NEXT: Type: I32
# CHECK-100-NEXT: Mutable: false
# CHECK-100-NEXT: InitExpr:
# CHECK-100-NEXT: Opcode: I32_CONST
# CHECK-100-NEXT: Value: 100

# CHECK-100: - Type: EXPORT
# CHECK-100: - Name: __table_base
# CHECK-100-NEXT: Kind: GLOBAL
# CHECK-100-NEXT: Index: 1
19 changes: 17 additions & 2 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ static void readConfigs(opt::InputArgList &args) {

config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
config->globalBase = args::getInteger(args, OPT_global_base, 0);
config->tableBase = args::getInteger(args, OPT_table_base, 0);
config->maxMemory = args::getInteger(args, OPT_max_memory, 0);
config->zStackSize =
args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize);
Expand Down Expand Up @@ -573,6 +574,17 @@ static void setConfigs() {
if (config->exportTable)
error("-shared/-pie is incompatible with --export-table");
config->importTable = true;
} else {
// Default table base. Defaults to 1, reserving 0 for the NULL function
// pointer.
if (!config->tableBase)
config->tableBase = 1;
// The default offset for static/global data, for when --global-base is
// not specified on the command line. The precise value of 1024 is
// somewhat arbitrary, and pre-dates wasm-ld (Its the value that
// emscripten used prior to wasm-ld).
if (!config->globalBase && !config->relocatable && !config->stackFirst)
config->globalBase = 1024;
}

if (config->relocatable) {
Expand Down Expand Up @@ -666,8 +678,11 @@ static void checkOptions(opt::InputArgList &args) {
warn("-Bsymbolic is only meaningful when combined with -shared");
}

if (config->globalBase && config->isPic) {
error("--global-base may not be used with -shared/-pie");
if (config->isPic) {
if (config->globalBase)
error("--global-base may not be used with -shared/-pie");
if (config->tableBase)
error("--table-base may not be used with -shared/-pie");
}
}

Expand Down
5 changes: 4 additions & 1 deletion lld/wasm/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def growable_table: FF<"growable-table">,
HelpText<"Remove maximum size from function table, allowing table to grow">;

def global_base: JJ<"global-base=">,
HelpText<"Where to start to place global data">;
HelpText<"Memory offset at which to place global data (Defaults to 1024)">;

def import_memory: FF<"import-memory">,
HelpText<"Import the module's memory from the default module of \"env\" with the name \"memory\".">;
Expand Down Expand Up @@ -224,6 +224,9 @@ def no_entry: FF<"no-entry">,
def stack_first: FF<"stack-first">,
HelpText<"Place stack at start of linear memory rather than after data">;

def table_base: JJ<"table-base=">,
HelpText<"Table offset at which to place address taken functions (Defaults to 1)">;

defm whole_archive: B<"whole-archive",
"Force load of all members in a static library",
"Do not force load of all members in a static library (default)">;
Expand Down
8 changes: 0 additions & 8 deletions lld/wasm/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,13 +358,6 @@ void Writer::layoutMemory() {
memoryPtr = config->globalBase;
}
} else {
if (!config->globalBase && !config->relocatable && !config->isPic) {
// The default offset for static/global data, for when --global-base is
// not specified on the command line. The precise value of 1024 is
// somewhat arbitrary, and pre-dates wasm-ld (Its the value that
// emscripten used prior to wasm-ld).
config->globalBase = 1024;
}
memoryPtr = config->globalBase;
}

Expand Down Expand Up @@ -1685,7 +1678,6 @@ void Writer::run() {
// For PIC code the table base is assigned dynamically by the loader.
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
if (!config->isPic) {
config->tableBase = 1;
if (WasmSym::definedTableBase)
WasmSym::definedTableBase->setVA(config->tableBase);
if (WasmSym::definedTableBase32)
Expand Down

0 comments on commit 93adcb7

Please sign in to comment.