diff options
| author | Rue <78876133+IOKG04@users.noreply.github.com> | 2025-07-28 14:54:52 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-28 14:54:52 +0200 |
| commit | 5381e7891dcdd7b6a9e74250cdcce221fe464cdc (patch) | |
| tree | 4c74744ed84120dccae6dc9811ce945911108a17 /src/link/Elf | |
| parent | 84ae54fbe64a15301317716e7f901d81585332d5 (diff) | |
| parent | dea3ed7f59347e87a1b8fa237202873988084ae8 (diff) | |
| download | zig-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.zig | 70 | ||||
| -rw-r--r-- | src/link/Elf/Thunk.zig | 15 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 10 | ||||
| -rw-r--r-- | src/link/Elf/relocation.zig | 24 | ||||
| -rw-r--r-- | src/link/Elf/synthetic_sections.zig | 75 |
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"); }; }; |
