From a2ddff74f82b518ed7d0b22ff88bf3b1ee97dbb2 Mon Sep 17 00:00:00 2001 From: Matthew Lugg Date: Thu, 13 Aug 2026 22:39:32 +0100 Subject: [PATCH] Elf2: fix incorrect validation in SPARC relocation It turns out that SPARC has a strange definition of "PC-relative" where the offsets are... unsigned? This results in some annoying restrictions when linking: specifically, the GOT needs to appear after all code segments, because these PC-relative relocations are used to access it. When violating that, we should at least get relocation errors, but because we were doing the wrong validation here, we were just triggering miscompilations instead. --- src/link/Elf2.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index f616f5dbaf223daa9381c6f12a48ec6d897dda80..3d05ddca385e3b1761f948ebed48471b81d68eb9 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -6665,7 +6665,7 @@ fn addRelocAssumeCapacity( .WDISP30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })), .WPLT30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })), - .PC22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .signed, .shift = .@"10" })), + .PC22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"10" })), .H44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"22" })), .M44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"12" })), -- 2.54.0