Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ELF linker: support common-page-size and max-page-size lld opts #14217

Merged
merged 1 commit into from
Jan 6, 2023
Merged
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
14 changes: 14 additions & 0 deletions lib/std/build/LibExeObjStep.zig
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ link_z_relro: bool = true,
/// Allow relocations to be lazily processed after load.
link_z_lazy: bool = false,

/// Common page size
link_z_common_page_size: ?u64 = null,

/// Maximum page size
link_z_max_page_size: ?u64 = null,

/// (Darwin) Install name for the dylib
install_name: ?[]const u8 = null,

Expand Down Expand Up @@ -1338,6 +1344,14 @@ fn make(step: *Step) !void {
try zig_args.append("-z");
try zig_args.append("lazy");
}
if (self.link_z_common_page_size) |size| {
try zig_args.append("-z");
try zig_args.append(builder.fmt("common-page-size={d}", .{size}));
}
if (self.link_z_max_page_size) |size| {
try zig_args.append("-z");
try zig_args.append(builder.fmt("max-page-size={d}", .{size}));
}

if (self.libc_file) |libc_file| {
try zig_args.append("--libc");
Expand Down
6 changes: 6 additions & 0 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,8 @@ pub const InitOptions = struct {
linker_z_now: bool = true,
linker_z_relro: bool = true,
linker_z_nocopyreloc: bool = false,
linker_z_common_page_size: ?u64 = null,
linker_z_max_page_size: ?u64 = null,
linker_tsaware: bool = false,
linker_nxcompat: bool = false,
linker_dynamicbase: bool = false,
Expand Down Expand Up @@ -1835,6 +1837,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
.z_nocopyreloc = options.linker_z_nocopyreloc,
.z_now = options.linker_z_now,
.z_relro = options.linker_z_relro,
.z_common_page_size = options.linker_z_common_page_size,
.z_max_page_size = options.linker_z_max_page_size,
.tsaware = options.linker_tsaware,
.nxcompat = options.linker_nxcompat,
.dynamicbase = options.linker_dynamicbase,
Expand Down Expand Up @@ -2628,6 +2632,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
man.hash.add(comp.bin_file.options.z_nocopyreloc);
man.hash.add(comp.bin_file.options.z_now);
man.hash.add(comp.bin_file.options.z_relro);
man.hash.add(comp.bin_file.options.z_common_page_size orelse 0);
man.hash.add(comp.bin_file.options.z_max_page_size orelse 0);
man.hash.add(comp.bin_file.options.hash_style);
man.hash.add(comp.bin_file.options.compress_debug_sections);
man.hash.add(comp.bin_file.options.include_compiler_rt);
Expand Down
2 changes: 2 additions & 0 deletions src/link.zig
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ pub const Options = struct {
z_nocopyreloc: bool,
z_now: bool,
z_relro: bool,
z_common_page_size: ?u64,
z_max_page_size: ?u64,
tsaware: bool,
nxcompat: bool,
dynamicbase: bool,
Expand Down
10 changes: 10 additions & 0 deletions src/link/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
man.hash.add(self.base.options.z_nocopyreloc);
man.hash.add(self.base.options.z_now);
man.hash.add(self.base.options.z_relro);
man.hash.add(self.base.options.z_common_page_size orelse 0);
man.hash.add(self.base.options.z_max_page_size orelse 0);
man.hash.add(self.base.options.hash_style);
// strip does not need to go into the linker hash because it is part of the hash namespace
if (self.base.options.link_libc) {
Expand Down Expand Up @@ -1594,6 +1596,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
// LLD defaults to -zrelro
try argv.append("-znorelro");
}
if (self.base.options.z_common_page_size) |size| {
try argv.append("-z");
try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size}));
}
if (self.base.options.z_max_page_size) |size| {
try argv.append("-z");
try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size}));
}

if (getLDMOption(target)) |ldm| {
// Any target ELF will use the freebsd osabi if suffixed with "_fbsd".
Expand Down
14 changes: 14 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,8 @@ const usage_build_generic =
\\ lazy Don't force all relocations to be processed on load
\\ relro (default) Force all relocations to be read-only after processing
\\ norelro Don't force all relocations to be read-only after processing
\\ common-page-size=[bytes] Set the common page size for ELF binaries
\\ max-page-size=[bytes] Set the max page size for ELF binaries
\\ -dynamic Force output to be dynamically linked
\\ -static Force output to be statically linked
\\ -Bsymbolic Bind global references locally
Expand Down Expand Up @@ -744,6 +746,8 @@ fn buildOutputType(
var linker_z_origin = false;
var linker_z_now = true;
var linker_z_relro = true;
var linker_z_common_page_size: ?u64 = null;
var linker_z_max_page_size: ?u64 = null;
var linker_tsaware = false;
var linker_nxcompat = false;
var linker_dynamicbase = false;
Expand Down Expand Up @@ -1323,6 +1327,10 @@ fn buildOutputType(
linker_z_relro = true;
} else if (mem.eql(u8, z_arg, "norelro")) {
linker_z_relro = false;
} else if (mem.startsWith(u8, z_arg, "common-page-size=")) {
linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);
} else if (mem.startsWith(u8, z_arg, "max-page-size=")) {
linker_z_max_page_size = parseIntSuffix(z_arg, "max-page-size=".len);
} else {
warn("unsupported linker extension flag: -z {s}", .{z_arg});
}
Expand Down Expand Up @@ -1915,6 +1923,10 @@ fn buildOutputType(
stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) });
};
} else if (mem.startsWith(u8, z_arg, "common-page-size=")) {
linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);
} else if (mem.startsWith(u8, z_arg, "max-page-size=")) {
linker_z_max_page_size = parseIntSuffix(z_arg, "max-page-size=".len);
} else {
warn("unsupported linker extension flag: -z {s}", .{z_arg});
}
Expand Down Expand Up @@ -3016,6 +3028,8 @@ fn buildOutputType(
.linker_z_origin = linker_z_origin,
.linker_z_now = linker_z_now,
.linker_z_relro = linker_z_relro,
.linker_z_common_page_size = linker_z_common_page_size,
.linker_z_max_page_size = linker_z_max_page_size,
.linker_tsaware = linker_tsaware,
.linker_nxcompat = linker_nxcompat,
.linker_dynamicbase = linker_dynamicbase,
Expand Down