| author | |
| committer | |
| log | 914f822025b9f761ccf0fd55a50d8cd6ecb51ec1 |
| tree | 878ed9f19077f184c209402dc5aafb23220d025e |
| parent | 4162f401cbaa2013eae8fa518cf255ce4c5c952b |
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 | => {}, |
| 1886 | 1889 | ||
| 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), |
| 2073 | 2076 | ||
| 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 | } |
| 11 | 11 | ||
| 12 | pub 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 | |||
| 24 | fn 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 | |||
| 12 | pub fn writeAddend( | 37 | pub fn writeAddend( |
| 13 | comptime Int: type, | 38 | comptime Int: type, |
| 14 | comptime op: enum { add, sub }, | 39 | comptime op: enum { add, sub }, |