| 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 | 465 | // to ask for more stack space. |
| 466 | 466 | expandStackSize(phdrs); |
| 467 | 467 | |
| 468 | // Disabled with the riscv backend because it cannot handle this code yet. | |
| 469 | if (builtin.zig_backend != .stage2_riscv64) { | |
| 470 | const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{ | |
| 471 | .name = "__init_array_start", | |
| 472 | .linkage = .weak, | |
| 473 | }); | |
| 474 | const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{ | |
| 475 | .name = "__init_array_end", | |
| 476 | .linkage = .weak, | |
| 477 | }); | |
| 478 | if (opt_init_array_start) |init_array_start| { | |
| 479 | const init_array_end = opt_init_array_end.?; | |
| 480 | const slice = init_array_start[0 .. init_array_end - init_array_start]; | |
| 481 | for (slice) |func| func(); | |
| 482 | } | |
| 468 | const opt_init_array_start = @extern([*]*const fn () callconv(.C) void, .{ | |
| 469 | .name = "__init_array_start", | |
| 470 | .linkage = .weak, | |
| 471 | }); | |
| 472 | const opt_init_array_end = @extern([*]*const fn () callconv(.C) void, .{ | |
| 473 | .name = "__init_array_end", | |
| 474 | .linkage = .weak, | |
| 475 | }); | |
| 476 | if (opt_init_array_start) |init_array_start| { | |
| 477 | const init_array_end = opt_init_array_end.?; | |
| 478 | const slice = init_array_start[0 .. init_array_end - init_array_start]; | |
| 479 | for (slice) |func| func(); | |
| 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 | 1510 | .mul, |
| 1511 | 1511 | .mul_wrap, |
| 1512 | 1512 | .div_trunc, |
| 1513 | .div_exact, | |
| 1513 | 1514 | .rem, |
| 1514 | 1515 | |
| 1515 | 1516 | .shl, .shl_exact, |
| ... | ... | @@ -1533,7 +1534,6 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void { |
| 1533 | 1534 | .mod, |
| 1534 | 1535 | .div_float, |
| 1535 | 1536 | .div_floor, |
| 1536 | .div_exact, | |
| 1537 | 1537 | => return func.fail("TODO: {s}", .{@tagName(tag)}), |
| 1538 | 1538 | |
| 1539 | 1539 | .sqrt, |
| ... | ... | @@ -2563,10 +2563,12 @@ fn genBinOp( |
| 2563 | 2563 | .mul_wrap, |
| 2564 | 2564 | .rem, |
| 2565 | 2565 | .div_trunc, |
| 2566 | .div_exact, | |
| 2566 | 2567 | => { |
| 2567 | 2568 | switch (tag) { |
| 2568 | 2569 | .rem, |
| 2569 | 2570 | .div_trunc, |
| 2571 | .div_exact, | |
| 2570 | 2572 | => { |
| 2571 | 2573 | if (!math.isPowerOfTwo(bit_size)) { |
| 2572 | 2574 | try func.truncateRegister(lhs_ty, lhs_reg); |
| ... | ... | @@ -2576,7 +2578,7 @@ fn genBinOp( |
| 2576 | 2578 | else => { |
| 2577 | 2579 | if (!math.isPowerOfTwo(bit_size)) |
| 2578 | 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 | 2582 | .{ @tagName(tag), bit_size }, |
| 2581 | 2583 | ); |
| 2582 | 2584 | }, |
| ... | ... | @@ -2604,7 +2606,7 @@ fn genBinOp( |
| 2604 | 2606 | 8, 16, 32 => if (is_unsigned) .remuw else .remw, |
| 2605 | 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 | 2610 | 8, 16, 32 => if (is_unsigned) .divuw else .divw, |
| 2609 | 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 | 63 | |
| 64 | 64 | hi_r_type = Elf.R_ZIG_GOT_HI20; |
| 65 | 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 | 71 | try atom_ptr.addReloc(elf_file, .{ |
src/link/Elf.zig+30-1| ... | ... | @@ -6059,11 +6059,40 @@ const RelaSection = struct { |
| 6059 | 6059 | }; |
| 6060 | 6060 | const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); |
| 6061 | 6061 | |
| 6062 | // TODO: add comptime check we don't clobber any reloc for any ISA | |
| 6063 | 6062 | pub const R_ZIG_GOT32: u32 = 0xff00; |
| 6064 | 6063 | pub const R_ZIG_GOTPCREL: u32 = 0xff01; |
| 6065 | 6064 | pub const R_ZIG_GOT_HI20: u32 = 0xff02; |
| 6066 | 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 | 6097 | fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 { |
| 6069 | 6098 | return switch (cpu_arch) { |
src/link/Elf/Atom.zig+18-2| ... | ... | @@ -2016,6 +2016,10 @@ const riscv = struct { |
| 2016 | 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 | 2023 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 2020 | 2024 | }, |
| 2021 | 2025 | } |
| ... | ... | @@ -2161,16 +2165,28 @@ const riscv = struct { |
| 2161 | 2165 | // Zig custom relocations |
| 2162 | 2166 | Elf.R_ZIG_GOT_HI20 => { |
| 2163 | 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 | 2169 | riscv_util.writeInstU(code[r_offset..][0..4], disp); |
| 2166 | 2170 | }, |
| 2167 | 2171 | |
| 2168 | 2172 | Elf.R_ZIG_GOT_LO12 => { |
| 2169 | 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 | 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 | 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 | 115 | switch (r_type) { |
| 116 | 116 | Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"), |
| 117 | 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 | 122 | else => switch (ctx.cpu_arch) { |
| 119 | 123 | .x86_64 => try writer.print("R_X86_64_{s}", .{@tagName(@as(elf.R_X86_64, @enumFromInt(r_type)))}), |
| 120 | 124 | .aarch64 => try writer.print("R_AARCH64_{s}", .{@tagName(@as(elf.R_AARCH64, @enumFromInt(r_type)))}), |