authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-23 14:58:08+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-23 15:06:07+01:00
log3e22077d46a02d1c4e02dd603b560978dc184a87
tree471896cda055375d4c647e69c6ee2602665f4915
parent0a84f85945a4d22c43b467c69ba7c26cd264659a

Fix the ELF base calculation

Find the effective ELF load address in dl_iterate_phdr by computing the difference between the in-memory phdr and its p_vaddr specified in the ELF file. This makes the dl_iterate_phdr test pass and restores the stack traces.

3 files changed, 15 insertions(+), 8 deletions(-)

lib/std/os.zig+15-4
......@@ -4340,7 +4340,7 @@ pub fn dl_iterate_phdr(
43404340
43414341 const elf_base = std.process.getBaseAddress();
43424342 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.
43444344 assert(mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF"));
43454345 const n_phdr = ehdr.e_phnum;
43464346 const phdrs = (@intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff))[0..n_phdr];
......@@ -4348,10 +4348,21 @@ pub fn dl_iterate_phdr(
43484348 var it = dl.linkmap_iterator(phdrs) catch unreachable;
43494349
43504350 // The executable has no dynamic link segment, create a single entry for
4351 // the whole ELF image
4351 // the whole ELF image.
43524352 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
43534364 var info = dl_phdr_info{
4354 .dlpi_addr = 0,
4365 .dlpi_addr = base_address,
43554366 .dlpi_name = "/proc/self/exe",
43564367 .dlpi_phdr = phdrs.ptr,
43574368 .dlpi_phnum = ehdr.e_phnum,
......@@ -4360,7 +4371,7 @@ pub fn dl_iterate_phdr(
43604371 return callback(&info, @sizeOf(dl_phdr_info), context);
43614372 }
43624373
4363 // Last return value from the callback function
4374 // Last return value from the callback function.
43644375 while (it.next()) |entry| {
43654376 var dlpi_phdr: [*]elf.Phdr = undefined;
43664377 var dlpi_phnum: u16 = undefined;
lib/std/os/test.zig-2
......@@ -386,8 +386,6 @@ fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
386386test "dl_iterate_phdr" {
387387 if (builtin.os.tag == .windows or builtin.os.tag == .wasi or builtin.os.tag == .macos)
388388 return error.SkipZigTest;
389 if (builtin.position_independent_executable)
390 return error.SkipZigTest;
391389
392390 var counter: usize = 0;
393391 try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);
lib/std/process.zig-2
......@@ -686,8 +686,6 @@ pub fn getBaseAddress() usize {
686686 if (base != 0) {
687687 return base;
688688 }
689 // XXX: Wrong for PIE executables, it should look at the difference
690 // between _DYNAMIC and the PT_DYNAMIC phdr instead.
691689 const phdr = os.system.getauxval(std.elf.AT_PHDR);
692690 return phdr - @sizeOf(std.elf.Ehdr);
693691 },