From 8161e61548135dcbc2c3563a61b75c08c8f7cb2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 26 Jul 2024 01:07:34 +0200 Subject: [PATCH] std.os.linux.start_pie: Add support for the new RELR relocation format. --- lib/std/os/linux/start_pie.zig | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/std/os/linux/start_pie.zig b/lib/std/os/linux/start_pie.zig index dbe3f5565e..5099f39563 100644 --- a/lib/std/os/linux/start_pie.zig +++ b/lib/std/os/linux/start_pie.zig @@ -277,4 +277,28 @@ pub fn relocate(phdrs: []elf.Phdr) void { @as(*usize, @ptrFromInt(base_addr + r.r_offset)).* = base_addr + @as(usize, @bitCast(r.r_addend)); } } + + const relr = sorted_dynv[elf.DT_RELR]; + if (relr != 0) { + const relrs = @call(.always_inline, std.mem.bytesAsSlice, .{ + elf.Relr, + @as([*]u8, @ptrFromInt(base_addr + relr))[0..sorted_dynv[elf.DT_RELRSZ]], + }); + var current: [*]usize = undefined; + for (relrs) |r| { + if ((r & 1) == 0) { + current = @ptrFromInt(base_addr + r); + current[0] += base_addr; + current += 1; + } else { + // Skip the first bit; there are 63 locations in the bitmap. + var i: if (@sizeOf(usize) == 8) u6 else u5 = 1; + while (i < @bitSizeOf(elf.Relr)) : (i += 1) { + if (((r >> i) & 1) != 0) current[i] += base_addr; + } + + current += @bitSizeOf(elf.Relr) - 1; + } + } + } }