authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-11 13:27:30+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-12 10:31:33+02:00
log53aa372d03a4770ad12b3d3b11efe6d509d1a5eb
treeb5cfb377d79b3b1c311051f65b2d7c3b359efa91
parent776beb793701ead66a0f6e765090931324ce1580
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Elf2: implement most remaining sparc relocations


1 files changed, 105 insertions(+), 17 deletions(-)

src/link/Elf2.zig+105-17
...@@ -1356,6 +1356,7 @@ const SymbolReloc = struct {...@@ -1356,6 +1356,7 @@ const SymbolReloc = struct {
1356 @"32[10:0]",1356 @"32[10:0]",
1357 @"32[11:0]",1357 @"32[11:0]",
1358 @"32[12:0]",1358 @"32[12:0]",
1359 @"32[18:0]",
1359 @"32[21:0]",1360 @"32[21:0]",
1360 @"32[21:10]",1361 @"32[21:10]",
1361 @"32[24:5]",1362 @"32[24:5]",
...@@ -1399,6 +1400,7 @@ const SymbolReloc = struct {...@@ -1399,6 +1400,7 @@ const SymbolReloc = struct {
1399 @"12",1400 @"12",
1400 @"22",1401 @"22",
1401 @"32",1402 @"32",
1403 @"42",
1402 @"52",1404 @"52",
1403 },1405 },
14041406
...@@ -1418,6 +1420,7 @@ const SymbolReloc = struct {...@@ -1418,6 +1420,7 @@ const SymbolReloc = struct {
1418 .@"12" => .{ 12, false },1420 .@"12" => .{ 12, false },
1419 .@"22" => .{ 22, false },1421 .@"22" => .{ 22, false },
1420 .@"32" => .{ 32, false },1422 .@"32" => .{ 32, false },
1423 .@"42" => .{ 42, false },
1421 .@"52" => .{ 52, false },1424 .@"52" => .{ 52, false },
1422 };1425 };
14231426
...@@ -1438,6 +1441,7 @@ const SymbolReloc = struct {...@@ -1438,6 +1441,7 @@ const SymbolReloc = struct {
1438 .@"32[10:0]" => .{ 32, 10, 0 },1441 .@"32[10:0]" => .{ 32, 10, 0 },
1439 .@"32[11:0]" => .{ 32, 11, 0 },1442 .@"32[11:0]" => .{ 32, 11, 0 },
1440 .@"32[12:0]" => .{ 32, 12, 0 },1443 .@"32[12:0]" => .{ 32, 12, 0 },
1444 .@"32[18:0]" => .{ 32, 18, 0 },
1441 .@"32[21:0]" => .{ 32, 21, 0 },1445 .@"32[21:0]" => .{ 32, 21, 0 },
1442 .@"32[21:10]" => .{ 32, 21, 10 },1446 .@"32[21:10]" => .{ 32, 21, 10 },
1443 .@"32[24:5]" => .{ 32, 24, 5 },1447 .@"32[24:5]" => .{ 32, 24, 5 },
...@@ -1500,7 +1504,10 @@ const SymbolReloc = struct {...@@ -1500,7 +1504,10 @@ const SymbolReloc = struct {
1500 larch_b26,1504 larch_b26,
1501 larch_call36,1505 larch_call36,
15021506
1507 sparc_hix22,
1503 sparc_le_hix22,1508 sparc_le_hix22,
1509 sparc_wdisp10,
1510 sparc_wdisp16,
15041511
1505 fn applyInner(1512 fn applyInner(
1506 s: Special,1513 s: Special,
...@@ -1598,6 +1605,17 @@ const SymbolReloc = struct {...@@ -1598,6 +1605,17 @@ const SymbolReloc = struct {
1598 else => unreachable,1605 else => unreachable,
1599 }1606 }
1600 },1607 },
1608
1609 .sparc_hix22 => {
1610 const dest_ptr: *align(1) packed struct(u32) {
1611 imm22: u22,
1612 b22_31: u10,
1613 } = @ptrCast(dest_slice);
1614 elf.targetStore(dest_ptr, .{
1615 .imm22 = @truncate(~(target.value(elf) +% addend) >> 10),
1616 .b22_31 = elf.targetLoad(dest_ptr).b22_31,
1617 });
1618 },
1601 .sparc_le_hix22 => {1619 .sparc_le_hix22 => {
1602 const tls_phndx = elf.getNode(elf.ni.tls.unwrap().?).segment;1620 const tls_phndx = elf.getNode(elf.ni.tls.unwrap().?).segment;
1603 const tls_size: u64 = switch (elf.phdrSlice()) {1621 const tls_size: u64 = switch (elf.phdrSlice()) {
...@@ -1615,6 +1633,57 @@ const SymbolReloc = struct {...@@ -1615,6 +1633,57 @@ const SymbolReloc = struct {
1615 .b22_31 = elf.targetLoad(dest_ptr).b22_31,1633 .b22_31 = elf.targetLoad(dest_ptr).b22_31,
1616 });1634 });
1617 },1635 },
1636 .sparc_wdisp16, .sparc_wdisp10 => {
1637 const target_vaddr: u64 = elf.pltEntryTargetAddr(target) orelse target.value(elf);
1638 const jump_offset: i64 = @bitCast(target_vaddr +% addend -% dest_vaddr);
1639 if ((jump_offset >> 2) << 2 != jump_offset) {
1640 return error.RelocationMisaligned;
1641 }
1642 const shifted_jump_offset: i64 = @shrExact(jump_offset, 2);
1643 switch (s) {
1644 .sparc_wdisp10 => {
1645 if ((shifted_jump_offset << (64 - 10)) >> (64 - 10) != shifted_jump_offset) {
1646 return error.RelocationOverflow;
1647 }
1648 const truncated: i10 = @intCast(shifted_jump_offset);
1649 const parts: packed struct { lo8: u8, hi2: u2 } = @bitCast(truncated);
1650 const inst: *align(1) packed struct(u32) {
1651 b0_4: u5,
1652 disp10: u8,
1653 b13_18: u6,
1654 d2: u2,
1655 b21_31: u11,
1656 } = @ptrCast(dest_slice[0..4]);
1657 elf.targetStore(inst, .{
1658 .b0_4 = elf.targetLoad(inst).b0_4,
1659 .disp10 = parts.lo8,
1660 .b13_18 = elf.targetLoad(inst).b13_18,
1661 .d2 = parts.hi2,
1662 .b21_31 = elf.targetLoad(inst).b21_31,
1663 });
1664 },
1665 .sparc_wdisp16 => {
1666 if ((shifted_jump_offset << (64 - 16)) >> (64 - 16) != shifted_jump_offset) {
1667 return error.RelocationOverflow;
1668 }
1669 const truncated: i16 = @intCast(shifted_jump_offset);
1670 const parts: packed struct { lo14: u14, hi2: u2 } = @bitCast(truncated);
1671 const inst: *align(1) packed struct(u32) {
1672 disp14: u14,
1673 b14_19: u6,
1674 d2: u2,
1675 b22_31: u10,
1676 } = @ptrCast(dest_slice[0..4]);
1677 elf.targetStore(inst, .{
1678 .disp14 = parts.lo14,
1679 .b14_19 = elf.targetLoad(inst).b14_19,
1680 .d2 = parts.hi2,
1681 .b22_31 = elf.targetLoad(inst).b22_31,
1682 });
1683 },
1684 else => unreachable,
1685 }
1686 },
1618 }1687 }
1619 }1688 }
1620 };1689 };
...@@ -1649,6 +1718,10 @@ const SymbolReloc = struct {...@@ -1649,6 +1718,10 @@ const SymbolReloc = struct {
1649 .larch_b21,1718 .larch_b21,
1650 .larch_b26,1719 .larch_b26,
1651 .larch_call36,1720 .larch_call36,
1721
1722 .sparc_hix22,
1723 .sparc_wdisp10,
1724 .sparc_wdisp16,
1652 => false,1725 => false,
1653 },1726 },
1654 },1727 },
...@@ -9006,23 +9079,6 @@ fn addRelocAssumeCapacity(...@@ -9006,23 +9079,6 @@ fn addRelocAssumeCapacity(
9006 .TLS_TPOFF64,9079 .TLS_TPOFF64,
9007 => return error.NonStaticRelocation,9080 => return error.NonStaticRelocation,
90089081
9009 .WDISP22,
9010 .HI22,
9011 .LO10,
9012 .HH22,
9013 .HM10,
9014 .LM22,
9015 .PC_HH22,
9016 .PC_HM10,
9017 .PC_LM22,
9018 .WDISP16,
9019 .WDISP19,
9020 .HIX22,
9021 .LOX10,
9022 .H34,
9023 .WDISP10,
9024 => return error.UnimplementedRelocation,
9025
9026 // Nobody seems to support these.9082 // Nobody seems to support these.
9027 .HIPLT22,9083 .HIPLT22,
9028 .LOPLT10,9084 .LOPLT10,
...@@ -9080,8 +9136,19 @@ fn addRelocAssumeCapacity(...@@ -9080,8 +9136,19 @@ fn addRelocAssumeCapacity(
9080 .PLT32 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltabs, .{ .dest = .@"32", .cast = .unsigned, .shift = .@"0" })),9136 .PLT32 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltabs, .{ .dest = .@"32", .cast = .unsigned, .shift = .@"0" })),
9081 .PLT64 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltabs, .{ .dest = .@"64", .cast = .unsigned, .shift = .@"0" })),9137 .PLT64 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltabs, .{ .dest = .@"64", .cast = .unsigned, .shift = .@"0" })),
90829138
9139 .WDISP10 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .special(.sparc_wdisp10)),
9140 .WDISP16 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .special(.sparc_wdisp16)),
9141 .WDISP19 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[18:0]", .cast = .signed, .shift = .@"2_exact" })),
9142 .WDISP22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[21:0]", .cast = .signed, .shift = .@"2_exact" })),
9083 .WDISP30, .WPLT30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })),9143 .WDISP30, .WPLT30 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.pltrel, .{ .dest = .@"32[29:0]", .cast = .signed, .shift = .@"2_exact" })),
9084 .PC22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"10" })),9144 .PC22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"10" })),
9145 .PC_LM22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .trunc, .shift = .@"10" })),
9146 .PC_HH22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"42" })),
9147 .HI22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"10" })),
9148 .LM22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .trunc, .shift = .@"10" })),
9149 .HH22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"42" })),
9150 .HIX22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .special(.sparc_hix22)),
9151 .H34 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"12" })),
9085 .H44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"22" })),9152 .H44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[21:0]", .cast = .unsigned, .shift = .@"22" })),
9086 .M44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"12" })),9153 .M44 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"12" })),
90879154
...@@ -9118,6 +9185,22 @@ fn addRelocAssumeCapacity(...@@ -9118,6 +9185,22 @@ fn addRelocAssumeCapacity(
9118 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:10] = 0b000" });9185 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:10] = 0b000" });
9119 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"0" }));9186 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"0" }));
9120 },9187 },
9188 .PC_HM10 => {
9189 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:10] = 0b000" });
9190 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.rel, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"32" }));
9191 },
9192 .LO10 => {
9193 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:10] = 0b000" });
9194 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"0" }));
9195 },
9196 .HM10 => {
9197 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:10] = 0b000" });
9198 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"32" }));
9199 },
9200 .LOX10 => {
9201 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:10] = 0b111" });
9202 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[9:0]", .cast = .trunc, .shift = .@"0" }));
9203 },
9121 .L44 => {9204 .L44 => {
9122 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:12] = 0b0" });9205 try elf.one_shot_fixups.append(elf.base.comp.gpa, .{ .node = node, .offset = offset, .action = .@"32[12:12] = 0b0" });
9123 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[11:0]", .cast = .trunc, .shift = .@"0" }));9206 try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .simple(.abs, .{ .dest = .@"32[11:0]", .cast = .trunc, .shift = .@"0" }));
...@@ -9269,12 +9352,17 @@ fn addSymbolRelocAssumeCapacity(...@@ -9269,12 +9352,17 @@ fn addSymbolRelocAssumeCapacity(
9269 .larch_pcala_hi20,9352 .larch_pcala_hi20,
9270 .larch_pcala64_lo20,9353 .larch_pcala64_lo20,
9271 .larch_pcala64_hi12,9354 .larch_pcala64_hi12,
9355
9356 .sparc_hix22,
9272 => true,9357 => true,
92739358
9274 .larch_b21,9359 .larch_b21,
9275 .larch_b26,9360 .larch_b26,
9276 .larch_call36,9361 .larch_call36,
9362
9277 .sparc_le_hix22,9363 .sparc_le_hix22,
9364 .sparc_wdisp10,
9365 .sparc_wdisp16,
9278 => false,9366 => false,
9279 },9367 },
9280 };9368 };