authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-07-06 21:20:40+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-07-09 10:54:49+02:00
log0de1b576c590a67cd04691e7ac8686860b8e9400
treed31e118b2c004a93ff873d1268363d67a6ac73de
parent09b38f89e3a6c39b468326bc7499f243b241c144
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Elf2: implement some sparc-specific TLS symbol relocations


1 files changed, 72 insertions(+), 6 deletions(-)

src/link/Elf2.zig+72-6
......@@ -1186,11 +1186,27 @@ const SymbolReloc = struct {
11861186 sparc_h44,
11871187 sparc_m44,
11881188 sparc_l44,
1189 sparc_ldo_hix22,
1190 sparc_ldo_lox10,
1191 sparc_le_hix22,
1192 sparc_le_lox10,
11891193
11901194 fn dependsOnTlsSize(t: SymbolReloc.Type) bool {
11911195 return switch (t) {
1192 .tpoff32, .tpoff64 => true,
1193 .larch_tpoff32_lo12, .larch_tpoff32_hi20, .larch_tpoff64_lo20, .larch_tpoff64_hi12 => true,
1196 .tpoff32,
1197 .tpoff64,
1198 => true,
1199
1200 .larch_tpoff32_lo12,
1201 .larch_tpoff32_hi20,
1202 .larch_tpoff64_lo20,
1203 .larch_tpoff64_hi12,
1204 => true,
1205
1206 .sparc_le_hix22,
1207 .sparc_le_lox10,
1208 => true,
1209
11941210 else => false,
11951211 };
11961212 }
......@@ -1570,6 +1586,44 @@ const SymbolReloc = struct {
15701586 result.imm13 = @as(u12, @truncate(target_value));
15711587 elf.targetStore(dest_ptr, result);
15721588 },
1589 .sparc_ldo_hix22 => {
1590 const dest_ptr: *link.sparc.reloc.Simm22 = @ptrCast(@alignCast(dest_slice));
1591 var result = elf.targetLoad(dest_ptr);
1592 result.simm22 = @truncate(target_value >> 10);
1593 elf.targetStore(dest_ptr, result);
1594 },
1595 .sparc_ldo_lox10 => {
1596 const dest_ptr: *link.sparc.reloc.Simm13 = @ptrCast(@alignCast(dest_slice));
1597 var result = elf.targetLoad(dest_ptr);
1598 result.simm13 = @as(u10, @truncate(target_value));
1599 elf.targetStore(dest_ptr, result);
1600 },
1601 .sparc_le_hix22 => {
1602 const tls_phndx = elf.getNode(elf.ni.tls).segment;
1603 const tls_size: u64 = switch (elf.phdrSlice()) {
1604 inline else => |phdr| tls_size: {
1605 assert(elf.targetLoad(&phdr[tls_phndx].type) == .TLS);
1606 break :tls_size elf.targetLoad(&phdr[tls_phndx].memsz);
1607 },
1608 };
1609 const dest_ptr: *link.sparc.reloc.Imm22 = @ptrCast(@alignCast(dest_slice));
1610 var result = elf.targetLoad(dest_ptr);
1611 result.imm22 = @truncate(~(target_value -% tls_size) >> 10);
1612 elf.targetStore(dest_ptr, result);
1613 },
1614 .sparc_le_lox10 => {
1615 const tls_phndx = elf.getNode(elf.ni.tls).segment;
1616 const tls_size: u64 = switch (elf.phdrSlice()) {
1617 inline else => |phdr| tls_size: {
1618 assert(elf.targetLoad(&phdr[tls_phndx].type) == .TLS);
1619 break :tls_size elf.targetLoad(&phdr[tls_phndx].memsz);
1620 },
1621 };
1622 const dest_ptr: *link.sparc.reloc.Simm13 = @ptrCast(@alignCast(dest_slice));
1623 var result = elf.targetLoad(dest_ptr);
1624 result.simm13 = @as(u13, 0b1110000000000) | @as(u10, @truncate(target_value -% tls_size));
1625 elf.targetStore(dest_ptr, result);
1626 },
15731627 }
15741628 }
15751629
......@@ -6307,12 +6361,8 @@ fn addRelocAssumeCapacity(
63076361 .TLS_GD_LO10,
63086362 .TLS_GD_CALL,
63096363 .TLS_LDM_CALL,
6310 .TLS_LDO_HIX22,
6311 .TLS_LDO_LOX10,
63126364 .TLS_IE_HI22,
63136365 .TLS_IE_LO10,
6314 .TLS_LE_HIX22,
6315 .TLS_LE_LOX10,
63166366 .TLS_DTPMOD32,
63176367 .TLS_DTPMOD64,
63186368 .H34,
......@@ -6345,6 +6395,10 @@ fn addRelocAssumeCapacity(
63456395 .SIZE64 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .size64),
63466396
63476397 // Relocations targeting a TLS symbol
6398 .TLS_LDO_HIX22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .sparc_ldo_hix22),
6399 .TLS_LDO_LOX10 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .sparc_ldo_lox10),
6400 .TLS_LE_HIX22 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .sparc_le_hix22),
6401 .TLS_LE_LOX10 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .sparc_le_lox10),
63486402 .TLS_DTPOFF32 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .dtpoff32),
63496403 .TLS_DTPOFF64 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .dtpoff64),
63506404 .TLS_TPOFF32 => try elf.addSymbolRelocAssumeCapacity(node, offset, target, addend, .tpoff32),
......@@ -6450,6 +6504,10 @@ fn addSymbolRelocAssumeCapacity(
64506504 .sparc_h44,
64516505 .sparc_m44,
64526506 .sparc_l44,
6507 .sparc_ldo_hix22,
6508 .sparc_ldo_lox10,
6509 .sparc_le_hix22,
6510 .sparc_le_lox10,
64536511 => unreachable,
64546512 } },
64556513 .LOONGARCH => .{ .LOONGARCH = switch (@"type") {
......@@ -6495,6 +6553,10 @@ fn addSymbolRelocAssumeCapacity(
64956553 .sparc_h44,
64966554 .sparc_m44,
64976555 .sparc_l44,
6556 .sparc_ldo_hix22,
6557 .sparc_ldo_lox10,
6558 .sparc_le_hix22,
6559 .sparc_le_lox10,
64986560 => unreachable,
64996561 } },
65006562 .SPARCV9 => .{ .SPARC = switch (@"type") {
......@@ -6541,6 +6603,10 @@ fn addSymbolRelocAssumeCapacity(
65416603 .sparc_h44 => .H44,
65426604 .sparc_m44 => .M44,
65436605 .sparc_l44 => .L44,
6606 .sparc_ldo_hix22 => .TLS_LDO_HIX22,
6607 .sparc_ldo_lox10 => .TLS_LDO_LOX10,
6608 .sparc_le_hix22 => .TLS_LE_HIX22,
6609 .sparc_le_lox10 => .TLS_LE_LOX10,
65446610 } },
65456611 };
65466612