authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-24 20:54:17+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-04-24 20:54:17+02:00
loge4825dbd771906722508933bb355e342b992869b
treeec74b05ae082005e38daef57c7ea55fb10169a97
parent12eff09ff486e80ed073edb54074c7d3afbd6fc0

Other


1 files changed, 79 insertions(+), 0 deletions(-)

std/dynamic_library.zig+79
......@@ -19,6 +19,85 @@ pub const DynLib = switch (builtin.os) {
1919 else => void,
2020};
2121
22const LinkMap = extern struct {
23 l_addr: usize,
24 l_name: [*]u8,
25 l_ld: [*c]elf.Dyn,
26 l_next: [*c]LinkMap,
27 l_prev: [*c]LinkMap,
28
29 pub const Iterator = struct {
30 lm_ptr: [*c]LinkMap,
31
32 fn end(self: *const Iterator) bool {
33 return self.lm_ptr == 0;
34 }
35
36 fn next(self: *Iterator) ?*LinkMap {
37 if (self.lm_ptr != 0) {
38 const ptr = self.lm_ptr;
39 self.lm_ptr = self.lm_ptr.*.l_next;
40 return ptr;
41 }
42 return null;
43 }
44 };
45};
46
47const RDebug = extern struct {
48 r_version: i32,
49 r_map: [*c]LinkMap,
50 r_brk: usize,
51 r_ldbase: usize,
52};
53
54fn elf_get_va_offset(phdrs: []elf.Phdr) !usize {
55 for (phdrs) |*phdr| {
56 if (phdr.p_type == elf.PT_LOAD) {
57 return @ptrToInt(phdr) - phdr.p_vaddr;
58 }
59 }
60 return error.InvalidExe;
61}
62
63pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
64 const va_offset = try elf_get_va_offset(phdrs);
65
66 const dyn_table = init: {
67 for (phdrs) |*phdr| {
68 if (phdr.p_type == elf.PT_DYNAMIC) {
69 const ptr = @intToPtr([*]elf.Dyn, va_offset + phdr.p_vaddr);
70 break :init ptr[0..phdr.p_memsz / @sizeOf(elf.Dyn)];
71 }
72 }
73 // No PT_DYNAMIC means this is either a statically-linked program or a
74 // badly corrupted one
75 return LinkMap.Iterator{.lm_ptr = 0};
76 };
77
78 const link_map_ptr = init: {
79 for (dyn_table) |*dyn| {
80 switch (dyn.d_tag) {
81 elf.DT_DEBUG => {
82 const r_debug = @intToPtr(*RDebug, dyn.d_un.d_ptr);
83 if (r_debug.r_version != 1) return error.InvalidExe;
84 break :init r_debug.r_map;
85 },
86 elf.DT_PLTGOT => {
87 const got_table = @intToPtr([*]usize, dyn.d_un.d_ptr);
88 // The address to the link_map structure is stored in the
89 // second slot
90 break :init @intToPtr([*c]LinkMap, got_table[1]);
91 },
92 else => { }
93 }
94 }
95 return error.InvalidExe;
96 };
97
98 return LinkMap.Iterator{.lm_ptr = link_map_ptr};
99}
100
22101pub const LinuxDynLib = struct {
23102 elf_lib: ElfLib,
24103 fd: i32,