aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2024-03-08 14:13:30 +0100
committerJakub Konka <kubkon@jakubkonka.com>2024-03-08 22:46:17 +0100
commit109d2321b0d92f20e75dcc0b7074026cefe1090e (patch)
tree428ff4af212fdabbe69c552b6358d351c851eb27 /src/link/Elf
parentc1dbf01aa3e7ee1922762e6f9b86b2ad4c4a7e6f (diff)
downloadzig-109d2321b0d92f20e75dcc0b7074026cefe1090e.tar.gz
zig-109d2321b0d92f20e75dcc0b7074026cefe1090e.zip
link: refactor common aarch64 helpers
Diffstat (limited to 'src/link/Elf')
-rw-r--r--src/link/Elf/Atom.zig33
-rw-r--r--src/link/Elf/synthetic_sections.zig11
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");