authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-23 08:55:34-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-11-23 08:55:34-08:00
log9d2fe1682f19bd21a393deeea2c4173b4429b482
tree471896cda055375d4c647e69c6ee2602665f4915
parentc7170e4a5480581db5f30913eebd9ad4f7cd121e
parent3e22077d46a02d1c4e02dd603b560978dc184a87
signature Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7204 from LemonBoy/piecrash

Fix logic for detecting _DYNAMIC symbol

5 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};
6161
62// TODO: This should be weak (#1917)
63extern var _DYNAMIC: [128]elf.Dyn;
64
65comptime {
66 if (std.Target.current.os.tag == .linux) {
67 asm (
68 \\ .weak _DYNAMIC
69 \\ .hidden _DYNAMIC
70 );
71 }
72}
73
74pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {62pub 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 a64 // No PT_DYNAMIC means this is either a statically-linked program or a
77 // badly corrupted one65 // badly corrupted dynamically-linked one.
78 return LinkMap.Iterator{ .current = null };66 return LinkMap.Iterator{ .current = null };
79 }67 };
8068
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(
43404340
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 image4343 // 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;
43494349
4350 // The executable has no dynamic link segment, create a single entry for4350 // The executable has no dynamic link segment, create a single entry for
4351 // the whole ELF image4351 // 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 }
43624373
4363 // Last return value from the callback function4374 // 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], _DYNAMIC61 \\ 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}
6768
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 {
386test "dl_iterate_phdr" {386test "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;
391389
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)