| author | |
| committer | |
| log | 8ea323822ba1fc2f54940841b2cedb3494230a3c |
| tree | 6ba1a9006af4f9e0e7737310cd646f4f836edf8e |
| parent | eb1a199dff2b54271bd275c2528bdd898bf1d4eb |
| parent | 2b8a71489a24649342e797f609fc6bb1b141a422 |
| signature |
6 files changed, 72 insertions(+), 21 deletions(-)
lib/std/start.zig+12-15| ... | @@ -465,21 +465,18 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn { | ... | @@ -465,21 +465,18 @@ fn posixCallMainAndExit(argc_argv_ptr: [*]usize) callconv(.C) noreturn { |
| 465 | // to ask for more stack space. | 465 | // to ask for more stack space. |
| 466 | expandStackSize(phdrs); | 466 | expandStackSize(phdrs); |
| 467 | 467 | ||
| 468 | // Disabled with the riscv backend because it cannot handle this code yet. | 468 | const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{ |
| 469 | if (builtin.zig_backend != .stage2_riscv64) { | 469 | .name = "__init_array_start", |
| 470 | const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{ | 470 | .linkage = .weak, |
| 471 | .name = "__init_array_start", | 471 | }); |
| 472 | .linkage = .weak, | 472 | const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{ |
| 473 | }); | 473 | .name = "__init_array_end", |
| 474 | const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{ | 474 | .linkage = .weak, |
| 475 | .name = "__init_array_end", | 475 | }); |
| 476 | .linkage = .weak, | 476 | if (opt_init_array_start) |init_array_start| { |
| 477 | }); | 477 | const init_array_end = opt_init_array_end.?; |
| 478 | if (opt_init_array_start) |init_array_start| { | 478 | const slice = init_array_start[0 .. init_array_end - init_array_start]; |
| 479 | const init_array_end = opt_init_array_end.?; | 479 | for (slice) |func| func(); |
| 480 | const slice = init_array_start[0 .. init_array_end - init_array_start]; | ||
| 481 | for (slice) |func| func(); | ||
| 482 | } | ||
| 483 | } | 480 | } |
| 484 | } | 481 | } |
| 485 | 482 |
src/arch/riscv64/CodeGen.zig+5-3| ... | @@ -1510,6 +1510,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1510,6 +1510,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1510 | .mul, | 1510 | .mul, |
| 1511 | .mul_wrap, | 1511 | .mul_wrap, |
| 1512 | .div_trunc, | 1512 | .div_trunc, |
| 1513 | .div_exact, | ||
| 1513 | .rem, | 1514 | .rem, |
| 1514 | 1515 | ||
| 1515 | .shl, .shl_exact, | 1516 | .shl, .shl_exact, |
| ... | @@ -1533,7 +1534,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1533,7 +1534,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1533 | .mod, | 1534 | .mod, |
| 1534 | .div_float, | 1535 | .div_float, |
| 1535 | .div_floor, | 1536 | .div_floor, |
| 1536 | .div_exact, | ||
| 1537 | => return func.fail("TODO: {s}", .{@tagName(tag)}), | 1537 | => return func.fail("TODO: {s}", .{@tagName(tag)}), |
| 1538 | 1538 | ||
| 1539 | .sqrt, | 1539 | .sqrt, |
| ... | @@ -2563,10 +2563,12 @@ fn genBinOp( | ... | @@ -2563,10 +2563,12 @@ fn genBinOp( |
| 2563 | .mul_wrap, | 2563 | .mul_wrap, |
| 2564 | .rem, | 2564 | .rem, |
| 2565 | .div_trunc, | 2565 | .div_trunc, |
| 2566 | .div_exact, | ||
| 2566 | => { | 2567 | => { |
| 2567 | switch (tag) { | 2568 | switch (tag) { |
| 2568 | .rem, | 2569 | .rem, |
| 2569 | .div_trunc, | 2570 | .div_trunc, |
| 2571 | .div_exact, | ||
| 2570 | => { | 2572 | => { |
| 2571 | if (!math.isPowerOfTwo(bit_size)) { | 2573 | if (!math.isPowerOfTwo(bit_size)) { |
| 2572 | try func.truncateRegister(lhs_ty, lhs_reg); | 2574 | try func.truncateRegister(lhs_ty, lhs_reg); |
| ... | @@ -2576,7 +2578,7 @@ fn genBinOp( | ... | @@ -2576,7 +2578,7 @@ fn genBinOp( |
| 2576 | else => { | 2578 | else => { |
| 2577 | if (!math.isPowerOfTwo(bit_size)) | 2579 | if (!math.isPowerOfTwo(bit_size)) |
| 2578 | return func.fail( | 2580 | return func.fail( |
| 2579 | "TODO: genBinOp verify {s} non-pow 2, found {}", | 2581 | "TODO: genBinOp verify if needs to truncate {s} non-pow 2, found {}", |
| 2580 | .{ @tagName(tag), bit_size }, | 2582 | .{ @tagName(tag), bit_size }, |
| 2581 | ); | 2583 | ); |
| 2582 | }, | 2584 | }, |
| ... | @@ -2604,7 +2606,7 @@ fn genBinOp( | ... | @@ -2604,7 +2606,7 @@ fn genBinOp( |
| 2604 | 8, 16, 32 => if (is_unsigned) .remuw else .remw, | 2606 | 8, 16, 32 => if (is_unsigned) .remuw else .remw, |
| 2605 | else => if (is_unsigned) .remu else .rem, | 2607 | else => if (is_unsigned) .remu else .rem, |
| 2606 | }, | 2608 | }, |
| 2607 | .div_trunc => switch (bit_size) { | 2609 | .div_trunc, .div_exact => switch (bit_size) { |
| 2608 | 8, 16, 32 => if (is_unsigned) .divuw else .divw, | 2610 | 8, 16, 32 => if (is_unsigned) .divuw else .divw, |
| 2609 | else => if (is_unsigned) .divu else .div, | 2611 | else => if (is_unsigned) .divu else .div, |
| 2610 | }, | 2612 | }, |
src/arch/riscv64/Emit.zig+3| ... | @@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -63,6 +63,9 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 63 | 63 | ||
| 64 | hi_r_type = Elf.R_ZIG_GOT_HI20; | 64 | hi_r_type = Elf.R_ZIG_GOT_HI20; |
| 65 | lo_r_type = Elf.R_ZIG_GOT_LO12; | 65 | lo_r_type = Elf.R_ZIG_GOT_LO12; |
| 66 | } else if (sym.flags.needs_got) { | ||
| 67 | hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887 | ||
| 68 | lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887 | ||
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | try atom_ptr.addReloc(elf_file, .{ | 71 | try atom_ptr.addReloc(elf_file, .{ |
src/link/Elf.zig+30-1| ... | @@ -6059,11 +6059,40 @@ const RelaSection = struct { | ... | @@ -6059,11 +6059,40 @@ const RelaSection = struct { |
| 6059 | }; | 6059 | }; |
| 6060 | const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); | 6060 | const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); |
| 6061 | 6061 | ||
| 6062 | // TODO: add comptime check we don't clobber any reloc for any ISA | ||
| 6063 | pub const R_ZIG_GOT32: u32 = 0xff00; | 6062 | pub const R_ZIG_GOT32: u32 = 0xff00; |
| 6064 | pub const R_ZIG_GOTPCREL: u32 = 0xff01; | 6063 | pub const R_ZIG_GOTPCREL: u32 = 0xff01; |
| 6065 | pub const R_ZIG_GOT_HI20: u32 = 0xff02; | 6064 | pub const R_ZIG_GOT_HI20: u32 = 0xff02; |
| 6066 | pub const R_ZIG_GOT_LO12: u32 = 0xff03; | 6065 | pub const R_ZIG_GOT_LO12: u32 = 0xff03; |
| 6066 | pub const R_GOT_HI20_STATIC: u32 = 0xff04; | ||
| 6067 | pub const R_GOT_LO12_I_STATIC: u32 = 0xff05; | ||
| 6068 | |||
| 6069 | // Comptime asserts that no Zig relocs overlap with another ISA's reloc number | ||
| 6070 | comptime { | ||
| 6071 | const zig_relocs = .{ | ||
| 6072 | R_ZIG_GOT32, | ||
| 6073 | R_ZIG_GOT_HI20, | ||
| 6074 | R_ZIG_GOT_LO12, | ||
| 6075 | R_ZIG_GOTPCREL, | ||
| 6076 | R_GOT_HI20_STATIC, | ||
| 6077 | R_GOT_LO12_I_STATIC, | ||
| 6078 | }; | ||
| 6079 | |||
| 6080 | const other_relocs = .{ | ||
| 6081 | elf.R_X86_64, | ||
| 6082 | elf.R_AARCH64, | ||
| 6083 | elf.R_RISCV, | ||
| 6084 | elf.R_PPC64, | ||
| 6085 | }; | ||
| 6086 | |||
| 6087 | @setEvalBranchQuota(@min(other_relocs.len * zig_relocs.len * 256, 6200)); | ||
| 6088 | for (other_relocs) |relocs| { | ||
| 6089 | for (@typeInfo(relocs).Enum.fields) |reloc| { | ||
| 6090 | for (zig_relocs) |zig_reloc| { | ||
| 6091 | assert(reloc.value != zig_reloc); | ||
| 6092 | } | ||
| 6093 | } | ||
| 6094 | } | ||
| 6095 | } | ||
| 6067 | 6096 | ||
| 6068 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { | 6097 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { |
| 6069 | return switch (cpu_arch) { | 6098 | return switch (cpu_arch) { |
src/link/Elf/Atom.zig+18-2| ... | @@ -2016,6 +2016,10 @@ const riscv = struct { | ... | @@ -2016,6 +2016,10 @@ const riscv = struct { |
| 2016 | assert(symbol.flags.has_zig_got); | 2016 | assert(symbol.flags.has_zig_got); |
| 2017 | }, | 2017 | }, |
| 2018 | 2018 | ||
| 2019 | Elf.R_GOT_HI20_STATIC, | ||
| 2020 | Elf.R_GOT_LO12_I_STATIC, | ||
| 2021 | => symbol.flags.needs_got = true, | ||
| 2022 | |||
| 2019 | else => try atom.reportUnhandledRelocError(rel, elf_file), | 2023 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 2020 | }, | 2024 | }, |
| 2021 | } | 2025 | } |
| ... | @@ -2161,16 +2165,28 @@ const riscv = struct { | ... | @@ -2161,16 +2165,28 @@ const riscv = struct { |
| 2161 | // Zig custom relocations | 2165 | // Zig custom relocations |
| 2162 | Elf.R_ZIG_GOT_HI20 => { | 2166 | Elf.R_ZIG_GOT_HI20 => { |
| 2163 | assert(target.flags.has_zig_got); | 2167 | assert(target.flags.has_zig_got); |
| 2164 | const disp: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow); | 2168 | const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); |
| 2165 | riscv_util.writeInstU(code[r_offset..][0..4], disp); | 2169 | riscv_util.writeInstU(code[r_offset..][0..4], disp); |
| 2166 | }, | 2170 | }, |
| 2167 | 2171 | ||
| 2168 | Elf.R_ZIG_GOT_LO12 => { | 2172 | Elf.R_ZIG_GOT_LO12 => { |
| 2169 | assert(target.flags.has_zig_got); | 2173 | assert(target.flags.has_zig_got); |
| 2170 | const value: u32 = @bitCast(math.cast(i32, G + ZIG_GOT + A) orelse return error.Overflow); | 2174 | const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); |
| 2171 | riscv_util.writeInstI(code[r_offset..][0..4], value); | 2175 | riscv_util.writeInstI(code[r_offset..][0..4], value); |
| 2172 | }, | 2176 | }, |
| 2173 | 2177 | ||
| 2178 | Elf.R_GOT_HI20_STATIC => { | ||
| 2179 | assert(target.flags.has_got); | ||
| 2180 | const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow); | ||
| 2181 | riscv_util.writeInstU(code[r_offset..][0..4], disp); | ||
| 2182 | }, | ||
| 2183 | |||
| 2184 | Elf.R_GOT_LO12_I_STATIC => { | ||
| 2185 | assert(target.flags.has_got); | ||
| 2186 | const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow); | ||
| 2187 | riscv_util.writeInstI(code[r_offset..][0..4], disp); | ||
| 2188 | }, | ||
| 2189 | |||
| 2174 | else => try atom.reportUnhandledRelocError(rel, elf_file), | 2190 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 2175 | }, | 2191 | }, |
| 2176 | } | 2192 | } |
src/link/Elf/relocation.zig+4| ... | @@ -115,6 +115,10 @@ fn formatRelocType( | ... | @@ -115,6 +115,10 @@ fn formatRelocType( |
| 115 | switch (r_type) { | 115 | switch (r_type) { |
| 116 | Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"), | 116 | Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"), |
| 117 | Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"), | 117 | Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"), |
| 118 | Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"), | ||
| 119 | Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"), | ||
| 120 | Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"), | ||
| 121 | Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"), | ||
| 118 | else => switch (ctx.cpu_arch) { | 122 | else => switch (ctx.cpu_arch) { |
| 119 | .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}), | 123 | .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}), |
| 120 | .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}), | 124 | .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}), |