diff options
| author | David Rubin <daviru007@icloud.com> | 2024-12-15 00:39:04 -0800 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2025-02-11 20:41:52 +0100 |
| commit | 914f822025b9f761ccf0fd55a50d8cd6ecb51ec1 (patch) | |
| tree | 878ed9f19077f184c209402dc5aafb23220d025e /src | |
| parent | 4162f401cbaa2013eae8fa518cf255ce4c5c952b (diff) | |
| download | zig-914f822025b9f761ccf0fd55a50d8cd6ecb51ec1.tar.gz zig-914f822025b9f761ccf0fd55a50d8cd6ecb51ec1.zip | |
link.Elf: implement non-alloc `{SET,SUB}_ULEB128`
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Elf/Atom.zig | 6 | ||||
| -rw-r--r-- | src/link/riscv.zig | 25 |
2 files changed, 31 insertions, 0 deletions
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 10e6f669d3..33a4663e79 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -1882,6 +1882,9 @@ const riscv = struct { .LO12_S, .ADD32, .SUB32, + + .SUB_ULEB128, + .SET_ULEB128, => {}, else => try atom.reportUnhandledRelocError(rel, elf_file), @@ -2071,6 +2074,9 @@ const riscv = struct { .SET6 => riscv_util.writeSetSub6(.set, code[r_offset..][0..1], S + A), .SUB6 => riscv_util.writeSetSub6(.sub, code[r_offset..][0..1], S + A), + .SET_ULEB128 => try riscv_util.writeSetSubUleb(.set, stream, S + A), + .SUB_ULEB128 => try riscv_util.writeSetSubUleb(.sub, stream, S - A), + else => try atom.reportUnhandledRelocError(rel, elf_file), } } diff --git a/src/link/riscv.zig b/src/link/riscv.zig index 106fd1a817..bb16cb7d80 100644 --- a/src/link/riscv.zig +++ b/src/link/riscv.zig @@ -9,6 +9,31 @@ pub fn writeSetSub6(comptime op: enum { set, sub }, code: *[1]u8, addend: anytyp mem.writeInt(u8, code, value, .little); } +pub fn writeSetSubUleb(comptime op: enum { set, sub }, stream: *std.io.FixedBufferStream([]u8), addend: i64) !void { + switch (op) { + .set => try overwriteUleb(stream, @intCast(addend)), + .sub => { + const position = try stream.getPos(); + const value: u64 = try std.leb.readUleb128(u64, stream.reader()); + try stream.seekTo(position); + try overwriteUleb(stream, value -% @as(u64, @intCast(addend))); + }, + } +} + +fn overwriteUleb(stream: *std.io.FixedBufferStream([]u8), addend: u64) !void { + var value: u64 = addend; + const writer = stream.writer(); + + while (true) { + const byte = stream.buffer[stream.pos]; + if (byte & 0x80 == 0) break; + try writer.writeByte(0x80 | @as(u8, @truncate(value & 0x7f))); + value >>= 7; + } + stream.buffer[stream.pos] = @truncate(value & 0x7f); +} + pub fn writeAddend( comptime Int: type, comptime op: enum { add, sub }, |
