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