aboutsummaryrefslogtreecommitdiff
path: root/src/link/Elf
diff options
context:
space:
mode:
authorRue <78876133+IOKG04@users.noreply.github.com>2025-07-28 14:54:52 +0200
committerGitHub <noreply@github.com>2025-07-28 14:54:52 +0200
commit5381e7891dcdd7b6a9e74250cdcce221fe464cdc (patch)
tree4c74744ed84120dccae6dc9811ce945911108a17 /src/link/Elf
parent84ae54fbe64a15301317716e7f901d81585332d5 (diff)
parentdea3ed7f59347e87a1b8fa237202873988084ae8 (diff)
downloadzig-5381e7891dcdd7b6a9e74250cdcce221fe464cdc.tar.gz
zig-5381e7891dcdd7b6a9e74250cdcce221fe464cdc.zip
Merge branch 'ziglang:master' into some-documentation-updates-0
Diffstat (limited to 'src/link/Elf')
-rw-r--r--src/link/Elf/Atom.zig70
-rw-r--r--src/link/Elf/Thunk.zig15
-rw-r--r--src/link/Elf/ZigObject.zig10
-rw-r--r--src/link/Elf/relocation.zig24
-rw-r--r--src/link/Elf/synthetic_sections.zig75
5 files changed, 91 insertions, 103 deletions
diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig
index 5966bae02c..4bb88f2af3 100644
--- a/src/link/Elf/Atom.zig
+++ b/src/link/Elf/Atom.zig
@@ -1627,7 +1627,7 @@ const aarch64 = struct {
const S_ = th.targetAddress(target_index, elf_file);
break :blk math.cast(i28, S_ + A - P) orelse return error.Overflow;
};
- aarch64_util.writeBranchImm(disp, code);
+ util.writeBranchImm(disp, code);
},
.PREL32 => {
@@ -1640,15 +1640,18 @@ const aarch64 = struct {
mem.writeInt(u64, code_buffer[r_offset..][0..8], @bitCast(value), .little);
},
+ .ADR_PREL_LO21 => {
+ const value = math.cast(i21, S + A - P) orelse return error.Overflow;
+ util.writeAdrInst(value, code);
+ },
+
.ADR_PREL_PG_HI21 => {
// TODO: check for relaxation of ADRP+ADD
- const pages = @as(u21, @bitCast(try aarch64_util.calcNumberOfPages(P, S + A)));
- aarch64_util.writeAdrpInst(pages, code);
+ util.writeAdrInst(try util.calcNumberOfPages(P, S + A), code);
},
.ADR_GOT_PAGE => if (target.flags.has_got) {
- const pages = @as(u21, @bitCast(try aarch64_util.calcNumberOfPages(P, G + GOT + A)));
- aarch64_util.writeAdrpInst(pages, code);
+ util.writeAdrInst(try util.calcNumberOfPages(P, G + GOT + A), code);
} else {
// TODO: relax
var err = try diags.addErrorWithNotes(1);
@@ -1663,12 +1666,12 @@ const aarch64 = struct {
.LD64_GOT_LO12_NC => {
assert(target.flags.has_got);
const taddr = @as(u64, @intCast(G + GOT + A));
- aarch64_util.writeLoadStoreRegInst(@divExact(@as(u12, @truncate(taddr)), 8), code);
+ util.writeLoadStoreRegInst(@divExact(@as(u12, @truncate(taddr)), 8), code);
},
.ADD_ABS_LO12_NC => {
const taddr = @as(u64, @intCast(S + A));
- aarch64_util.writeAddImmInst(@truncate(taddr), code);
+ util.writeAddImmInst(@truncate(taddr), code);
},
.LDST8_ABS_LO12_NC,
@@ -1687,57 +1690,54 @@ const aarch64 = struct {
.LDST128_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 16),
else => unreachable,
};
- aarch64_util.writeLoadStoreRegInst(off, code);
+ util.writeLoadStoreRegInst(off, code);
},
.TLSLE_ADD_TPREL_HI12 => {
const value = math.cast(i12, (S + A - TP) >> 12) orelse
return error.Overflow;
- aarch64_util.writeAddImmInst(@bitCast(value), code);
+ util.writeAddImmInst(@bitCast(value), code);
},
.TLSLE_ADD_TPREL_LO12_NC => {
const value: i12 = @truncate(S + A - TP);
- aarch64_util.writeAddImmInst(@bitCast(value), code);
+ util.writeAddImmInst(@bitCast(value), code);
},
.TLSIE_ADR_GOTTPREL_PAGE21 => {
const S_ = target.gotTpAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
- const pages: u21 = @bitCast(try aarch64_util.calcNumberOfPages(P, S_ + A));
- aarch64_util.writeAdrpInst(pages, code);
+ util.writeAdrInst(try util.calcNumberOfPages(P, S_ + A), code);
},
.TLSIE_LD64_GOTTPREL_LO12_NC => {
const S_ = target.gotTpAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
- aarch64_util.writeLoadStoreRegInst(off, code);
+ util.writeLoadStoreRegInst(off, code);
},
.TLSGD_ADR_PAGE21 => {
const S_ = target.tlsGdAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
- const pages: u21 = @bitCast(try aarch64_util.calcNumberOfPages(P, S_ + A));
- aarch64_util.writeAdrpInst(pages, code);
+ util.writeAdrInst(try util.calcNumberOfPages(P, S_ + A), code);
},
.TLSGD_ADD_LO12_NC => {
const S_ = target.tlsGdAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
const off: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
- aarch64_util.writeAddImmInst(off, code);
+ util.writeAddImmInst(off, code);
},
.TLSDESC_ADR_PAGE21 => {
if (target.flags.has_tlsdesc) {
const S_ = target.tlsDescAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
- const pages: u21 = @bitCast(try aarch64_util.calcNumberOfPages(P, S_ + A));
- aarch64_util.writeAdrpInst(pages, code);
+ util.writeAdrInst(try util.calcNumberOfPages(P, S_ + A), code);
} else {
relocs_log.debug(" relaxing adrp => nop", .{});
- mem.writeInt(u32, code, Instruction.nop().toU32(), .little);
+ util.encoding.Instruction.nop().write(code);
}
},
@@ -1746,10 +1746,10 @@ const aarch64 = struct {
const S_ = target.tlsDescAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
- aarch64_util.writeLoadStoreRegInst(off, code);
+ util.writeLoadStoreRegInst(off, code);
} else {
relocs_log.debug(" relaxing ldr => nop", .{});
- mem.writeInt(u32, code, Instruction.nop().toU32(), .little);
+ util.encoding.Instruction.nop().write(code);
}
},
@@ -1758,32 +1758,18 @@ const aarch64 = struct {
const S_ = target.tlsDescAddress(elf_file);
relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
const off: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
- aarch64_util.writeAddImmInst(off, code);
+ util.writeAddImmInst(off, code);
} else {
- const old_inst: Instruction = .{
- .add_subtract_immediate = mem.bytesToValue(@FieldType(
- Instruction,
- @tagName(Instruction.add_subtract_immediate),
- ), code),
- };
- const rd: Register = @enumFromInt(old_inst.add_subtract_immediate.rd);
- relocs_log.debug(" relaxing add({s}) => movz(x0, {x})", .{ @tagName(rd), S + A - TP });
+ relocs_log.debug(" relaxing add => movz(x0, {x})", .{S + A - TP});
const value: u16 = @bitCast(math.cast(i16, (S + A - TP) >> 16) orelse return error.Overflow);
- mem.writeInt(u32, code, Instruction.movz(.x0, value, 16).toU32(), .little);
+ util.encoding.Instruction.movz(.x0, value, .{ .lsl = .@"16" }).write(code);
}
},
.TLSDESC_CALL => if (!target.flags.has_tlsdesc) {
- const old_inst: Instruction = .{
- .unconditional_branch_register = mem.bytesToValue(@FieldType(
- Instruction,
- @tagName(Instruction.unconditional_branch_register),
- ), code),
- };
- const rn: Register = @enumFromInt(old_inst.unconditional_branch_register.rn);
- relocs_log.debug(" relaxing br({s}) => movk(x0, {x})", .{ @tagName(rn), S + A - TP });
+ relocs_log.debug(" relaxing br => movk(x0, {x})", .{S + A - TP});
const value: u16 = @bitCast(@as(i16, @truncate(S + A - TP)));
- mem.writeInt(u32, code, Instruction.movk(.x0, value, 0).toU32(), .little);
+ util.encoding.Instruction.movk(.x0, value, .{}).write(code);
},
else => try atom.reportUnhandledRelocError(rel, elf_file),
@@ -1819,9 +1805,7 @@ const aarch64 = struct {
}
}
- const aarch64_util = @import("../aarch64.zig");
- const Instruction = aarch64_util.Instruction;
- const Register = aarch64_util.Register;
+ const util = @import("../aarch64.zig");
};
const riscv = struct {
diff --git a/src/link/Elf/Thunk.zig b/src/link/Elf/Thunk.zig
index 2af0c9c9d3..59b867be78 100644
--- a/src/link/Elf/Thunk.zig
+++ b/src/link/Elf/Thunk.zig
@@ -95,18 +95,21 @@ const aarch64 = struct {
const sym = elf_file.symbol(ref).?;
const saddr = thunk.address(elf_file) + @as(i64, @intCast(i * trampoline_size));
const taddr = sym.address(.{}, elf_file);
- const pages = try util.calcNumberOfPages(saddr, taddr);
- try writer.writeInt(u32, Instruction.adrp(.x16, pages).toU32(), .little);
- const off: u12 = @truncate(@as(u64, @bitCast(taddr)));
- try writer.writeInt(u32, Instruction.add(.x16, .x16, off, false).toU32(), .little);
- try writer.writeInt(u32, Instruction.br(.x16).toU32(), .little);
+ try writer.writeInt(u32, @bitCast(
+ util.encoding.Instruction.adrp(.x16, try util.calcNumberOfPages(saddr, taddr) << 12),
+ ), .little);
+ try writer.writeInt(u32, @bitCast(util.encoding.Instruction.add(
+ .x16,
+ .x16,
+ .{ .immediate = @truncate(@as(u64, @bitCast(taddr))) },
+ )), .little);
+ try writer.writeInt(u32, @bitCast(util.encoding.Instruction.br(.x16)), .little);
}
}
const trampoline_size = 3 * @sizeOf(u32);
const util = @import("../aarch64.zig");
- const Instruction = util.Instruction;
};
const assert = std.debug.assert;
diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig
index c8f37125ed..f49406b751 100644
--- a/src/link/Elf/ZigObject.zig
+++ b/src/link/Elf/ZigObject.zig
@@ -1270,9 +1270,13 @@ fn updateNavCode(
log.debug("updateNavCode {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
- const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
- const required_alignment = switch (pt.navAlignment(nav_index)) {
- .none => target_util.defaultFunctionAlignment(target),
+ const mod = zcu.navFileScope(nav_index).mod.?;
+ const target = &mod.resolved_target.result;
+ const required_alignment = switch (nav.status.fully_resolved.alignment) {
+ .none => switch (mod.optimize_mode) {
+ .Debug, .ReleaseSafe, .ReleaseFast => target_util.defaultFunctionAlignment(target),
+ .ReleaseSmall => target_util.minFunctionAlignment(target),
+ },
else => |a| a.maxStrict(target_util.minFunctionAlignment(target)),
};
diff --git a/src/link/Elf/relocation.zig b/src/link/Elf/relocation.zig
index 305dcda789..366d19d9b3 100644
--- a/src/link/Elf/relocation.zig
+++ b/src/link/Elf/relocation.zig
@@ -94,14 +94,18 @@ pub fn encode(comptime kind: Kind, cpu_arch: std.Target.Cpu.Arch) u32 {
pub const dwarf = struct {
pub fn crossSectionRelocType(format: DW.Format, cpu_arch: std.Target.Cpu.Arch) u32 {
return switch (cpu_arch) {
- .x86_64 => @intFromEnum(switch (format) {
- .@"32" => elf.R_X86_64.@"32",
+ .x86_64 => @intFromEnum(@as(elf.R_X86_64, switch (format) {
+ .@"32" => .@"32",
.@"64" => .@"64",
- }),
- .riscv64 => @intFromEnum(switch (format) {
- .@"32" => elf.R_RISCV.@"32",
+ })),
+ .aarch64 => @intFromEnum(@as(elf.R_AARCH64, switch (format) {
+ .@"32" => .ABS32,
+ .@"64" => .ABS64,
+ })),
+ .riscv64 => @intFromEnum(@as(elf.R_RISCV, switch (format) {
+ .@"32" => .@"32",
.@"64" => .@"64",
- }),
+ })),
else => @panic("TODO unhandled cpu arch"),
};
}
@@ -121,6 +125,14 @@ pub const dwarf = struct {
},
.debug_frame => .PC32,
})),
+ .aarch64 => @intFromEnum(@as(elf.R_AARCH64, switch (source_section) {
+ else => switch (address_size) {
+ .@"32" => .ABS32,
+ .@"64" => .ABS64,
+ else => unreachable,
+ },
+ .debug_frame => .PREL32,
+ })),
.riscv64 => @intFromEnum(@as(elf.R_RISCV, switch (source_section) {
else => switch (address_size) {
.@"32" => .@"32",
diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig
index 3f2ac7cb16..2ab71d8c49 100644
--- a/src/link/Elf/synthetic_sections.zig
+++ b/src/link/Elf/synthetic_sections.zig
@@ -810,54 +810,43 @@ pub const PltSection = struct {
const got_plt_addr: i64 = @intCast(shdrs[elf_file.section_indexes.got_plt.?].sh_addr);
// TODO: relax if possible
// .got.plt[2]
- const pages = try aarch64_util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16);
- const ldr_off = try math.divExact(u12, @truncate(@as(u64, @bitCast(got_plt_addr + 16))), 8);
+ const pages = try util.calcNumberOfPages(plt_addr + 4, got_plt_addr + 16);
+ const ldr_off: u12 = @truncate(@as(u64, @bitCast(got_plt_addr + 16)));
const add_off: u12 = @truncate(@as(u64, @bitCast(got_plt_addr + 16)));
- const preamble = &[_]Instruction{
- Instruction.stp(
- .x16,
- .x30,
- Register.sp,
- Instruction.LoadStorePairOffset.pre_index(-16),
- ),
- Instruction.adrp(.x16, pages),
- Instruction.ldr(.x17, .x16, Instruction.LoadStoreOffset.imm(ldr_off)),
- Instruction.add(.x16, .x16, add_off, false),
- Instruction.br(.x17),
- Instruction.nop(),
- Instruction.nop(),
- Instruction.nop(),
+ const preamble = [_]util.encoding.Instruction{
+ .stp(.x16, .x30, .{ .pre_index = .{ .base = .sp, .index = -16 } }),
+ .adrp(.x16, pages << 12),
+ .ldr(.x17, .{ .unsigned_offset = .{ .base = .x16, .offset = ldr_off } }),
+ .add(.x16, .x16, .{ .immediate = add_off }),
+ .br(.x17),
+ .nop(),
+ .nop(),
+ .nop(),
};
comptime assert(preamble.len == 8);
- for (preamble) |inst| {
- try writer.writeInt(u32, inst.toU32(), .little);
- }
+ for (preamble) |inst| try writer.writeInt(util.encoding.Instruction.Backing, @bitCast(inst), .little);
}
for (plt.symbols.items) |ref| {
const sym = elf_file.symbol(ref).?;
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 math.divExact(u12, @truncate(@as(u64, @bitCast(target_addr))), 8);
+ const pages = try util.calcNumberOfPages(source_addr, target_addr);
+ const ldr_off: u12 = @truncate(@as(u64, @bitCast(target_addr)));
const add_off: u12 = @truncate(@as(u64, @bitCast(target_addr)));
- const insts = &[_]Instruction{
- Instruction.adrp(.x16, pages),
- Instruction.ldr(.x17, .x16, Instruction.LoadStoreOffset.imm(ldr_off)),
- Instruction.add(.x16, .x16, add_off, false),
- Instruction.br(.x17),
+ const insts = [_]util.encoding.Instruction{
+ .adrp(.x16, pages << 12),
+ .ldr(.x17, .{ .unsigned_offset = .{ .base = .x16, .offset = ldr_off } }),
+ .add(.x16, .x16, .{ .immediate = add_off }),
+ .br(.x17),
};
comptime assert(insts.len == 4);
- for (insts) |inst| {
- try writer.writeInt(u32, inst.toU32(), .little);
- }
+ for (insts) |inst| try writer.writeInt(util.encoding.Instruction.Backing, @bitCast(inst), .little);
}
}
- const aarch64_util = @import("../aarch64.zig");
- const Instruction = aarch64_util.Instruction;
- const Register = aarch64_util.Register;
+ const util = @import("../aarch64.zig");
};
};
@@ -979,24 +968,20 @@ pub const PltGotSection = struct {
const sym = elf_file.symbol(ref).?;
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 math.divExact(u12, @truncate(@as(u64, @bitCast(target_addr))), 8);
- const insts = &[_]Instruction{
- Instruction.adrp(.x16, pages),
- Instruction.ldr(.x17, .x16, Instruction.LoadStoreOffset.imm(off)),
- Instruction.br(.x17),
- Instruction.nop(),
+ const pages = try util.calcNumberOfPages(source_addr, target_addr);
+ const off: u12 = @truncate(@as(u64, @bitCast(target_addr)));
+ const insts = [_]util.encoding.Instruction{
+ .adrp(.x16, pages << 12),
+ .ldr(.x17, .{ .unsigned_offset = .{ .base = .x16, .offset = off } }),
+ .br(.x17),
+ .nop(),
};
comptime assert(insts.len == 4);
- for (insts) |inst| {
- try writer.writeInt(u32, inst.toU32(), .little);
- }
+ for (insts) |inst| try writer.writeInt(util.encoding.Instruction.Backing, @bitCast(inst), .little);
}
}
- const aarch64_util = @import("../aarch64.zig");
- const Instruction = aarch64_util.Instruction;
- const Register = aarch64_util.Register;
+ const util = @import("../aarch64.zig");
};
};