| author | |
| committer | |
| log | 9d2fe1682f19bd21a393deeea2c4173b4429b482 |
| tree | 471896cda055375d4c647e69c6ee2602665f4915 |
| parent | c7170e4a5480581db5f30913eebd9ad4f7cd121e |
| parent | 3e22077d46a02d1c4e02dd603b560978dc184a87 |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
Fix logic for detecting _DYNAMIC symbol5 files changed, 21 insertions(+), 23 deletions(-)
lib/std/dynamic_library.zig+3-15| ... | @@ -59,24 +59,12 @@ const RDebug = extern struct { | ... | @@ -59,24 +59,12 @@ const RDebug = extern struct { |
| 59 | r_ldbase: usize, | 59 | r_ldbase: usize, |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | // TODO: This should be weak (#1917) | ||
| 63 | extern var _DYNAMIC: [128]elf.Dyn; | ||
| 64 | |||
| 65 | comptime { | ||
| 66 | if (std.Target.current.os.tag == .linux) { | ||
| 67 | asm ( | ||
| 68 | \\ .weak _DYNAMIC | ||
| 69 | \\ .hidden _DYNAMIC | ||
| 70 | ); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator { | 62 | pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator { |
| 75 | if (@ptrToInt(&_DYNAMIC[0]) == 0) { | 63 | const _DYNAMIC = @extern([*]elf.Dyn, .{ .name = "_DYNAMIC", .linkage = .Weak }) orelse { |
| 76 | // No PT_DYNAMIC means this is either a statically-linked program or a | 64 | // No PT_DYNAMIC means this is either a statically-linked program or a |
| 77 | // badly corrupted one | 65 | // badly corrupted dynamically-linked one. |
| 78 | return LinkMap.Iterator{ .current = null }; | 66 | return LinkMap.Iterator{ .current = null }; |
| 79 | } | 67 | }; |
| 80 | 68 | ||
| 81 | const link_map_ptr = init: { | 69 | const link_map_ptr = init: { |
| 82 | var i: usize = 0; | 70 | var i: usize = 0; |
lib/std/os.zig+15-4| ... | @@ -4340,7 +4340,7 @@ pub fn dl_iterate_phdr( | ... | @@ -4340,7 +4340,7 @@ pub fn dl_iterate_phdr( |
| 4340 | 4340 | ||
| 4341 | const elf_base = std.process.getBaseAddress(); | 4341 | const elf_base = std.process.getBaseAddress(); |
| 4342 | const ehdr = @intToPtr(*elf.Ehdr, elf_base); | 4342 | const ehdr = @intToPtr(*elf.Ehdr, elf_base); |
| 4343 | // Make sure the base address points to an ELF image | 4343 | // Make sure the base address points to an ELF image. |
| 4344 | assert(mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF")); | 4344 | assert(mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF")); |
| 4345 | const n_phdr = ehdr.e_phnum; | 4345 | const n_phdr = ehdr.e_phnum; |
| 4346 | const phdrs = (@intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff))[0..n_phdr]; | 4346 | const phdrs = (@intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff))[0..n_phdr]; |
| ... | @@ -4348,10 +4348,21 @@ pub fn dl_iterate_phdr( | ... | @@ -4348,10 +4348,21 @@ pub fn dl_iterate_phdr( |
| 4348 | var it = dl.linkmap_iterator(phdrs) catch unreachable; | 4348 | var it = dl.linkmap_iterator(phdrs) catch unreachable; |
| 4349 | 4349 | ||
| 4350 | // The executable has no dynamic link segment, create a single entry for | 4350 | // The executable has no dynamic link segment, create a single entry for |
| 4351 | // the whole ELF image | 4351 | // the whole ELF image. |
| 4352 | if (it.end()) { | 4352 | if (it.end()) { |
| 4353 | // Find the base address for the ELF image, if this is a PIE the value | ||
| 4354 | // is non-zero. | ||
| 4355 | const base_address = for (phdrs) |*phdr| { | ||
| 4356 | if (phdr.p_type == elf.PT_PHDR) { | ||
| 4357 | break @ptrToInt(phdrs.ptr) - phdr.p_vaddr; | ||
| 4358 | // We could try computing the difference between _DYNAMIC and | ||
| 4359 | // the p_vaddr of the PT_DYNAMIC section, but using the phdr is | ||
| 4360 | // good enough (Is it?). | ||
| 4361 | } | ||
| 4362 | } else unreachable; | ||
| 4363 | |||
| 4353 | var info = dl_phdr_info{ | 4364 | var info = dl_phdr_info{ |
| 4354 | .dlpi_addr = 0, | 4365 | .dlpi_addr = base_address, |
| 4355 | .dlpi_name = "/proc/self/exe", | 4366 | .dlpi_name = "/proc/self/exe", |
| 4356 | .dlpi_phdr = phdrs.ptr, | 4367 | .dlpi_phdr = phdrs.ptr, |
| 4357 | .dlpi_phnum = ehdr.e_phnum, | 4368 | .dlpi_phnum = ehdr.e_phnum, |
| ... | @@ -4360,7 +4371,7 @@ pub fn dl_iterate_phdr( | ... | @@ -4360,7 +4371,7 @@ pub fn dl_iterate_phdr( |
| 4360 | return callback(&info, @sizeOf(dl_phdr_info), context); | 4371 | return callback(&info, @sizeOf(dl_phdr_info), context); |
| 4361 | } | 4372 | } |
| 4362 | 4373 | ||
| 4363 | // Last return value from the callback function | 4374 | // Last return value from the callback function. |
| 4364 | while (it.next()) |entry| { | 4375 | while (it.next()) |entry| { |
| 4365 | var dlpi_phdr: [*]elf.Phdr = undefined; | 4376 | var dlpi_phdr: [*]elf.Phdr = undefined; |
| 4366 | var dlpi_phnum: u16 = undefined; | 4377 | var dlpi_phnum: u16 = undefined; |
lib/std/os/linux/start_pie.zig+2-1| ... | @@ -56,12 +56,13 @@ fn getDynamicSymbol() [*]elf.Dyn { | ... | @@ -56,12 +56,13 @@ fn getDynamicSymbol() [*]elf.Dyn { |
| 56 | : [ret] "=r" (-> usize) | 56 | : [ret] "=r" (-> usize) |
| 57 | ), | 57 | ), |
| 58 | .riscv64 => asm volatile ( | 58 | .riscv64 => asm volatile ( |
| 59 | \\ .weak _DYNAMIC | ||
| 60 | \\ .hidden _DYNAMIC | ||
| 59 | \\ lla %[ret], _DYNAMIC | 61 | \\ lla %[ret], _DYNAMIC |
| 60 | : [ret] "=r" (-> usize) | 62 | : [ret] "=r" (-> usize) |
| 61 | ), | 63 | ), |
| 62 | else => @compileError("???"), | 64 | else => @compileError("???"), |
| 63 | }; | 65 | }; |
| 64 | if (addr == 0) unreachable; | ||
| 65 | return @intToPtr([*]elf.Dyn, addr); | 66 | return @intToPtr([*]elf.Dyn, addr); |
| 66 | } | 67 | } |
| 67 | 68 |
lib/std/os/test.zig-2| ... | @@ -386,8 +386,6 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { | ... | @@ -386,8 +386,6 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 386 | test "dl_iterate_phdr" { | 386 | test "dl_iterate_phdr" { |
| 387 | if (builtin.os.tag == .windows or builtin.os.tag == .wasi or builtin.os.tag == .macos) | 387 | if (builtin.os.tag == .windows or builtin.os.tag == .wasi or builtin.os.tag == .macos) |
| 388 | return error.SkipZigTest; | 388 | return error.SkipZigTest; |
| 389 | if (builtin.position_independent_executable) | ||
| 390 | return error.SkipZigTest; | ||
| 391 | 389 | ||
| 392 | var counter: usize = 0; | 390 | var counter: usize = 0; |
| 393 | try os.dl_iterate_phdr(&counter, IterFnError, iter_fn); | 391 | try os.dl_iterate_phdr(&counter, IterFnError, iter_fn); |
test/stack_traces.zig+1-1| ... | @@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { | ... | @@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { |
| 282 | \\source.zig:10:8: [address] in main (test) | 282 | \\source.zig:10:8: [address] in main (test) |
| 283 | \\ foo(); | 283 | \\ foo(); |
| 284 | \\ ^ | 284 | \\ ^ |
| 285 | \\start.zig:331:29: [address] in std.start.posixCallMainAndExit (test) | 285 | \\start.zig:337:29: [address] in std.start.posixCallMainAndExit (test) |
| 286 | \\ return root.main(); | 286 | \\ return root.main(); |
| 287 | \\ ^ | 287 | \\ ^ |
| 288 | \\start.zig:162:5: [address] in std.start._start (test) | 288 | \\start.zig:162:5: [address] in std.start._start (test) |