| author | |
| committer | |
| log | fe8bdf6f049e59cffe0033baa4d1738a64fd21cf |
| tree | 8d37291f9b748a43fb63847e861643913d6df6a9 |
| parent | c71b78eb0196cbad9fbb01ce9137d09796b48726 |
Closes #231318 files changed, 40 insertions(+), 32 deletions(-)
src/Zcu/PerThread.zig+2-2| ... | ... | @@ -1705,7 +1705,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai |
| 1705 | 1705 | lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) { |
| 1706 | 1706 | error.OutOfMemory => return error.OutOfMemory, |
| 1707 | 1707 | error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), |
| 1708 | error.Overflow => { | |
| 1708 | error.Overflow, error.RelocationNotByteAligned => { | |
| 1709 | 1709 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( |
| 1710 | 1710 | gpa, |
| 1711 | 1711 | zcu.navSrcLoc(nav_index), |
| ... | ... | @@ -3131,7 +3131,7 @@ pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error |
| 3131 | 3131 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 3132 | 3132 | error.OutOfMemory => return error.OutOfMemory, |
| 3133 | 3133 | error.CodegenFail => assert(zcu.failed_codegen.contains(nav_index)), |
| 3134 | error.Overflow => { | |
| 3134 | error.Overflow, error.RelocationNotByteAligned => { | |
| 3135 | 3135 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( |
| 3136 | 3136 | gpa, |
| 3137 | 3137 | zcu.navSrcLoc(nav_index), |
src/codegen.zig+15-10| ... | ... | @@ -23,10 +23,7 @@ const Zir = std.zig.Zir; |
| 23 | 23 | const Alignment = InternPool.Alignment; |
| 24 | 24 | const dev = @import("dev.zig"); |
| 25 | 25 | |
| 26 | pub const CodeGenError = error{ | |
| 27 | OutOfMemory, | |
| 28 | /// Compiler was asked to operate on a number larger than supported. | |
| 29 | Overflow, | |
| 26 | pub const CodeGenError = GenerateSymbolError || error{ | |
| 30 | 27 | /// Indicates the error is already stored in Zcu `failed_codegen`. |
| 31 | 28 | CodegenFail, |
| 32 | 29 | }; |
| ... | ... | @@ -177,6 +174,8 @@ pub const GenerateSymbolError = error{ |
| 177 | 174 | OutOfMemory, |
| 178 | 175 | /// Compiler was asked to operate on a number larger than supported. |
| 179 | 176 | Overflow, |
| 177 | /// Compiler was asked to produce a non-byte-aligned relocation. | |
| 178 | RelocationNotByteAligned, | |
| 180 | 179 | }; |
| 181 | 180 | |
| 182 | 181 | pub fn generateSymbol( |
| ... | ... | @@ -481,12 +480,18 @@ pub fn generateSymbol( |
| 481 | 480 | // pointer may point to a decl which must be marked used |
| 482 | 481 | // but can also result in a relocation. Therefore we handle those separately. |
| 483 | 482 | if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .pointer) { |
| 484 | const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(zcu)) orelse | |
| 485 | return error.Overflow; | |
| 486 | var tmp_list = try std.ArrayListUnmanaged(u8).initCapacity(gpa, field_size); | |
| 487 | defer tmp_list.deinit(gpa); | |
| 488 | try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent); | |
| 489 | @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items); | |
| 483 | const field_offset = std.math.divExact(u16, bits, 8) catch |err| switch (err) { | |
| 484 | error.DivisionByZero => unreachable, | |
| 485 | error.UnexpectedRemainder => return error.RelocationNotByteAligned, | |
| 486 | }; | |
| 487 | code.items.len = current_pos + field_offset; | |
| 488 | // TODO: code.lockPointers(); | |
| 489 | defer { | |
| 490 | assert(code.items.len == current_pos + field_offset + @divExact(target.ptrBitWidth(), 8)); | |
| 491 | // TODO: code.unlockPointers(); | |
| 492 | code.items.len = current_pos + abi_size; | |
| 493 | } | |
| 494 | try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent); | |
| 490 | 495 | } else { |
| 491 | 496 | Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable; |
| 492 | 497 | } |
src/link.zig+3-8| ... | ... | @@ -26,6 +26,7 @@ const Package = @import("Package.zig"); |
| 26 | 26 | const dev = @import("dev.zig"); |
| 27 | 27 | const ThreadSafeQueue = @import("ThreadSafeQueue.zig").ThreadSafeQueue; |
| 28 | 28 | const target_util = @import("target.zig"); |
| 29 | const codegen = @import("codegen.zig"); | |
| 29 | 30 | |
| 30 | 31 | pub const LdScript = @import("link/LdScript.zig"); |
| 31 | 32 | |
| ... | ... | @@ -683,13 +684,7 @@ pub const File = struct { |
| 683 | 684 | |
| 684 | 685 | /// Note that `LinkFailure` is not a member of this error set because the error message |
| 685 | 686 | /// must be attached to `Zcu.failed_codegen` rather than `Compilation.link_diags`. |
| 686 | pub const UpdateNavError = error{ | |
| 687 | Overflow, | |
| 688 | OutOfMemory, | |
| 689 | /// Indicates the error is already reported and stored in | |
| 690 | /// `failed_codegen` on the Zcu. | |
| 691 | CodegenFail, | |
| 692 | }; | |
| 687 | pub const UpdateNavError = codegen.CodeGenError; | |
| 693 | 688 | |
| 694 | 689 | /// Called from within CodeGen to retrieve the symbol index of a global symbol. |
| 695 | 690 | /// If no symbol exists yet with this name, a new undefined global symbol will |
| ... | ... | @@ -920,7 +915,7 @@ pub const File = struct { |
| 920 | 915 | decl_val: InternPool.Index, |
| 921 | 916 | decl_align: InternPool.Alignment, |
| 922 | 917 | src_loc: Zcu.LazySrcLoc, |
| 923 | ) !@import("codegen.zig").GenResult { | |
| 918 | ) !codegen.GenResult { | |
| 924 | 919 | switch (base.tag) { |
| 925 | 920 | .c => unreachable, |
| 926 | 921 | .spirv => unreachable, |
src/link/Coff.zig+1-1| ... | ... | @@ -1134,7 +1134,7 @@ pub fn updateFunc( |
| 1134 | 1134 | ) catch |err| switch (err) { |
| 1135 | 1135 | error.CodegenFail => return error.CodegenFail, |
| 1136 | 1136 | error.OutOfMemory => return error.OutOfMemory, |
| 1137 | error.Overflow => |e| { | |
| 1137 | error.Overflow, error.RelocationNotByteAligned => |e| { | |
| 1138 | 1138 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, try Zcu.ErrorMsg.create( |
| 1139 | 1139 | gpa, |
| 1140 | 1140 | zcu.navSrcLoc(nav_index), |
src/link/Dwarf.zig+1-2| ... | ... | @@ -23,12 +23,11 @@ debug_str: StringSection, |
| 23 | 23 | pub const UpdateError = error{ |
| 24 | 24 | ReinterpretDeclRef, |
| 25 | 25 | Unimplemented, |
| 26 | OutOfMemory, | |
| 27 | 26 | EndOfStream, |
| 28 | Overflow, | |
| 29 | 27 | Underflow, |
| 30 | 28 | UnexpectedEndOfFile, |
| 31 | 29 | } || |
| 30 | codegen.GenerateSymbolError || | |
| 32 | 31 | std.fs.File.OpenError || |
| 33 | 32 | std.fs.File.SetEndPosError || |
| 34 | 33 | std.fs.File.CopyRangeError || |
src/link/Plan9.zig+3-1| ... | ... | @@ -1090,7 +1090,9 @@ fn updateLazySymbolAtom( |
| 1090 | 1090 | ) catch |err| switch (err) { |
| 1091 | 1091 | error.OutOfMemory => return error.OutOfMemory, |
| 1092 | 1092 | error.CodegenFail => return error.LinkFailure, |
| 1093 | error.Overflow => return diags.fail("codegen failure: encountered number too big for compiler", .{}), | |
| 1093 | error.Overflow, | |
| 1094 | error.RelocationNotByteAligned, | |
| 1095 | => return diags.fail("unable to codegen: {s}", .{@errorName(err)}), | |
| 1094 | 1096 | }; |
| 1095 | 1097 | const code = code_buffer.items; |
| 1096 | 1098 | // duped_code is freed when the atom is freed |
src/register_manager.zig+1-8| ... | ... | @@ -14,14 +14,7 @@ const link = @import("link.zig"); |
| 14 | 14 | |
| 15 | 15 | const log = std.log.scoped(.register_manager); |
| 16 | 16 | |
| 17 | pub const AllocationError = error{ | |
| 18 | OutOfRegisters, | |
| 19 | OutOfMemory, | |
| 20 | /// Compiler was asked to operate on a number larger than supported. | |
| 21 | Overflow, | |
| 22 | /// Indicates the error is already stored in `failed_codegen` on the Zcu. | |
| 23 | CodegenFail, | |
| 24 | }; | |
| 17 | pub const AllocationError = @import("codegen.zig").CodeGenError || error{OutOfRegisters}; | |
| 25 | 18 | |
| 26 | 19 | pub fn RegisterManager( |
| 27 | 20 | comptime Function: type, |
test/behavior/packed-struct.zig+14| ... | ... | @@ -1349,3 +1349,17 @@ test "assign packed struct initialized with RLS to packed struct literal field" |
| 1349 | 1349 | try expect(outer.inner.x == x); |
| 1350 | 1350 | try expect(outer.x == x); |
| 1351 | 1351 | } |
| 1352 | ||
| 1353 | test "byte-aligned packed relocation" { | |
| 1354 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | |
| 1355 | if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; | |
| 1356 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 1357 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | |
| 1358 | ||
| 1359 | const S = struct { | |
| 1360 | var global: u8 align(2) = 0; | |
| 1361 | var packed_value: packed struct { x: u8, y: *align(2) u8 } = .{ .x = 111, .y = &global }; | |
| 1362 | }; | |
| 1363 | try expect(S.packed_value.x == 111); | |
| 1364 | try expect(S.packed_value.y == &S.global); | |
| 1365 | } |