diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-11-22 17:30:34 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-11-22 17:30:34 -0700 |
| commit | c7170e4a5480581db5f30913eebd9ad4f7cd121e (patch) | |
| tree | fba79b8f4241c94f886e7708d18081e8fc0e31fe /lib/std/dynamic_library.zig | |
| parent | 98d5bfbd4d21e99363a0a68ef5a0d0104c302ecb (diff) | |
| parent | abc717f203060f7ab16d36f2afe681d838b46801 (diff) | |
| download | zig-c7170e4a5480581db5f30913eebd9ad4f7cd121e.tar.gz zig-c7170e4a5480581db5f30913eebd9ad4f7cd121e.zip | |
Support PIE (Position Independent Executables)
Closes #4503
Revives #3960
Merges branch 'pie' into master
Diffstat (limited to 'lib/std/dynamic_library.zig')
| -rw-r--r-- | lib/std/dynamic_library.zig | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index aca6cf958c..0de4bed84d 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -59,48 +59,48 @@ const RDebug = extern struct { r_ldbase: usize, }; -fn elf_get_va_offset(phdrs: []elf.Phdr) !usize { - for (phdrs) |*phdr| { - if (phdr.p_type == elf.PT_LOAD) { - return @ptrToInt(phdr) - phdr.p_vaddr; - } +// TODO: This should be weak (#1917) +extern var _DYNAMIC: [128]elf.Dyn; + +comptime { + if (std.Target.current.os.tag == .linux) { + asm ( + \\ .weak _DYNAMIC + \\ .hidden _DYNAMIC + ); } - return error.InvalidExe; } pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator { - const va_offset = try elf_get_va_offset(phdrs); - - const dyn_table = init: { - for (phdrs) |*phdr| { - if (phdr.p_type == elf.PT_DYNAMIC) { - const ptr = @intToPtr([*]elf.Dyn, va_offset + phdr.p_vaddr); - break :init ptr[0 .. phdr.p_memsz / @sizeOf(elf.Dyn)]; - } - } + if (@ptrToInt(&_DYNAMIC[0]) == 0) { // No PT_DYNAMIC means this is either a statically-linked program or a // badly corrupted one return LinkMap.Iterator{ .current = null }; - }; + } const link_map_ptr = init: { - for (dyn_table) |*dyn| { - switch (dyn.d_tag) { + var i: usize = 0; + while (_DYNAMIC[i].d_tag != elf.DT_NULL) : (i += 1) { + switch (_DYNAMIC[i].d_tag) { elf.DT_DEBUG => { - const r_debug = @intToPtr(*RDebug, dyn.d_val); - if (r_debug.r_version != 1) return error.InvalidExe; - break :init r_debug.r_map; + const ptr = @intToPtr(?*RDebug, _DYNAMIC[i].d_val); + if (ptr) |r_debug| { + if (r_debug.r_version != 1) return error.InvalidExe; + break :init r_debug.r_map; + } }, elf.DT_PLTGOT => { - const got_table = @intToPtr([*]usize, dyn.d_val); - // The address to the link_map structure is stored in the - // second slot - break :init @intToPtr(?*LinkMap, got_table[1]); + const ptr = @intToPtr(?[*]usize, _DYNAMIC[i].d_val); + if (ptr) |got_table| { + // The address to the link_map structure is stored in + // the second slot + break :init @intToPtr(?*LinkMap, got_table[1]); + } }, else => {}, } } - return error.InvalidExe; + return LinkMap.Iterator{ .current = null }; }; return LinkMap.Iterator{ .current = link_map_ptr }; |
