| author | |
| committer | |
| log | b23404af3d3141037f83257379743c9cdb0de473 |
| tree | 95f1675b826838265ea8ab72167eb449720e569c |
| parent | b64ce08c993f0871b2f9be7df561da69d9a9037e |
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 #309665 files changed, 28 insertions(+), 30 deletions(-)
lib/std/dynamic_library.zig+8-21| ... | ... | @@ -302,27 +302,14 @@ pub const ElfDynLib = struct { |
| 302 | 302 | const extended_memsz = mem.alignForward(usize, ph.p_memsz + extra_bytes, page_size); |
| 303 | 303 | const ptr = @as([*]align(std.heap.page_size_min) u8, @ptrFromInt(aligned_addr)); |
| 304 | 304 | const prot = elfToProt(ph.p_flags); |
| 305 | if ((ph.p_flags & elf.PF_W) == 0) { | |
| 306 | // If it does not need write access, it can be mapped from the fd. | |
| 307 | _ = try posix.mmap( | |
| 308 | ptr, | |
| 309 | extended_memsz, | |
| 310 | prot, | |
| 311 | .{ .TYPE = .PRIVATE, .FIXED = true }, | |
| 312 | file.handle, | |
| 313 | ph.p_offset - extra_bytes, | |
| 314 | ); | |
| 315 | } else { | |
| 316 | const sect_mem = try posix.mmap( | |
| 317 | ptr, | |
| 318 | extended_memsz, | |
| 319 | prot, | |
| 320 | .{ .TYPE = .PRIVATE, .FIXED = true, .ANONYMOUS = true }, | |
| 321 | -1, | |
| 322 | 0, | |
| 323 | ); | |
| 324 | @memcpy(sect_mem[0..ph.p_filesz], file_bytes[0..ph.p_filesz]); | |
| 325 | } | |
| 305 | _ = try posix.mmap( | |
| 306 | ptr, | |
| 307 | extended_memsz, | |
| 308 | prot, | |
| 309 | .{ .TYPE = .PRIVATE, .FIXED = true }, | |
| 310 | file.handle, | |
| 311 | ph.p_offset - extra_bytes, | |
| 312 | ); | |
| 326 | 313 | }, |
| 327 | 314 | else => {}, |
| 328 | 315 | } |
test/standalone/load_dynamic_library/add.zig deleted-3| ... | ... | @@ -1,3 +0,0 @@ |
| 1 | export fn add(a: i32, b: i32) i32 { | |
| 2 | return a + b; | |
| 3 | } |
test/standalone/load_dynamic_library/build.zig+6-2| ... | ... | @@ -11,12 +11,16 @@ pub fn build(b: *std.Build) void { |
| 11 | 11 | if (builtin.os.tag == .wasi) return; |
| 12 | 12 | if (builtin.os.tag == .windows) return; |
| 13 | 13 | |
| 14 | // ld and lld do not agree on the format of the .hash section | |
| 15 | // Tracked by https://codeberg.org/ziglang/zig/issues/35746 | |
| 16 | if (builtin.cpu.arch == .s390x and builtin.os.tag == .linux) return; | |
| 17 | ||
| 14 | 18 | const lib = b.addLibrary(.{ |
| 15 | 19 | .linkage = .dynamic, |
| 16 | .name = "add", | |
| 20 | .name = "lib", | |
| 17 | 21 | .version = .{ .major = 1, .minor = 0, .patch = 0 }, |
| 18 | 22 | .root_module = b.createModule(.{ |
| 19 | .root_source_file = b.path("add.zig"), | |
| 23 | .root_source_file = b.path("lib.zig"), | |
| 20 | 24 | .optimize = optimize, |
| 21 | 25 | .target = target, |
| 22 | 26 | }), |
test/standalone/load_dynamic_library/lib.zig created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | export fn addInts(a: i32, b: i32) i32 { | |
| 2 | return a + b; | |
| 3 | } | |
| 4 | ||
| 5 | var forty_two: i32 = 42; | |
| 6 | export fn fortyTwo() i32 { | |
| 7 | return forty_two; | |
| 8 | } |
test/standalone/load_dynamic_library/main.zig+6-4| ... | ... | @@ -8,9 +8,11 @@ pub fn main(init: std.process.Init) !void { |
| 8 | 8 | var lib = try std.DynLib.open(dynlib_name); |
| 9 | 9 | defer lib.close(); |
| 10 | 10 | |
| 11 | const Add = *const fn (i32, i32) callconv(.c) i32; | |
| 12 | const addFn = lib.lookup(Add, "add") orelse return error.SymbolNotFound; | |
| 11 | const AddInts = *const fn (i32, i32) callconv(.c) i32; | |
| 12 | const addInts = lib.lookup(AddInts, "addInts").?; | |
| 13 | std.debug.assert(addInts(12, 34) == 46); | |
| 13 | 14 | |
| 14 | const result = addFn(12, 34); | |
| 15 | std.debug.assert(result == 46); | |
| 15 | const FortyTwo = *const fn () callconv(.c) i32; | |
| 16 | const fortyTwo = lib.lookup(FortyTwo, "fortyTwo").?; | |
| 17 | std.debug.assert(fortyTwo() == 42); | |
| 16 | 18 | } |