authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2023-01-05 21:21:29+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-05 19:39:17-07:00
log6ad92108e2cbba06064724d8d91abaede20f355a
tree4551c42980bf7044fd67edcbe51f7d9a257344c6
parentc28c38d1e5648a45e8b3b2edbd1c732edb8d2642

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: https://github.com/jart/blink/issues/14

5 files changed, 46 insertions(+), 0 deletions(-)

lib/std/build/LibExeObjStep.zig+14
...@@ -155,6 +155,12 @@ link_z_relro: bool = true,...@@ -155,6 +155,12 @@ link_z_relro: bool = true,
155/// Allow relocations to be lazily processed after load.155/// Allow relocations to be lazily processed after load.
156link_z_lazy: bool = false,156link_z_lazy: bool = false,
157157
158/// Common page size
159link_z_common_page_size: ?u64 = null,
160
161/// Maximum page size
162link_z_max_page_size: ?u64 = null,
163
158/// (Darwin) Install name for the dylib164/// (Darwin) Install name for the dylib
159install_name: ?[]const u8 = null,165install_name: ?[]const u8 = null,
160166
...@@ -1338,6 +1344,14 @@ fn make(step: *Step) !void {...@@ -1338,6 +1344,14 @@ fn make(step: *Step) !void {
1338 try zig_args.append("-z");1344 try zig_args.append("-z");
1339 try zig_args.append("lazy");1345 try zig_args.append("lazy");
1340 }1346 }
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
1342 if (self.libc_file) |libc_file| {1356 if (self.libc_file) |libc_file| {
1343 try zig_args.append("--libc");1357 try zig_args.append("--libc");
src/Compilation.zig+6
...@@ -979,6 +979,8 @@ pub const InitOptions = struct {...@@ -979,6 +979,8 @@ pub const InitOptions = struct {
979 linker_z_now: bool = true,979 linker_z_now: bool = true,
980 linker_z_relro: bool = true,980 linker_z_relro: bool = true,
981 linker_z_nocopyreloc: bool = false,981 linker_z_nocopyreloc: bool = false,
982 linker_z_common_page_size: ?u64 = null,
983 linker_z_max_page_size: ?u64 = null,
982 linker_tsaware: bool = false,984 linker_tsaware: bool = false,
983 linker_nxcompat: bool = false,985 linker_nxcompat: bool = false,
984 linker_dynamicbase: bool = false,986 linker_dynamicbase: bool = false,
...@@ -1842,6 +1844,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {...@@ -1842,6 +1844,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1842 .z_nocopyreloc = options.linker_z_nocopyreloc,1844 .z_nocopyreloc = options.linker_z_nocopyreloc,
1843 .z_now = options.linker_z_now,1845 .z_now = options.linker_z_now,
1844 .z_relro = options.linker_z_relro,1846 .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,
1845 .tsaware = options.linker_tsaware,1849 .tsaware = options.linker_tsaware,
1846 .nxcompat = options.linker_nxcompat,1850 .nxcompat = options.linker_nxcompat,
1847 .dynamicbase = options.linker_dynamicbase,1851 .dynamicbase = options.linker_dynamicbase,
...@@ -2637,6 +2641,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes...@@ -2637,6 +2641,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
2637 man.hash.add(comp.bin_file.options.z_nocopyreloc);2641 man.hash.add(comp.bin_file.options.z_nocopyreloc);
2638 man.hash.add(comp.bin_file.options.z_now);2642 man.hash.add(comp.bin_file.options.z_now);
2639 man.hash.add(comp.bin_file.options.z_relro);2643 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);
2640 man.hash.add(comp.bin_file.options.hash_style);2646 man.hash.add(comp.bin_file.options.hash_style);
2641 man.hash.add(comp.bin_file.options.compress_debug_sections);2647 man.hash.add(comp.bin_file.options.compress_debug_sections);
2642 man.hash.add(comp.bin_file.options.include_compiler_rt);2648 man.hash.add(comp.bin_file.options.include_compiler_rt);
src/link.zig+2
...@@ -121,6 +121,8 @@ pub const Options = struct {...@@ -121,6 +121,8 @@ pub const Options = struct {
121 z_nocopyreloc: bool,121 z_nocopyreloc: bool,
122 z_now: bool,122 z_now: bool,
123 z_relro: bool,123 z_relro: bool,
124 z_common_page_size: ?u64,
125 z_max_page_size: ?u64,
124 tsaware: bool,126 tsaware: bool,
125 nxcompat: bool,127 nxcompat: bool,
126 dynamicbase: bool,128 dynamicbase: bool,
src/link/Elf.zig+10
...@@ -1390,6 +1390,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1390,6 +1390,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1390 man.hash.add(self.base.options.z_nocopyreloc);1390 man.hash.add(self.base.options.z_nocopyreloc);
1391 man.hash.add(self.base.options.z_now);1391 man.hash.add(self.base.options.z_now);
1392 man.hash.add(self.base.options.z_relro);1392 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);
1393 man.hash.add(self.base.options.hash_style);1395 man.hash.add(self.base.options.hash_style);
1394 // strip does not need to go into the linker hash because it is part of the hash namespace1396 // strip does not need to go into the linker hash because it is part of the hash namespace
1395 if (self.base.options.link_libc) {1397 if (self.base.options.link_libc) {
...@@ -1594,6 +1596,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v...@@ -1594,6 +1596,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
1594 // LLD defaults to -zrelro1596 // LLD defaults to -zrelro
1595 try argv.append("-znorelro");1597 try argv.append("-znorelro");
1596 }1598 }
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
1598 if (getLDMOption(target)) |ldm| {1608 if (getLDMOption(target)) |ldm| {
1599 // Any target ELF will use the freebsd osabi if suffixed with "_fbsd".1609 // Any target ELF will use the freebsd osabi if suffixed with "_fbsd".
src/main.zig+14
...@@ -495,6 +495,8 @@ const usage_build_generic =...@@ -495,6 +495,8 @@ const usage_build_generic =
495 \\ lazy Don't force all relocations to be processed on load495 \\ lazy Don't force all relocations to be processed on load
496 \\ relro (default) Force all relocations to be read-only after processing496 \\ relro (default) Force all relocations to be read-only after processing
497 \\ norelro Don't force all relocations to be read-only after processing497 \\ 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
498 \\ -dynamic Force output to be dynamically linked500 \\ -dynamic Force output to be dynamically linked
499 \\ -static Force output to be statically linked501 \\ -static Force output to be statically linked
500 \\ -Bsymbolic Bind global references locally502 \\ -Bsymbolic Bind global references locally
...@@ -744,6 +746,8 @@ fn buildOutputType(...@@ -744,6 +746,8 @@ fn buildOutputType(
744 var linker_z_origin = false;746 var linker_z_origin = false;
745 var linker_z_now = true;747 var linker_z_now = true;
746 var linker_z_relro = true;748 var linker_z_relro = true;
749 var linker_z_common_page_size: ?u64 = null;
750 var linker_z_max_page_size: ?u64 = null;
747 var linker_tsaware = false;751 var linker_tsaware = false;
748 var linker_nxcompat = false;752 var linker_nxcompat = false;
749 var linker_dynamicbase = false;753 var linker_dynamicbase = false;
...@@ -1325,6 +1329,10 @@ fn buildOutputType(...@@ -1325,6 +1329,10 @@ fn buildOutputType(
1325 linker_z_relro = true;1329 linker_z_relro = true;
1326 } else if (mem.eql(u8, z_arg, "norelro")) {1330 } else if (mem.eql(u8, z_arg, "norelro")) {
1327 linker_z_relro = false;1331 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);
1328 } else {1336 } else {
1329 warn("unsupported linker extension flag: -z {s}", .{z_arg});1337 warn("unsupported linker extension flag: -z {s}", .{z_arg});
1330 }1338 }
...@@ -1923,6 +1931,10 @@ fn buildOutputType(...@@ -1923,6 +1931,10 @@ fn buildOutputType(
1923 stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {1931 stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
1924 fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) });1932 fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) });
1925 };1933 };
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);
1926 } else {1938 } else {
1927 warn("unsupported linker extension flag: -z {s}", .{z_arg});1939 warn("unsupported linker extension flag: -z {s}", .{z_arg});
1928 }1940 }
...@@ -3042,6 +3054,8 @@ fn buildOutputType(...@@ -3042,6 +3054,8 @@ fn buildOutputType(
3042 .linker_z_origin = linker_z_origin,3054 .linker_z_origin = linker_z_origin,
3043 .linker_z_now = linker_z_now,3055 .linker_z_now = linker_z_now,
3044 .linker_z_relro = linker_z_relro,3056 .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,
3045 .linker_tsaware = linker_tsaware,3059 .linker_tsaware = linker_tsaware,
3046 .linker_nxcompat = linker_nxcompat,3060 .linker_nxcompat = linker_nxcompat,
3047 .linker_dynamicbase = linker_dynamicbase,3061 .linker_dynamicbase = linker_dynamicbase,