diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2025-03-22 21:56:32 -0400 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-03-23 18:35:34 -0400 |
| commit | 6705cbd5eb8f242a567e24ec21cd3c9b82eb3343 (patch) | |
| tree | 821c4e5f2fe7f7b695b0b24045b904114fde0344 /src/codegen.zig | |
| parent | f45f9649e3fc2aa2b6a76476f2467f02ffc7d461 (diff) | |
| download | zig-6705cbd5eb8f242a567e24ec21cd3c9b82eb3343.tar.gz zig-6705cbd5eb8f242a567e24ec21cd3c9b82eb3343.zip | |
codegen: fix packed byte-aligned relocations
Closes #23131
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index ad241d047d..bad8a97f1c 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -23,10 +23,7 @@ const Zir = std.zig.Zir; const Alignment = InternPool.Alignment; const dev = @import("dev.zig"); -pub const CodeGenError = error{ - OutOfMemory, - /// Compiler was asked to operate on a number larger than supported. - Overflow, +pub const CodeGenError = GenerateSymbolError || error{ /// Indicates the error is already stored in Zcu `failed_codegen`. CodegenFail, }; @@ -177,6 +174,8 @@ pub const GenerateSymbolError = error{ OutOfMemory, /// Compiler was asked to operate on a number larger than supported. Overflow, + /// Compiler was asked to produce a non-byte-aligned relocation. + RelocationNotByteAligned, }; pub fn generateSymbol( @@ -481,12 +480,18 @@ pub fn generateSymbol( // pointer may point to a decl which must be marked used // but can also result in a relocation. Therefore we handle those separately. if (Type.fromInterned(field_ty).zigTypeTag(zcu) == .pointer) { - const field_size = math.cast(usize, Type.fromInterned(field_ty).abiSize(zcu)) orelse - return error.Overflow; - var tmp_list = try std.ArrayListUnmanaged(u8).initCapacity(gpa, field_size); - defer tmp_list.deinit(gpa); - try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent); - @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items); + const field_offset = std.math.divExact(u16, bits, 8) catch |err| switch (err) { + error.DivisionByZero => unreachable, + error.UnexpectedRemainder => return error.RelocationNotByteAligned, + }; + code.items.len = current_pos + field_offset; + // TODO: code.lockPointers(); + defer { + assert(code.items.len == current_pos + field_offset + @divExact(target.ptrBitWidth(), 8)); + // TODO: code.unlockPointers(); + code.items.len = current_pos + abi_size; + } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent); } else { Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable; } |
