Skip to content

Commit 6ad9210

Browse files
jedisct1andrewrk
authored andcommitted
ELF linker: support common-page-size and max-page-size lld opts
These linker flags are required to build static ELF binaries that can run under the Blink emulator: jart/blink#14
1 parent c28c38d commit 6ad9210

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

lib/std/build/LibExeObjStep.zig

+14
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ link_z_relro: bool = true,
155155
/// Allow relocations to be lazily processed after load.
156156
link_z_lazy: bool = false,
157157

158+
/// Common page size
159+
link_z_common_page_size: ?u64 = null,
160+
161+
/// Maximum page size
162+
link_z_max_page_size: ?u64 = null,
163+
158164
/// (Darwin) Install name for the dylib
159165
install_name: ?[]const u8 = null,
160166

@@ -1338,6 +1344,14 @@ fn make(step: *Step) !void {
13381344
try zig_args.append("-z");
13391345
try zig_args.append("lazy");
13401346
}
1347+
if (self.link_z_common_page_size) |size| {
1348+
try zig_args.append("-z");
1349+
try zig_args.append(builder.fmt("common-page-size={d}", .{size}));
1350+
}
1351+
if (self.link_z_max_page_size) |size| {
1352+
try zig_args.append("-z");
1353+
try zig_args.append(builder.fmt("max-page-size={d}", .{size}));
1354+
}
13411355

13421356
if (self.libc_file) |libc_file| {
13431357
try zig_args.append("--libc");

src/Compilation.zig

+6
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,8 @@ pub const InitOptions = struct {
979979
linker_z_now: bool = true,
980980
linker_z_relro: bool = true,
981981
linker_z_nocopyreloc: bool = false,
982+
linker_z_common_page_size: ?u64 = null,
983+
linker_z_max_page_size: ?u64 = null,
982984
linker_tsaware: bool = false,
983985
linker_nxcompat: bool = false,
984986
linker_dynamicbase: bool = false,
@@ -1842,6 +1844,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
18421844
.z_nocopyreloc = options.linker_z_nocopyreloc,
18431845
.z_now = options.linker_z_now,
18441846
.z_relro = options.linker_z_relro,
1847+
.z_common_page_size = options.linker_z_common_page_size,
1848+
.z_max_page_size = options.linker_z_max_page_size,
18451849
.tsaware = options.linker_tsaware,
18461850
.nxcompat = options.linker_nxcompat,
18471851
.dynamicbase = options.linker_dynamicbase,
@@ -2637,6 +2641,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
26372641
man.hash.add(comp.bin_file.options.z_nocopyreloc);
26382642
man.hash.add(comp.bin_file.options.z_now);
26392643
man.hash.add(comp.bin_file.options.z_relro);
2644+
man.hash.add(comp.bin_file.options.z_common_page_size orelse 0);
2645+
man.hash.add(comp.bin_file.options.z_max_page_size orelse 0);
26402646
man.hash.add(comp.bin_file.options.hash_style);
26412647
man.hash.add(comp.bin_file.options.compress_debug_sections);
26422648
man.hash.add(comp.bin_file.options.include_compiler_rt);

src/link.zig

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ pub const Options = struct {
121121
z_nocopyreloc: bool,
122122
z_now: bool,
123123
z_relro: bool,
124+
z_common_page_size: ?u64,
125+
z_max_page_size: ?u64,
124126
tsaware: bool,
125127
nxcompat: bool,
126128
dynamicbase: bool,

src/link/Elf.zig

+10
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
13901390
man.hash.add(self.base.options.z_nocopyreloc);
13911391
man.hash.add(self.base.options.z_now);
13921392
man.hash.add(self.base.options.z_relro);
1393+
man.hash.add(self.base.options.z_common_page_size orelse 0);
1394+
man.hash.add(self.base.options.z_max_page_size orelse 0);
13931395
man.hash.add(self.base.options.hash_style);
13941396
// strip does not need to go into the linker hash because it is part of the hash namespace
13951397
if (self.base.options.link_libc) {
@@ -1594,6 +1596,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
15941596
// LLD defaults to -zrelro
15951597
try argv.append("-znorelro");
15961598
}
1599+
if (self.base.options.z_common_page_size) |size| {
1600+
try argv.append("-z");
1601+
try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size}));
1602+
}
1603+
if (self.base.options.z_max_page_size) |size| {
1604+
try argv.append("-z");
1605+
try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size}));
1606+
}
15971607

15981608
if (getLDMOption(target)) |ldm| {
15991609
// Any target ELF will use the freebsd osabi if suffixed with "_fbsd".

src/main.zig

+14
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ const usage_build_generic =
495495
\\ lazy Don't force all relocations to be processed on load
496496
\\ relro (default) Force all relocations to be read-only after processing
497497
\\ norelro Don't force all relocations to be read-only after processing
498+
\\ common-page-size=[bytes] Set the common page size for ELF binaries
499+
\\ max-page-size=[bytes] Set the max page size for ELF binaries
498500
\\ -dynamic Force output to be dynamically linked
499501
\\ -static Force output to be statically linked
500502
\\ -Bsymbolic Bind global references locally
@@ -744,6 +746,8 @@ fn buildOutputType(
744746
var linker_z_origin = false;
745747
var linker_z_now = true;
746748
var linker_z_relro = true;
749+
var linker_z_common_page_size: ?u64 = null;
750+
var linker_z_max_page_size: ?u64 = null;
747751
var linker_tsaware = false;
748752
var linker_nxcompat = false;
749753
var linker_dynamicbase = false;
@@ -1325,6 +1329,10 @@ fn buildOutputType(
13251329
linker_z_relro = true;
13261330
} else if (mem.eql(u8, z_arg, "norelro")) {
13271331
linker_z_relro = false;
1332+
} else if (mem.startsWith(u8, z_arg, "common-page-size=")) {
1333+
linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);
1334+
} else if (mem.startsWith(u8, z_arg, "max-page-size=")) {
1335+
linker_z_max_page_size = parseIntSuffix(z_arg, "max-page-size=".len);
13281336
} else {
13291337
warn("unsupported linker extension flag: -z {s}", .{z_arg});
13301338
}
@@ -1923,6 +1931,10 @@ fn buildOutputType(
19231931
stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
19241932
fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) });
19251933
};
1934+
} else if (mem.startsWith(u8, z_arg, "common-page-size=")) {
1935+
linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);
1936+
} else if (mem.startsWith(u8, z_arg, "max-page-size=")) {
1937+
linker_z_max_page_size = parseIntSuffix(z_arg, "max-page-size=".len);
19261938
} else {
19271939
warn("unsupported linker extension flag: -z {s}", .{z_arg});
19281940
}
@@ -3042,6 +3054,8 @@ fn buildOutputType(
30423054
.linker_z_origin = linker_z_origin,
30433055
.linker_z_now = linker_z_now,
30443056
.linker_z_relro = linker_z_relro,
3057+
.linker_z_common_page_size = linker_z_common_page_size,
3058+
.linker_z_max_page_size = linker_z_max_page_size,
30453059
.linker_tsaware = linker_tsaware,
30463060
.linker_nxcompat = linker_nxcompat,
30473061
.linker_dynamicbase = linker_dynamicbase,

0 commit comments

Comments
 (0)