diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 14:20:35 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 22:46:17 +0100 |
| commit | 310cef09724067f4df38b42c928cb120fdc09df8 (patch) | |
| tree | 43a0c6cc166c47a9371edc858b9853b4edb53b3f /src | |
| parent | 109d2321b0d92f20e75dcc0b7074026cefe1090e (diff) | |
| download | zig-310cef09724067f4df38b42c928cb120fdc09df8.tar.gz zig-310cef09724067f4df38b42c928cb120fdc09df8.zip | |
elf+aarch64: handle TLSDESC non-relaxed
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Elf.zig | 3 | ||||
| -rw-r--r-- | src/link/Elf/Atom.zig | 53 |
2 files changed, 48 insertions, 8 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 12f02f9761..78cc434b2f 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2105,7 +2105,6 @@ fn scanRelocs(self: *Elf) !void { } if (sym.flags.needs_tlsdesc) { log.debug("'{s}' needs TLSDESC", .{sym.name(self)}); - try self.dynsym.addSymbol(index, self); try self.got.addTlsDescSymbol(index, self); } } @@ -4497,7 +4496,7 @@ fn writeAtoms(self: *Elf) !void { const buffer = try gpa.alloc(u8, sh_size); defer gpa.free(buffer); const padding_byte: u8 = if (shdr.sh_type == elf.SHT_PROGBITS and - shdr.sh_flags & elf.SHF_EXECINSTR != 0) + shdr.sh_flags & elf.SHF_EXECINSTR != 0 and self.getTarget().cpu.arch == .x86_64) 0xcc // int3 else 0; diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 9a896c1396..00cf419f60 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -1622,6 +1622,22 @@ const aarch64 = struct { } }, + .TLSLE_ADD_TPREL_HI12, + .TLSLE_ADD_TPREL_LO12_NC, + => { + if (is_dyn_lib) try atom.reportPicError(symbol, rel, elf_file); + }, + + .TLSDESC_ADR_PAGE21, + .TLSDESC_LD64_LO12, + .TLSDESC_ADD_LO12, + => { + const should_relax = elf_file.base.isStatic() or (!is_dyn_lib and !symbol.flags.import); + if (!should_relax and true) { // TODO + symbol.flags.needs_tlsdesc = true; + } + }, + .ADD_ABS_LO12_NC, .ADR_PREL_LO21, .LDST8_ABS_LO12_NC, @@ -1629,14 +1645,9 @@ const aarch64 = struct { .LDST32_ABS_LO12_NC, .LDST64_ABS_LO12_NC, .LDST128_ABS_LO12_NC, + .TLSDESC_CALL, => {}, - .TLSLE_ADD_TPREL_HI12, - .TLSLE_ADD_TPREL_LO12_NC, - => { - if (is_dyn_lib) try atom.reportPicError(symbol, rel, elf_file); - }, - else => try atom.reportUnhandledRelocError(rel, elf_file), } } @@ -1757,6 +1768,36 @@ const aarch64 = struct { aarch64_util.writeAddImmInst(@bitCast(value), code[rel.r_offset..][0..4]); }, + .TLSDESC_ADR_PAGE21 => { + assert(target.flags.has_tlsdesc); // TODO relax + const S_: i64 = @intCast(target.tlsDescAddress(elf_file)); + const saddr: u64 = @intCast(P); + const taddr: u64 = @intCast(S_ + A); + relocs_log.debug(" [{x} => {x}]", .{ P, taddr }); + const pages: u21 = @bitCast(try aarch64_util.calcNumberOfPages(saddr, taddr)); + aarch64_util.writeAdrpInst(pages, code[rel.r_offset..][0..4]); + }, + + .TLSDESC_LD64_LO12 => { + const S_: i64 = @intCast(target.tlsDescAddress(elf_file)); + const taddr: u64 = @intCast(S_ + A); + relocs_log.debug(" [{x} => {x}]", .{ P, taddr }); + const offset: u12 = try math.divExact(u12, @truncate(taddr), 8); + aarch64_util.writeLoadStoreRegInst(offset, code[rel.r_offset..][0..4]); + }, + + .TLSDESC_ADD_LO12 => { + const S_: i64 = @intCast(target.tlsDescAddress(elf_file)); + const taddr: u64 = @intCast(S_ + A); + relocs_log.debug(" [{x} => {x}]", .{ P, taddr }); + const offset: u12 = @truncate(taddr); + aarch64_util.writeAddImmInst(offset, code[rel.r_offset..][0..4]); + }, + + .TLSDESC_CALL => if (!target.flags.has_tlsdesc) { + mem.writeInt(u32, code[rel.r_offset..][0..4], aarch64_util.Instruction.nop().toU32(), .little); + }, + else => try atom.reportUnhandledRelocError(rel, elf_file), } } |
