authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-05 12:14:53+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-05-05 13:00:20+02:00
log07dfccf9674c2f7196c31b25813ea9e3e7e1dad6
treea67df2a3aaaf6ff77cf80a9e1fa96d2dbe355498
parente4825dbd771906722508933bb355e342b992869b

Review


3 files changed, 45 insertions(+), 36 deletions(-)

std/c/linux.zig+3-1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const linux = @import("../os/linux.zig");
1pub use @import("../os/linux/errno.zig");2pub use @import("../os/linux/errno.zig");
23
3pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;4pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
...@@ -12,4 +13,5 @@ pub const pthread_attr_t = extern struct {...@@ -12,4 +13,5 @@ pub const pthread_attr_t = extern struct {
12/// See std.elf for constants for this13/// See std.elf for constants for this
13pub extern fn getauxval(__type: c_ulong) c_ulong;14pub extern fn getauxval(__type: c_ulong) c_ulong;
1415
15pub extern fn dl_iterate_phdr(callback: *const c_void, data: ?*c_void) i32;16pub const dl_iterate_phdr_callback = extern fn (info: *linux.dl_phdr_info, size: usize, data: ?*c_void) c_int;
17pub extern fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
std/dynamic_library.zig+19-15
...@@ -19,25 +19,29 @@ pub const DynLib = switch (builtin.os) {...@@ -19,25 +19,29 @@ pub const DynLib = switch (builtin.os) {
19 else => void,19 else => void,
20};20};
2121
22// The link_map structure is not completely specified beside the fields
23// reported below, any libc is free to store additional data in the remaining
24// space.
25// An iterator is provided in order to traverse the linked list in a idiomatic
26// fashion.
22const LinkMap = extern struct {27const LinkMap = extern struct {
23 l_addr: usize,28 l_addr: usize,
24 l_name: [*]u8,29 l_name: [*]const u8,
25 l_ld: [*c]elf.Dyn,30 l_ld: ?*elf.Dyn,
26 l_next: [*c]LinkMap,31 l_next: ?*LinkMap,
27 l_prev: [*c]LinkMap,32 l_prev: ?*LinkMap,
2833
29 pub const Iterator = struct {34 pub const Iterator = struct {
30 lm_ptr: [*c]LinkMap,35 current: ?*LinkMap,
3136
32 fn end(self: *const Iterator) bool {37 fn end(self: *Iterator) bool {
33 return self.lm_ptr == 0;38 return self.current == null;
34 }39 }
3540
36 fn next(self: *Iterator) ?*LinkMap {41 fn next(self: *Iterator) ?*LinkMap {
37 if (self.lm_ptr != 0) {42 if (self.current) |it| {
38 const ptr = self.lm_ptr;43 self.current = it.l_next;
39 self.lm_ptr = self.lm_ptr.*.l_next;44 return it;
40 return ptr;
41 }45 }
42 return null;46 return null;
43 }47 }
...@@ -46,7 +50,7 @@ const LinkMap = extern struct {...@@ -46,7 +50,7 @@ const LinkMap = extern struct {
4650
47const RDebug = extern struct {51const RDebug = extern struct {
48 r_version: i32,52 r_version: i32,
49 r_map: [*c]LinkMap,53 r_map: ?*LinkMap,
50 r_brk: usize,54 r_brk: usize,
51 r_ldbase: usize,55 r_ldbase: usize,
52};56};
...@@ -72,7 +76,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {...@@ -72,7 +76,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
72 }76 }
73 // No PT_DYNAMIC means this is either a statically-linked program or a77 // No PT_DYNAMIC means this is either a statically-linked program or a
74 // badly corrupted one78 // badly corrupted one
75 return LinkMap.Iterator{.lm_ptr = 0};79 return LinkMap.Iterator{.current = null};
76 };80 };
7781
78 const link_map_ptr = init: {82 const link_map_ptr = init: {
...@@ -87,7 +91,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {...@@ -87,7 +91,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
87 const got_table = @intToPtr([*]usize, dyn.d_un.d_ptr);91 const got_table = @intToPtr([*]usize, dyn.d_un.d_ptr);
88 // The address to the link_map structure is stored in the92 // The address to the link_map structure is stored in the
89 // second slot93 // second slot
90 break :init @intToPtr([*c]LinkMap, got_table[1]);94 break :init @intToPtr(?*LinkMap, got_table[1]);
91 },95 },
92 else => { }96 else => { }
93 }97 }
...@@ -95,7 +99,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {...@@ -95,7 +99,7 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
95 return error.InvalidExe;99 return error.InvalidExe;
96 };100 };
97101
98 return LinkMap.Iterator{.lm_ptr = link_map_ptr};102 return LinkMap.Iterator{.current = link_map_ptr};
99}103}
100104
101pub const LinuxDynLib = struct {105pub const LinuxDynLib = struct {
std/os/linux.zig+23-20
...@@ -4,6 +4,7 @@ const builtin = @import("builtin");...@@ -4,6 +4,7 @@ const builtin = @import("builtin");
4const maxInt = std.math.maxInt;4const maxInt = std.math.maxInt;
5const elf = std.elf;5const elf = std.elf;
6const vdso = @import("linux/vdso.zig");6const vdso = @import("linux/vdso.zig");
7const dl = @import("../dynamic_library.zig");
7pub use switch (builtin.arch) {8pub 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 {
15371538
1538pub const dl_phdr_info = extern struct {1539pub 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};
15441545
1545const DynLib = @import("../dynamic_library.zig");
1546
1547// XXX: This should be weak1546// XXX: This should be weak
1548extern const __ehdr_start: elf.Ehdr = undefined;1547extern const __ehdr_start: elf.Ehdr = undefined;
15491548
1550pub fn dl_iterate_phdr(callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) i32, data: ?*c_void) isize {1549pub 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 }
15541553
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];
15581557
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 };
15691569
...@@ -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 function1573 // 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 };
15821578
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 image1584 // 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 }
15921588
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 }