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 {
18821882 .LO12_S,
18831883 .ADD32,
18841884 .SUB32,
1885
1886 .SUB_ULEB128,
1887 .SET_ULEB128,
18851888 => {},
18861889
18871890 else => try atom.reportUnhandledRelocError(rel, elf_file),
......@@ -2071,6 +2074,9 @@ const riscv = struct {
20712074 .SET6 => riscv_util.writeSetSub6(.set, code[r_offset..][0..1], S + A),
20722075 .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
20742080 else => try atom.reportUnhandledRelocError(rel, elf_file),
20752081 }
20762082 }
src/link/riscv.zig+25
......@@ -9,6 +9,31 @@ pub fn writeSetSub6(comptime op: enum { set, sub }, code: *[1]u8, addend: anytyp
99 mem.writeInt(u8, code, value, .little);
1010}
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
1237pub fn writeAddend(
1338 comptime Int: type,
1439 comptime op: enum { add, sub },