authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-24 20:53:46+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-24 20:53:46+02:00
log074ddf1ac6cefaff21d8b49a126556158ec5bc6b
tree747db95fa48a4d65d263086070209e71b20b7dc9
parent3bc361178c0f37ee9ffb67698401027a9f656664

Implementation of dl_phdr_info


2 files changed, 65 insertions(+), 0 deletions(-)

std/c/linux.zig+2
......@@ -11,3 +11,5 @@ pub const pthread_attr_t = extern struct {
1111
1212/// See std.elf for constants for this
1313pub extern fn getauxval(__type: c_ulong) c_ulong;
14
15pub extern fn dl_iterate_phdr(callback: *const c_void, data: ?*c_void) i32;
std/os/linux.zig+63
......@@ -2,6 +2,7 @@ const std = @import("../std.zig");
22const assert = std.debug.assert;
33const builtin = @import("builtin");
44const maxInt = std.math.maxInt;
5const elf = std.elf;
56const vdso = @import("linux/vdso.zig");
67pub use switch (builtin.arch) {
78 builtin.Arch.x86_64 => @import("linux/x86_64.zig"),
......@@ -1534,6 +1535,68 @@ pub const dirent64 = extern struct {
15341535 d_name: u8, // field address is the address of first byte of name https://github.com/ziglang/zig/issues/173
15351536};
15361537
1538pub const dl_phdr_info = extern struct {
1539 dlpi_addr: usize,
1540 dlpi_name: [*c]const u8,
1541 dlpi_phdr: [*c]*c_void,
1542 dlpi_phnum: u16,
1543};
1544
1545const DynLib = @import("../dynamic_library.zig");
1546
1547// XXX: This should be weak
1548extern const __ehdr_start: elf.Ehdr = undefined;
1549
1550pub fn dl_iterate_phdr(callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) i32, data: ?*c_void) isize {
1551 if (builtin.link_libc) {
1552 return std.c.dl_iterate_phdr(@ptrCast(*const c_void, callback), data);
1553 }
1554
1555 const elf_base = @ptrToInt(&__ehdr_start);
1556 const n_phdr = __ehdr_start.e_phnum;
1557 const phdrs = (@intToPtr([*]elf.Phdr, elf_base + __ehdr_start.e_phoff))[0..n_phdr];
1558
1559 var it = DynLib.linkmap_iterator(phdrs) catch return 0;
1560 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{
1564 .dlpi_addr = elf_base,
1565 .dlpi_name = c"/proc/self/exe",
1566 .dlpi_phdr = @intToPtr([*c]*c_void, elf_base + __ehdr_start.e_phoff),
1567 .dlpi_phnum = __ehdr_start.e_phnum,
1568 };
1569
1570 return callback(&info, @sizeOf(dl_phdr_info), data);
1571 }
1572
1573 // Last return value from the callback function
1574 var last_r: isize = 0;
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 };
1582
1583 if (entry.l_addr != 0) {
1584 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;
1587 } else {
1588 // 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;
1591 }
1592
1593 last_r = callback(&info, @sizeOf(dl_phdr_info), data);
1594 if (last_r != 0) break;
1595 }
1596
1597 return last_r;
1598}
1599
15371600test "import" {
15381601 if (builtin.os == builtin.Os.linux) {
15391602 _ = @import("linux/test.zig");