diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 14:13:30 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-08 22:46:17 +0100 |
| commit | 109d2321b0d92f20e75dcc0b7074026cefe1090e (patch) | |
| tree | 428ff4af212fdabbe69c552b6358d351c851eb27 /src/link/Elf | |
| parent | c1dbf01aa3e7ee1922762e6f9b86b2ad4c4a7e6f (diff) | |
| download | zig-109d2321b0d92f20e75dcc0b7074026cefe1090e.tar.gz zig-109d2321b0d92f20e75dcc0b7074026cefe1090e.zip | |
link: refactor common aarch64 helpers
Diffstat (limited to 'src/link/Elf')
| -rw-r--r-- | src/link/Elf/Atom.zig | 33 | ||||
| -rw-r--r-- | src/link/Elf/synthetic_sections.zig | 11 |
2 files changed, 24 insertions, 20 deletions
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 71f9d79fac..9a896c1396 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -1689,7 +1689,7 @@ const aarch64 = struct { }); return; }; - try aarch64_util.writeBranchImm(disp, code[r_offset..][0..4]); + aarch64_util.writeBranchImm(disp, code[r_offset..][0..4]); }, .ADR_PREL_PG_HI21 => { @@ -1697,14 +1697,14 @@ const aarch64 = struct { const saddr = @as(u64, @intCast(P)); const taddr = @as(u64, @intCast(S + A)); const pages = @as(u21, @bitCast(try aarch64_util.calcNumberOfPages(saddr, taddr))); - try aarch64_util.writePages(pages, code[r_offset..][0..4]); + aarch64_util.writeAdrpInst(pages, code[r_offset..][0..4]); }, .ADR_GOT_PAGE => if (target.flags.has_got) { const saddr = @as(u64, @intCast(P)); const taddr = @as(u64, @intCast(G + GOT + A)); const pages = @as(u21, @bitCast(try aarch64_util.calcNumberOfPages(saddr, taddr))); - try aarch64_util.writePages(pages, code[r_offset..][0..4]); + aarch64_util.writeAdrpInst(pages, code[r_offset..][0..4]); } else { // TODO: relax var err = try elf_file.addErrorWithNotes(1); @@ -1719,10 +1719,14 @@ const aarch64 = struct { .LD64_GOT_LO12_NC => { assert(target.flags.has_got); const taddr = @as(u64, @intCast(G + GOT + A)); - try aarch64_util.writePageOffset(.load_store_64, taddr, code[r_offset..][0..4]); + aarch64_util.writeLoadStoreRegInst(@divExact(@as(u12, @truncate(taddr)), 8), code[rel.r_offset..][0..4]); + }, + + .ADD_ABS_LO12_NC => { + const taddr = @as(u64, @intCast(S + A)); + aarch64_util.writeAddImmInst(@truncate(taddr), code[rel.r_offset..][0..4]); }, - .ADD_ABS_LO12_NC, .LDST8_ABS_LO12_NC, .LDST16_ABS_LO12_NC, .LDST32_ABS_LO12_NC, @@ -1731,27 +1735,26 @@ const aarch64 = struct { => { // TODO: NC means no overflow check const taddr = @as(u64, @intCast(S + A)); - const kind: aarch64_util.PageOffsetInstKind = switch (r_type) { - .ADD_ABS_LO12_NC => .arithmetic, - .LDST8_ABS_LO12_NC => .load_store_8, - .LDST16_ABS_LO12_NC => .load_store_16, - .LDST32_ABS_LO12_NC => .load_store_32, - .LDST64_ABS_LO12_NC => .load_store_64, - .LDST128_ABS_LO12_NC => .load_store_128, + const offset: u12 = switch (r_type) { + .LDST8_ABS_LO12_NC => @truncate(taddr), + .LDST16_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 2), + .LDST32_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 4), + .LDST64_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 8), + .LDST128_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 16), else => unreachable, }; - try aarch64_util.writePageOffset(kind, taddr, code[r_offset..][0..4]); + aarch64_util.writeLoadStoreRegInst(offset, code[rel.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]); + aarch64_util.writeAddImmInst(@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]); + aarch64_util.writeAddImmInst(@bitCast(value), code[rel.r_offset..][0..4]); }, else => try atom.reportUnhandledRelocError(rel, elf_file), diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig index 289c22d61f..04a3793561 100644 --- a/src/link/Elf/synthetic_sections.zig +++ b/src/link/Elf/synthetic_sections.zig @@ -1028,8 +1028,8 @@ pub const PltSection = struct { // TODO: relax if possible // .got.plt[2] const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16); - const ldr_off = try aarch64_util.calcPageOffset(.load_store_64, got_plt_addr + 16); - const add_off = try aarch64_util.calcPageOffset(.arithmetic, got_plt_addr + 16); + const ldr_off = try math.divExact(u12, @truncate(got_plt_addr + 16), 8); + const add_off: u12 = @truncate(got_plt_addr + 16); const preamble = &[_]Instruction{ Instruction.stp( @@ -1057,8 +1057,8 @@ pub const PltSection = struct { const target_addr = sym.gotPltAddress(elf_file); const source_addr = sym.pltAddress(elf_file); const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr); - const ldr_off = try aarch64_util.calcPageOffset(.load_store_64, target_addr); - const add_off = try aarch64_util.calcPageOffset(.arithmetic, target_addr); + const ldr_off = try math.divExact(u12, @truncate(target_addr), 8); + const add_off: u12 = @truncate(target_addr); const insts = &[_]Instruction{ Instruction.adrp(.x16, pages), Instruction.ldr(.x17, .x16, Instruction.LoadStoreOffset.imm(ldr_off)), @@ -1202,7 +1202,7 @@ pub const PltGotSection = struct { const target_addr = sym.gotAddress(elf_file); const source_addr = sym.pltGotAddress(elf_file); const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr); - const off = try aarch64_util.calcPageOffset(.load_store_64, target_addr); + const off = try math.divExact(u12, @truncate(target_addr), 8); const insts = &[_]Instruction{ Instruction.adrp(.x16, pages), Instruction.ldr(.x17, .x16, Instruction.LoadStoreOffset.imm(off)), @@ -1758,6 +1758,7 @@ fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void { const assert = std.debug.assert; const builtin = @import("builtin"); const elf = std.elf; +const math = std.math; const mem = std.mem; const log = std.log.scoped(.link); const relocation = @import("relocation.zig"); |
