diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-07 23:01:06 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 22:46:17 +0100 |
| commit | c1dbf01aa3e7ee1922762e6f9b86b2ad4c4a7e6f (patch) | |
| tree | 6a2c6b2eba57d235cbf0fba7ded107bdd50a5300 /src | |
| parent | 69f9f359dd5107cd071f3801a6824336b5d2bce6 (diff) | |
| download | zig-c1dbf01aa3e7ee1922762e6f9b86b2ad4c4a7e6f.tar.gz zig-c1dbf01aa3e7ee1922762e6f9b86b2ad4c4a7e6f.zip | |
elf+aarch64: resolve TLS LE model
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Elf/Atom.zig | 20 | ||||
| -rw-r--r-- | src/link/aarch64.zig | 11 |
2 files changed, 30 insertions, 1 deletions
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 5dc5835c9f..71f9d79fac 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -1592,6 +1592,8 @@ const aarch64 = struct { _ = it; const r_type: elf.R_AARCH64 = @enumFromInt(rel.r_type()); + const is_dyn_lib = elf_file.base.isDynLib(); + switch (r_type) { .ABS64 => { try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file); @@ -1629,6 +1631,12 @@ const aarch64 = struct { .LDST128_ABS_LO12_NC, => {}, + .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), } } @@ -1650,7 +1658,6 @@ const aarch64 = struct { const cwriter = stream.writer(); const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; - _ = TP; _ = DTP; _ = ZIG_GOT; @@ -1736,6 +1743,17 @@ const aarch64 = struct { try aarch64_util.writePageOffset(kind, taddr, code[r_offset..][0..4]); }, + .TLSLE_ADD_TPREL_HI12 => { + const value = math.cast(i12, (S + A - TP) >> 12) orelse + return error.Overflow; + try aarch64_util.writeAddInst(@bitCast(value), code[rel.r_offset..][0..4]); + }, + + .TLSLE_ADD_TPREL_LO12_NC => { + const value: i12 = @truncate(S + A - TP); + try aarch64_util.writeAddInst(@bitCast(value), code[rel.r_offset..][0..4]); + }, + else => try atom.reportUnhandledRelocError(rel, elf_file), } } diff --git a/src/link/aarch64.zig b/src/link/aarch64.zig index a9295026d2..273dee7493 100644 --- a/src/link/aarch64.zig +++ b/src/link/aarch64.zig @@ -95,6 +95,17 @@ pub fn writeBranchImm(disp: i28, code: *[4]u8) !void { mem.writeInt(u32, code, inst.toU32(), .little); } +pub fn writeAddInst(value: u12, code: *[4]u8) !void { + var inst = Instruction{ + .add_subtract_immediate = mem.bytesToValue(std.meta.TagPayload( + Instruction, + Instruction.add_subtract_immediate, + ), code), + }; + inst.add_subtract_immediate.imm12 = value; + mem.writeInt(u32, code, inst.toU32(), .little); +} + const assert = std.debug.assert; const bits = @import("../arch/aarch64/bits.zig"); const builtin = @import("builtin"); |
