From b23404af3d3141037f83257379743c9cdb0de473 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 12 Jun 2026 07:29:14 -0400 Subject: [PATCH] DynLib: fix elf loading The comment was just bogus given that these are private (COW) mappings. This code will need extra logic for handling multiple load segments overlapping the same page, but the deleted logic was not even close. Closes #30966 --- lib/std/dynamic_library.zig | 29 +++++-------------- test/standalone/load_dynamic_library/add.zig | 3 -- .../standalone/load_dynamic_library/build.zig | 8 +++-- test/standalone/load_dynamic_library/lib.zig | 8 +++++ test/standalone/load_dynamic_library/main.zig | 10 ++++--- 5 files changed, 28 insertions(+), 30 deletions(-) delete mode 100644 test/standalone/load_dynamic_library/add.zig create mode 100644 test/standalone/load_dynamic_library/lib.zig diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index d7cea3b3cd3699e4e0a4d5700b241fdc4656ac4e..3f39089510ee6ccf85f90625dfcf542cfb11bf70 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -302,27 +302,14 @@ pub const ElfDynLib = struct { const extended_memsz = mem.alignForward(usize, ph.p_memsz + extra_bytes, page_size); const ptr = @as([*]align(std.heap.page_size_min) u8, @ptrFromInt(aligned_addr)); const prot = elfToProt(ph.p_flags); - if ((ph.p_flags & elf.PF_W) == 0) { - // If it does not need write access, it can be mapped from the fd. - _ = try posix.mmap( - ptr, - extended_memsz, - prot, - .{ .TYPE = .PRIVATE, .FIXED = true }, - file.handle, - ph.p_offset - extra_bytes, - ); - } else { - const sect_mem = try posix.mmap( - ptr, - extended_memsz, - prot, - .{ .TYPE = .PRIVATE, .FIXED = true, .ANONYMOUS = true }, - -1, - 0, - ); - @memcpy(sect_mem[0..ph.p_filesz], file_bytes[0..ph.p_filesz]); - } + _ = try posix.mmap( + ptr, + extended_memsz, + prot, + .{ .TYPE = .PRIVATE, .FIXED = true }, + file.handle, + ph.p_offset - extra_bytes, + ); }, else => {}, } diff --git a/test/standalone/load_dynamic_library/add.zig b/test/standalone/load_dynamic_library/add.zig deleted file mode 100644 index a04ec1544dc82e27afb137de2672a48d726a72fc..0000000000000000000000000000000000000000 --- a/test/standalone/load_dynamic_library/add.zig +++ /dev/null @@ -1,3 +0,0 @@ -export fn add(a: i32, b: i32) i32 { - return a + b; -} diff --git a/test/standalone/load_dynamic_library/build.zig b/test/standalone/load_dynamic_library/build.zig index 2160b2b3e474a558725d9f2c39eb98f7a1be9d8a..8af976e9929eef069673e71c0bb1c1a738ef4e7d 100644 --- a/test/standalone/load_dynamic_library/build.zig +++ b/test/standalone/load_dynamic_library/build.zig @@ -11,12 +11,16 @@ pub fn build(b: *std.Build) void { if (builtin.os.tag == .wasi) return; if (builtin.os.tag == .windows) return; + // ld and lld do not agree on the format of the .hash section + // Tracked by https://codeberg.org/ziglang/zig/issues/35746 + if (builtin.cpu.arch == .s390x and builtin.os.tag == .linux) return; + const lib = b.addLibrary(.{ .linkage = .dynamic, - .name = "add", + .name = "lib", .version = .{ .major = 1, .minor = 0, .patch = 0 }, .root_module = b.createModule(.{ - .root_source_file = b.path("add.zig"), + .root_source_file = b.path("lib.zig"), .optimize = optimize, .target = target, }), diff --git a/test/standalone/load_dynamic_library/lib.zig b/test/standalone/load_dynamic_library/lib.zig new file mode 100644 index 0000000000000000000000000000000000000000..d5f45bce7ccb715ed1ef1902780caaf65b1a5875 --- /dev/null +++ b/test/standalone/load_dynamic_library/lib.zig @@ -0,0 +1,8 @@ +export fn addInts(a: i32, b: i32) i32 { + return a + b; +} + +var forty_two: i32 = 42; +export fn fortyTwo() i32 { + return forty_two; +} diff --git a/test/standalone/load_dynamic_library/main.zig b/test/standalone/load_dynamic_library/main.zig index ac64e67cdaddf18d0904f5ecff78306542930fef..a8e9e9b6d6661a8536178be3148347ea7448c634 100644 --- a/test/standalone/load_dynamic_library/main.zig +++ b/test/standalone/load_dynamic_library/main.zig @@ -8,9 +8,11 @@ pub fn main(init: std.process.Init) !void { var lib = try std.DynLib.open(dynlib_name); defer lib.close(); - const Add = *const fn (i32, i32) callconv(.c) i32; - const addFn = lib.lookup(Add, "add") orelse return error.SymbolNotFound; + const AddInts = *const fn (i32, i32) callconv(.c) i32; + const addInts = lib.lookup(AddInts, "addInts").?; + std.debug.assert(addInts(12, 34) == 46); - const result = addFn(12, 34); - std.debug.assert(result == 46); + const FortyTwo = *const fn () callconv(.c) i32; + const fortyTwo = lib.lookup(FortyTwo, "fortyTwo").?; + std.debug.assert(fortyTwo() == 42); } -- 2.54.0