| ... | ... | @@ -4,6 +4,7 @@ const builtin = @import("builtin"); |
| 4 | 4 | const maxInt = std.math.maxInt; |
| 5 | 5 | const elf = std.elf; |
| 6 | 6 | const vdso = @import("linux/vdso.zig"); |
| 7 | const dl = @import("../dynamic_library.zig"); |
| 7 | 8 | pub use switch (builtin.arch) { |
| 8 | 9 | builtin.Arch.x86_64 => @import("linux/x86_64.zig"), |
| 9 | 10 | builtin.Arch.i386 => @import("linux/i386.zig"), |
| ... | ... | @@ -1537,33 +1538,32 @@ pub const dirent64 = extern struct { |
| 1537 | 1538 | |
| 1538 | 1539 | pub const dl_phdr_info = extern struct { |
| 1539 | 1540 | dlpi_addr: usize, |
| 1540 | | dlpi_name: [*c]const u8, |
| 1541 | | dlpi_phdr: [*c]*c_void, |
| 1541 | dlpi_name: ?[*]const u8, |
| 1542 | dlpi_phdr: [*]elf.Phdr, |
| 1542 | 1543 | dlpi_phnum: u16, |
| 1543 | 1544 | }; |
| 1544 | 1545 | |
| 1545 | | const DynLib = @import("../dynamic_library.zig"); |
| 1546 | | |
| 1547 | 1546 | // XXX: This should be weak |
| 1548 | 1547 | extern const __ehdr_start: elf.Ehdr = undefined; |
| 1549 | 1548 | |
| 1550 | | pub fn dl_iterate_phdr(callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) i32, data: ?*c_void) isize { |
| 1549 | pub fn dl_iterate_phdr(comptime T: type, callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, data: ?*T) isize { |
| 1551 | 1550 | if (builtin.link_libc) { |
| 1552 | | return std.c.dl_iterate_phdr(@ptrCast(*const c_void, callback), data); |
| 1551 | return std.c.dl_iterate_phdr(@ptrCast(std.c.dl_iterate_phdr_callback, callback), @ptrCast(?*c_void, data)); |
| 1553 | 1552 | } |
| 1554 | 1553 | |
| 1555 | 1554 | const elf_base = @ptrToInt(&__ehdr_start); |
| 1556 | 1555 | const n_phdr = __ehdr_start.e_phnum; |
| 1557 | 1556 | const phdrs = (@intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff))[0..n_phdr]; |
| 1558 | 1557 | |
| 1559 | | var it = DynLib.linkmap_iterator(phdrs) catch return 0; |
| 1558 | var it = dl.linkmap_iterator(phdrs) catch return 0; |
| 1559 | |
| 1560 | // The executable has no dynamic link segment, create a single entry for |
| 1561 | // the whole ELF image |
| 1560 | 1562 | if (it.end()) { |
| 1561 | | // The executable has no dynamic link infos, create a single info |
| 1562 | | // struct for the whole ELF image |
| 1563 | 1563 | var info = dl_phdr_info{ |
| 1564 | 1564 | .dlpi_addr = elf_base, |
| 1565 | 1565 | .dlpi_name = c"/proc/self/exe", |
| 1566 | | .dlpi_phdr = @intToPtr([*c]*c_void, elf_base + __ehdr_start.e_phoff), |
| 1566 | .dlpi_phdr = @intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff), |
| 1567 | 1567 | .dlpi_phnum = __ehdr_start.e_phnum, |
| 1568 | 1568 | }; |
| 1569 | 1569 | |
| ... | ... | @@ -1573,23 +1573,26 @@ pub fn dl_iterate_phdr(callback: extern fn (info: *dl_phdr_info, size: usize, da |
| 1573 | 1573 | // Last return value from the callback function |
| 1574 | 1574 | var last_r: isize = 0; |
| 1575 | 1575 | while (it.next()) |entry| { |
| 1576 | | var info = dl_phdr_info{ |
| 1577 | | .dlpi_addr = entry.l_addr, |
| 1578 | | .dlpi_name = entry.l_name, |
| 1579 | | .dlpi_phdr = 0, |
| 1580 | | .dlpi_phnum = 0, |
| 1581 | | }; |
| 1576 | var dlpi_phdr: usize = undefined; |
| 1577 | var dlpi_phnum: u16 = undefined; |
| 1582 | 1578 | |
| 1583 | 1579 | if (entry.l_addr != 0) { |
| 1584 | 1580 | const elf_header = @intToPtr(*elf.Ehdr, entry.l_addr); |
| 1585 | | info.dlpi_phdr = @intToPtr([*c]*c_void, entry.l_addr + elf_header.e_phoff); |
| 1586 | | info.dlpi_phnum = elf_header.e_phnum; |
| 1581 | dlpi_phdr = entry.l_addr + elf_header.e_phoff; |
| 1582 | dlpi_phnum = elf_header.e_phnum; |
| 1587 | 1583 | } else { |
| 1588 | 1584 | // This is the running ELF image |
| 1589 | | info.dlpi_phdr = @intToPtr([*c]*c_void, elf_base + __ehdr_start.e_phoff); |
| 1590 | | info.dlpi_phnum = __ehdr_start.e_phnum; |
| 1585 | dlpi_phdr = elf_base + __ehdr_start.e_phoff; |
| 1586 | dlpi_phnum = __ehdr_start.e_phnum; |
| 1591 | 1587 | } |
| 1592 | 1588 | |
| 1589 | var info = dl_phdr_info{ |
| 1590 | .dlpi_addr = entry.l_addr, |
| 1591 | .dlpi_name = entry.l_name, |
| 1592 | .dlpi_phdr = @intToPtr([*]elf.Phdr, dlpi_phdr), |
| 1593 | .dlpi_phnum = dlpi_phnum, |
| 1594 | }; |
| 1595 | |
| 1593 | 1596 | last_r = callback(&info, @sizeOf(dl_phdr_info), data); |
| 1594 | 1597 | if (last_r != 0) break; |
| 1595 | 1598 | } |