mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
stage2: add 4 new linker flags for WebAssembly
--import-memory import memory from the environment --initial-memory=[bytes] initial size of the linear memory --max-memory=[bytes] maximum size of the linear memory --global-base=[addr] where to start to place global data See #8633
This commit is contained in:
parent
9bb7ff68cc
commit
d2cdfb9490
@ -1439,6 +1439,10 @@ pub const LibExeObjStep = struct {
|
||||
disable_sanitize_c: bool,
|
||||
sanitize_thread: bool,
|
||||
rdynamic: bool,
|
||||
import_memory: bool = false,
|
||||
initial_memory: ?u64 = null,
|
||||
max_memory: ?u64 = null,
|
||||
global_base: ?u64 = null,
|
||||
c_std: Builder.CStd,
|
||||
override_lib_dir: ?[]const u8,
|
||||
main_pkg_path: ?[]const u8,
|
||||
@ -2431,6 +2435,18 @@ pub const LibExeObjStep = struct {
|
||||
if (self.rdynamic) {
|
||||
try zig_args.append("-rdynamic");
|
||||
}
|
||||
if (self.import_memory) {
|
||||
try zig_args.append("--import-memory");
|
||||
}
|
||||
if (self.initial_memory) |initial_memory| {
|
||||
try zig_args.append(builder.fmt("--initial-memory={d}", .{initial_memory}));
|
||||
}
|
||||
if (self.max_memory) |max_memory| {
|
||||
try zig_args.append(builder.fmt("--max-memory={d}", .{max_memory}));
|
||||
}
|
||||
if (self.global_base) |global_base| {
|
||||
try zig_args.append(builder.fmt("--global-base={d}", .{global_base}));
|
||||
}
|
||||
|
||||
if (self.code_model != .default) {
|
||||
try zig_args.append("-mcmodel");
|
||||
|
||||
@ -716,6 +716,10 @@ pub const InitOptions = struct {
|
||||
linker_gc_sections: ?bool = null,
|
||||
linker_allow_shlib_undefined: ?bool = null,
|
||||
linker_bind_global_refs_locally: ?bool = null,
|
||||
linker_import_memory: ?bool = null,
|
||||
linker_initial_memory: ?u64 = null,
|
||||
linker_max_memory: ?u64 = null,
|
||||
linker_global_base: ?u64 = null,
|
||||
each_lib_rpath: ?bool = null,
|
||||
disable_c_depfile: bool = false,
|
||||
linker_z_nodelete: bool = false,
|
||||
@ -1401,6 +1405,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
|
||||
.function_sections = options.function_sections,
|
||||
.allow_shlib_undefined = options.linker_allow_shlib_undefined,
|
||||
.bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
|
||||
.import_memory = options.linker_import_memory orelse false,
|
||||
.initial_memory = options.linker_initial_memory,
|
||||
.max_memory = options.linker_max_memory,
|
||||
.global_base = options.linker_global_base,
|
||||
.z_nodelete = options.linker_z_nodelete,
|
||||
.z_notext = options.linker_z_notext,
|
||||
.z_defs = options.linker_z_defs,
|
||||
|
||||
@ -82,6 +82,10 @@ pub const Options = struct {
|
||||
nxcompat: bool,
|
||||
dynamicbase: bool,
|
||||
bind_global_refs_locally: bool,
|
||||
import_memory: bool,
|
||||
initial_memory: ?u64,
|
||||
max_memory: ?u64,
|
||||
global_base: ?u64,
|
||||
is_native_os: bool,
|
||||
is_native_abi: bool,
|
||||
pic: bool,
|
||||
|
||||
@ -681,6 +681,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
try man.addOptionalFile(compiler_rt_path);
|
||||
man.hash.addOptional(self.base.options.stack_size_override);
|
||||
man.hash.addListOfBytes(self.base.options.extra_lld_args);
|
||||
man.hash.add(self.base.options.import_memory);
|
||||
man.hash.addOptional(self.base.options.initial_memory);
|
||||
man.hash.addOptional(self.base.options.max_memory);
|
||||
man.hash.addOptional(self.base.options.global_base);
|
||||
|
||||
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
|
||||
_ = try man.hit();
|
||||
@ -754,6 +758,25 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (self.base.options.import_memory) {
|
||||
try argv.append("--import-memory");
|
||||
}
|
||||
|
||||
if (self.base.options.initial_memory) |initial_memory| {
|
||||
const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory});
|
||||
try argv.append(arg);
|
||||
}
|
||||
|
||||
if (self.base.options.max_memory) |max_memory| {
|
||||
const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory});
|
||||
try argv.append(arg);
|
||||
}
|
||||
|
||||
if (self.base.options.global_base) |global_base| {
|
||||
const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});
|
||||
try argv.append(arg);
|
||||
}
|
||||
|
||||
if (self.base.options.output_mode == .Exe) {
|
||||
// Increase the default stack size to a more reasonable value of 1MB instead of
|
||||
// the default of 1 Wasm page being 64KB, unless overridden by the user.
|
||||
|
||||
36
src/main.zig
36
src/main.zig
@ -332,7 +332,7 @@ const usage_build_generic =
|
||||
\\ -mno-red-zone Force-disable the "red-zone"
|
||||
\\ -fomit-frame-pointer Omit the stack frame pointer
|
||||
\\ -fno-omit-frame-pointer Store the stack frame pointer
|
||||
\\ -mexec-model=[value] Execution model (WASI only)
|
||||
\\ -mexec-model=[value] (WASI) Execution model
|
||||
\\ --name [name] Override root name (not a file path)
|
||||
\\ -O [mode] Choose what to optimize for
|
||||
\\ Debug (default) Optimizations off, safety on
|
||||
@ -424,6 +424,10 @@ const usage_build_generic =
|
||||
\\ --image-base [addr] Set base address for executable image
|
||||
\\ -framework [name] (Darwin) link against framework
|
||||
\\ -F[dir] (Darwin) add search path for frameworks
|
||||
\\ --import-memory (WebAssembly) import memory from the environment
|
||||
\\ --initial-memory=[bytes] (WebAssembly) initial size of the linear memory
|
||||
\\ --max-memory=[bytes] (WebAssembly) maximum size of the linear memory
|
||||
\\ --global-base=[addr] (WebAssembly) where to start to place global data
|
||||
\\
|
||||
\\Test Options:
|
||||
\\ --test-filter [text] Skip tests that do not match filter
|
||||
@ -609,6 +613,10 @@ fn buildOutputType(
|
||||
var linker_gc_sections: ?bool = null;
|
||||
var linker_allow_shlib_undefined: ?bool = null;
|
||||
var linker_bind_global_refs_locally: ?bool = null;
|
||||
var linker_import_memory: ?bool = null;
|
||||
var linker_initial_memory: ?u64 = null;
|
||||
var linker_max_memory: ?u64 = null;
|
||||
var linker_global_base: ?u64 = null;
|
||||
var linker_z_nodelete = false;
|
||||
var linker_z_notext = false;
|
||||
var linker_z_defs = false;
|
||||
@ -1125,6 +1133,14 @@ fn buildOutputType(
|
||||
} else {
|
||||
warn("unsupported linker extension flag: -z {s}", .{z_arg});
|
||||
}
|
||||
} else if (mem.eql(u8, arg, "--import-memory")) {
|
||||
linker_import_memory = true;
|
||||
} else if (mem.startsWith(u8, arg, "--initial-memory=")) {
|
||||
linker_initial_memory = parseIntSuffix(arg, "--initial-memory=".len);
|
||||
} else if (mem.startsWith(u8, arg, "--max-memory=")) {
|
||||
linker_max_memory = parseIntSuffix(arg, "--max-memory=".len);
|
||||
} else if (mem.startsWith(u8, arg, "--global-base=")) {
|
||||
linker_global_base = parseIntSuffix(arg, "--global-base=".len);
|
||||
} else if (mem.eql(u8, arg, "-Bsymbolic")) {
|
||||
linker_bind_global_refs_locally = true;
|
||||
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
||||
@ -1453,6 +1469,14 @@ fn buildOutputType(
|
||||
linker_allow_shlib_undefined = false;
|
||||
} else if (mem.eql(u8, arg, "-Bsymbolic")) {
|
||||
linker_bind_global_refs_locally = true;
|
||||
} else if (mem.eql(u8, arg, "--import-memory")) {
|
||||
linker_import_memory = true;
|
||||
} else if (mem.startsWith(u8, arg, "--initial-memory=")) {
|
||||
linker_initial_memory = parseIntSuffix(arg, "--initial-memory=".len);
|
||||
} else if (mem.startsWith(u8, arg, "--max-memory=")) {
|
||||
linker_max_memory = parseIntSuffix(arg, "--max-memory=".len);
|
||||
} else if (mem.startsWith(u8, arg, "--global-base=")) {
|
||||
linker_global_base = parseIntSuffix(arg, "--global-base=".len);
|
||||
} else if (mem.eql(u8, arg, "-z")) {
|
||||
i += 1;
|
||||
if (i >= linker_args.items.len) {
|
||||
@ -2148,6 +2172,10 @@ fn buildOutputType(
|
||||
.linker_gc_sections = linker_gc_sections,
|
||||
.linker_allow_shlib_undefined = linker_allow_shlib_undefined,
|
||||
.linker_bind_global_refs_locally = linker_bind_global_refs_locally,
|
||||
.linker_import_memory = linker_import_memory,
|
||||
.linker_initial_memory = linker_initial_memory,
|
||||
.linker_max_memory = linker_max_memory,
|
||||
.linker_global_base = linker_global_base,
|
||||
.linker_z_nodelete = linker_z_nodelete,
|
||||
.linker_z_notext = linker_z_notext,
|
||||
.linker_z_defs = linker_z_defs,
|
||||
@ -4371,3 +4399,9 @@ pub fn cmdChangelist(
|
||||
}
|
||||
try bw.flush();
|
||||
}
|
||||
|
||||
fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 {
|
||||
return std.fmt.parseUnsigned(u64, arg[prefix_len..], 0) catch |err| {
|
||||
fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user