aboutsummaryrefslogtreecommitdiff
path: root/lib/std/dynamic_library.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-11-22 17:30:34 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-11-22 17:30:34 -0700
commitc7170e4a5480581db5f30913eebd9ad4f7cd121e (patch)
treefba79b8f4241c94f886e7708d18081e8fc0e31fe /lib/std/dynamic_library.zig
parent98d5bfbd4d21e99363a0a68ef5a0d0104c302ecb (diff)
parentabc717f203060f7ab16d36f2afe681d838b46801 (diff)
downloadzig-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.zig52
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 };