authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-12-15 00:39:04-08:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-02-11 20:41:52+01:00
log914f822025b9f761ccf0fd55a50d8cd6ecb51ec1
tree878ed9f19077f184c209402dc5aafb23220d025e
parent4162f401cbaa2013eae8fa518cf255ce4c5c952b

link.Elf: implement non-alloc `{SET,SUB}_ULEB128`


2 files changed, 31 insertions(+), 0 deletions(-)

src/link/Elf/Atom.zig+6
...@@ -1882,6 +1882,9 @@ const riscv = struct {...@@ -1882,6 +1882,9 @@ const riscv = struct {
1882 .LO12_S,1882 .LO12_S,
1883 .ADD32,1883 .ADD32,
1884 .SUB32,1884 .SUB32,
1885
1886 .SUB_ULEB128,
1887 .SET_ULEB128,
1885 => {},1888 => {},
18861889
1887 else => try atom.reportUnhandledRelocError(rel, elf_file),1890 else => try atom.reportUnhandledRelocError(rel, elf_file),
...@@ -2071,6 +2074,9 @@ const riscv = struct {...@@ -2071,6 +2074,9 @@ const riscv = struct {
2071 .SET6 => riscv_util.writeSetSub6(.set, code[r_offset..][0..1], S + A),2074 .SET6 => riscv_util.writeSetSub6(.set, code[r_offset..][0..1], S + A),
2072 .SUB6 => riscv_util.writeSetSub6(.sub, code[r_offset..][0..1], S + A),2075 .SUB6 => riscv_util.writeSetSub6(.sub, code[r_offset..][0..1], S + A),
20732076
2077 .SET_ULEB128 => try riscv_util.writeSetSubUleb(.set, stream, S + A),
2078 .SUB_ULEB128 => try riscv_util.writeSetSubUleb(.sub, stream, S - A),
2079
2074 else => try atom.reportUnhandledRelocError(rel, elf_file),2080 else => try atom.reportUnhandledRelocError(rel, elf_file),
2075 }2081 }
2076 }2082 }
src/link/riscv.zig+25
...@@ -9,6 +9,31 @@ pub fn writeSetSub6(comptime op: enum { set, sub }, code: *[1]u8, addend: anytyp...@@ -9,6 +9,31 @@ pub fn writeSetSub6(comptime op: enum { set, sub }, code: *[1]u8, addend: anytyp
9 mem.writeInt(u8, code, value, .little);9 mem.writeInt(u8, code, value, .little);
10}10}
1111
12pub fn writeSetSubUleb(comptime op: enum { set, sub }, stream: *std.io.FixedBufferStream([]u8), addend: i64) !void {
13 switch (op) {
14 .set => try overwriteUleb(stream, @intCast(addend)),
15 .sub => {
16 const position = try stream.getPos();
17 const value: u64 = try std.leb.readUleb128(u64, stream.reader());
18 try stream.seekTo(position);
19 try overwriteUleb(stream, value -% @as(u64, @intCast(addend)));
20 },
21 }
22}
23
24fn overwriteUleb(stream: *std.io.FixedBufferStream([]u8), addend: u64) !void {
25 var value: u64 = addend;
26 const writer = stream.writer();
27
28 while (true) {
29 const byte = stream.buffer[stream.pos];
30 if (byte & 0x80 == 0) break;
31 try writer.writeByte(0x80 | @as(u8, @truncate(value & 0x7f)));
32 value >>= 7;
33 }
34 stream.buffer[stream.pos] = @truncate(value & 0x7f);
35}
36
12pub fn writeAddend(37pub fn writeAddend(
13 comptime Int: type,38 comptime Int: type,
14 comptime op: enum { add, sub },39 comptime op: enum { add, sub },