diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-11-23 14:58:08 +0100 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2020-11-23 15:06:07 +0100 |
| commit | 3e22077d46a02d1c4e02dd603b560978dc184a87 (patch) | |
| tree | 471896cda055375d4c647e69c6ee2602665f4915 /lib/std/os.zig | |
| parent | 0a84f85945a4d22c43b467c69ba7c26cd264659a (diff) | |
| download | zig-3e22077d46a02d1c4e02dd603b560978dc184a87.tar.gz zig-3e22077d46a02d1c4e02dd603b560978dc184a87.zip | |
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.
Diffstat (limited to 'lib/std/os.zig')
| -rw-r--r-- | lib/std/os.zig | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/lib/std/os.zig b/lib/std/os.zig index 2a6c8b2a52..e7c618431c 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -4340,7 +4340,7 @@ pub fn dl_iterate_phdr( const elf_base = std.process.getBaseAddress(); const ehdr = @intToPtr(*elf.Ehdr, elf_base); - // Make sure the base address points to an ELF image + // Make sure the base address points to an ELF image. assert(mem.eql(u8, ehdr.e_ident[0..4], "\x7fELF")); const n_phdr = ehdr.e_phnum; const phdrs = (@intToPtr([*]elf.Phdr, elf_base + ehdr.e_phoff))[0..n_phdr]; @@ -4348,10 +4348,21 @@ pub fn dl_iterate_phdr( var it = dl.linkmap_iterator(phdrs) catch unreachable; // The executable has no dynamic link segment, create a single entry for - // the whole ELF image + // the whole ELF image. if (it.end()) { + // Find the base address for the ELF image, if this is a PIE the value + // is non-zero. + const base_address = for (phdrs) |*phdr| { + if (phdr.p_type == elf.PT_PHDR) { + break @ptrToInt(phdrs.ptr) - phdr.p_vaddr; + // We could try computing the difference between _DYNAMIC and + // the p_vaddr of the PT_DYNAMIC section, but using the phdr is + // good enough (Is it?). + } + } else unreachable; + var info = dl_phdr_info{ - .dlpi_addr = 0, + .dlpi_addr = base_address, .dlpi_name = "/proc/self/exe", .dlpi_phdr = phdrs.ptr, .dlpi_phnum = ehdr.e_phnum, @@ -4360,7 +4371,7 @@ pub fn dl_iterate_phdr( return callback(&info, @sizeOf(dl_phdr_info), context); } - // Last return value from the callback function + // Last return value from the callback function. while (it.next()) |entry| { var dlpi_phdr: [*]elf.Phdr = undefined; var dlpi_phnum: u16 = undefined; |
